Skip to content

Commit 8d04da6

Browse files
authored
Merge pull request #1086 from sveltejs/gh-1082
[WIP] Fix HTML escaping and non-top-level <script> and <style> issues
2 parents dbe8105 + f6e6cb6 commit 8d04da6

File tree

7 files changed

+23
-8
lines changed

7 files changed

+23
-8
lines changed

src/generators/nodes/Element.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,10 @@ export default class Element extends Node {
432432

433433
if (isVoidElementName(node.name)) return open + '>';
434434

435+
if (node.name === 'script' || node.name === 'style') {
436+
return `${open}>${node.data}</${node.name}>`;
437+
}
438+
435439
return `${open}>${node.children.map(toHTML).join('')}</${node.name}>`;
436440
}
437441
}
@@ -756,4 +760,4 @@ const events = [
756760
node.isMediaNode() &&
757761
(name === 'buffered' || name === 'seekable')
758762
}
759-
];
763+
];

src/generators/server-side-rendering/visitors/Element.ts

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ export default function visitElement(
6060

6161
if (node.name === 'textarea' && textareaContents !== undefined) {
6262
generator.append(textareaContents);
63+
} else if (node.name === 'script' || node.name === 'style') {
64+
generator.append(node.data);
6365
} else {
6466
node.children.forEach((child: Node) => {
6567
visit(generator, block, child);

src/parse/state/tag.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ export default function tag(parser: Parser) {
213213
parser.eat('>', true);
214214

215215
if (selfClosing) {
216+
// don't push self-closing elements onto the stack
216217
element.end = parser.index;
217218
} else if (name === 'textarea') {
218219
// special case
@@ -223,8 +224,12 @@ export default function tag(parser: Parser) {
223224
);
224225
parser.read(/<\/textarea>/);
225226
element.end = parser.index;
227+
} else if (name === 'script' || name === 'style') {
228+
// special case
229+
element.data = parser.readUntil(new RegExp(`</${name}>`));
230+
parser.eat(`</${name}>`, true);
231+
element.end = parser.index;
226232
} else {
227-
// don't push self-closing elements onto the stack
228233
parser.stack.push(element);
229234
}
230235
}

src/utils/stringify.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ export function escape(data: string, { onlyEscapeAtSymbol = false } = {}) {
99
}
1010

1111
const escaped = {
12-
'"': '&quot;',
13-
"'": '&##39;',
1412
'&': '&amp;',
1513
'<': '&lt;',
16-
'>': '&gt;'
14+
'>': '&gt;',
1715
};
1816

1917
export function escapeHTML(html) {
20-
return String(html).replace(/["'&<>]/g, match => escaped[match]);
21-
}
18+
return String(html).replace(/[&<>]/g, match => escaped[match]);
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
html: `
3+
<div>'foo'<span/></div>
4+
`
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div>'foo'<span/></div>
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<div>
2-
<p>foo: &#39;&#39;</p>
2+
<p>foo: ''</p>
33
</div>

0 commit comments

Comments
 (0)