summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authordavidot <davidot@serenityos.org>2022-11-14 21:52:58 +0100
committerLinus Groh <mail@linusgroh.de>2022-11-15 12:00:36 +0000
commitb3edd9486966b8ec611a117335bce676dbc12161 (patch)
tree01a735994e5a8b5c06267d110c5d0e4d1895280e /Userland/Libraries
parent8e624c8f6dd891abf02dadba803436173e7cc344 (diff)
downloadserenity-b3edd9486966b8ec611a117335bce676dbc12161.zip
LibJS: Treat '\\' as an escaped character in template literals
Before this change we would ignore that the second backslash is escaped and template strings ending with ` \\` would be unterminated as the second slash was used to escape the closing quote.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibJS/Lexer.cpp9
-rw-r--r--Userland/Libraries/LibJS/Tests/template-literals.js3
2 files changed, 11 insertions, 1 deletions
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"}');
});