mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1159973 - Abort parsing when TokenStream::SourceCoords hits OOM. r=jorendorff
This commit is contained in:
parent
487c6066bb
commit
eb05619abf
@ -2289,7 +2289,8 @@ js::LookupAsmJSModuleInCache(ExclusiveContext* cx,
|
||||
if (!atEnd)
|
||||
return true;
|
||||
|
||||
parser.tokenStream.advance(module->srcEndBeforeCurly());
|
||||
if (!parser.tokenStream.advance(module->srcEndBeforeCurly()))
|
||||
return false;
|
||||
|
||||
{
|
||||
// Delay flushing until dynamic linking.
|
||||
|
@ -417,7 +417,10 @@ bool
|
||||
BytecodeEmitter::updateLineNumberNotes(uint32_t offset)
|
||||
{
|
||||
TokenStream* ts = &parser->tokenStream;
|
||||
if (!ts->srcCoords.isOnThisLine(offset, currentLine())) {
|
||||
bool onThisLine;
|
||||
if (!ts->srcCoords.isOnThisLine(offset, currentLine(), &onThisLine))
|
||||
return ts->reportError(JSMSG_OUT_OF_MEMORY);
|
||||
if (!onThisLine) {
|
||||
unsigned line = ts->srcCoords.lineNum(offset);
|
||||
unsigned delta = line - currentLine();
|
||||
|
||||
|
@ -1971,7 +1971,8 @@ Parser<FullParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
||||
// while LazyScript::{begin,end} offsets are relative to the outermost
|
||||
// script source.
|
||||
uint32_t userbufBase = lazyOuter->begin() - lazyOuter->column();
|
||||
tokenStream.advance(fun->lazyScript()->end() - userbufBase);
|
||||
if (!tokenStream.advance(fun->lazyScript()->end() - userbufBase))
|
||||
return false;
|
||||
|
||||
*pbodyProcessed = true;
|
||||
return true;
|
||||
|
@ -162,7 +162,7 @@ TokenStream::SourceCoords::SourceCoords(ExclusiveContext* cx, uint32_t ln)
|
||||
lineStartOffsets_.infallibleAppend(maxPtr);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
TokenStream::SourceCoords::add(uint32_t lineNum, uint32_t lineStartOffset)
|
||||
{
|
||||
uint32_t lineIndex = lineNumToIndex(lineNum);
|
||||
@ -171,21 +171,21 @@ TokenStream::SourceCoords::add(uint32_t lineNum, uint32_t lineStartOffset)
|
||||
MOZ_ASSERT(lineStartOffsets_[0] == 0 && lineStartOffsets_[sentinelIndex] == MAX_PTR);
|
||||
|
||||
if (lineIndex == sentinelIndex) {
|
||||
// We haven't seen this newline before. Update lineStartOffsets_.
|
||||
// We ignore any failures due to OOM -- because we always have a
|
||||
// sentinel node, it'll just be like the newline wasn't present. I.e.
|
||||
// the line numbers will be wrong, but the code won't crash or anything
|
||||
// like that.
|
||||
lineStartOffsets_[lineIndex] = lineStartOffset;
|
||||
|
||||
// We haven't seen this newline before. Update lineStartOffsets_
|
||||
// only if lineStartOffsets_.append succeeds, to keep sentinel.
|
||||
// Otherwise return false to tell TokenStream about OOM.
|
||||
uint32_t maxPtr = MAX_PTR;
|
||||
(void)lineStartOffsets_.append(maxPtr);
|
||||
if (!lineStartOffsets_.append(maxPtr))
|
||||
return false;
|
||||
|
||||
lineStartOffsets_[lineIndex] = lineStartOffset;
|
||||
} else {
|
||||
// We have seen this newline before (and ungot it). Do nothing (other
|
||||
// than checking it hasn't mysteriously changed).
|
||||
MOZ_ASSERT(lineStartOffsets_[lineIndex] == lineStartOffset);
|
||||
// This path can be executed after hitting OOM, so check lineIndex.
|
||||
MOZ_ASSERT_IF(lineIndex < sentinelIndex, lineStartOffsets_[lineIndex] == lineStartOffset);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
@ -360,7 +360,8 @@ TokenStream::updateLineInfoForEOL()
|
||||
prevLinebase = linebase;
|
||||
linebase = userbuf.offset();
|
||||
lineno++;
|
||||
srcCoords.add(lineno, linebase);
|
||||
if (!srcCoords.add(lineno, linebase))
|
||||
flags.hitOOM = true;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void
|
||||
@ -493,7 +494,7 @@ TokenStream::TokenBuf::findEOLMax(size_t start, size_t max)
|
||||
return start + n;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
TokenStream::advance(size_t position)
|
||||
{
|
||||
const char16_t* end = userbuf.rawCharPtrAt(position);
|
||||
@ -504,6 +505,11 @@ TokenStream::advance(size_t position)
|
||||
cur->pos.begin = userbuf.offset();
|
||||
MOZ_MAKE_MEM_UNDEFINED(&cur->type, sizeof(cur->type));
|
||||
lookahead = 0;
|
||||
|
||||
if (flags.hitOOM)
|
||||
return reportError(JSMSG_OUT_OF_MEMORY);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1631,6 +1637,9 @@ TokenStream::getTokenInternal(TokenKind* ttp, Modifier modifier)
|
||||
MOZ_CRASH("should have jumped to |out| or |error|");
|
||||
|
||||
out:
|
||||
if (flags.hitOOM)
|
||||
return reportError(JSMSG_OUT_OF_MEMORY);
|
||||
|
||||
flags.isDirtyLine = true;
|
||||
tp->pos.end = userbuf.offset();
|
||||
MOZ_ASSERT(IsTokenSane(tp));
|
||||
@ -1638,6 +1647,9 @@ TokenStream::getTokenInternal(TokenKind* ttp, Modifier modifier)
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (flags.hitOOM)
|
||||
return reportError(JSMSG_OUT_OF_MEMORY);
|
||||
|
||||
flags.isDirtyLine = true;
|
||||
tp->pos.end = userbuf.offset();
|
||||
MOZ_MAKE_MEM_UNDEFINED(&tp->type, sizeof(tp->type));
|
||||
|
@ -351,9 +351,10 @@ class MOZ_STACK_CLASS TokenStream
|
||||
bool sawOctalEscape:1; // Saw an octal character escape.
|
||||
bool hadError:1; // Hit a syntax error, at start or during a
|
||||
// token.
|
||||
bool hitOOM:1; // Hit OOM.
|
||||
|
||||
Flags()
|
||||
: isEOF(), isDirtyLine(), sawOctalEscape(), hadError()
|
||||
: isEOF(), isDirtyLine(), sawOctalEscape(), hadError(), hitOOM()
|
||||
{}
|
||||
};
|
||||
|
||||
@ -435,11 +436,16 @@ class MOZ_STACK_CLASS TokenStream
|
||||
// it's the same as the line that the current token ends on, that's a
|
||||
// stronger condition than what we are looking for, and we don't need
|
||||
// to return TOK_EOL.
|
||||
if (lookahead != 0 && srcCoords.isOnThisLine(curr.pos.end, lineno)) {
|
||||
if (lookahead != 0) {
|
||||
bool onThisLine;
|
||||
if (!srcCoords.isOnThisLine(curr.pos.end, lineno, &onThisLine))
|
||||
return reportError(JSMSG_OUT_OF_MEMORY);
|
||||
if (onThisLine) {
|
||||
MOZ_ASSERT(!flags.hadError);
|
||||
*ttp = tokens[(cursor + 1) & ntokensMask].type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// The above check misses two cases where we don't have to return
|
||||
// TOK_EOL.
|
||||
@ -525,7 +531,7 @@ class MOZ_STACK_CLASS TokenStream
|
||||
Token lookaheadTokens[maxLookahead];
|
||||
};
|
||||
|
||||
void advance(size_t position);
|
||||
bool advance(size_t position);
|
||||
void tell(Position*);
|
||||
void seek(const Position& pos);
|
||||
bool seek(const Position& pos, const TokenStream& other);
|
||||
@ -626,14 +632,16 @@ class MOZ_STACK_CLASS TokenStream
|
||||
public:
|
||||
SourceCoords(ExclusiveContext* cx, uint32_t ln);
|
||||
|
||||
void add(uint32_t lineNum, uint32_t lineStartOffset);
|
||||
bool add(uint32_t lineNum, uint32_t lineStartOffset);
|
||||
bool fill(const SourceCoords& other);
|
||||
|
||||
bool isOnThisLine(uint32_t offset, uint32_t lineNum) const {
|
||||
bool isOnThisLine(uint32_t offset, uint32_t lineNum, bool* onThisLine) const {
|
||||
uint32_t lineIndex = lineNumToIndex(lineNum);
|
||||
MOZ_ASSERT(lineIndex + 1 < lineStartOffsets_.length()); // +1 due to sentinel
|
||||
return lineStartOffsets_[lineIndex] <= offset &&
|
||||
if (lineIndex + 1 >= lineStartOffsets_.length()) // +1 due to sentinel
|
||||
return false;
|
||||
*onThisLine = lineStartOffsets_[lineIndex] <= offset &&
|
||||
offset < lineStartOffsets_[lineIndex + 1];
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t lineNum(uint32_t offset) const;
|
||||
|
Loading…
Reference in New Issue
Block a user