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

LibJS: Disallow multiple __proto__ keys in object expression

This commit is contained in:
davidot 2021-07-12 01:32:01 +02:00 committed by Andreas Kling
parent 93b57e6d8c
commit 697882a7ad

View file

@ -968,6 +968,11 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
consume();
};
// It is a Syntax Error if PropertyNameList of PropertyDefinitionList contains any duplicate
// entries for "__proto__" and at least two of those entries were obtained from productions of
// the form PropertyDefinition : PropertyName : AssignmentExpression .
bool has_direct_proto_property = false;
while (!done() && !match(TokenType::CurlyClose)) {
property_type = ObjectProperty::Type::KeyValue;
RefPtr<Expression> property_name;
@ -984,6 +989,8 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
continue;
}
auto type = m_state.current_token.type();
if (match(TokenType::Asterisk)) {
consume();
property_type = ObjectProperty::Type::KeyValue;
@ -1005,6 +1012,8 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
property_name = parse_property_key();
}
bool is_proto = (type == TokenType::StringLiteral || type == TokenType::Identifier) && is<StringLiteral>(*property_name) && static_cast<StringLiteral const&>(*property_name).value() == "__proto__";
if (property_type == ObjectProperty::Type::Getter || property_type == ObjectProperty::Type::Setter) {
if (!match(TokenType::ParenOpen)) {
expected("'(' for object getter or setter property");
@ -1037,6 +1046,11 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
continue;
}
consume();
if (is_proto) {
if (has_direct_proto_property)
syntax_error("Property name '__proto__' must not appear more than once in object literal");
has_direct_proto_property = true;
}
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_name, parse_expression(2), property_type, false));
} else if (property_name && property_value) {
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_name, *property_value, property_type, false));