mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:47:44 +00:00
LibJS: Don't hang when parsing invalid destructuring assignment target
Previously, certain crafted input could cause the JS parser to hang, as it repeatedly tried to parse an EOF token after hitting an "invalid destructuring assignment target" error. This change ensures that we stop parsing after hitting this error condition.
This commit is contained in:
parent
01d938c77b
commit
b5875700e2
2 changed files with 20 additions and 7 deletions
|
@ -3061,12 +3061,14 @@ RefPtr<BindingPattern const> Parser::parse_binding_pattern(Parser::AllowDuplicat
|
||||||
if (allow_member_expressions == AllowMemberExpressions::Yes && is_rest) {
|
if (allow_member_expressions == AllowMemberExpressions::Yes && is_rest) {
|
||||||
auto expression_position = position();
|
auto expression_position = position();
|
||||||
auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals });
|
auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals });
|
||||||
if (is<MemberExpression>(*expression))
|
if (is<MemberExpression>(*expression)) {
|
||||||
alias = static_ptr_cast<MemberExpression const>(expression);
|
alias = static_ptr_cast<MemberExpression const>(expression);
|
||||||
else if (is<Identifier>(*expression))
|
} else if (is<Identifier>(*expression)) {
|
||||||
name = static_ptr_cast<Identifier const>(expression);
|
name = static_ptr_cast<Identifier const>(expression);
|
||||||
else
|
} else {
|
||||||
syntax_error("Invalid destructuring assignment target", expression_position);
|
syntax_error("Invalid destructuring assignment target", expression_position);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
} else if (match_identifier_name() || match(TokenType::StringLiteral) || match(TokenType::NumericLiteral) || match(TokenType::BigIntLiteral)) {
|
} else if (match_identifier_name() || match(TokenType::StringLiteral) || match(TokenType::NumericLiteral) || match(TokenType::BigIntLiteral)) {
|
||||||
if (match(TokenType::StringLiteral) || match(TokenType::NumericLiteral))
|
if (match(TokenType::StringLiteral) || match(TokenType::NumericLiteral))
|
||||||
needs_alias = true;
|
needs_alias = true;
|
||||||
|
@ -3099,16 +3101,19 @@ RefPtr<BindingPattern const> Parser::parse_binding_pattern(Parser::AllowDuplicat
|
||||||
auto expression_position = position();
|
auto expression_position = position();
|
||||||
auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals });
|
auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals });
|
||||||
if (is<ArrayExpression>(*expression) || is<ObjectExpression>(*expression)) {
|
if (is<ArrayExpression>(*expression) || is<ObjectExpression>(*expression)) {
|
||||||
if (auto synthesized_binding_pattern = synthesize_binding_pattern(*expression))
|
if (auto synthesized_binding_pattern = synthesize_binding_pattern(*expression)) {
|
||||||
alias = synthesized_binding_pattern.release_nonnull();
|
alias = synthesized_binding_pattern.release_nonnull();
|
||||||
else
|
} else {
|
||||||
syntax_error("Invalid destructuring assignment target", expression_position);
|
syntax_error("Invalid destructuring assignment target", expression_position);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
} else if (is<MemberExpression>(*expression)) {
|
} else if (is<MemberExpression>(*expression)) {
|
||||||
alias = static_ptr_cast<MemberExpression const>(expression);
|
alias = static_ptr_cast<MemberExpression const>(expression);
|
||||||
} else if (is<Identifier>(*expression)) {
|
} else if (is<Identifier>(*expression)) {
|
||||||
alias = static_ptr_cast<Identifier const>(expression);
|
alias = static_ptr_cast<Identifier const>(expression);
|
||||||
} else {
|
} else {
|
||||||
syntax_error("Invalid destructuring assignment target", expression_position);
|
syntax_error("Invalid destructuring assignment target", expression_position);
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
} else if (match(TokenType::CurlyOpen) || match(TokenType::BracketOpen)) {
|
} else if (match(TokenType::CurlyOpen) || match(TokenType::BracketOpen)) {
|
||||||
auto binding_pattern = parse_binding_pattern(allow_duplicates, allow_member_expressions);
|
auto binding_pattern = parse_binding_pattern(allow_duplicates, allow_member_expressions);
|
||||||
|
@ -3131,16 +3136,19 @@ RefPtr<BindingPattern const> Parser::parse_binding_pattern(Parser::AllowDuplicat
|
||||||
auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals });
|
auto expression = parse_expression(2, Associativity::Right, { TokenType::Equals });
|
||||||
|
|
||||||
if (is<ArrayExpression>(*expression) || is<ObjectExpression>(*expression)) {
|
if (is<ArrayExpression>(*expression) || is<ObjectExpression>(*expression)) {
|
||||||
if (auto synthesized_binding_pattern = synthesize_binding_pattern(*expression))
|
if (auto synthesized_binding_pattern = synthesize_binding_pattern(*expression)) {
|
||||||
alias = synthesized_binding_pattern.release_nonnull();
|
alias = synthesized_binding_pattern.release_nonnull();
|
||||||
else
|
} else {
|
||||||
syntax_error("Invalid destructuring assignment target", expression_position);
|
syntax_error("Invalid destructuring assignment target", expression_position);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
} else if (is<MemberExpression>(*expression)) {
|
} else if (is<MemberExpression>(*expression)) {
|
||||||
alias = static_ptr_cast<MemberExpression const>(expression);
|
alias = static_ptr_cast<MemberExpression const>(expression);
|
||||||
} else if (is<Identifier>(*expression)) {
|
} else if (is<Identifier>(*expression)) {
|
||||||
alias = static_ptr_cast<Identifier const>(expression);
|
alias = static_ptr_cast<Identifier const>(expression);
|
||||||
} else {
|
} else {
|
||||||
syntax_error("Invalid destructuring assignment target", expression_position);
|
syntax_error("Invalid destructuring assignment target", expression_position);
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
} else if (match(TokenType::BracketOpen) || match(TokenType::CurlyOpen)) {
|
} else if (match(TokenType::BracketOpen) || match(TokenType::CurlyOpen)) {
|
||||||
auto pattern = parse_binding_pattern(allow_duplicates, allow_member_expressions);
|
auto pattern = parse_binding_pattern(allow_duplicates, allow_member_expressions);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
test("Assigning to an invalid destructuring assignment target should fail immediately", () => {
|
||||||
|
expect(() => {
|
||||||
|
eval("[[function=a{1,}=");
|
||||||
|
}).toThrow(SyntaxError);
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue