mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:57:34 +00:00
LibJS: Disallow multiple __proto__ keys in object expression
This commit is contained in:
parent
93b57e6d8c
commit
697882a7ad
1 changed files with 14 additions and 0 deletions
|
@ -968,6 +968,11 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||||
consume();
|
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)) {
|
while (!done() && !match(TokenType::CurlyClose)) {
|
||||||
property_type = ObjectProperty::Type::KeyValue;
|
property_type = ObjectProperty::Type::KeyValue;
|
||||||
RefPtr<Expression> property_name;
|
RefPtr<Expression> property_name;
|
||||||
|
@ -984,6 +989,8 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto type = m_state.current_token.type();
|
||||||
|
|
||||||
if (match(TokenType::Asterisk)) {
|
if (match(TokenType::Asterisk)) {
|
||||||
consume();
|
consume();
|
||||||
property_type = ObjectProperty::Type::KeyValue;
|
property_type = ObjectProperty::Type::KeyValue;
|
||||||
|
@ -1005,6 +1012,8 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||||
property_name = parse_property_key();
|
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 (property_type == ObjectProperty::Type::Getter || property_type == ObjectProperty::Type::Setter) {
|
||||||
if (!match(TokenType::ParenOpen)) {
|
if (!match(TokenType::ParenOpen)) {
|
||||||
expected("'(' for object getter or setter property");
|
expected("'(' for object getter or setter property");
|
||||||
|
@ -1037,6 +1046,11 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
consume();
|
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));
|
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) {
|
} 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));
|
properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_name, *property_value, property_type, false));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue