From c2ebaa9d87fc896623c09fcf299284b1ae5a8ba0 Mon Sep 17 00:00:00 2001 From: davidot Date: Sat, 27 Nov 2021 00:16:01 +0100 Subject: LibJS: Replace the verify in private identifier with a syntax error Since sometimes expressions are parsed without checking we can hit this expression without it being followed by an 'in'. --- Userland/Libraries/LibJS/Parser.cpp | 5 +++-- .../Libraries/LibJS/Tests/classes/class-private-fields.js | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'Userland/Libraries') diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 4ea3b10a9a..184571ba31 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -1439,7 +1439,8 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression() goto read_as_identifier; return { parse_await_expression() }; case TokenType::PrivateIdentifier: - VERIFY(next_token().type() == TokenType::In); + if (next_token().type() != TokenType::In) + syntax_error("Cannot have a private identifier in expression if not followed by 'in'"); if (!is_private_identifier_valid()) syntax_error(String::formatted("Reference to undeclared private field or method '{}'", m_state.current_token.value())); return { create_ast_node({ m_state.current_token.filename(), rule_start.position(), position() }, consume().value()) }; @@ -3483,7 +3484,7 @@ bool Parser::match_expression() const || type == TokenType::TemplateLiteralStart || type == TokenType::NullLiteral || match_identifier() - || (type == TokenType::PrivateIdentifier && next_token().type() == TokenType::In) + || type == TokenType::PrivateIdentifier || type == TokenType::Await || type == TokenType::New || type == TokenType::Class diff --git a/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js b/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js index 286019a538..2eebaa6245 100644 --- a/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js +++ b/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js @@ -96,6 +96,18 @@ test("slash after private identifier is treated as division", () => { expect(A.getDivided()).toBe(2); }); +test("private identifier not followed by 'in' throws", () => { + expect(`class A { #field = 2; method() { return #field instanceof 1; }}`).not.toEval(); + expect(`class A { #field = 2; method() { return #field < 1; }}`).not.toEval(); + expect(`class A { #field = 2; method() { return #field + 1; }}`).not.toEval(); + expect(`class A { #field = 2; method() { return #field ** 1; }}`).not.toEval(); + expect(`class A { #field = 2; method() { return !#field; } }`).not.toEval(); + expect(`class A { #field = 2; method() { return ~#field; } }`).not.toEval(); + expect(`class A { #field = 2; method() { return ++#field; } }`).not.toEval(); + + expect(`class A { #field = 2; method() { return #field in 1; }}`).toEval(); +}); + test("cannot have static and non static field with the same description", () => { expect("class A { static #simple; #simple; }").not.toEval(); }); -- cgit v1.2.3