From 7ceafcbdf5bd2155704839f97b869e689f66feeb Mon Sep 17 00:00:00 2001 From: tenderlove Date: Tue, 14 May 2013 17:26:41 +0000 Subject: * ext/psych/lib/psych.rb: Adding Psych.safe_load for loading a user defined, restricted subset of Ruby object types. * ext/psych/lib/psych/class_loader.rb: A class loader for encapsulating the logic for which objects are allowed to be deserialized. * ext/psych/lib/psych/deprecated.rb: Changes to use the class loader * ext/psych/lib/psych/exception.rb: ditto * ext/psych/lib/psych/json/stream.rb: ditto * ext/psych/lib/psych/nodes/node.rb: ditto * ext/psych/lib/psych/scalar_scanner.rb: ditto * ext/psych/lib/psych/stream.rb: ditto * ext/psych/lib/psych/streaming.rb: ditto * ext/psych/lib/psych/visitors/json_tree.rb: ditto * ext/psych/lib/psych/visitors/to_ruby.rb: ditto * ext/psych/lib/psych/visitors/yaml_tree.rb: ditto * ext/psych/psych_to_ruby.c: ditto * test/psych/helper.rb: ditto * test/psych/test_safe_load.rb: tests for restricted subset. * test/psych/test_scalar_scanner.rb: ditto * test/psych/visitors/test_to_ruby.rb: ditto * test/psych/visitors/test_yaml_tree.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40750 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/psych/helper.rb | 2 +- test/psych/test_safe_load.rb | 97 +++++++++++++++++++++++++++++++++++ test/psych/test_scalar_scanner.rb | 2 +- test/psych/visitors/test_to_ruby.rb | 4 +- test/psych/visitors/test_yaml_tree.rb | 4 +- 5 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 test/psych/test_safe_load.rb (limited to 'test') diff --git a/test/psych/helper.rb b/test/psych/helper.rb index 77ab0bb9d7..f9b73cf5b5 100644 --- a/test/psych/helper.rb +++ b/test/psych/helper.rb @@ -60,7 +60,7 @@ module Psych end def assert_cycle( obj ) - v = Visitors::YAMLTree.new + v = Visitors::YAMLTree.create v << obj assert_equal(obj, Psych.load(v.tree.yaml)) assert_equal( obj, Psych::load(Psych.dump(obj))) diff --git a/test/psych/test_safe_load.rb b/test/psych/test_safe_load.rb new file mode 100644 index 0000000000..dd299c0ebf --- /dev/null +++ b/test/psych/test_safe_load.rb @@ -0,0 +1,97 @@ +require 'psych/helper' + +module Psych + class TestSafeLoad < TestCase + class Foo; end + + [1, 2.2, {}, [], "foo"].each do |obj| + define_method(:"test_basic_#{obj.class}") do + assert_safe_cycle obj + end + end + + def test_no_recursion + x = [] + x << x + assert_raises(Psych::BadAlias) do + Psych.safe_load Psych.dump(x) + end + end + + def test_explicit_recursion + x = [] + x << x + assert_equal(x, Psych.safe_load(Psych.dump(x), [], [], true)) + end + + def test_symbol_whitelist + yml = Psych.dump :foo + assert_raises(Psych::DisallowedClass) do + Psych.safe_load yml + end + assert_equal(:foo, Psych.safe_load(yml, [Symbol], [:foo])) + end + + def test_symbol + assert_raises(Psych::DisallowedClass) do + assert_safe_cycle :foo + end + assert_raises(Psych::DisallowedClass) do + Psych.safe_load '--- !ruby/symbol foo', [] + end + assert_safe_cycle :foo, [Symbol] + assert_safe_cycle :foo, %w{ Symbol } + assert_equal :foo, Psych.safe_load('--- !ruby/symbol foo', [Symbol]) + end + + def test_foo + assert_raises(Psych::DisallowedClass) do + Psych.safe_load '--- !ruby/object:Foo {}', [Foo] + end + assert_raises(Psych::DisallowedClass) do + assert_safe_cycle Foo.new + end + assert_kind_of(Foo, Psych.safe_load(Psych.dump(Foo.new), [Foo])) + end + + X = Struct.new(:x) + def test_struct_depends_on_sym + assert_safe_cycle(X.new, [X, Symbol]) + assert_raises(Psych::DisallowedClass) do + cycle X.new, [X] + end + end + + def test_anon_struct + assert Psych.safe_load(<<-eoyml, [Struct, Symbol]) +--- !ruby/struct + foo: bar + eoyml + + assert_raises(Psych::DisallowedClass) do + Psych.safe_load(<<-eoyml, [Struct]) +--- !ruby/struct + foo: bar + eoyml + end + + assert_raises(Psych::DisallowedClass) do + Psych.safe_load(<<-eoyml, [Symbol]) +--- !ruby/struct + foo: bar + eoyml + end + end + + private + + def cycle object, whitelist = [] + Psych.safe_load(Psych.dump(object), whitelist) + end + + def assert_safe_cycle object, whitelist = [] + other = cycle object, whitelist + assert_equal object, other + end + end +end diff --git a/test/psych/test_scalar_scanner.rb b/test/psych/test_scalar_scanner.rb index a7bf17c912..e8e423cb05 100644 --- a/test/psych/test_scalar_scanner.rb +++ b/test/psych/test_scalar_scanner.rb @@ -7,7 +7,7 @@ module Psych def setup super - @ss = Psych::ScalarScanner.new + @ss = Psych::ScalarScanner.new ClassLoader.new end def test_scan_time diff --git a/test/psych/visitors/test_to_ruby.rb b/test/psych/visitors/test_to_ruby.rb index 022cc2d2d4..c13d980468 100644 --- a/test/psych/visitors/test_to_ruby.rb +++ b/test/psych/visitors/test_to_ruby.rb @@ -6,7 +6,7 @@ module Psych class TestToRuby < TestCase def setup super - @visitor = ToRuby.new + @visitor = ToRuby.create end def test_object @@ -88,7 +88,7 @@ description: end def test_exception - exc = Exception.new 'hello' + exc = ::Exception.new 'hello' mapping = Nodes::Mapping.new nil, '!ruby/exception' mapping.children << Nodes::Scalar.new('message') diff --git a/test/psych/visitors/test_yaml_tree.rb b/test/psych/visitors/test_yaml_tree.rb index 496cdd05cc..40702bce79 100644 --- a/test/psych/visitors/test_yaml_tree.rb +++ b/test/psych/visitors/test_yaml_tree.rb @@ -5,7 +5,7 @@ module Psych class TestYAMLTree < TestCase def setup super - @v = Visitors::YAMLTree.new + @v = Visitors::YAMLTree.create end def test_tree_can_be_called_twice @@ -18,7 +18,7 @@ module Psych def test_yaml_tree_can_take_an_emitter io = StringIO.new e = Psych::Emitter.new io - v = Visitors::YAMLTree.new({}, e) + v = Visitors::YAMLTree.create({}, e) v.start v << "hello world" v.finish -- cgit v1.2.3