]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(ssr): fix escape and handling for raw Text, Comment and Static vnodes
authorEvan You <yyx990803@gmail.com>
Fri, 1 May 2020 15:52:40 +0000 (11:52 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 1 May 2020 15:52:40 +0000 (11:52 -0400)
packages/server-renderer/__tests__/renderToString.spec.ts
packages/server-renderer/src/renderToString.ts

index f0ee6961f7c381488b8b5bbc663fac9e40a96aae..ed58e2a38df8e307d3b4fd69f0ae5efbe3e8b2cc 100644 (file)
@@ -6,7 +6,9 @@ import {
   resolveComponent,
   ComponentOptions,
   ref,
-  defineComponent
+  defineComponent,
+  createTextVNode,
+  createStaticVNode
 } from 'vue'
 import { escapeHtml, mockWarn } from '@vue/shared'
 import { renderToString, renderComponent } from '../src/renderToString'
@@ -511,6 +513,33 @@ describe('ssr: renderToString', () => {
     })
   })
 
+  describe('raw vnode types', () => {
+    test('Text', async () => {
+      expect(await renderToString(createTextVNode('hello <div>'))).toBe(
+        `hello &lt;div&gt;`
+      )
+    })
+
+    test('Comment', async () => {
+      // https://www.w3.org/TR/html52/syntax.html#comments
+      expect(
+        await renderToString(
+          h('div', [
+            createCommentVNode('>foo'),
+            createCommentVNode('->foo'),
+            createCommentVNode('<!--foo-->'),
+            createCommentVNode('--!>foo<!-')
+          ])
+        )
+      ).toBe(`<div><!--foo--><!--foo--><!--foo--><!--foo--></div>`)
+    })
+
+    test('Static', async () => {
+      const content = `<div id="ok">hello<span>world</span></div>`
+      expect(await renderToString(createStaticVNode(content))).toBe(content)
+    })
+  })
+
   describe('scopeId', () => {
     // note: here we are only testing scopeId handling for vdom serialization.
     // compiled srr render functions will include scopeId directly in strings.
index 26a5e706ca9d3cfd764bb95876300b9a3585a412..57f4ab1d32cd0f6b788f1916eb6d78cc222ab129 100644 (file)
@@ -7,6 +7,7 @@ import {
   createVNode,
   Text,
   Comment,
+  Static,
   Fragment,
   ssrUtils,
   Slots,
@@ -229,6 +230,9 @@ function ssrCompile(
   return (compileCache[template] = Function('require', code)(require))
 }
 
+// https://www.w3.org/TR/html52/syntax.html#comments
+const commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g
+
 function renderVNode(
   push: PushFn,
   vnode: VNode,
@@ -237,10 +241,17 @@ function renderVNode(
   const { type, shapeFlag, children } = vnode
   switch (type) {
     case Text:
-      push(children as string)
+      push(escapeHtml(children as string))
       break
     case Comment:
-      push(children ? `<!--${children}-->` : `<!---->`)
+      push(
+        children
+          ? `<!--${(children as string).replace(commentStripRE, '')}-->`
+          : `<!---->`
+      )
+      break
+    case Static:
+      push(children as string)
       break
     case Fragment:
       push(`<!--[-->`) // open