From 530c2f9e4c9757c457fcc0a8b46ed914664c46e3 Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Fri, 2 Dec 2022 13:45:54 +0100 Subject: [PATCH] [FIX] compiler: correctly escape backslashes when emitting block string Previously, when a template contained backslashes, they were not escaped when creating the blockstring, meaning they would be interpreted as an escape sequence within the JS string. This means that backslashes preceding most characters were completely ignored and didn't end up in the final block, double backslashes were collapsed to a single one, and backslashes that constituted valid escape sequences in JS would be treated as those (eg, \n would be a newline). When creating a JS string expression from a string value, all characters with special meaning in JS should be escaped, we were correctly escaping backticks as these would unexpectedly close the string if not escaped, but forgot to escape backslashes. This commit fixes that. closes #1300 --- src/compiler/code_generator.ts | 2 +- .../compiler/__snapshots__/attributes.test.ts.snap | 13 +++++++++++++ tests/compiler/attributes.test.ts | 5 +++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/compiler/code_generator.ts b/src/compiler/code_generator.ts index 479a6c0f..b401ff5d 100644 --- a/src/compiler/code_generator.ts +++ b/src/compiler/code_generator.ts @@ -294,7 +294,7 @@ export class CodeGenerator { for (let block of this.blocks) { if (block.dom) { let xmlString = block.asXmlString(); - xmlString = xmlString.replace(/`/g, "\\`"); + xmlString = xmlString.replace(/\\/g, "\\\\").replace(/`/g, "\\`"); if (block.dynamicTagName) { xmlString = xmlString.replace(/^<\w+/, `<\${tag || '${block.dom.nodeName}'}`); xmlString = xmlString.replace(/\w+>$/, `\${tag || '${block.dom.nodeName}'}>`); diff --git a/tests/compiler/__snapshots__/attributes.test.ts.snap b/tests/compiler/__snapshots__/attributes.test.ts.snap index c536cefd..6fc68183 100644 --- a/tests/compiler/__snapshots__/attributes.test.ts.snap +++ b/tests/compiler/__snapshots__/attributes.test.ts.snap @@ -430,6 +430,19 @@ exports[`attributes static attributes on void elements 1`] = ` }" `; +exports[`attributes static attributes with backslash or backtick 1`] = ` +"function anonymous(app, bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, comment } = bdom; + + let block1 = createBlock(\`
\`); + + return function template(ctx, node, key = \\"\\") { + return block1(); + } +}" +`; + exports[`attributes static attributes with backticks 1`] = ` "function anonymous(app, bdom, helpers ) { diff --git a/tests/compiler/attributes.test.ts b/tests/compiler/attributes.test.ts index f88290b2..e2a86b3e 100644 --- a/tests/compiler/attributes.test.ts +++ b/tests/compiler/attributes.test.ts @@ -12,6 +12,11 @@ describe("attributes", () => { expect(renderToString(template)).toBe(`
`); }); + test("static attributes with backslash or backtick", () => { + const template = `
`; + expect(renderToString(template)).toBe(`
`); + }); + test("two classes", () => { const template = `
`; expect(renderToString(template)).toBe(`
`);