-
-
Notifications
You must be signed in to change notification settings - Fork 17.3k
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
Newline/Paragraph separators not escaped for use in JSONP #1132
Comments
it uses JSON.stringify(), so I dont want to mess with anything it does, if there really is a problem it's with v8 |
Er, not sure if I was clear enough. JSON.stringify() does the right thing: it does not escape \U+2028 and \U+2029 because they do not need to be escaped per the JSON spec. JSON.stringify() return a string that is perfectly valid in JS. That's not the problem. The problem arises when this string is wrapped in JS code for use in JSONP. In that case, the client receives JavaScript, not JSON, and uses the JavaScript parser. When that parser bumps into the U+2028 character, it considers it's a newline and as newlines are not allowed in the middle of strings in JavaScript it throws an exception. In short, the problem lies with the JSONP mode in Express, not with JSON.stringify(). |
ohhh sorry somehow I missed the P on JSON haha |
I'm running into this issue as well right now @visionmedia |
I wont have time to look at it right away, I head out of town tomorrow morning |
nvm, it's literally an issue in V8 http://code.google.com/p/v8/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Priority%20Owner%20Summary%20HW%20OS%20Area%20Stars&groupby=&sort=&id=1939. We were not using ExpressJS JSONP either. |
But, we have the case where the JSON returned by expressjs through |
It looks like the "bug" will not be fixed in v8, because fixing it would violate es5. Using the replace solution from @c4milo would be the correct solution, then.
Or perhaps the following (not sure which is faster):
|
@visionmedia any update? |
@c4milo @visionmedia the issue doesn't actually affect JSON. Those characters do not need to be escaped in JSON, only in JavaScript. Since JSONP is technically JavaScript, that's why it is a problem there. // Works (JSON):
console.log(JSON.parse(JSON.stringify(["test\u2028ing"])))
// Doesn't work (JSONP):
eval('console.log(' + JSON.stringify(["test\u2028ing"]) + ')') Putting the replaces in |
@c4milo Your example there was not even JSON. JSON is always a string, but you gave an object as an argument to |
LOL, yeah you are totally right. Gah, that's what happen when you work from home when two kids are visiting |
Anyway, the thing is |
yes sir, no need for that middleware at all. |
I think that the Webpack JSON loader seems like the right place to handle this issue. For whatever reason, the JSON and Javascript specifications disagree on whether or not strings can contain the unicode Newline or Paragraph characters. In the case that a JSON object containing one of these characters is being printed to a script tag, we should escape them. See also, this discussion: expressjs/express#1132 (comment)
I think that the Webpack JSON loader seems like the right place to handle this issue. For whatever reason, the JSON and Javascript specifications disagree on whether or not strings can contain the unicode Newline or Paragraph characters. In the case that a JSON object containing one of these characters is being printed to a script tag, we should escape them. See also, this discussion: expressjs/express#1132 (comment)
For better or for worse, JSON is not a true subset of JavaScript as two characters sneaked their way into JSON:
\u2028
: line separator\u2029
: paragraph separatorFor JavaScript, these two characters are considered to be the same as
\n
. That's transparent most of the time, but JSONP is all about returning JSON wrapped into JavaScript and, as such, the JSON that gets wrapped must conform to the JavaScript language.JSON.stringify
does not guarantee that (well, it depends on the parser used, but the one in node.js does not).In particular, the following code will trigger a JavaScript exception if fetched from within a Web browser:
The separator characters need to be escaped before they are returned, with code such as:
body.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')
See JSON: The JavaScript subset that isn't for a good summary of the problem.
The text was updated successfully, but these errors were encountered: