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(); }