Commit 693c6056 authored by brettw's avatar brettw Committed by Commit bot

Fix some crashes in GN.

GN would read past the end of the file if the last line was a comment that didn't end in a newline.

It also would get confused if an end-of-file was reached after an assignment or a unary operator.

BUG=478169

Review URL: https://codereview.chromium.org/1275853006

Cr-Commit-Position: refs/heads/master@{#342417}
parent 8fbf16aa
......@@ -374,6 +374,11 @@ scoped_ptr<ParseNode> Parser::Not(Token token) {
scoped_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1);
if (has_error())
return scoped_ptr<ParseNode>();
if (!expr) {
if (!has_error())
*err_ = Err(token, "Expected right-hand side for '!'.");
return scoped_ptr<ParseNode>();
}
scoped_ptr<UnaryOpNode> unary_op(new UnaryOpNode);
unary_op->set_op(token);
unary_op->set_operand(expr.Pass());
......@@ -393,7 +398,7 @@ scoped_ptr<ParseNode> Parser::BinaryOperator(scoped_ptr<ParseNode> left,
ParseExpression(expressions_[token.type()].precedence + 1);
if (!right) {
if (!has_error()) {
*err_ = Err(token, "Expected right hand side for '" +
*err_ = Err(token, "Expected right-hand side for '" +
token.value().as_string() + "'");
}
return scoped_ptr<ParseNode>();
......@@ -451,6 +456,11 @@ scoped_ptr<ParseNode> Parser::Assignment(scoped_ptr<ParseNode> left,
return scoped_ptr<ParseNode>();
}
scoped_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT);
if (!value) {
if (!has_error())
*err_ = Err(token, "Expected right-hand side for assignment.");
return scoped_ptr<ParseNode>();
}
scoped_ptr<BinaryOpNode> assign(new BinaryOpNode);
assign->set_op(token);
assign->set_left(left.Pass());
......
......@@ -181,6 +181,9 @@ TEST(Parser, UnaryOp) {
DoExpressionPrintTest("!foo",
"UNARY(!)\n"
" IDENTIFIER(foo)\n");
// No contents for binary operator.
DoExpressionErrorTest("a = !", 1, 5);
}
TEST(Parser, List) {
......@@ -215,6 +218,8 @@ TEST(Parser, Assignment) {
" BINARY(=)\n"
" IDENTIFIER(a)\n"
" LITERAL(2)\n");
DoExpressionErrorTest("a = ", 1, 3);
}
TEST(Parser, Accessor) {
......
......@@ -128,7 +128,8 @@ std::vector<Token> Tokenizer::Run() {
location.line_number() ||
tokens_.back().location().char_offset() != location.char_offset())) {
type = Token::LINE_COMMENT;
Advance(); // The current \n.
if (!at_end()) // Could be EOF.
Advance(); // The current \n.
// If this comment is separated from the next syntax element, then we
// want to tag it as a block comment. This will become a standalone
// statement at the parser level to keep this comment separate, rather
......
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