Skip to content

Commit 3c31b71

Browse files
authored
fix(compiler-vapor): escape html for safer template output (#13919)
1 parent 23bc91c commit 3c31b71

File tree

3 files changed

+11
-3
lines changed

3 files changed

+11
-3
lines changed

packages/compiler-vapor/__tests__/transforms/transformText.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,10 @@ describe('compiler: text transform', () => {
4848
expect(ir.block.operation).toMatchObject([])
4949
expect(ir.block.effect.length).toBe(1)
5050
})
51+
52+
it('escapes raw static text when generating the template string', () => {
53+
const { ir } = compileWithTextTransform('<code>&lt;script&gt;</code>')
54+
expect(ir.template).toContain('<code>&lt;script&gt;</code>')
55+
expect(ir.template).not.toContain('<code><script></code>')
56+
})
5157
})

packages/compiler-vapor/src/transforms/transformComment.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
} from '@vue/compiler-dom'
77
import type { NodeTransform, TransformContext } from '../transform'
88
import { DynamicFlag } from '../ir'
9+
import { escapeHtml } from '@vue/shared'
910

1011
export const transformComment: NodeTransform = (node, context) => {
1112
if (node.type !== NodeTypes.COMMENT) return
@@ -14,7 +15,7 @@ export const transformComment: NodeTransform = (node, context) => {
1415
context.comment.push(node)
1516
context.dynamic.flags |= DynamicFlag.NON_TEMPLATE
1617
} else {
17-
context.template += `<!--${node.content}-->`
18+
context.template += `<!--${escapeHtml(node.content)}-->`
1819
}
1920
}
2021

packages/compiler-vapor/src/transforms/transformText.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
isConstantExpression,
1717
isStaticExpression,
1818
} from '../utils'
19+
import { escapeHtml } from '@vue/shared'
1920

2021
type TextLike = TextNode | InterpolationNode
2122
const seen = new WeakMap<
@@ -82,7 +83,7 @@ export const transformText: NodeTransform = (node, context) => {
8283
} else if (node.type === NodeTypes.INTERPOLATION) {
8384
processInterpolation(context as TransformContext<InterpolationNode>)
8485
} else if (node.type === NodeTypes.TEXT) {
85-
context.template += node.content
86+
context.template += escapeHtml(node.content)
8687
}
8788
}
8889

@@ -143,7 +144,7 @@ function processTextContainer(
143144
const literals = values.map(getLiteralExpressionValue)
144145

145146
if (literals.every(l => l != null)) {
146-
context.childrenTemplate = literals.map(l => String(l))
147+
context.childrenTemplate = literals.map(l => escapeHtml(String(l)))
147148
} else {
148149
context.childrenTemplate = [' ']
149150
context.registerOperation({

0 commit comments

Comments
 (0)