diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2013-04-05 10:12:02 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2013-04-05 10:12:02 -0700 |
commit | 0c82d6d009eceb2bac048c2262f68c1fc494dde9 (patch) | |
tree | f1a4131230d187f71f70d90d12dd0264cad85f6e | |
parent | b4537454d9da6e901dcacf4c4e36de08095f79a3 (diff) | |
download | psych-0c82d6d009eceb2bac048c2262f68c1fc494dde9.tar.gz |
* ext/psych/lib/psych/visitors/to_ruby.rb: correctly register
self-referential strings. Fixes tenderlove/psych #135
* test/psych/test_string.rb: appropriate test.
-rw-r--r-- | CHANGELOG.rdoc | 7 | ||||
-rw-r--r-- | lib/psych/visitors/to_ruby.rb | 24 | ||||
-rw-r--r-- | test/psych/test_string.rb | 25 |
3 files changed, 49 insertions, 7 deletions
diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index 9f28f80..2df0bb5 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,3 +1,10 @@ +Sat Apr 6 02:06:04 2013 Aaron Patterson <aaron@tenderlovemaking.com> + + * ext/psych/lib/psych/visitors/to_ruby.rb: correctly register + self-referential strings. Fixes tenderlove/psych #135 + + * test/psych/test_string.rb: appropriate test. + Fri Mar 1 09:15:00 2013 Zachary Scott <zachary@zacharyscott.net> * lib/psych.rb: specify in rdoc what object is returned in parser diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb index 9ccf420..b59bc38 100644 --- a/lib/psych/visitors/to_ruby.rb +++ b/lib/psych/visitors/to_ruby.rb @@ -180,15 +180,25 @@ module Psych end when /^!(?:str|ruby\/string)(?::(.*))?/, 'tag:yaml.org,2002:str' - klass = resolve_class($1) - members = Hash[*o.children.map { |c| accept c }] - string = members.delete 'str' + klass = resolve_class($1) + members = {} + string = nil - if klass - string = klass.allocate.replace string - register(o, string) - end + o.children.each_slice(2) do |k,v| + key = accept k + value = accept v + if key == 'str' + if klass + string = klass.allocate.replace value + else + string = value + end + register(o, string) + else + members[key] = value + end + end init_with(string, members.map { |k,v| [k.to_s.sub(/^@/, ''),v] }, o) when /^!ruby\/array:(.*)$/ klass = resolve_class($1) diff --git a/test/psych/test_string.rb b/test/psych/test_string.rb index a298831..0bdba18 100644 --- a/test/psych/test_string.rb +++ b/test/psych/test_string.rb @@ -15,6 +15,31 @@ module Psych end end + def test_string_subclass_with_anchor + y = Psych.load <<-eoyml +--- +body: + string: &70121654388580 !ruby/string + str: ! 'foo' + x: + body: *70121654388580 + eoyml + assert_equal({"body"=>{"string"=>"foo", "x"=>{"body"=>"foo"}}}, y) + end + + def test_self_referential_string + y = Psych.load <<-eoyml +--- +string: &70121654388580 !ruby/string + str: ! 'foo' + body: *70121654388580 + eoyml + + assert_equal({"string"=>"foo"}, y) + value = y['string'] + assert_equal value, value.instance_variable_get(:@body) + end + def test_another_subclass_with_attributes y = Psych.load Psych.dump Y.new("foo").tap {|y| y.val = 1} assert_equal "foo", y |