From b65ab427ad5b0742f708877319203c2cc9d7e304 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Fri, 9 Feb 2018 01:07:12 -0500 Subject: [PATCH 1/3] fix escaping of sigils in component attribute values in SSR --- src/generators/server-side-rendering/visitors/Component.ts | 4 ++-- test/runtime/samples/sigil-component-attribute/Widget.html | 1 + test/runtime/samples/sigil-component-attribute/_config.js | 4 ++++ test/runtime/samples/sigil-component-attribute/main.html | 6 ++++++ 4 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 test/runtime/samples/sigil-component-attribute/Widget.html create mode 100644 test/runtime/samples/sigil-component-attribute/_config.js create mode 100644 test/runtime/samples/sigil-component-attribute/main.html diff --git a/src/generators/server-side-rendering/visitors/Component.ts b/src/generators/server-side-rendering/visitors/Component.ts index 4843010fcb..2169ee9b6e 100644 --- a/src/generators/server-side-rendering/visitors/Component.ts +++ b/src/generators/server-side-rendering/visitors/Component.ts @@ -6,7 +6,7 @@ import { AppendTarget } from '../interfaces'; import { Node } from '../../../interfaces'; import getObject from '../../../utils/getObject'; import getTailSnippet from '../../../utils/getTailSnippet'; -import { stringify } from '../../../utils/stringify'; +import { escape, stringify } from '../../../utils/stringify'; export default function visitComponent( generator: SsrGenerator, @@ -14,7 +14,7 @@ export default function visitComponent( node: Node ) { function stringifyAttribute(chunk: Node) { - if (chunk.type === 'Text') return chunk.data; + if (chunk.type === 'Text') return escape(chunk.data); if (chunk.type === 'MustacheTag') { block.contextualise(chunk.expression); const { snippet } = chunk.metadata; diff --git a/test/runtime/samples/sigil-component-attribute/Widget.html b/test/runtime/samples/sigil-component-attribute/Widget.html new file mode 100644 index 0000000000..f0136f9405 --- /dev/null +++ b/test/runtime/samples/sigil-component-attribute/Widget.html @@ -0,0 +1 @@ +
{{value}}
diff --git a/test/runtime/samples/sigil-component-attribute/_config.js b/test/runtime/samples/sigil-component-attribute/_config.js new file mode 100644 index 0000000000..079bf3e9ab --- /dev/null +++ b/test/runtime/samples/sigil-component-attribute/_config.js @@ -0,0 +1,4 @@ +export default { + data: { foo: 'foo' }, + html: `
foo @ foo # foo
`, +}; diff --git a/test/runtime/samples/sigil-component-attribute/main.html b/test/runtime/samples/sigil-component-attribute/main.html new file mode 100644 index 0000000000..c9302309d2 --- /dev/null +++ b/test/runtime/samples/sigil-component-attribute/main.html @@ -0,0 +1,6 @@ + + + From b3e8cfece1aaead38072a8db2c1d4f26eea27e9b Mon Sep 17 00:00:00 2001 From: Conduitry Date: Fri, 9 Feb 2018 01:28:00 -0500 Subject: [PATCH 2/3] fix escaping of template string characters --- src/generators/server-side-rendering/visitors/Component.ts | 6 ++++-- src/generators/server-side-rendering/visitors/Text.ts | 4 ++-- .../visitors/shared/stringifyAttributeValue.ts | 4 ++-- src/utils/stringify.ts | 4 ++++ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/generators/server-side-rendering/visitors/Component.ts b/src/generators/server-side-rendering/visitors/Component.ts index 2169ee9b6e..a5cef9120f 100644 --- a/src/generators/server-side-rendering/visitors/Component.ts +++ b/src/generators/server-side-rendering/visitors/Component.ts @@ -6,7 +6,7 @@ import { AppendTarget } from '../interfaces'; import { Node } from '../../../interfaces'; import getObject from '../../../utils/getObject'; import getTailSnippet from '../../../utils/getTailSnippet'; -import { escape, stringify } from '../../../utils/stringify'; +import { escape, escapeTemplate, stringify } from '../../../utils/stringify'; export default function visitComponent( generator: SsrGenerator, @@ -14,7 +14,9 @@ export default function visitComponent( node: Node ) { function stringifyAttribute(chunk: Node) { - if (chunk.type === 'Text') return escape(chunk.data); + if (chunk.type === 'Text') { + return escapeTemplate(escape(chunk.data)); + } if (chunk.type === 'MustacheTag') { block.contextualise(chunk.expression); const { snippet } = chunk.metadata; diff --git a/src/generators/server-side-rendering/visitors/Text.ts b/src/generators/server-side-rendering/visitors/Text.ts index 44b1665b2b..092aa535c0 100644 --- a/src/generators/server-side-rendering/visitors/Text.ts +++ b/src/generators/server-side-rendering/visitors/Text.ts @@ -1,6 +1,6 @@ import { SsrGenerator } from '../index'; import Block from '../Block'; -import { escape, escapeHTML } from '../../../utils/stringify'; +import { escape, escapeHTML, escapeTemplate } from '../../../utils/stringify'; import { Node } from '../../../interfaces'; export default function visitText( @@ -8,5 +8,5 @@ export default function visitText( block: Block, node: Node ) { - generator.append(escapeHTML(escape(node.data).replace(/(\${|`|\\)/g, '\\$1'))); + generator.append(escapeTemplate(escapeHTML(escape(node.data)))); } diff --git a/src/generators/server-side-rendering/visitors/shared/stringifyAttributeValue.ts b/src/generators/server-side-rendering/visitors/shared/stringifyAttributeValue.ts index d2df80beab..a5399414cd 100644 --- a/src/generators/server-side-rendering/visitors/shared/stringifyAttributeValue.ts +++ b/src/generators/server-side-rendering/visitors/shared/stringifyAttributeValue.ts @@ -1,12 +1,12 @@ import Block from '../../Block'; -import { escape } from '../../../../utils/stringify'; +import { escape, escapeTemplate } from '../../../../utils/stringify'; import { Node } from '../../../../interfaces'; export default function stringifyAttributeValue(block: Block, chunks: Node[]) { return chunks .map((chunk: Node) => { if (chunk.type === 'Text') { - return escape(chunk.data).replace(/"/g, '"'); + return escapeTemplate(escape(chunk.data).replace(/"/g, '"')); } block.contextualise(chunk.expression); diff --git a/src/utils/stringify.ts b/src/utils/stringify.ts index 0fb151c162..43cbd934c3 100644 --- a/src/utils/stringify.ts +++ b/src/utils/stringify.ts @@ -17,3 +17,7 @@ const escaped = { export function escapeHTML(html) { return String(html).replace(/[&<>]/g, match => escaped[match]); } + +export function escapeTemplate(str) { + return str.replace(/(\${|`|\\)/g, '\\$1'); +} From acc7c244eded7e5eef66d27d7da12eb7a4870911 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Fri, 9 Feb 2018 01:34:25 -0500 Subject: [PATCH 3/3] expand escape-template-literals test --- test/runtime/samples/escape-template-literals/Widget.html | 1 + test/runtime/samples/escape-template-literals/_config.js | 2 +- test/runtime/samples/escape-template-literals/main.html | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/escape-template-literals/Widget.html diff --git a/test/runtime/samples/escape-template-literals/Widget.html b/test/runtime/samples/escape-template-literals/Widget.html new file mode 100644 index 0000000000..f0136f9405 --- /dev/null +++ b/test/runtime/samples/escape-template-literals/Widget.html @@ -0,0 +1 @@ +
{{value}}
diff --git a/test/runtime/samples/escape-template-literals/_config.js b/test/runtime/samples/escape-template-literals/_config.js index df22784ba7..1419d65679 100644 --- a/test/runtime/samples/escape-template-literals/_config.js +++ b/test/runtime/samples/escape-template-literals/_config.js @@ -1,3 +1,3 @@ export default { - html: '`${foo}\\n`' + html: '`${foo}\\n`\n
foo
\n
`${foo}\\n`
', }; diff --git a/test/runtime/samples/escape-template-literals/main.html b/test/runtime/samples/escape-template-literals/main.html index 4705d114d2..138b390cfa 100644 --- a/test/runtime/samples/escape-template-literals/main.html +++ b/test/runtime/samples/escape-template-literals/main.html @@ -1 +1,8 @@ `${foo}\n` +
foo
+ + +