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/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 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