2012-04-19 4 views
5

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] 

私の環境やセットアップには、それが誤って解析する原因となる何かがありますか?

+0

ヒント: 's [" f "]。バイト.to_a' – Phrogz

+0

失敗したマシンで' 'foo'.encoding'とは何ですか?ソースコードの上部にエンコードコメントがありますか? – Phrogz

+0

'' foo'.encoding'は両方のマシンで '#'です。私はまた、ASCII-8BITの入力に関する問題を再現しました。エスケープされたバージョンの入力はすべて7ビットのASCIIなので、それは大したことではないはずです。 – bklimt

答えて

1

JSON Gem(少なくとも1.6.6)または最新の1.7.1をアップグレードしてみてください。

5

最近、この同じ問題が発生しました。これは、になりました。これはRuby 1.9.2でthis bufferと宣言され、どのようにしてoptimized by GCCが得られたのでしょうか。 this commitに修正されました。

-O0でRubyを再コンパイルしたり、新しいバージョンのRuby(1.9.3以上)を使用して修正することができます。

関連する問題