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

Side by Side Diff: pkg/analyzer/lib/src/generated/parser.dart

Issue 2823993002: Issue 25558. Report an error, but don't crash when AST it too deep. (Closed)
Patch Set: Created 3 years, 8 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.generated.parser; 5 library analyzer.src.generated.parser;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import "dart:math" as math; 8 import "dart:math" as math;
9 9
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 static String _AWAIT = Keyword.AWAIT.syntax; 163 static String _AWAIT = Keyword.AWAIT.syntax;
164 164
165 static String _HIDE = Keyword.HIDE.syntax; 165 static String _HIDE = Keyword.HIDE.syntax;
166 166
167 static String _SHOW = Keyword.SHOW.syntax; 167 static String _SHOW = Keyword.SHOW.syntax;
168 168
169 static String SYNC = Keyword.SYNC.syntax; 169 static String SYNC = Keyword.SYNC.syntax;
170 170
171 static String _YIELD = Keyword.YIELD.syntax; 171 static String _YIELD = Keyword.YIELD.syntax;
172 172
173 static const int _MAX_TREE_DEPTH = 300;
174
173 /** 175 /**
174 * The source being parsed. 176 * The source being parsed.
175 */ 177 */
176 final Source _source; 178 final Source _source;
177 179
178 /** 180 /**
179 * The error listener that will be informed of any errors that are found 181 * The error listener that will be informed of any errors that are found
180 * during the parse. 182 * during the parse.
181 */ 183 */
182 final AnalysisErrorListener _errorListener; 184 final AnalysisErrorListener _errorListener;
(...skipping 25 matching lines...) Expand all
208 * A flag indicating whether parser is to parse function bodies. 210 * A flag indicating whether parser is to parse function bodies.
209 */ 211 */
210 bool _parseFunctionBodies = true; 212 bool _parseFunctionBodies = true;
211 213
212 /** 214 /**
213 * The next token to be parsed. 215 * The next token to be parsed.
214 */ 216 */
215 Token _currentToken; 217 Token _currentToken;
216 218
217 /** 219 /**
220 * The depth of the current AST. When this depth is too high, so we're at the
221 * risk of overflowing the stack, we stop parsing and report an error.
222 */
223 int _treeDepth = 0;
224
225 /**
218 * A flag indicating whether the parser is currently in a function body marked 226 * A flag indicating whether the parser is currently in a function body marked
219 * as being 'async'. 227 * as being 'async'.
220 */ 228 */
221 bool _inAsync = false; 229 bool _inAsync = false;
222 230
223 /** 231 /**
224 * A flag indicating whether the parser is currently in a function body marked 232 * A flag indicating whether the parser is currently in a function body marked
225 * (by a star) as being a generator. 233 * (by a star) as being a generator.
226 */ 234 */
227 bool _inGenerator = false; 235 bool _inGenerator = false;
(...skipping 1725 matching lines...) Expand 10 before | Expand all | Expand 10 after
1953 } 1961 }
1954 directives.add(directive); 1962 directives.add(directive);
1955 } else if (type == TokenType.SEMICOLON) { 1963 } else if (type == TokenType.SEMICOLON) {
1956 // TODO(brianwilkerson) Consider moving this error detection into 1964 // TODO(brianwilkerson) Consider moving this error detection into
1957 // _parseCompilationUnitMember (in the places where EXPECTED_EXECUTABLE 1965 // _parseCompilationUnitMember (in the places where EXPECTED_EXECUTABLE
1958 // is being generated). 1966 // is being generated).
1959 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, 1967 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
1960 [_currentToken.lexeme]); 1968 [_currentToken.lexeme]);
1961 _advance(); 1969 _advance();
1962 } else { 1970 } else {
1963 CompilationUnitMember member = 1971 CompilationUnitMember member;
1964 parseCompilationUnitMember(commentAndMetadata); 1972 try {
1973 member = parseCompilationUnitMember(commentAndMetadata);
1974 } on _TooDeepTreeError {
1975 _reportErrorForToken(ParserErrorCode.STACK_OVERFLOW, _currentToken);
1976 Token eof = new Token(TokenType.EOF, 0);
1977 eof.previous = eof;
1978 eof.setNext(eof);
1979 return astFactory.compilationUnit(eof, null, null, null, eof);
1980 }
1965 if (member != null) { 1981 if (member != null) {
1966 declarations.add(member); 1982 declarations.add(member);
1967 } 1983 }
1968 } 1984 }
1969 if (identical(_currentToken, memberStart)) { 1985 if (identical(_currentToken, memberStart)) {
1970 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, 1986 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
1971 [_currentToken.lexeme]); 1987 [_currentToken.lexeme]);
1972 _advance(); 1988 _advance();
1973 while (!_matches(TokenType.EOF) && 1989 while (!_matches(TokenType.EOF) &&
1974 !_couldBeStartOfCompilationUnitMember()) { 1990 !_couldBeStartOfCompilationUnitMember()) {
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 /** 2721 /**
2706 * Parse an expression that might contain a cascade. Return the expression 2722 * Parse an expression that might contain a cascade. Return the expression
2707 * that was parsed. 2723 * that was parsed.
2708 * 2724 *
2709 * expression ::= 2725 * expression ::=
2710 * assignableExpression assignmentOperator expression 2726 * assignableExpression assignmentOperator expression
2711 * | conditionalExpression cascadeSection* 2727 * | conditionalExpression cascadeSection*
2712 * | throwExpression 2728 * | throwExpression
2713 */ 2729 */
2714 Expression parseExpression2() { 2730 Expression parseExpression2() {
2715 Keyword keyword = _currentToken.keyword; 2731 if (_treeDepth > _MAX_TREE_DEPTH) {
2716 if (keyword == Keyword.THROW) { 2732 throw new _TooDeepTreeError();
2717 return parseThrowExpression();
2718 } else if (keyword == Keyword.RETHROW) {
2719 // TODO(brianwilkerson) Rethrow is a statement again.
2720 return parseRethrowExpression();
2721 } 2733 }
2722 // 2734 _treeDepth++;
2723 // assignableExpression is a subset of conditionalExpression, so we can 2735 try {
2724 // parse a conditional expression and then determine whether it is followed 2736 Keyword keyword = _currentToken.keyword;
2725 // by an assignmentOperator, checking for conformance to the restricted 2737 if (keyword == Keyword.THROW) {
2726 // grammar after making that determination. 2738 return parseThrowExpression();
2727 // 2739 } else if (keyword == Keyword.RETHROW) {
2728 Expression expression = parseConditionalExpression(); 2740 // TODO(brianwilkerson) Rethrow is a statement again.
2729 TokenType type = _currentToken.type; 2741 return parseRethrowExpression();
2730 if (type == TokenType.PERIOD_PERIOD) { 2742 }
2731 List<Expression> cascadeSections = <Expression>[]; 2743 //
2732 do { 2744 // assignableExpression is a subset of conditionalExpression, so we can
2733 Expression section = parseCascadeSection(); 2745 // parse a conditional expression and then determine whether it is followe d
2734 if (section != null) { 2746 // by an assignmentOperator, checking for conformance to the restricted
2735 cascadeSections.add(section); 2747 // grammar after making that determination.
2736 } 2748 //
2737 } while (_currentToken.type == TokenType.PERIOD_PERIOD); 2749 Expression expression = parseConditionalExpression();
2738 return astFactory.cascadeExpression(expression, cascadeSections); 2750 TokenType type = _currentToken.type;
2739 } else if (type.isAssignmentOperator) { 2751 if (type == TokenType.PERIOD_PERIOD) {
2740 Token operator = getAndAdvance(); 2752 List<Expression> cascadeSections = <Expression>[];
2741 _ensureAssignable(expression); 2753 do {
2742 return astFactory.assignmentExpression( 2754 Expression section = parseCascadeSection();
2743 expression, operator, parseExpression2()); 2755 if (section != null) {
2756 cascadeSections.add(section);
2757 }
2758 } while (_currentToken.type == TokenType.PERIOD_PERIOD);
2759 return astFactory.cascadeExpression(expression, cascadeSections);
2760 } else if (type.isAssignmentOperator) {
2761 Token operator = getAndAdvance();
2762 _ensureAssignable(expression);
2763 return astFactory.assignmentExpression(
2764 expression, operator, parseExpression2());
2765 }
2766 return expression;
2767 } finally {
2768 _treeDepth--;
2744 } 2769 }
2745 return expression;
2746 } 2770 }
2747 2771
2748 /** 2772 /**
2749 * Parse a list of expressions. Return the expression that was parsed. 2773 * Parse a list of expressions. Return the expression that was parsed.
2750 * 2774 *
2751 * expressionList ::= 2775 * expressionList ::=
2752 * expression (',' expression)* 2776 * expression (',' expression)*
2753 */ 2777 */
2754 List<Expression> parseExpressionList() { 2778 List<Expression> parseExpressionList() {
2755 List<Expression> expressions = <Expression>[parseExpression2()]; 2779 List<Expression> expressions = <Expression>[parseExpression2()];
(...skipping 2032 matching lines...) Expand 10 before | Expand all | Expand 10 after
4788 return parseStatement2(); 4812 return parseStatement2();
4789 } 4813 }
4790 4814
4791 /** 4815 /**
4792 * Parse a statement. Return the statement that was parsed. 4816 * Parse a statement. Return the statement that was parsed.
4793 * 4817 *
4794 * statement ::= 4818 * statement ::=
4795 * label* nonLabeledStatement 4819 * label* nonLabeledStatement
4796 */ 4820 */
4797 Statement parseStatement2() { 4821 Statement parseStatement2() {
4798 List<Label> labels = null; 4822 if (_treeDepth > _MAX_TREE_DEPTH) {
4799 while (_matchesIdentifier() && _currentToken.next.type == TokenType.COLON) { 4823 throw new _TooDeepTreeError();
4800 Label label = parseLabel(isDeclaration: true); 4824 }
4825 _treeDepth++;
4826 try {
4827 List<Label> labels = null;
4828 while (
4829 _matchesIdentifier() && _currentToken.next.type == TokenType.COLON) {
4830 Label label = parseLabel(isDeclaration: true);
4831 if (labels == null) {
4832 labels = <Label>[label];
4833 } else {
4834 labels.add(label);
4835 }
4836 }
4837 Statement statement = parseNonLabeledStatement();
4801 if (labels == null) { 4838 if (labels == null) {
4802 labels = <Label>[label]; 4839 return statement;
4803 } else {
4804 labels.add(label);
4805 } 4840 }
4841 return astFactory.labeledStatement(labels, statement);
4842 } finally {
4843 _treeDepth--;
4806 } 4844 }
4807 Statement statement = parseNonLabeledStatement();
4808 if (labels == null) {
4809 return statement;
4810 }
4811 return astFactory.labeledStatement(labels, statement);
4812 } 4845 }
4813 4846
4814 /** 4847 /**
4815 * Parse a sequence of statements, starting with the given [token]. Return the 4848 * Parse a sequence of statements, starting with the given [token]. Return the
4816 * statements that were parsed, or `null` if the tokens do not represent a 4849 * statements that were parsed, or `null` if the tokens do not represent a
4817 * recognizable sequence of statements. 4850 * recognizable sequence of statements.
4818 */ 4851 */
4819 List<Statement> parseStatements(Token token) { 4852 List<Statement> parseStatements(Token token) {
4820 _currentToken = token; 4853 _currentToken = token;
4821 return _parseStatementList(); 4854 return _parseStatementList();
(...skipping 3738 matching lines...) Expand 10 before | Expand all | Expand 10 after
8560 } 8593 }
8561 if (modifiers.finalKeyword != null) { 8594 if (modifiers.finalKeyword != null) {
8562 _reportErrorForToken( 8595 _reportErrorForToken(
8563 ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword); 8596 ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword);
8564 } 8597 }
8565 if (modifiers.varKeyword != null) { 8598 if (modifiers.varKeyword != null) {
8566 _reportErrorForToken(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword); 8599 _reportErrorForToken(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword);
8567 } 8600 }
8568 } 8601 }
8569 } 8602 }
8603
8604 /**
8605 * Instances of this class are thrown when the parser detects that AST has
8606 * too many nested expressions to be parsed safely and avoid possibility of
8607 * [StackOverflowError] in the parser or during later analysis.
8608 */
8609 class _TooDeepTreeError {}
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/error/syntactic_errors.dart ('k') | tests/language/language_analyzer2.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698