Perhaps more pervasive and despairingly problematic is number representation. JSON only, per specification, supports arbitrary precision numeric representation. However, Javascript is -- also per specification (as I understand it) -- entirely floating point. That makes working with money in Javascript somewhat hazardous. While there are various arbitrary precision libraries out there for Javascript to assuage this, the problem is most JSON-parsing routines will always force one through a floating point conversion anyway, so a loss of precision is more or less inevitable.<p>While swiftly coercing raw off-the-wire number representations to one's arbitrary precision library of choice can avoid most cases of noticeable accumulated error, it is irksome that the only way everyone seems to get by is by cross their fingers that any loss in precision caused by "JSON.parse" is meaningless to their application.<p>Or, the problem can be soundly avoided by using strings in the JSON payload, which is lame but effective and probably one's best practical choice. It is clearly an example of corruption spreading from Javascript to an otherwise reasonable feature of the data representation format JSON.
Magnus Holm did a great job describing this after he fixed the problem in Rack::JSONP. Good reference as well for those interested in the topic:<p><a href="http://timelessrepo.com/json-isnt-a-javascript-subset" rel="nofollow">http://timelessrepo.com/json-isnt-a-javascript-subset</a>
The "uniname" command in the uniutils package (apt-get install uniutils) is great for checking "invisible" or weird Unicode characters. `echo '{"str": "own ed"}' | uniname` will show the LINE SEPARATOR (\u002028) hidden in the string.
I have to comment on this line:<p>> Some libraries implement an unsafe, but fast, JSON parse using “eval” for older browsers<p>eval is not fast! In fact it is the opposite of fast. Most JIT optimizations go away in the face of eval()! Do not use it even if you <i>know</i> it's safe. Use JSON.parse instead.
This is a good catch, but the presentation is awfully passive aggressive. Yes, if JSON wants to strictly be a subset of JS, then those two characters need to be treated specially - either excluded from JSON, or specially escaped in JSON libraries. The simplest solution, clearly, is to exclude them from JSON. (You can still use those characters, but you have to escape them). There's no compelling reason not to do this - and I doubt that this will cause a problem anyway.
The other reason: if you are using a Turing-complete language to eval your nominally context free grammar as if it were code, you are an idiot who is asking to be hacked, whether through quirks like this or otherwise. (This also goes for PHP and ERB.) <a href="http://www.cs.dartmouth.edu/~sergey/langsec/occupy/" rel="nofollow">http://www.cs.dartmouth.edu/~sergey/langsec/occupy/</a>
I often pass inline data from server -> client JS using a meta tag. In rails3 it would look like:<p><meta name='blah' content="<%= @data.to_json %>" /><p>However this has always seemed unclean to me. Does anyone else have a better, alternative method of inlining data? I'd rather not use inline scripts for the exact reason they mention.
I feel really dense, but I don't understand why the example line is throwing an error. The article mentions line terminators, but it doesn't seem to contain any, and I also don't understand why "owned" would be escaped the way the author says... it looks as though the interpreter is just rejecting the use of quotes around the key. But I'm sure I'm just missing something, so I'd be much obliged if someone could enlighten me.
anyone else see the strangest mess on view source for that page? (chrome on ubuntu)<p>[edit: i guess it's confused by the line break characters. i reported an issue.]<p>[edit2: whoa, wget seems to show the same thing when i look at the source in emacs...]<p>[edit3: ok, i am an idiot. it's just quotes in a bunch of meta tags. sorry. move along. nothing to see here.]
One more thing that really bugs me about JSON is that it doesn't support Infinity, -Infinity and NaN. Python's JSON library does, which leads to some interesting breakages.<p>Sure, for NaN you can use null, but for Infinity, you have to use really large/small numbers, which can also lead to other problems.
Another problem is unicode characters that are not in the basic multilingual plane. JSON supports those, but many Javascript environments (like basically all browsers) do not.
The other thing is that JSON scoffs at trailing comma (both in object and array literals), while JavaScript engines are perfectly happy to accept them.
Judofyr has covered this in depth on his blog: <a href="http://timelessrepo.com/json-isnt-a-javascript-subset" rel="nofollow">http://timelessrepo.com/json-isnt-a-javascript-subset</a>