Commit 9ac65ceb authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Validate patterns non-parenthesized in ValidatePattern

No-Tree-Checks: true
No-Try: true
Change-Id: I8b8651e499c2d862ae9f81a18af11d610214c0cd
Reviewed-on: https://chromium-review.googlesource.com/c/1350118
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57818}
parent dd065511
...@@ -250,7 +250,7 @@ class Expression : public AstNode { ...@@ -250,7 +250,7 @@ class Expression : public AstNode {
bool IsCompileTimeValue(); bool IsCompileTimeValue();
bool IsValidPattern() { bool IsPattern() {
STATIC_ASSERT(kObjectLiteral + 1 == kArrayLiteral); STATIC_ASSERT(kObjectLiteral + 1 == kArrayLiteral);
return IsInRange(node_type(), kObjectLiteral, kArrayLiteral); return IsInRange(node_type(), kObjectLiteral, kArrayLiteral);
} }
......
...@@ -901,6 +901,15 @@ class ParserBase { ...@@ -901,6 +901,15 @@ class ParserBase {
} }
} }
void ValidatePattern(ExpressionT expression) {
if (expression->is_parenthesized()) {
impl()->ReportMessageAt(
Scanner::Location(expression->position(), end_position()),
MessageTemplate::kInvalidDestructuringTarget);
}
ValidatePattern();
}
void ValidateFormalParameters(LanguageMode language_mode, void ValidateFormalParameters(LanguageMode language_mode,
const FormalParametersT& parameters, const FormalParametersT& parameters,
bool allow_duplicates) { bool allow_duplicates) {
...@@ -2635,13 +2644,8 @@ ParserBase<Impl>::ParseAssignmentExpression() { ...@@ -2635,13 +2644,8 @@ ParserBase<Impl>::ParseAssignmentExpression() {
} }
// Destructuring assignmment. // Destructuring assignmment.
if (V8_UNLIKELY(expression->IsValidPattern() && op == Token::ASSIGN)) { if (V8_UNLIKELY(expression->IsPattern() && op == Token::ASSIGN)) {
if (expression->is_parenthesized()) { ValidatePattern(expression);
impl()->ReportMessageAt(
Scanner::Location(expression->position(), end_position()),
MessageTemplate::kInvalidDestructuringTarget);
}
ValidatePattern();
// This is definitely not an expression so don't accumulate // This is definitely not an expression so don't accumulate
// expression-related errors. // expression-related errors.
...@@ -4381,7 +4385,7 @@ ParserBase<Impl>::RewriteInvalidReferenceExpression(ExpressionT expression, ...@@ -4381,7 +4385,7 @@ ParserBase<Impl>::RewriteInvalidReferenceExpression(ExpressionT expression,
template <typename Impl> template <typename Impl>
void ParserBase<Impl>::CheckArrowFormalParameter(ExpressionT formal) { void ParserBase<Impl>::CheckArrowFormalParameter(ExpressionT formal) {
if (formal->is_parenthesized() || if (formal->is_parenthesized() ||
!(impl()->IsIdentifier(formal) || formal->IsValidPattern() || !(impl()->IsIdentifier(formal) || formal->IsPattern() ||
formal->IsAssignment())) { formal->IsAssignment())) {
classifier()->RecordBindingPatternError( classifier()->RecordBindingPatternError(
Scanner::Location(formal->position(), end_position()), Scanner::Location(formal->position(), end_position()),
...@@ -4413,7 +4417,7 @@ void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression, ...@@ -4413,7 +4417,7 @@ void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression,
return; return;
} }
if (expression->is_parenthesized() || if (expression->is_parenthesized() ||
(!expression->IsValidPattern() && !expression->IsAssignment())) { (!expression->IsPattern() && !expression->IsAssignment())) {
classifier()->RecordPatternError( classifier()->RecordPatternError(
Scanner::Location(begin, end), Scanner::Location(begin, end),
MessageTemplate::kInvalidDestructuringTarget); MessageTemplate::kInvalidDestructuringTarget);
...@@ -5361,10 +5365,10 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement( ...@@ -5361,10 +5365,10 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
int lhs_end_pos = end_position(); int lhs_end_pos = end_position();
bool is_for_each = CheckInOrOf(&for_info.mode); bool is_for_each = CheckInOrOf(&for_info.mode);
bool is_destructuring = is_for_each && expression->IsValidPattern(); bool is_destructuring = is_for_each && expression->IsPattern();
if (is_destructuring) { if (is_destructuring) {
ValidatePattern(); ValidatePattern(expression);
} else { } else {
ValidateExpression(); ValidateExpression();
} }
...@@ -5496,8 +5500,13 @@ ParserBase<Impl>::ParseForEachStatementWithoutDeclarations( ...@@ -5496,8 +5500,13 @@ ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
ForInfo* for_info, ZonePtrList<const AstRawString>* labels, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels) { ZonePtrList<const AstRawString>* own_labels) {
// Initializer is reference followed by in/of. // Initializer is reference followed by in/of.
if (V8_UNLIKELY(!expression->IsValidPattern() && if (expression->IsPattern()) {
!IsValidReferenceExpression(expression))) { if (expression->is_parenthesized()) {
impl()->ReportMessageAt(
Scanner::Location(expression->position(), end_position()),
MessageTemplate::kInvalidDestructuringTarget);
}
} else if (V8_UNLIKELY(!IsValidReferenceExpression(expression))) {
expression = RewriteInvalidReferenceExpression( expression = RewriteInvalidReferenceExpression(
expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
kSyntaxError); kSyntaxError);
...@@ -5698,8 +5707,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement( ...@@ -5698,8 +5707,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
ExpressionT lhs = each_variable = ParseLeftHandSideExpression(); ExpressionT lhs = each_variable = ParseLeftHandSideExpression();
int lhs_end_pos = end_position(); int lhs_end_pos = end_position();
if (lhs->IsValidPattern()) { if (lhs->IsPattern()) {
ValidatePattern(); ValidatePattern(lhs);
} else { } else {
ValidateExpression(); ValidateExpression();
if (V8_UNLIKELY(!IsValidReferenceExpression(lhs))) { if (V8_UNLIKELY(!IsValidReferenceExpression(lhs))) {
......
...@@ -1816,7 +1816,7 @@ Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, ...@@ -1816,7 +1816,7 @@ Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
return InitializeForOfStatement(for_of, each, subject, body, finalize, return InitializeForOfStatement(for_of, each, subject, body, finalize,
IteratorType::kNormal, each->position()); IteratorType::kNormal, each->position());
} else { } else {
if (each->IsValidPattern()) { if (each->IsPattern()) {
Variable* temp = NewTemporary(ast_value_factory()->empty_string()); Variable* temp = NewTemporary(ast_value_factory()->empty_string());
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
Expression* assign_each = Expression* assign_each =
...@@ -2053,7 +2053,7 @@ Statement* Parser::InitializeForOfStatement( ...@@ -2053,7 +2053,7 @@ Statement* Parser::InitializeForOfStatement(
{ {
assign_each = assign_each =
factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
if (each->IsValidPattern()) { if (each->IsPattern()) {
assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment()); assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment());
} }
} }
......
...@@ -239,7 +239,7 @@ class PreParserExpression { ...@@ -239,7 +239,7 @@ class PreParserExpression {
return TypeField::decode(code_) == kArrayLiteralExpression; return TypeField::decode(code_) == kArrayLiteralExpression;
} }
bool IsValidPattern() const { bool IsPattern() const {
STATIC_ASSERT(kObjectLiteralExpression + 1 == kArrayLiteralExpression); STATIC_ASSERT(kObjectLiteralExpression + 1 == kArrayLiteralExpression);
return IsInRange(TypeField::decode(code_), kObjectLiteralExpression, return IsInRange(TypeField::decode(code_), kObjectLiteralExpression,
kArrayLiteralExpression); kArrayLiteralExpression);
......
...@@ -1191,6 +1191,12 @@ ...@@ -1191,6 +1191,12 @@
assertEquals(undefined, eval('try {throw [1, 2, 3]} catch([x]) {}')); assertEquals(undefined, eval('try {throw [1, 2, 3]} catch([x]) {}'));
})(); })();
// Property access as declaration target.
assertThrows("let [o.x=1]=[]", SyntaxError); assertThrows("let [o.x=1]=[]", SyntaxError);
assertThrows("let {x:o.f=1}={x:1}", SyntaxError); assertThrows("let {x:o.f=1}={x:1}", SyntaxError);
assertThrows("(o.f=1)=>0", SyntaxError); assertThrows("(o.f=1)=>0", SyntaxError);
// Invalidly parenthesized declaration targets.
assertThrows("for (({x}) of [{x:1}]) {}", SyntaxError);
assertThrows("for (var ({x}) of [{x:1}]) {}", SyntaxError);
assertThrows("for await (({x}) of [{x:1}]) {}", SyntaxError);
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