Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve support for instance variables in Marshal.dump #2393

Merged
merged 8 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 9 additions & 27 deletions spec/core/marshal/dump_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,7 @@ def _dump(level)
it "dumps an Array with instance variables" do
a = []
a.instance_variable_set(:@ivar, 1)
NATFIXME 'dumps an Array with instance variables', exception: SpecFailedException do
Marshal.dump(a).should == "\004\bI[\000\006:\n@ivari\006"
end
Marshal.dump(a).should == "\004\bI[\000\006:\n@ivari\006"
end

it "dumps an extended Array" do
Expand Down Expand Up @@ -566,9 +564,7 @@ def _dump(level)
it "dumps a Hash with instance variables" do
a = {}
a.instance_variable_set(:@ivar, 1)
NATFIXME 'dumps a Hash with instance variables', exception: SpecFailedException do
Marshal.dump(a).should == "\004\bI{\000\006:\n@ivari\006"
end
Marshal.dump(a).should == "\004\bI{\000\006:\n@ivari\006"
end

it "dumps an extended Hash" do
Expand All @@ -593,9 +589,7 @@ def _dump(level)

describe "with a Struct" do
it "dumps a Struct" do
NATFIXME 'dumps a Struct', exception: SpecFailedException do
Marshal.dump(Struct::Pyramid.new).should == "\004\bS:\024Struct::Pyramid\000"
end
Marshal.dump(Struct::Pyramid.new).should == "\004\bS:\024Struct::Pyramid\000"
end

it "dumps a Struct" do
Expand All @@ -607,9 +601,7 @@ def _dump(level)
it "dumps a Struct with instance variables" do
st = Struct.new("Thick").new
st.instance_variable_set(:@ivar, 1)
NATFIXME 'dumps a Struct with instance variables', exception: SpecFailedException do
Marshal.dump(st).should == "\004\bIS:\022Struct::Thick\000\006:\n@ivari\006"
end
Marshal.dump(st).should == "\004\bIS:\022Struct::Thick\000\006:\n@ivari\006"
Struct.send(:remove_const, :Thick)
end

Expand Down Expand Up @@ -826,31 +818,23 @@ def finalizer.noop(_)

describe "with an Exception" do
it "dumps an empty Exception" do
NATFIXME 'dumps an empty Exception', exception: SpecFailedException do
Marshal.dump(Exception.new).should == "\x04\bo:\x0EException\a:\tmesg0:\abt0"
end
Marshal.dump(Exception.new).should == "\x04\bo:\x0EException\a:\tmesg0:\abt0"
end

it "dumps the message for the exception" do
NATFIXME 'dumps the message for the exception', exception: SpecFailedException do
Marshal.dump(Exception.new("foo")).should == "\x04\bo:\x0EException\a:\tmesg\"\bfoo:\abt0"
end
Marshal.dump(Exception.new("foo")).should == "\x04\bo:\x0EException\a:\tmesg\"\bfoo:\abt0"
end

it "contains the filename in the backtrace" do
obj = Exception.new("foo")
obj.set_backtrace(["foo/bar.rb:10"])
NATFIXME 'contains the filename in the backtrace', exception: SpecFailedException do
Marshal.dump(obj).should == "\x04\bo:\x0EException\a:\tmesg\"\bfoo:\abt[\x06\"\x12foo/bar.rb:10"
end
Marshal.dump(obj).should == "\x04\bo:\x0EException\a:\tmesg\"\bfoo:\abt[\x06\"\x12foo/bar.rb:10"
end

it "dumps instance variables if they exist" do
obj = Exception.new("foo")
obj.instance_variable_set(:@ivar, 1)
NATFIXME 'dumps instance variables if they exist', exception: SpecFailedException do
Marshal.dump(obj).should == "\x04\bo:\x0EException\b:\tmesg\"\bfoo:\abt0:\n@ivari\x06"
end
Marshal.dump(obj).should == "\x04\bo:\x0EException\b:\tmesg\"\bfoo:\abt0:\n@ivari\x06"
end

it "dumps the cause for the exception" do
Expand Down Expand Up @@ -880,9 +864,7 @@ def finalizer.noop(_)
rescue => e
end

