diff options
author | davidot <davidot@serenityos.org> | 2022-11-17 10:24:20 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-11-17 16:05:20 +0000 |
commit | 16ac43c9d4f5ac61a7be2b679773e696592e2216 (patch) | |
tree | 88b248a9289622872a8275be65f5c82c3be6f4f0 | |
parent | 49fc0e251447e7e68c5935a4069ab26dda489456 (diff) | |
download | serenity-16ac43c9d4f5ac61a7be2b679773e696592e2216.zip |
LibJS: Make sure private identifier is valid in optional chain
If we don't check that a private identifier is valid this can break the
assumption that we have a private environment when evaluation the
private identifier. Also an unknown private identifier this should
be a SyntaxError.
-rw-r--r-- | Userland/Libraries/LibJS/Parser.cpp | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Tests/classes/class-private-fields.js | 35 |
2 files changed, 38 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 06ee18cefc..7af6cd93e7 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -3174,6 +3174,9 @@ NonnullRefPtr<OptionalChain> Parser::parse_optional_chain(NonnullRefPtr<Expressi } else if (match(TokenType::Period)) { consume(); if (match(TokenType::PrivateIdentifier)) { + if (!is_private_identifier_valid()) + syntax_error(String::formatted("Reference to undeclared private field or method '{}'", m_state.current_token.value())); + auto start = position(); auto private_identifier = consume(); chain.append(OptionalChain::PrivateMemberReference { diff --git a/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js b/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js index a00dd74235..30017ad78b 100644 --- a/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js +++ b/Userland/Libraries/LibJS/Tests/classes/class-private-fields.js @@ -148,3 +148,38 @@ test("using 'arguments' via indirect eval throws at runtime instead of parse tim } }).toThrowWithMessage(ReferenceError, "'arguments' is not defined"); }); + +test("unknown private name gives SyntaxError", () => { + expect(`#n`).not.toEval(); + expect(`obj.#n`).not.toEval(); + expect(`this.#n`).not.toEval(); + expect(`if (#n) 1;`).not.toEval(); + expect(`1?.#n`).not.toEval(); + expect(`1?.n.#n`).not.toEval(); +}); + +// OSS-FUZZ Issue 53363: top level unknown private names seg faults +expect(() => eval(`#n`)).toThrowWithMessage( + SyntaxError, + "Reference to undeclared private field or method '#n'" +); +expect(() => eval(`obj.#n`)).toThrowWithMessage( + SyntaxError, + "Reference to undeclared private field or method '#n'" +); +expect(() => eval(`this.#n`)).toThrowWithMessage( + SyntaxError, + "Reference to undeclared private field or method '#n'" +); +expect(() => eval(`if (#n) 1;`)).toThrowWithMessage( + SyntaxError, + "Reference to undeclared private field or method '#n'" +); +expect(() => eval(`1?.#n`)).toThrowWithMessage( + SyntaxError, + "Reference to undeclared private field or method '#n'" +); +expect(() => eval(`1?.n.#n`)).toThrowWithMessage( + SyntaxError, + "Reference to undeclared private field or method '#n'" +); |