mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:57:43 +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:
parent
063228c02e
commit
d69ed91790
3 changed files with 11 additions and 9 deletions
|
@ -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; }
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue