From 0974991d051517802ad319022d9e46313d6cd4d4 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Mon, 14 Dec 2020 13:05:24 +0000 Subject: LibJS: Don't treat '?.' followed by decimal digit as QuestionMarkPeriod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the spec: https://tc39.es/ecma262/#sec-punctuators OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] We were missing the lookahead and therefore incorrectly treating any '?.' as TokenType::QuestionMarkPeriod. Fixes #4409. --- Libraries/LibJS/Lexer.cpp | 11 +++++++---- Libraries/LibJS/Tests/operators/ternary-basic.js | 4 ++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Libraries/LibJS/Lexer.cpp b/Libraries/LibJS/Lexer.cpp index 047c5437e9..89758ded1c 100644 --- a/Libraries/LibJS/Lexer.cpp +++ b/Libraries/LibJS/Lexer.cpp @@ -598,10 +598,13 @@ Token Lexer::next() auto two_chars_view = m_source.substring_view(m_position - 1, 2); auto it = s_two_char_tokens.find(two_chars_view.hash(), [&](auto& entry) { return entry.key == two_chars_view; }); if (it != s_two_char_tokens.end()) { - found_two_char_token = true; - consume(); - consume(); - token_type = it->value; + // OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] + if (!(it->value == TokenType::QuestionMarkPeriod && m_position + 1 < m_source.length() && isdigit(m_source[m_position + 1]))) { + found_two_char_token = true; + consume(); + consume(); + token_type = it->value; + } } } diff --git a/Libraries/LibJS/Tests/operators/ternary-basic.js b/Libraries/LibJS/Tests/operators/ternary-basic.js index 164d01e534..c0f68fdf83 100644 --- a/Libraries/LibJS/Tests/operators/ternary-basic.js +++ b/Libraries/LibJS/Tests/operators/ternary-basic.js @@ -14,3 +14,7 @@ test("object values", () => { expect(o.f ? true : false).toBeTrue(); expect(1 ? o.f : null).toBeTrue(); }); + +test("issue #4409, '?.' followed by decimal digit", () => { + expect("return false?.1:.2").toEvalTo(0.2); +}); -- cgit v1.2.3