Skip to content

Commit ce160ce

Browse files
committed
Disallow anonymous Data from being dumped
This feature leaked out without much discussion, but there's many reasons why it should not be supported: * Each instance of an anonymous Data in the stream will cause a new Data subtype to be defined. * Multiple objects of the same anonymous Data cannot be round- tripped, since they will no longer be of the same type after loading. As with anonymous classes and singleton objects, Psych should reject such objects rather than attempt to fake a Data class that appears to fit the original structure.
1 parent 5af4cec commit ce160ce

File tree

3 files changed

+8
-4
lines changed

3 files changed

+8
-4
lines changed

lib/psych/visitors/yaml_tree.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ def visit_Object o
163163
alias :visit_Delegator :visit_Object
164164

165165
def visit_Data o
166+
raise TypeError, "can't dump anonymous Data: #{o}" unless o.class.name
166167
ivars = o.instance_variables
167168
if ivars.empty?
168169
tag = ['!ruby/data', o.class.name].compact.join(':')

test/psych/test_object_references.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ def test_struct_has_references
3131
assert_reference_trip Struct.new(:foo).new(1)
3232
end
3333

34+
D = Data.define(:foo)
35+
3436
def test_data_has_references
3537
omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
36-
assert_reference_trip Data.define(:foo).new(1)
38+
assert_reference_trip D.new(1)
3739
end
3840

3941
def assert_reference_trip obj

test/psych/visitors/test_yaml_tree.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,14 @@ def test_data
8383
def test_data_anon
8484
omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
8585
d = Data.define(:foo).new('bar')
86-
obj = Psych.unsafe_load(Psych.dump(d))
87-
assert_equal d.foo, obj.foo
86+
assert_raise(TypeError) { Psych.dump(d) }
8887
end
8988

89+
D2 = Data.define(:method)
90+
9091
def test_data_override_method
9192
omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
92-
d = Data.define(:method).new('override')
93+
d = D2.new('override')
9394
obj = Psych.unsafe_load(Psych.dump(d))
9495
assert_equal d.method, obj.method
9596
end

0 commit comments

Comments
 (0)