YAML.load で symbol や object が指定されたらエラーにする

YAML.load で symbol や object が指定されたらエラーにするには、以下のように指定すれば可能のようです。

error_proc = Proc.new do |type,value|
  raise YAML::Error, "Invalid #{type.inspect}, #{value.inspect}"
end

YAML.add_domain_type('ruby.yaml.org,2002', RUBY_VERSION == "1.8.2" ? /^object/ : 'object', &error_proc)
YAML.add_domain_type('ruby.yaml.org,2002', 'sym',    &error_proc)
YAML.add_domain_type('ruby.yaml.org,2002', 'symbol', &error_proc)

指定前:

p YAML.load("--- :to_s")
# => :to_s

p YAML.load("--- !ruby/sym to_s")
# => :to_s

p YAML.load("--- !ruby/symbol to_s")
# => :to_s

p YAML.load("--- !ruby/object:Object { foo: 1 }")
# => #<Object:0xb7996cb4 @foo=1>

p YAML.load("--- !tag:ruby.yaml.org,2002:sym to_s")
# => :to_s

p YAML.load("--- !tag:ruby.yaml.org,2002:symbol to_s")
# => :to_s

p YAML.load("--- !tag:ruby.yaml.org,2002:object:Object { foo: 1 }")
# => #<Object:0xb7a2fd88 @foo=1>

指定後:

p YAML.load("--- :to_s")
# => YAML::Error: Invalid "tag:ruby.yaml.org,2002:sym", "to_s"

p YAML.load("--- !ruby/sym to_s")
# => YAML::Error: Invalid "tag:ruby.yaml.org,2002:sym", "to_s"

p YAML.load("--- !ruby/symbol to_s")
# => YAML::Error: Invalid "tag:ruby.yaml.org,2002:symbol", "to_s"

p YAML.load("--- !ruby/object:Object { foo: 1 }")
# => YAML::Error: Invalid "tag:ruby.yaml.org,2002:object", {"foo"=>1}

p YAML.load("--- !tag:ruby.yaml.org,2002:sym to_s")
# => YAML::Error: Invalid "tag:ruby.yaml.org,2002:sym", "to_s"

p YAML.load("--- !tag:ruby.yaml.org,2002:symbol to_s")
# => YAML::Error: Invalid "tag:ruby.yaml.org,2002:symbol", "to_s"

最初は YAML.add_ruby_type を使用していたが 1.8.3 - 1.8.4 では ↓ のようなエラーになってしまう。

$ ruby1.8.3 -ryaml -e 'YAML.add_ruby_type("sym", &error_proc)'
/home/foobar/ruby/1.8.3/lib/ruby/1.8/yaml.rb:314:in `add_ruby_type': undefined local variable or method `type_tag' for YAML:Module (NameError)
        from -e:1

また 1.8.2 では次のようにするとメモリを喰い潰して SEGV になってしまった。1.8.3 - 1.8.5 では問題ない。

$ ruby1.8.2 -ryaml -e 'p YAML.load("--- !ruby/object")'
/home/foobar/ruby/1.8.2/lib/ruby/1.8/yaml.rb:119: [BUG] Segmentation fault
ruby 1.8.2 (2004-12-25) [i386-linux]

Aborted