Skip to content

Commit

Permalink
Fixes to Marshal.load with ivars
Browse files Browse the repository at this point in the history
Don't add an additional '@' to the name, and make an exception for the
internal encoding value of Strings.
  • Loading branch information
herwinw committed Dec 14, 2024
1 parent 9942374 commit dfaf2d9
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 19 deletions.
28 changes: 11 additions & 17 deletions spec/core/marshal/shared/load.rb
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@
s.instance_variable_set(:@foo, 10)
obj = ['5', s, 'hi'].extend(Meths, MethsMore)
obj.instance_variable_set(:@mix, s)
NATFIXME 'loads an array having ivar', exception: NameError, message: "`@@foo' is not allowed as an instance variable name" do
NATFIXME 'loads an array having ivar', exception: ArgumentError, message: 'dump format error' do
new_obj = Marshal.send(@method, "\004\bI[\b\"\0065I\"\twell\006:\t@fooi\017\"\ahi\006:\t@mix@\a")
new_obj.should == obj
new_obj.instance_variable_get(:@mix).should equal new_obj[1]
Expand Down Expand Up @@ -609,8 +609,8 @@
h = { key: s }
h.instance_variable_set :@hash_ivar, 'hash ivar'

NATFIXME 'issue with additional @ in ivar name', exception: NameError do
unmarshalled = Marshal.send(@method, Marshal.dump(h))
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
Expand Down Expand Up @@ -755,10 +755,8 @@ def io.binmode; raise "binmode"; end
end

it "loads a string with an ivar" do
NATFIXME 'loads a string with an ivar', exception: NameError, message: "`@@foo' is not allowed as an instance variable name" do
str = Marshal.send(@method, "\x04\bI\"\x00\x06:\t@fooI\"\bbar\x06:\x06EF")
str.instance_variable_get("@foo").should == "bar"
end
str = Marshal.send(@method, "\x04\bI\"\x00\x06:\t@fooI\"\bbar\x06:\x06EF")
str.instance_variable_get("@foo").should == "bar"
end

it "loads a String subclass with custom constructor" do
Expand Down Expand Up @@ -789,9 +787,7 @@ def io.binmode; raise "binmode"; end
data = "\x04\bI\"\x0Fm\x00\xF6\x00h\x00r\x00e\x00\x06:\rencoding\"\rUTF-16LE"
result = Marshal.send(@method, data)
result.should == str
NATFIXME 'loads a String in another encoding', exception: SpecFailedException do
result.encoding.should equal(Encoding::UTF_16LE)
end
result.encoding.should equal(Encoding::UTF_16LE)
end

it "loads a String as BINARY if no encoding is specified at the end" do
Expand Down Expand Up @@ -830,11 +826,9 @@ def io.binmode; raise "binmode"; end
it "loads a struct having ivar" do
obj = Struct.new("Thick").new
obj.instance_variable_set(:@foo, 5)
NATFIXME 'ivar names', exception: NameError, message: "`@@foo' is not allowed as an instance variable name" do
reloaded = Marshal.send(@method, "\004\bIS:\022Struct::Thick\000\006:\t@fooi\n")
reloaded.should == obj
reloaded.instance_variable_get(:@foo).should == 5
end
reloaded = Marshal.send(@method, "\004\bIS:\022Struct::Thick\000\006:\t@fooi\n")
reloaded.should == obj
reloaded.instance_variable_get(:@foo).should == 5
Struct.send(:remove_const, :Thick)
end

Expand Down Expand Up @@ -1081,8 +1075,8 @@ def io.binmode; raise "binmode"; end
obj = Regexp.new("hello")
obj.instance_variable_set(:@regexp_ivar, [42])

NATFIXME 'Correct incorrect ivar name', exception: NameError, message: "`@@regexp_ivar' is not allowed as an instance variable name" do
new_obj = Marshal.send(@method, "\x04\bI/\nhello\x00\a:\x06EF:\x11@regexp_ivar[\x06i/")
new_obj = Marshal.send(@method, "\x04\bI/\nhello\x00\a:\x06EF:\x11@regexp_ivar[\x06i/")
NATFIXME 'restore the regexp instance variables', exception: SpecFailedException do
new_obj.instance_variables.should == [:@regexp_ivar]
new_obj.instance_variable_get(:@regexp_ivar).should == [42]
end
Expand Down
5 changes: 3 additions & 2 deletions src/marshal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,10 @@ def read_ivars(object)
elsif value == true
object.force_encoding(Encoding::UTF_8)
end
elsif name == :encoding
object.force_encoding(value)
else
ivar_name = '@' + name.to_s
object.instance_variable_set(ivar_name, value)
object.instance_variable_set(name, value)
end
end
end
Expand Down

0 comments on commit dfaf2d9

Please sign in to comment.