From d4d7ef9c047fb867b4163c6a2709f1654d8c6d42 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 4 Jan 2018 22:33:55 -0500 Subject: [PATCH 1/3] failing tests for #1066 --- test/parser/samples/html-entities/input.html | 1 + test/parser/samples/html-entities/output.json | 42 +++++++++++++++++++ .../html-entities-inside-elements/_config.js | 5 +++ .../html-entities-inside-elements/main.html | 1 + 4 files changed, 49 insertions(+) create mode 100644 test/parser/samples/html-entities/input.html create mode 100644 test/parser/samples/html-entities/output.json create mode 100644 test/runtime/samples/html-entities-inside-elements/_config.js create mode 100644 test/runtime/samples/html-entities-inside-elements/main.html diff --git a/test/parser/samples/html-entities/input.html b/test/parser/samples/html-entities/input.html new file mode 100644 index 0000000000..69aa63b174 --- /dev/null +++ b/test/parser/samples/html-entities/input.html @@ -0,0 +1 @@ +

this <em>should</em> not be <strong>bold</strong>

\ No newline at end of file diff --git a/test/parser/samples/html-entities/output.json b/test/parser/samples/html-entities/output.json new file mode 100644 index 0000000000..1bfda7ae26 --- /dev/null +++ b/test/parser/samples/html-entities/output.json @@ -0,0 +1,42 @@ +{ + "hash": 488075009, + "html": { + "start": 0, + "end": 93, + "type": "Fragment", + "children": [ + { + "start": 0, + "end": 93, + "type": "Element", + "name": "p", + "attributes": [], + "children": [ + { + "start": 3, + "end": 43, + "type": "Text", + "data": "this <em>should</em> not be " + }, + { + "start": 43, + "end": 89, + "type": "Element", + "name": "span", + "attributes": [], + "children": [ + { + "start": 49, + "end": 82, + "type": "Text", + "data": "<strong>bold</strong>" + } + ] + } + ] + } + ] + }, + "css": null, + "js": null +} \ No newline at end of file diff --git a/test/runtime/samples/html-entities-inside-elements/_config.js b/test/runtime/samples/html-entities-inside-elements/_config.js new file mode 100644 index 0000000000..a53af0a297 --- /dev/null +++ b/test/runtime/samples/html-entities-inside-elements/_config.js @@ -0,0 +1,5 @@ +export default { + html: ` +

this <em>should</em> not be <strong>bold</strong>

+ ` +}; \ No newline at end of file diff --git a/test/runtime/samples/html-entities-inside-elements/main.html b/test/runtime/samples/html-entities-inside-elements/main.html new file mode 100644 index 0000000000..69aa63b174 --- /dev/null +++ b/test/runtime/samples/html-entities-inside-elements/main.html @@ -0,0 +1 @@ +

this <em>should</em> not be <strong>bold</strong>

\ No newline at end of file From d280d1d458f9ffe24829dc0b1af5d92c3309771e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 4 Jan 2018 22:50:52 -0500 Subject: [PATCH 2/3] remove incorrect test --- test/parser/samples/html-entities/input.html | 1 - test/parser/samples/html-entities/output.json | 42 ------------------- 2 files changed, 43 deletions(-) delete mode 100644 test/parser/samples/html-entities/input.html delete mode 100644 test/parser/samples/html-entities/output.json diff --git a/test/parser/samples/html-entities/input.html b/test/parser/samples/html-entities/input.html deleted file mode 100644 index 69aa63b174..0000000000 --- a/test/parser/samples/html-entities/input.html +++ /dev/null @@ -1 +0,0 @@ -

this <em>should</em> not be <strong>bold</strong>

\ No newline at end of file diff --git a/test/parser/samples/html-entities/output.json b/test/parser/samples/html-entities/output.json deleted file mode 100644 index 1bfda7ae26..0000000000 --- a/test/parser/samples/html-entities/output.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "hash": 488075009, - "html": { - "start": 0, - "end": 93, - "type": "Fragment", - "children": [ - { - "start": 0, - "end": 93, - "type": "Element", - "name": "p", - "attributes": [], - "children": [ - { - "start": 3, - "end": 43, - "type": "Text", - "data": "this <em>should</em> not be " - }, - { - "start": 43, - "end": 89, - "type": "Element", - "name": "span", - "attributes": [], - "children": [ - { - "start": 49, - "end": 82, - "type": "Text", - "data": "<strong>bold</strong>" - } - ] - } - ] - } - ] - }, - "css": null, - "js": null -} \ No newline at end of file From 7026222792d437f0e39a4ec4fd6b7924c2a7dfc9 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 4 Jan 2018 22:51:28 -0500 Subject: [PATCH 3/3] escape HTML - fixes #1066 --- src/generators/nodes/Element.ts | 4 ++-- .../server-side-rendering/visitors/Text.ts | 4 ++-- src/utils/stringify.ts | 12 ++++++++++++ .../samples/component-data-empty/_actual.html | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/generators/nodes/Element.ts b/src/generators/nodes/Element.ts index f66882677d..5c0ffabf14 100644 --- a/src/generators/nodes/Element.ts +++ b/src/generators/nodes/Element.ts @@ -1,5 +1,5 @@ import deindent from '../../utils/deindent'; -import { stringify } from '../../utils/stringify'; +import { stringify, escapeHTML } from '../../utils/stringify'; import flattenReference from '../../utils/flattenReference'; import isVoidElementName from '../../utils/isVoidElementName'; import validCalleeObjects from '../../utils/validCalleeObjects'; @@ -414,7 +414,7 @@ export default class Element extends Node { } function toHTML(node: Element | Text) { - if (node.type === 'Text') return node.data; + if (node.type === 'Text') return escapeHTML(node.data); let open = `<${node.name}`; diff --git a/src/generators/server-side-rendering/visitors/Text.ts b/src/generators/server-side-rendering/visitors/Text.ts index 0e897aaaa6..44b1665b2b 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 } from '../../../utils/stringify'; +import { escape, escapeHTML } 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(escape(node.data).replace(/(\${|`|\\)/g, '\\$1')); + generator.append(escapeHTML(escape(node.data).replace(/(\${|`|\\)/g, '\\$1'))); } diff --git a/src/utils/stringify.ts b/src/utils/stringify.ts index 26037827c7..b5f982eb1d 100644 --- a/src/utils/stringify.ts +++ b/src/utils/stringify.ts @@ -7,3 +7,15 @@ export function escape(data: string, { onlyEscapeAtSymbol = false } = {}) { return match + match[0]; }); } + +const escaped = { + '"': '"', + "'": '&##39;', + '&': '&', + '<': '<', + '>': '>' +}; + +export function escapeHTML(html) { + return String(html).replace(/["'&<>]/g, match => escaped[match]); +} \ No newline at end of file diff --git a/test/server-side-rendering/samples/component-data-empty/_actual.html b/test/server-side-rendering/samples/component-data-empty/_actual.html index 85fe1fe733..55ea8a032c 100644 --- a/test/server-side-rendering/samples/component-data-empty/_actual.html +++ b/test/server-side-rendering/samples/component-data-empty/_actual.html @@ -1,3 +1,3 @@
-

foo: ''

+

foo: ''

\ No newline at end of file