NATFIXME 'dumps the message for the raised NoMethodError exception', exception: SpecFailedException do
Marshal.dump(e).should =~ /undefined method [`']foo' for ("":String|an instance of String)/
end
Marshal.dump(e).should =~ /undefined method [`']foo' for ("":String|an instance of String)/
end

it "raises TypeError if an Object is an instance of an anonymous class" do
Expand Down
56 changes: 25 additions & 31 deletions spec/core/marshal/shared/load.rb
Original file line number Diff line number Diff line change
Expand Up @@ -610,10 +610,8 @@
h.instance_variable_set :@hash_ivar, 'hash ivar'

unmarshalled = Marshal.send(@method, Marshal.dump(h))
NATFIXME 'it preserves hash ivars when hash contains a string having ivar', exception: SpecFailedException do
unmarshalled.instance_variable_get(:@hash_ivar).should == 'hash ivar'
unmarshalled[:key].instance_variable_get(:@string_ivar).should == 'string ivar'
end
unmarshalled.instance_variable_get(:@hash_ivar).should == 'hash ivar'
unmarshalled[:key].instance_variable_get(:@string_ivar).should == 'string ivar'
end

ruby_version_is "3.1" do
Expand Down Expand Up @@ -848,10 +846,12 @@ def io.binmode; raise "binmode"; end
Thread.current[threadlocal_key] = nil

dumped = Marshal.dump(s)
loaded = Marshal.send(@method, dumped)
NATFIXME 'it does not call initialize on the unmarshaled struct', exception: ArgumentError, message: 'dump format error' do
loaded = Marshal.send(@method, dumped)

Thread.current[threadlocal_key].should == nil
loaded.a.should == 'foo'
Thread.current[threadlocal_key].should == nil
loaded.a.should == 'foo'
end
end
end

Expand Down Expand Up @@ -886,39 +886,33 @@ def io.binmode; raise "binmode"; end
describe "for an Exception" do
it "loads a marshalled exception with no message" do
obj = Exception.new
NATFIXME 'Support exception', exception: NameError, message: "`bt' is not allowed as an instance variable name" do
loaded = Marshal.send(@method, "\004\bo:\016Exception\a:\abt0:\tmesg0")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
loaded = Marshal.send(@method, "\x04\bo:\x0EException\a:\tmesg0:\abt0")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
end
loaded = Marshal.send(@method, "\004\bo:\016Exception\a:\abt0:\tmesg0")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
loaded = Marshal.send(@method, "\x04\bo:\x0EException\a:\tmesg0:\abt0")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
end

it "loads a marshalled exception with a message" do
obj = Exception.new("foo")
NATFIXME 'Support exception with message', exception: NameError, message: "`bt' is not allowed as an instance variable name" do
loaded = Marshal.send(@method, "\004\bo:\016Exception\a:\abt0:\tmesg\"\bfoo")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
loaded = Marshal.send(@method, "\x04\bo:\x0EException\a:\tmesgI\"\bfoo\x06:\x06EF:\abt0")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
end
loaded = Marshal.send(@method, "\004\bo:\016Exception\a:\abt0:\tmesg\"\bfoo")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
loaded = Marshal.send(@method, "\x04\bo:\x0EException\a:\tmesgI\"\bfoo\x06:\x06EF:\abt0")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
end

it "loads a marshalled exception with a backtrace" do
obj = Exception.new("foo")
obj.set_backtrace(["foo/bar.rb:10"])
NATFIXME 'Support exception with backtrace', exception: NameError, message: "`bt' is not allowed as an instance variable name" do
loaded = Marshal.send(@method, "\004\bo:\016Exception\a:\abt[\006\"\022foo/bar.rb:10:\tmesg\"\bfoo")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
loaded = Marshal.send(@method, "\x04\bo:\x0EException\a:\tmesgI\"\bfoo\x06:\x06EF:\abt[\x06I\"\x12foo/bar.rb:10\x06;\aF")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
end
loaded = Marshal.send(@method, "\004\bo:\016Exception\a:\abt[\006\"\022foo/bar.rb:10:\tmesg\"\bfoo")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
loaded = Marshal.send(@method, "\x04\bo:\x0EException\a:\tmesgI\"\bfoo\x06:\x06EF:\abt[\x06I\"\x12foo/bar.rb:10\x06;\aF")
loaded.message.should == obj.message
loaded.backtrace.should == obj.backtrace
end

it "loads an marshalled exception with ivars" do
Expand Down
Loading
Loading