Browse Source

fix(compiler-vapor): escape html for safer template output (#13919)

edison 7 months ago
parent
commit
3c31b71abc

+ 6 - 0
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('<code>&lt;script&gt;</code>')
+    expect(ir.template).toContain('<code>&lt;script&gt;</code>')
+    expect(ir.template).not.toContain('<code><script></code>')
+  })
 })

+ 2 - 1
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 += `<!--${node.content}-->`
+    context.template += `<!--${escapeHtml(node.content)}-->`
   }
 }
 

+ 3 - 2
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<InterpolationNode>)
   } 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({