Skip to content

Commit

Permalink
* ext/psych/lib/psych/visitors/to_ruby.rb: correctly register
Browse files Browse the repository at this point in the history
  self-referential strings. Fixes tenderlove/psych ruby#135

* test/psych/test_string.rb: appropriate test.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40137 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
tenderlove committed Apr 5, 2013
1 parent fbb29bc commit 7a7bb64
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Sat Apr 6 02:06:04 2013 Aaron Patterson <[email protected]>

* ext/psych/lib/psych/visitors/to_ruby.rb: correctly register
self-referential strings. Fixes tenderlove/psych #135

* test/psych/test_string.rb: appropriate test.

Sat Apr 6 01:21:56 2013 Tanaka Akira <[email protected]>

* ext/socket/init.c (cloexec_accept): Fix a compile error on
Expand Down
24 changes: 17 additions & 7 deletions ext/psych/lib/psych/visitors/to_ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,25 @@ def visit_Psych_Nodes_Mapping o
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)
Expand Down
25 changes: 25 additions & 0 deletions test/psych/test_string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,31 @@ def initialize
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
Expand Down

0 comments on commit 7a7bb64

Please sign in to comment.