News for hackers. Stuff that matters.
Re:JSON: The JavaScript subset that isn't by ot on Sunday May 15, 2011 @06:12PM (#2550916)
tl;dr: the JSON specification accepts two obscure Unicode codepoints in string literals that the JS specification doesn't. eval() may fail on valid JSON. Workaround: escape those codepoints.

Plus sensationalistic title and pedantic introduction.

Re:JSON: The JavaScript subset that isn't by arturadib on Monday May 16, 2011 @08:28AM (#2552328)
Hey, thanks for the tl;dr. That was useful.

> Plus sensationalistic title and pedantic introduction.

This, not so useful (and unkind)...

Had the author written merely the tl;dr line above do you think his important observation would have gotten the attention it deserves?

The author outlined his thought process to show that his observation was actually based on non-trivial research.

While I like tl;dr's, I appreciate intros that put things in context, and I'm more likely to trust observations whose underpinnings are spelled out.

Re:JSON: The JavaScript subset that isn't by mathias on Monday May 16, 2011 @08:24AM (#2552319)
This post is based on ES3. Both U+2028 and U+2029 are valid in ES5 string literals as part of a LineContinuation. See http://es5.github.com/#x7.3 (ES5) instead of http://bclary.com/2004/11/07/#a-7.3 (ES3).

So really, the title should be: “JSON: The ES3 subset that isn’t.”

Issue reported: https://github.com/judofyr/timeless/issues/57

Re:JSON: The JavaScript subset that isn't by tomstuart on Sunday May 15, 2011 @12:21PM (#2550184)
Valid point, but not a great example. You get a syntax error in Safari's Web Inspector even if you type that JSON yourself (i.e. no Unicode funny business):

  > {"JSON":"rocks!"}
  SyntaxError: Parse error
Re:JSON: The JavaScript subset that isn't by gildas on Sunday May 15, 2011 @12:22PM (#2550185)
Right, you don't need "U+2028" character to reproduce the error. Why ? Because the parser handles {} as a block code, not as an object declaration.

