[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
This commit is contained in:
Samuel Degueldre
2022-12-02 13:45:54 +01:00
committed by Géry Debongnie
parent ef8baa23d7
commit 530c2f9e4c
3 changed files with 19 additions and 1 deletions
+1 -1
View File
@@ -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}'}>`);
@@ -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(\`<div foo=\\"\\\\\\\\a\\" bar=\\"\\\\\\\\n\\" baz=\\"\\\\\`\\"/>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`attributes static attributes with backticks 1`] = `
"function anonymous(app, bdom, helpers
) {
+5
View File
@@ -12,6 +12,11 @@ describe("attributes", () => {
expect(renderToString(template)).toBe(`<div foo="a" bar="b" baz="c"></div>`);
});
test("static attributes with backslash or backtick", () => {
const template = `<div foo="\\a" bar="\\n" baz="\`"/>`;
expect(renderToString(template)).toBe(`<div foo="\\a" bar="\\n" baz="\`"></div>`);
});
test("two classes", () => {
const template = `<div class="a b"/>`;
expect(renderToString(template)).toBe(`<div class="a b"></div>`);