Bug #5390
closedYAML.load が、正しく解析できないエンコーディングの文字列も受け付けてしまう
Description
[[ruby-list:48419]] にてバグ扱いでいいだろうという話がありましたのでバグとして報告します。
YAML.load がどのように実装されているのかコードを追いきれなかったのですが、動きを見る限り、与えられた文字列のエンコーディングを気にせずにパースしているように思います。 このため、Shift_JIS のようなエンコーディングの文字列の一部を正しくパースできません。
--- source code ---
coding: Shift_JIS¶
require "yaml"
text = '[ "噂" ]' # Shift_JIS の '噂' の 2 バイト目はバックスラッシュと同じバイト値
str = YAML.load( text ).first # エラー発生
--- output ---
/home/nobuoka/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/syck.rb:135:in load': syntax error on line 0, col 9:
' (ArgumentError)
from /home/nobuoka/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/syck.rb:135:in load' from yaml_cp932.rb:4:in
'
Shift_JIS の文字列でもほとんどの場合は例外発生せずにパースされるので、Shift_JIS の文字列を使っている場合に問題が起こる可能性をユーザーが認識しづらいという問題があります。 よって、現在の動きはバグとして、以下のいずれかの動きに変更した方が良いのではないでしょうか。
*UTF-8 (UTF-16 も?) 以外のエンコーディングの文字列が渡された場合に例外を発生させる
*UTF-8 以外のエンコーディングの文字列が渡された場合に、自動的に UTF-8 に変換して処理を進める
*YAML の解析部分でエンコーディングを考慮するようにして、Shift_JIS などでも正しく解析できるようにする
Updated by naruse (Yui NARUSE) about 13 years ago
- Status changed from Open to Assigned
- Assignee set to tenderlovemaking (Aaron Patterson)
*UTF-8 以外のエンコーディングの文字列が渡された場合に、自動的に UTF-8 に変換して処理を進める
がいいのではないかと思っています。
*YAML の解析部分でエンコーディングを考慮するようにして、Shift_JIS などでも正しく解析できるようにする
なお、これはYAMLの仕様にエンコーディングを与える方法が規定されていないので、YAML仕様の範囲内では不可能なはずです。
Updated by ayumin (Ayumu AIZAWA) almost 13 years ago
YAML::ENGINE.yamler が syck のみ再現します。
ruby1.9.2 をお使いの場合は require 'yaml' する前に require 'psych' するか YAML::ENGINE.yamler = 'psych' すると以下のようにPsych::SyntaxErrorとなります。
---- ruby 2.0.0dev
$ cat bug_5390.rb
coding: Shift_JIS¶
require 'yaml'
text = '["?"]'
p YAML::ENGINE.yamler
p text.encoding
str = YAML.load(text).first
$ ruby -v bug_5390.rb
ruby 2.0.0dev (2011-12-30 trunk 34161) [x86_64-darwin10.8.0]
"psych"
#Encoding:Shift_JIS
/Users/ayumin/tmp/ruby/lib/ruby/2.0.0/psych.rb:192:in parse': (<unknown>): invalid leading UTF-8 octet at line 1 column 1 (Psych::SyntaxError) from /Users/ayumin/tmp/ruby/lib/ruby/2.0.0/psych.rb:192:in
parse_stream'
from /Users/ayumin/tmp/ruby/lib/ruby/2.0.0/psych.rb:150:in parse' from /Users/ayumin/tmp/ruby/lib/ruby/2.0.0/psych.rb:126:in
load'
from bug_5390.rb:6:in `'
---- ruby1.9.2
$ cat bug_5390.rb
coding: Shift_JIS¶
require 'yaml'
text = '["?"]'
YAML::ENGINE.yamler = 'psych'
str = YAML.load(text).first
$ ruby -v bug_5390.rb
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin10.8.0]
/Users/ayumin/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/deprecated.rb:79: warning: method redefined; discarding old to_yaml_properties
/Users/ayumin/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/syck/rubytypes.rb:13: warning: previous definition of to_yaml_properties was here
/Users/ayumin/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:148:in parse': couldn't parse YAML at line 1 column 0 (Psych::SyntaxError) from /Users/ayumin/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:148:in
parse_stream'
from /Users/ayumin/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:119:in parse' from /Users/ayumin/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:106:in
load'
from bug_5390.rb:5:in `'
Updated by tenderlovemaking (Aaron Patterson) over 12 years ago
返事が遅くなって、ごめんなさい。
YAML のファイルフォーマットは UTF8, UTF16LE, と UTF16BE のみサポートしますが、Psych だけは String をパースする時に文字コードを UTF8 に変換します。
例: https://gist.github.com/1902995
ファイルを使用する場合、ファイルの文字例は以下の UTF8 、UTF16LE 、 UTF16BEの一つのみ使用可能です。
Updated by ayumin (Ayumu AIZAWA) over 12 years ago
- Status changed from Assigned to Closed
1.9.2はもうすぐメンテナンス終了で、1.9.3からPsychがデフォルトです。
こちらのチケットはCloseします。