diff --git a/Userland/Libraries/LibJS/Lexer.cpp b/Userland/Libraries/LibJS/Lexer.cpp index 17dec6c963..0baad82b58 100644 --- a/Userland/Libraries/LibJS/Lexer.cpp +++ b/Userland/Libraries/LibJS/Lexer.cpp @@ -610,8 +610,15 @@ Token Lexer::next() consume(); m_template_states.last().in_expr = true; } else { + // TemplateCharacter :: + // $ [lookahead ≠ {] + // \ TemplateEscapeSequence + // \ NotEscapeSequence + // LineContinuation + // LineTerminatorSequence + // SourceCharacter but not one of ` or \ or $ or LineTerminator while (!match('$', '{') && m_current_char != '`' && !is_eof()) { - if (match('\\', '$') || match('\\', '`')) + if (match('\\', '$') || match('\\', '`') || match('\\', '\\')) consume(); consume(); } diff --git a/Userland/Libraries/LibJS/Tests/template-literals.js b/Userland/Libraries/LibJS/Tests/template-literals.js index 985be79fa1..5bbe8590cc 100644 --- a/Userland/Libraries/LibJS/Tests/template-literals.js +++ b/Userland/Libraries/LibJS/Tests/template-literals.js @@ -7,6 +7,9 @@ test("plain literals with expression-like characters", () => { test("plain literals with escaped special characters", () => { expect(`foo\``).toBe("foo`"); + expect(`foo\\`).toBe("foo\\"); + expect(`foo\\\``).toBe("foo\\`"); + expect(`foo\\\\`).toBe("foo\\\\"); expect(`foo\$`).toBe("foo$"); expect(`foo \${"bar"}`).toBe('foo ${"bar"}'); });