gn: Don't do an out-of-bound access if a file ends after 'else' BUG=640857 Review-Url: https://codereview.chromium.org/2282493002 Cr-Original-Commit-Position: refs/heads/master@{#414461} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 5aba5ce9d5f3184b1e659c319e962c57274cbe03
diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc index 57a398e..41ee6b6 100644 --- a/tools/gn/parser.cc +++ b/tools/gn/parser.cc
@@ -388,7 +388,8 @@ if (has_error()) { // Don't overwrite current error, but make progress through tokens so that // a loop that's expecting a particular token will still terminate. - cur_++; + if (!at_end()) + cur_++; return Token(Location(), Token::INVALID, base::StringPiece()); } if (at_end()) { @@ -708,7 +709,7 @@ return stmt; } if (!has_error()) { - Token token = at_end() ? tokens_[tokens_.size() - 1] : cur_token(); + Token token = cur_or_last_token(); *err_ = Err(token, "Expecting assignment or function call."); } return std::unique_ptr<ParseNode>(); @@ -755,7 +756,7 @@ } else if (LookAhead(Token::IF)) { condition->set_if_false(ParseStatement()); } else { - *err_ = Err(cur_token(), "Expected '{' or 'if' after 'else'."); + *err_ = Err(cur_or_last_token(), "Expected '{' or 'if' after 'else'."); return std::unique_ptr<ParseNode>(); } }
diff --git a/tools/gn/parser.h b/tools/gn/parser.h index 29580da..22acb47 100644 --- a/tools/gn/parser.h +++ b/tools/gn/parser.h
@@ -111,8 +111,13 @@ const char* error_message); Token Consume(); + // Call this only if !at_end(). const Token& cur_token() const { return tokens_[cur_]; } + const Token& cur_or_last_token() const { + return at_end() ? tokens_[tokens_.size() - 1] : cur_token(); + } + bool done() const { return at_end() || has_error(); } bool at_end() const { return cur_ >= tokens_.size(); } bool has_error() const { return err_->has_error(); }