Actually, the "good example" should be : var obj = {"JSON":"ro
cks!"}

Re:JSON: The JavaScript subset that isn't by judofyr on Sunday May 15, 2011 @12:28PM (#2550201)
Re:JSON: The JavaScript subset that isn't by tmcw on Sunday May 15, 2011 @12:29PM (#2550205)
Though, to his credit, in the little REPL that he shows, he typed ({"JSON":"rocks!"}), not {"JSON":"rocks!"} - the former is valid.
Re:JSON: The JavaScript subset that isn't by judofyr on Sunday May 15, 2011 @12:33PM (#2550214)
To tomstuart's credit, I fixed the post after he wrote that comment.

Meta: Right after I originally wrote this comment I saw that tomstuart answered too, so I decided to delete my comment. Well, it appears that so did Tom, and suddenly there were no replies here.

Re:JSON: The JavaScript subset that isn't by tomstuart on Sunday May 15, 2011 @12:46PM (#2550243)
HN feature request: compare-and-swap comment semantics.
Re:JSON: The JavaScript subset that isn't by nbpoole on Sunday May 15, 2011 @12:23PM (#2550186)
Indeed. You get the same error in Chrome and a slightly different one in Firefox. That isn't valid JavaScript on its own.
Re:JSON: The JavaScript subset that isn't by lautis on Sunday May 15, 2011 @01:33PM (#2550326)

  > {"JSON":"rocks!"}
I don't think this is such a good point. While the example is not a valid expression, it is a perfectly good JS value/statement, like (almost) all other JSON. Wikipedia might go a bit too far in saying that all JSON formatted text is legal JS code, but (IMHO) it still is a perfectly good subset.

The unicode part is a clear error and should be fixed.

Re:JSON: The JavaScript subset that isn't by p1mrx on Sunday May 15, 2011 @08:52PM (#2551239)
Another caveat: it's unsafe to embed arbitrary JSON in an HTML <script> tag, because a string containing "</script>" will get picked up by the parser.

This particular case can be patched by replacing "</" with "<\/".

Re:JSON: The JavaScript subset that isn't by tszming on Sunday May 15, 2011 @12:55PM (#2550257)
If you always escape the Unicode characters when you output JSON, you don't have this problem. At least Facebook/Twitter are using this method.
Re:JSON: The JavaScript subset that isn't by thousande on Sunday May 15, 2011 @05:49PM (#2550863)
One trick is to base64 encode and decode the data
Re:JSON: The JavaScript subset that isn't by SeoxyS on Sunday May 15, 2011 @03:23PM (#2550573)
It sounds to me more like the javascript specification has a bug or design flaw, rather than saying as a blanket statement that JSON isn't really part of JS. Ideally, javascript and JS implementations should fix that flaw, rather than parsers having to work around it.
Re:JSON: The JavaScript subset that isn't by judofyr on Sunday May 15, 2011 @03:36PM (#2550611)
ECMAScript was standardized over ten years ago. The specification has been publicly available and (as far as I know) every implementation has treated line terminators equally. We can't just change 5+ implementations of JS to make it compatible with a some tiny data format that works fine 99% of the time anyway.

I'm not saying that JSON isn't a part of JS; of course it is! I'm just saying that it isn't a strict subset of JS and that you can't depend on eval() doing the right thing.

Re:JSON: The JavaScript subset that isn't by _prototype_ on Sunday May 15, 2011 @05:50PM (#2550865)
Does anyone know if the jQuery JSON parser has this fix by any chase?
Re:JSON: The JavaScript subset that isn't by mhansen on Sunday May 15, 2011 @10:12PM (#2551384)
jQuery JSON parser will delegate to JSON.parse where available, which doesn't have this problem.

Using JSONP with jQuery, you have to directly eval() the response from the server, and you don't control what the server sends - it could send invalid javascript with these code points in it. You can't fix that from the client-side, jQuery can't fix that.

The servers have to be patched.

Re:JSON: The JavaScript subset that isn't by mtodd on Sunday May 15, 2011 @02:47PM (#2550480)
Thanks for sharing this tricky bit of knowledge, Magnus. Glad you're helping raise awareness on this further :)
Re:JSON: The JavaScript subset that isn't by mtodd on Sunday May 15, 2011 @02:47PM (#2550482)
Oh, and thanks again for patching the JSONP middleware.
Re:JSON: The JavaScript subset that isn't by voidfiles on Monday May 16, 2011 @04:14AM (#2551967)
JSONP does not force you to use eval. All that JSONP is doing is telling the web service to write JavaScript in such a way to immediately invoke a function with the name of the callback. Usually it's just called with a string. What you do with that string is up to you.
Re:JSON: The JavaScript subset that isn't by tomstuart on Monday May 16, 2011 @06:12AM (#2552104)
JSONP does force you to use eval, because JSONP means "instead of returning JSON for me to parse with a JSON library, return executable JavaScript for me to point at with the src attribute of a <script> element". The string consisting of the argument to the callback is de facto evaled by the user agent (when the executable JavaScript is executed) in order for it to become a JavaScript value at all.

The user agent evals the JSONP response before anything else happens: the server might return the string 'yourCallback({"JSON":"rocks!"});', which gets evaled to a function invocation whose argument is whatever the string '{"JSON":"rocks!"}' evals to. If that string doesn't successfully eval (as per the OP), your JSONP is broken.

Re:JSON: The JavaScript subset that isn't by rmccue on Monday May 16, 2011 @06:47AM (#2552150)
Perhaps we need a JSONP callback that instead does `yourFunction(JSON.parse('{"JSON":"rocks!"}'))` (though, slightly more sophisticated, I hope).
Re:JSON: The JavaScript subset that isn't by mhansen on Monday May 16, 2011 @09:28AM (#2552442)
That still won't work unless you escape the line endings. And you'll also need to escape single quotes.
Re:JSON: The JavaScript subset that isn't by rimantas on Monday May 16, 2011 @06:35AM (#2552139)
You are mixing eval() with other stuff.
Re:JSON: The JavaScript subset that isn't by threedaymonk on Monday May 16, 2011 @07:16AM (#2552199)
Or, conversely, everyone here is confusing eval() with evaluation in general. JSONP does not call eval() as such, but it does evaluate the server response as JavaScript, because it ends up as:

    <script src="/whatever?callback=foo"></script>
The source of which is something like

    foo({"a":"b"})
Therefore, the hash supplied to foo() must be valid JavaScript.
Re:JSON: The JavaScript subset that isn't by gildas on Monday May 16, 2011 @04:45AM (#2552000)
Moreover, JSON.parse will be able to parse the JSON text containing the "U+2028" character without any issue.
Re:JSON: The JavaScript subset that isn't by stoodder on Sunday May 15, 2011 @02:42PM (#2550470)
Sounds like something that a 3rd party javascript library could handle :). Point made though.
Re:JSON: The JavaScript subset that isn't by mhansen on Sunday May 15, 2011 @10:10PM (#2551381)
No. Using JSONP, you are forced to directly eval() code from another domain - you can't just use a javascript library to change that code.
Re:JSON: The JavaScript subset that isn't by Hawramani on Sunday May 15, 2011 @12:26PM (#2550197)
JSON started out with JavaScript and slowly expanded beyond the ECMAScript specifications to become more versatile. I don't see what the big deal is.

Humans prefer easily processable and storable information, and for this reason they like to think JSON is JavaScript Object Notation.

This reminds of how ECMA doesn't like to be called the _European_ Computer Manufacturer's Association, since they have now grown beyond that, and prefer being called Ecma.

Re:JSON: The JavaScript subset that isn't by tomstuart on Sunday May 15, 2011 @12:28PM (#2550202)
As the OP says, the big deal is that people frequently assume that JavaScript's eval is an acceptable JSON parser — for example, this is the fundamental assumption which makes JSONP work. If your JSON isn't guaranteed to be valid JavaScript, you might run into actual problems.
Re:JSON: The JavaScript subset that isn't by DougBTX on Sunday May 15, 2011 @02:41PM (#2550467)
It does seem more like a bug in the JSON spec than anything else.
Re:JSON: The JavaScript subset that isn't by burgerbrain on Sunday May 15, 2011 @03:51PM (#2550652)
Wouldn't using eval to parse JSON be quite hazardous in the same way as python's pickle, and thus be limited to pretty specific use-cases (limited moreso than just simply to JS)?
Re:JSON: The JavaScript subset that isn't by comex on Sunday May 15, 2011 @04:53PM (#2550767)
It used to be quite common and is still done (and is required for the hack known as JSONP); lots of the time you're retrieving JSON from the same server you loaded the original page from so it's safe.
Re:JSON: The JavaScript subset that isn't by Hawramani on Sunday May 15, 2011 @01:05PM (#2550277)
I see. Should have read the whole thing before commenting.