Commit 4e18f868 authored by Florian Sattler's avatar Florian Sattler Committed by Commit Bot

[scanner] Add error state to scanner to prevent further processing.

BUG=v8:7926

Change-Id: Ib4dd3017c7d6f28025ab308063d7dedd0138dfa6
Reviewed-on: https://chromium-review.googlesource.com/c/1291470
Commit-Queue: Florian Sattler <sattlerf@google.com>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56848}
parent 98b257fe
...@@ -647,7 +647,10 @@ class ParserBase { ...@@ -647,7 +647,10 @@ class ParserBase {
bool stack_overflow() const { bool stack_overflow() const {
return pending_error_handler()->stack_overflow(); return pending_error_handler()->stack_overflow();
} }
void set_stack_overflow() { pending_error_handler()->set_stack_overflow(); } void set_stack_overflow() {
scanner_->set_parser_error();
pending_error_handler()->set_stack_overflow();
}
void CheckStackOverflow() { void CheckStackOverflow() {
// Any further calls to Next or peek will return the illegal token. // Any further calls to Next or peek will return the illegal token.
if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow(); if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow();
...@@ -655,10 +658,7 @@ class ParserBase { ...@@ -655,10 +658,7 @@ class ParserBase {
int script_id() { return script_id_; } int script_id() { return script_id_; }
void set_script_id(int id) { script_id_ = id; } void set_script_id(int id) { script_id_ = id; }
V8_INLINE Token::Value peek() { V8_INLINE Token::Value peek() { return scanner()->peek(); }
if (stack_overflow()) return Token::ILLEGAL;
return scanner()->peek();
}
// Returns the position past the following semicolon (if it exists), and the // Returns the position past the following semicolon (if it exists), and the
// position past the end of the current token otherwise. // position past the end of the current token otherwise.
...@@ -666,15 +666,9 @@ class ParserBase { ...@@ -666,15 +666,9 @@ class ParserBase {
return (peek() == Token::SEMICOLON) ? peek_end_position() : end_position(); return (peek() == Token::SEMICOLON) ? peek_end_position() : end_position();
} }
V8_INLINE Token::Value PeekAhead() { V8_INLINE Token::Value PeekAhead() { return scanner()->PeekAhead(); }
if (stack_overflow()) return Token::ILLEGAL;
return scanner()->PeekAhead();
}
V8_INLINE Token::Value Next() { V8_INLINE Token::Value Next() { return scanner()->Next(); }
if (stack_overflow()) return Token::ILLEGAL;
return scanner()->Next();
}
V8_INLINE void Consume(Token::Value token) { V8_INLINE void Consume(Token::Value token) {
Token::Value next = scanner()->Next(); Token::Value next = scanner()->Next();
...@@ -4449,7 +4443,10 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) { ...@@ -4449,7 +4443,10 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
if (impl()->ParsingDynamicFunctionDeclaration()) { if (impl()->ParsingDynamicFunctionDeclaration()) {
// We don't want dynamic functions to actually declare their name // We don't want dynamic functions to actually declare their name
// "anonymous". We just want that name in the toString(). // "anonymous". We just want that name in the toString().
Consume(Token::IDENTIFIER);
// Consuming token we did not peek yet, which could lead to a ILLEGAL token
// in the case of a stackoverflow.
Expect(Token::IDENTIFIER, CHECK_OK);
DCHECK(scanner()->CurrentMatchesContextual(Token::ANONYMOUS)); DCHECK(scanner()->CurrentMatchesContextual(Token::ANONYMOUS));
} else if (peek_any_identifier()) { } else if (peek_any_identifier()) {
type = FunctionLiteral::kNamedExpression; type = FunctionLiteral::kNamedExpression;
......
...@@ -525,7 +525,9 @@ V8_INLINE Token::Value Scanner::ScanSingleToken() { ...@@ -525,7 +525,9 @@ V8_INLINE Token::Value Scanner::ScanSingleToken() {
return Token::IDENTIFIER; return Token::IDENTIFIER;
} }
if (IsDecimalDigit(c0_)) return ScanNumber(false); if (IsDecimalDigit(c0_)) return ScanNumber(false);
if (c0_ == kEndOfInput) return Token::EOS; if (c0_ == kEndOfInput) {
return source_->has_parser_error() ? Token::ILLEGAL : Token::EOS;
}
token = SkipWhiteSpace(); token = SkipWhiteSpace();
continue; continue;
} }
......
...@@ -42,6 +42,13 @@ class Utf16CharacterStream { ...@@ -42,6 +42,13 @@ class Utf16CharacterStream {
virtual ~Utf16CharacterStream() = default; virtual ~Utf16CharacterStream() = default;
void set_parser_error() {
buffer_cursor_ = buffer_end_;
has_parser_error_ = true;
}
bool has_parser_error() const { return has_parser_error_; }
inline uc32 Peek() { inline uc32 Peek() {
if (V8_LIKELY(buffer_cursor_ < buffer_end_)) { if (V8_LIKELY(buffer_cursor_ < buffer_end_)) {
return static_cast<uc32>(*buffer_cursor_); return static_cast<uc32>(*buffer_cursor_);
...@@ -145,7 +152,7 @@ class Utf16CharacterStream { ...@@ -145,7 +152,7 @@ class Utf16CharacterStream {
bool ReadBlockChecked() { bool ReadBlockChecked() {
size_t position = pos(); size_t position = pos();
USE(position); USE(position);
bool success = ReadBlock(); bool success = !has_parser_error() && ReadBlock();
// Post-conditions: 1, We should always be at the right position. // Post-conditions: 1, We should always be at the right position.
// 2, Cursor should be inside the buffer. // 2, Cursor should be inside the buffer.
...@@ -193,6 +200,7 @@ class Utf16CharacterStream { ...@@ -193,6 +200,7 @@ class Utf16CharacterStream {
const uint16_t* buffer_end_; const uint16_t* buffer_end_;
size_t buffer_pos_; size_t buffer_pos_;
RuntimeCallStats* runtime_call_stats_; RuntimeCallStats* runtime_call_stats_;
bool has_parser_error_ = false;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -225,6 +233,11 @@ class Scanner { ...@@ -225,6 +233,11 @@ class Scanner {
DISALLOW_COPY_AND_ASSIGN(BookmarkScope); DISALLOW_COPY_AND_ASSIGN(BookmarkScope);
}; };
// Sets the Scanner into an error state to stop further scanning and terminate
// the parsing by only returning ILLEGAL tokens after that.
void set_parser_error() { source_->set_parser_error(); }
bool has_parser_error_set() { return source_->has_parser_error(); }
// Representation of an interval of source positions. // Representation of an interval of source positions.
struct Location { struct Location {
Location(int b, int e) : beg_pos(b), end_pos(e) { } Location(int b, int e) : beg_pos(b), end_pos(e) { }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment