Merge pull request #1086 from sveltejs/gh-1082

[WIP] Fix HTML escaping and non-top-level <script> and <style> issues
pull/1090/head
Rich Harris 7 years ago committed by GitHub
commit 8d04da6839
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -432,6 +432,10 @@ export default class Element extends Node {
if (isVoidElementName(node.name)) return open + '>'; if (isVoidElementName(node.name)) return open + '>';
if (node.name === 'script' || node.name === 'style') {
return `${open}>${node.data}</${node.name}>`;
}
return `${open}>${node.children.map(toHTML).join('')}</${node.name}>`; return `${open}>${node.children.map(toHTML).join('')}</${node.name}>`;
} }
} }
@ -756,4 +760,4 @@ const events = [
node.isMediaNode() && node.isMediaNode() &&
(name === 'buffered' || name === 'seekable') (name === 'buffered' || name === 'seekable')
} }
]; ];

@ -60,6 +60,8 @@ export default function visitElement(
if (node.name === 'textarea' && textareaContents !== undefined) { if (node.name === 'textarea' && textareaContents !== undefined) {
generator.append(textareaContents); generator.append(textareaContents);
} else if (node.name === 'script' || node.name === 'style') {
generator.append(node.data);
} else { } else {
node.children.forEach((child: Node) => { node.children.forEach((child: Node) => {
visit(generator, block, child); visit(generator, block, child);

@ -213,6 +213,7 @@ export default function tag(parser: Parser) {
parser.eat('>', true); parser.eat('>', true);
if (selfClosing) { if (selfClosing) {
// don't push self-closing elements onto the stack
element.end = parser.index; element.end = parser.index;
} else if (name === 'textarea') { } else if (name === 'textarea') {
// special case // special case
@ -223,8 +224,12 @@ export default function tag(parser: Parser) {
); );
parser.read(/<\/textarea>/); parser.read(/<\/textarea>/);
element.end = parser.index; element.end = parser.index;
} else if (name === 'script' || name === 'style') {
// special case
element.data = parser.readUntil(new RegExp(`</${name}>`));
parser.eat(`</${name}>`, true);
element.end = parser.index;
} else { } else {
// don't push self-closing elements onto the stack
parser.stack.push(element); parser.stack.push(element);
} }
} }

@ -9,13 +9,11 @@ export function escape(data: string, { onlyEscapeAtSymbol = false } = {}) {
} }
const escaped = { const escaped = {
'"': '&quot;',
"'": '&##39;',
'&': '&amp;', '&': '&amp;',
'<': '&lt;', '<': '&lt;',
'>': '&gt;' '>': '&gt;',
}; };
export function escapeHTML(html) { export function escapeHTML(html) {
return String(html).replace(/["'&<>]/g, match => escaped[match]); return String(html).replace(/[&<>]/g, match => escaped[match]);
} }

@ -0,0 +1,5 @@
export default {
html: `
<div>'foo'<span/></div>
`
};

@ -1,3 +1,3 @@
<div> <div>
<p>foo: &#39;&#39;</p> <p>foo: ''</p>
</div> </div>
Loading…
Cancel
Save