Subject: [Json] Another json interop soft spot

From: Tim Bray <[email-masked]>
Date: Thu, 23 Apr 2015 09:26:13 -0700

irb(main):004:0> JSON.parse ' {"a\b": "b"}'

=> {"a\b"=>"b"}

irb(main):005:0> JSON.parse ' {"a\\b": "b"}'

=> {"a\b"=>"b"}

I think the first example is probably illegal per the grammar, but I bet
lots of parsers accept it.

---

From: Carsten Bormann <[email-masked]>
Date: Thu, 23 Apr 2015 18:43:12 +0200

Tim Bray wrote:
> JSON.parse ' {"a\b": "b"}'

You fell into a nasty Ruby trap here:
In a single-quoted string, a single backslash remains a single backslash
unless it is followed by either another backslash or a single quote.

$ irb -rjson
>> RUBY_VERSION
=> "2.2.2"
>> JSON.parse ' {"a\b": "b"}'
=> {"a\b"=>"b"}
>> JSON.parse ' {"a\\b": "b"}'
=> {"a\b"=>"b"}
>> (JSON.parse ' {"a\\b": "b"}').keys[0].size
=> 2
>> (JSON.parse ' {"a\b": "b"}').keys[0].size
=> 2
>> (JSON.parse ' {"a\b": "b"}').keys[0].hexi
=> "6108"
>> (JSON.parse ' {"a\\b": "b"}').keys[0].hexi
=> "6108"
>> ('{"a\b": "b"}').size
=> 12
>> ('{"a\\b": "b"}').size
=> 12
>> ('{"a\\b": "b"}').hexi
=> "7b22615c62223a202262227d"
>> ('{"a\b": "b"}').hexi
=> "7b22615c62223a202262227d"
>> 'a\b'.hexi
=> "615c62"
>> 'a\\b'.hexi
=> "615c62"

(String#hexi is in my .irbrc and does the obvious bytes.map{|x| "%02x" %
x}.join thing.)

Textbook example of quoting hell...

Now, the bug in the default Ruby JSON parser you really are addressing
is illustrated by this:

>> (JSON.parse ' {"a\\c": "b"}').keys[0].hexi
=> "6163"

Of course, \c is not allowed in JSON strings.

Fix:

$ irb -roj
>> (Oj.load ' {"a\\c": "b"}').keys[0].hexi
Oj::ParseError: invalid escaped character at line 1, column 5 [parse.c:280]
	from (irb):3:in `load'
	from (irb):3
	from /Users/cabo/bin/irb:11:in `<main>'
>> (Oj.load ' {"a\\b": "b"}').keys[0].hexi
=> "6108"

Grüße, Carsten