From 5edb7ba546f5ad911c98575cca54d721fdebcac2 Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 23 Sep 2025 22:00:05 +0800 Subject: [PATCH 1/2] fix: escape HTML content in template string --- packages/compiler-vapor/src/transforms/transformComment.ts | 3 ++- packages/compiler-vapor/src/transforms/transformText.ts | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/compiler-vapor/src/transforms/transformComment.ts b/packages/compiler-vapor/src/transforms/transformComment.ts index 23c4069551f..f85498febce 100644 --- a/packages/compiler-vapor/src/transforms/transformComment.ts +++ b/packages/compiler-vapor/src/transforms/transformComment.ts @@ -6,6 +6,7 @@ import { } from '@vue/compiler-dom' import type { NodeTransform, TransformContext } from '../transform' import { DynamicFlag } from '../ir' +import { escapeHtml } from '@vue/shared' export const transformComment: NodeTransform = (node, context) => { if (node.type !== NodeTypes.COMMENT) return @@ -14,7 +15,7 @@ export const transformComment: NodeTransform = (node, context) => { context.comment.push(node) context.dynamic.flags |= DynamicFlag.NON_TEMPLATE } else { - context.template += `` + context.template += `` } } diff --git a/packages/compiler-vapor/src/transforms/transformText.ts b/packages/compiler-vapor/src/transforms/transformText.ts index e9c273b85c7..dd81bec1e80 100644 --- a/packages/compiler-vapor/src/transforms/transformText.ts +++ b/packages/compiler-vapor/src/transforms/transformText.ts @@ -16,6 +16,7 @@ import { isConstantExpression, isStaticExpression, } from '../utils' +import { escapeHtml } from '@vue/shared' type TextLike = TextNode | InterpolationNode const seen = new WeakMap< @@ -82,7 +83,7 @@ export const transformText: NodeTransform = (node, context) => { } else if (node.type === NodeTypes.INTERPOLATION) { processInterpolation(context as TransformContext) } else if (node.type === NodeTypes.TEXT) { - context.template += node.content + context.template += escapeHtml(node.content) } } @@ -143,7 +144,7 @@ function processTextContainer( const literals = values.map(getLiteralExpressionValue) if (literals.every(l => l != null)) { - context.childrenTemplate = literals.map(l => String(l)) + context.childrenTemplate = literals.map(l => escapeHtml(String(l))) } else { context.childrenTemplate = [' '] context.registerOperation({ From 0d8bac1514257b3c8d975f119fc12951db0b3bec Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 23 Sep 2025 22:40:11 +0800 Subject: [PATCH 2/2] test: add test --- .../__tests__/transforms/transformText.spec.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/compiler-vapor/__tests__/transforms/transformText.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformText.spec.ts index 20fa6d1fd00..dbff56f2a42 100644 --- a/packages/compiler-vapor/__tests__/transforms/transformText.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/transformText.spec.ts @@ -48,4 +48,10 @@ describe('compiler: text transform', () => { expect(ir.block.operation).toMatchObject([]) expect(ir.block.effect.length).toBe(1) }) + + it('escapes raw static text when generating the template string', () => { + const { ir } = compileWithTextTransform('<script>') + expect(ir.template).toContain('<script>') + expect(ir.template).not.toContain('