JSON.parse
を使用して、エスケープされたユニコード文字を含むJSONを解析しようとしています。しかし、1台のマシンでjson/ext
を使用すると、不正な値が返されます。たとえば、\u2030
はUTF-8でE2 80 B0
を返しますが、代わりに01 00 00
を取得しています。エスケープされた"\\u2030"
またはエスケープされていない"\u2030"
のいずれかで失敗します。Ruby JSON.parseがユニコードの不正なデータを返す
1.9.2p180 :001 > require 'json/ext'
=> true
1.9.2p180 :002 > s = JSON.parse '{"f":"\\u2030"}'
=> {"f"=>"\u0001\u0000\u0000"}
1.9.2p180 :003 > s["f"].encoding
=> #<Encoding:UTF-8>
1.9.2p180 :004 > s["f"].valid_encoding?
=> true
1.9.2p180 :005 > s["f"].bytes.map do |x| x; end
=> [1, 0, 0]
これは同じバージョンのrubyとそれに類する環境変数を持つ私の他のマシンで動作します。両方のマシンのGemfile.lockは同じです(json (= 1.6.3)
を含む)。両方のマシンでjson/pure
と動作します。
1.9.2p180 :001 > require 'json/pure'
=> true
1.9.2p180 :002 > s = JSON.parse '{"f":"\\u2030"}'
=> {"f"=>"‰"}
1.9.2p180 :003 > s["f"].encoding
=> #<Encoding:UTF-8>
1.9.2p180 :004 > s["f"].valid_encoding?
=> true
1.9.2p180 :005 > s["f"].bytes.map do |x| x; end
=> [226, 128, 176]
私の環境やセットアップには、それが誤って解析する原因となる何かがありますか?
ヒント: 's [" f "]。バイト.to_a' – Phrogz
失敗したマシンで' 'foo'.encoding'とは何ですか?ソースコードの上部にエンコードコメントがありますか? – Phrogz
'' foo'.encoding'は両方のマシンで '#'です。私はまた、ASCII-8BITの入力に関する問題を再現しました。エスケープされたバージョンの入力はすべて7ビットのASCIIなので、それは大したことではないはずです。 –
bklimt