1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:57:35 +00:00

LibJS: Check AssignmentExpression LHS in parser

There are many cases which shouldn't even parse, like

null = ...
true = ...
false = ...
123 = ...
"foo" = ...

However this *is* valid syntax:

foo() = ...

So we still have to keep the current code doing a runtime check if the
LHS value is a resolvable reference. I believe this was declared valid
syntax to *in theory* allow functions returning references - though in
practice that isn't a thing.

Fixes #2204.
This commit is contained in:
Linus Groh 2020-05-12 21:19:48 +01:00 committed by Andreas Kling
parent 063228c02e
commit d69ed91790
3 changed files with 11 additions and 9 deletions

View file

@ -60,6 +60,7 @@ public:
virtual bool is_scope_node() const { return false; }
virtual bool is_program() const { return false; }
virtual bool is_variable_declaration() const { return false; }
virtual bool is_call_expression() const { return false; }
virtual bool is_new_expression() const { return false; }
protected:
@ -583,6 +584,7 @@ public:
private:
virtual const char* class_name() const override { return "CallExpression"; }
virtual bool is_call_expression() const override { return true; }
struct ThisAndCallee {
Value this_value;
@ -603,6 +605,7 @@ public:
private:
virtual const char* class_name() const override { return "NewExpression"; }
virtual bool is_call_expression() const override { return false; }
virtual bool is_new_expression() const override { return true; }
};

View file

@ -755,6 +755,10 @@ NonnullRefPtr<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expre
return parse_call_expression(move(lhs));
case TokenType::Equals:
consume();
if (!lhs->is_identifier() && !lhs->is_member_expression() && !lhs->is_call_expression()) {
syntax_error("Invalid left-hand side in assignment");
return create_ast_node<ErrorExpression>();
}
return create_ast_node<AssignmentExpression>(AssignmentOp::Assignment, move(lhs), parse_expression(min_precedence, associativity));
case TokenType::Period:
consume();

View file

@ -1,22 +1,17 @@
load("test-common.js");
try {
function foo() { }
assertThrowsError(() => {
512 = 256;
foo() = "foo";
}, {
error: ReferenceError,
message: "Invalid left-hand side in assignment"
});
assertThrowsError(() => {
512 = 256;
}, {
error: ReferenceError,
message: "Invalid left-hand side in assignment"
});
assertThrowsError(() => {
"hello world" = "another thing?";
(function () { })() = "foo";
}, {
error: ReferenceError,
message: "Invalid left-hand side in assignment"