Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(624)

Side by Side Diff: tools/gn/parser.cc

Issue 2282493002: gn: Don't do an out-of-bound access if a file ends after 'else' (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/parser.h" 5 #include "tools/gn/parser.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 Token::Type types[1] = { type }; 381 Token::Type types[1] = { type };
382 return Consume(types, 1, error_message); 382 return Consume(types, 1, error_message);
383 } 383 }
384 384
385 Token Parser::Consume(Token::Type* types, 385 Token Parser::Consume(Token::Type* types,
386 size_t num_types, 386 size_t num_types,
387 const char* error_message) { 387 const char* error_message) {
388 if (has_error()) { 388 if (has_error()) {
389 // Don't overwrite current error, but make progress through tokens so that 389 // Don't overwrite current error, but make progress through tokens so that
390 // a loop that's expecting a particular token will still terminate. 390 // a loop that's expecting a particular token will still terminate.
391 cur_++; 391 if (!at_end())
Nico 2016/08/25 16:07:49 this is unrelated but seems like a good change so
392 cur_++;
392 return Token(Location(), Token::INVALID, base::StringPiece()); 393 return Token(Location(), Token::INVALID, base::StringPiece());
393 } 394 }
394 if (at_end()) { 395 if (at_end()) {
395 const char kEOFMsg[] = "I hit EOF instead."; 396 const char kEOFMsg[] = "I hit EOF instead.";
396 if (tokens_.empty()) 397 if (tokens_.empty())
397 *err_ = Err(Location(), error_message, kEOFMsg); 398 *err_ = Err(Location(), error_message, kEOFMsg);
398 else 399 else
399 *err_ = Err(tokens_[tokens_.size() - 1], error_message, kEOFMsg); 400 *err_ = Err(tokens_[tokens_.size() - 1], error_message, kEOFMsg);
400 return Token(Location(), Token::INVALID, base::StringPiece()); 401 return Token(Location(), Token::INVALID, base::StringPiece());
401 } 402 }
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 return BlockComment(Consume()); 702 return BlockComment(Consume());
702 } else { 703 } else {
703 // TODO(scottmg): Is this too strict? Just drop all the testing if we want 704 // TODO(scottmg): Is this too strict? Just drop all the testing if we want
704 // to allow "pointless" expressions and return ParseExpression() directly. 705 // to allow "pointless" expressions and return ParseExpression() directly.
705 std::unique_ptr<ParseNode> stmt = ParseExpression(); 706 std::unique_ptr<ParseNode> stmt = ParseExpression();
706 if (stmt) { 707 if (stmt) {
707 if (stmt->AsFunctionCall() || IsAssignment(stmt.get())) 708 if (stmt->AsFunctionCall() || IsAssignment(stmt.get()))
708 return stmt; 709 return stmt;
709 } 710 }
710 if (!has_error()) { 711 if (!has_error()) {
711 Token token = at_end() ? tokens_[tokens_.size() - 1] : cur_token(); 712 Token token = cur_or_last_token();
Nico 2016/08/25 16:07:49 this is just extract-function
712 *err_ = Err(token, "Expecting assignment or function call."); 713 *err_ = Err(token, "Expecting assignment or function call.");
713 } 714 }
714 return std::unique_ptr<ParseNode>(); 715 return std::unique_ptr<ParseNode>();
715 } 716 }
716 } 717 }
717 718
718 std::unique_ptr<BlockNode> Parser::ParseBlock( 719 std::unique_ptr<BlockNode> Parser::ParseBlock(
719 Token begin_brace, 720 Token begin_brace,
720 BlockNode::ResultMode result_mode) { 721 BlockNode::ResultMode result_mode) {
721 if (has_error()) 722 if (has_error())
(...skipping 26 matching lines...) Expand all
748 condition->set_if_true(ParseBlock( 749 condition->set_if_true(ParseBlock(
749 Consume(Token::LEFT_BRACE, "Expected '{' to start 'if' block."), 750 Consume(Token::LEFT_BRACE, "Expected '{' to start 'if' block."),
750 BlockNode::DISCARDS_RESULT)); 751 BlockNode::DISCARDS_RESULT));
751 if (Match(Token::ELSE)) { 752 if (Match(Token::ELSE)) {
752 if (LookAhead(Token::LEFT_BRACE)) { 753 if (LookAhead(Token::LEFT_BRACE)) {
753 condition->set_if_false(ParseBlock(Consume(), 754 condition->set_if_false(ParseBlock(Consume(),
754 BlockNode::DISCARDS_RESULT)); 755 BlockNode::DISCARDS_RESULT));
755 } else if (LookAhead(Token::IF)) { 756 } else if (LookAhead(Token::IF)) {
756 condition->set_if_false(ParseStatement()); 757 condition->set_if_false(ParseStatement());
757 } else { 758 } else {
758 *err_ = Err(cur_token(), "Expected '{' or 'if' after 'else'."); 759 *err_ = Err(cur_or_last_token(), "Expected '{' or 'if' after 'else'.");
Nico 2016/08/25 16:07:49 this is the fix
759 return std::unique_ptr<ParseNode>(); 760 return std::unique_ptr<ParseNode>();
760 } 761 }
761 } 762 }
762 if (has_error()) 763 if (has_error())
763 return std::unique_ptr<ParseNode>(); 764 return std::unique_ptr<ParseNode>();
764 return std::move(condition); 765 return std::move(condition);
765 } 766 }
766 767
767 void Parser::TraverseOrder(const ParseNode* root, 768 void Parser::TraverseOrder(const ParseNode* root,
768 std::vector<const ParseNode*>* pre, 769 std::vector<const ParseNode*>* pre,
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 break; 869 break;
869 } 870 }
870 } 871 }
871 872
872 // Suffix comments were assigned in reverse, so if there were multiple on 873 // Suffix comments were assigned in reverse, so if there were multiple on
873 // the same node, they need to be reversed. 874 // the same node, they need to be reversed.
874 if ((*i)->comments() && !(*i)->comments()->suffix().empty()) 875 if ((*i)->comments() && !(*i)->comments()->suffix().empty())
875 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix(); 876 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix();
876 } 877 }
877 } 878 }
OLDNEW
« no previous file with comments | « tools/gn/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698