Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vue-template-compiler double-escaping newlines in _ssrNode text string templates #7223

Closed
felixbuenemann opened this issue Dec 12, 2017 · 3 comments · Fixed by #7224
Closed
Labels

Comments

@felixbuenemann
Copy link
Contributor

Version

2.5.9

Reproduction link

https://gist.github.com/2b3c1a683b334022c626917b0abb2adc

(I used a Gist, because ssrCompile is not exposed by the globals build of Vue.)

Steps to reproduce

compiler = require('vue-template-compiler')
template = "<div id=\"foo,\nbar\">\n<textarea id=\"foo,\nbar\">foo\nbar</textarea>\n</div>"
result = compiler.ssrCompile(template)
console.log(result.render)
// output: with(this){return _c('div',{attrs:{"id":"foo,\nbar"}},[_ssrNode("<textarea id=\"foo,\\nbar\">foo\nbar</textarea>")])}

What is expected?

vue-template-compiler should not double-escape newlines in attributes for _ssrNode string templates.

What is actually happening?

vue-template-compiler double-escapes newlines in attributes of _ssrNodes.


If you look at the output from the reproduction steps, you will see that the newline character '\n' is only double escaped, if it is part of an attribute in an ssrNode, if is nor optimized to a string template and stored in the attrs property, is it fine and other newlines that are outside attributes are also fine.

The bug was observed with vue-template-compiler v2.5.9 and node.js v8.9.1.

While the above example seems silly, newlines in attribute are very common when using responsive images, with multiple sizes in the srcset attribute, which are usually broken onto one line per size/url for readability and this is how a colleague of mine ran into this bug, where responsive images were working differently between ssr and rehydration due to the problem, because the browser aborted srcset parsing when finding the "\n" literal string.

@felixbuenemann
Copy link
Contributor Author

While the report explicitly mentions newlines, the double escaping also occurs for other escape sequences like \t.

@felixbuenemann
Copy link
Contributor Author

It looks like the attribute is first escaped using JSON.stringify in processAttrs call to addAttr and then finally the whole string template is escaped again using JSON.stringify(textBuffer) inside flattenSegments, which causes the double escaping.

@felixbuenemann
Copy link
Contributor Author

I could fix the problem by applying the following patch to the genAttrSegment function:

diff --git a/src/server/optimizing-compiler/modules.js b/src/server/optimizing-compiler/modules.js
index 41b1af1d..69a7be87 100644
--- a/src/server/optimizing-compiler/modules.js
+++ b/src/server/optimizing-compiler/modules.js
@@ -77,7 +77,7 @@ function genAttrSegment (name: string, value: string): StringSegment {
         ? ` ${name}="${name}"`
         : value === '""'
           ? ` ${name}`
-          : ` ${name}=${value}`
+          : ` ${name}="${JSON.parse(value)}"`
     }
   } else {
     return {

felixbuenemann added a commit to felixbuenemann/vue that referenced this issue Dec 12, 2017
This fixes a double escaping of attribute values in the SSR optimizing
compiler by unescaping the value in `genAttrSegment` because literal
attribute values get escaped early during `processAttrs` before it is
known, if this attribute will be optimized to an _ssrNode string template,
which is escaped as well, causing the double escape.

fix vuejs#7223
@yyx990803 yyx990803 added the bug label Dec 12, 2017
yyx990803 pushed a commit that referenced this issue Dec 12, 2017
This fixes a double escaping of attribute values in the SSR optimizing
compiler by unescaping the value in `genAttrSegment` because literal
attribute values get escaped early during `processAttrs` before it is
known, if this attribute will be optimized to an _ssrNode string template,
which is escaped as well, causing the double escape.

fix #7223
yyx990803 added a commit that referenced this issue Dec 12, 2017
lovelope pushed a commit to lovelope/vue that referenced this issue Feb 1, 2018
This fixes a double escaping of attribute values in the SSR optimizing
compiler by unescaping the value in `genAttrSegment` because literal
attribute values get escaped early during `processAttrs` before it is
known, if this attribute will be optimized to an _ssrNode string template,
which is escaped as well, causing the double escape.

fix vuejs#7223
lovelope pushed a commit to lovelope/vue that referenced this issue Feb 1, 2018
f2009 pushed a commit to f2009/vue that referenced this issue Jan 25, 2019
This fixes a double escaping of attribute values in the SSR optimizing
compiler by unescaping the value in `genAttrSegment` because literal
attribute values get escaped early during `processAttrs` before it is
known, if this attribute will be optimized to an _ssrNode string template,
which is escaped as well, causing the double escape.

fix vuejs#7223
f2009 pushed a commit to f2009/vue that referenced this issue Jan 25, 2019
aJean pushed a commit to aJean/vue that referenced this issue Aug 19, 2020
This fixes a double escaping of attribute values in the SSR optimizing
compiler by unescaping the value in `genAttrSegment` because literal
attribute values get escaped early during `processAttrs` before it is
known, if this attribute will be optimized to an _ssrNode string template,
which is escaped as well, causing the double escape.

fix vuejs#7223
aJean pushed a commit to aJean/vue that referenced this issue Aug 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants