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

Unified Diff: src/parsing/preparser.cc

Issue 1757543003: Restrict FunctionDeclarations in Statement position (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: git cl format Created 4 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parsing/preparser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/preparser.cc
diff --git a/src/parsing/preparser.cc b/src/parsing/preparser.cc
index d335c8bdcd29433337d1173c9e17b3a1e116a999..c0dc9846465cf655271f9640b9f6964ccacee807 100644
--- a/src/parsing/preparser.cc
+++ b/src/parsing/preparser.cc
@@ -323,6 +323,14 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
return ParseSubStatement(ok);
}
+PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
+ if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
+ (legacy && allow_harmony_restrictive_declarations())) {
+ return ParseSubStatement(ok);
+ } else {
+ return ParseFunctionDeclaration(CHECK_OK);
+ }
+}
PreParser::Statement PreParser::ParseSubStatement(bool* ok) {
// Statement ::
@@ -397,20 +405,18 @@ PreParser::Statement PreParser::ParseSubStatement(bool* ok) {
case Token::TRY:
return ParseTryStatement(ok);
- case Token::FUNCTION: {
- Scanner::Location start_location = scanner()->peek_location();
- Statement statement = ParseFunctionDeclaration(CHECK_OK);
- Scanner::Location end_location = scanner()->location();
- if (is_strict(language_mode())) {
- PreParserTraits::ReportMessageAt(start_location.beg_pos,
- end_location.end_pos,
- MessageTemplate::kStrictFunction);
- *ok = false;
- return Statement::Default();
- } else {
- return statement;
- }
- }
+ case Token::FUNCTION:
+ // FunctionDeclaration only allowed as a StatementListItem, not in
+ // an arbitrary Statement position. Exceptions such as
+ // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
+ // are handled by calling ParseScopedStatement rather than
+ // ParseSubStatement directly.
+ ReportMessageAt(scanner()->peek_location(),
+ is_strict(language_mode())
+ ? MessageTemplate::kStrictFunction
+ : MessageTemplate::kSloppyFunction);
+ *ok = false;
+ return Statement::Default();
case Token::DEBUGGER:
return ParseDebuggerStatement(ok);
@@ -698,6 +704,10 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
DCHECK(is_sloppy(language_mode()) ||
!IsFutureStrictReserved(expr.AsIdentifier()));
Consume(Token::COLON);
+ // ES#sec-labelled-function-declarations Labelled Function Declarations
+ if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
+ return ParseFunctionDeclaration(ok);
+ }
Statement statement = ParseStatement(ok);
return statement.IsJumpStatement() ? Statement::Default() : statement;
// Preparsing is disabled for extensions (because the extension details
@@ -726,10 +736,10 @@ PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
Expect(Token::LPAREN, CHECK_OK);
ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
- Statement stat = ParseSubStatement(CHECK_OK);
+ Statement stat = ParseScopedStatement(false, CHECK_OK);
if (peek() == Token::ELSE) {
Next();
- Statement else_stat = ParseSubStatement(CHECK_OK);
+ Statement else_stat = ParseScopedStatement(false, CHECK_OK);
stat = (stat.IsJumpStatement() && else_stat.IsJumpStatement()) ?
Statement::Jump() : Statement::Default();
} else {
@@ -825,7 +835,7 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
Scope* with_scope = NewScope(scope_, WITH_SCOPE);
BlockState block_state(&scope_, with_scope);
- ParseSubStatement(CHECK_OK);
+ ParseScopedStatement(true, CHECK_OK);
return Statement::Default();
}
@@ -875,7 +885,7 @@ PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
// 'do' Statement 'while' '(' Expression ')' ';'
Expect(Token::DO, CHECK_OK);
- ParseSubStatement(CHECK_OK);
+ ParseScopedStatement(true, CHECK_OK);
Expect(Token::WHILE, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK);
ParseExpression(true, CHECK_OK);
@@ -893,7 +903,7 @@ PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
Expect(Token::LPAREN, CHECK_OK);
ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
- ParseSubStatement(ok);
+ ParseScopedStatement(true, ok);
return Statement::Default();
}
@@ -945,7 +955,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
}
Expect(Token::RPAREN, CHECK_OK);
- ParseSubStatement(CHECK_OK);
+ ParseScopedStatement(true, CHECK_OK);
return Statement::Default();
}
} else {
@@ -983,7 +993,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
}
Expect(Token::RPAREN, CHECK_OK);
- ParseSubStatement(CHECK_OK);
+ ParseScopedStatement(true, CHECK_OK);
return Statement::Default();
}
}
@@ -1009,7 +1019,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
}
Expect(Token::RPAREN, CHECK_OK);
- ParseSubStatement(ok);
+ ParseScopedStatement(true, ok);
return Statement::Default();
}
« no previous file with comments | « src/parsing/preparser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698