Actions
Bug #18141
closedMarshal load with proc yield objects before they are fully initialized
Description
I assume this is a bug because I can't find any spec or test for this behaviour:
Consider the following script:
payload = Marshal.dump("foo")
Marshal.load(payload, -> (obj) {
if obj.is_a?(String)
p [obj, obj.encoding]
end
obj
})
p [:final, string, string.encoding]
outputs:
["foo", #<Encoding:ASCII-8BIT>]
[:final, "foo", #<Encoding:UTF-8>]
So Marshal
call the proc before the string get its encoding assigned, this is because the encoding is stored alongside as a TYPE_IVAR
. I think in such cases Marshal
should delay calling the proc until the object is fully restored.
A corollary to this behaviour is that the following code:
Marshal.load(payload, :freeze.to_proc)
raises with can't modify frozen String: "foo" (FrozenError)
.
The same happens with any instance variable on Array
or Hash
foo = {}
foo.instance_variable_set(:@bar, 42)
payload = Marshal.dump(foo)
object = Marshal.load(payload, ->(obj) {
if obj.is_a?(Hash)
p [obj, obj.instance_variable_get(:@bar)]
obj.freeze
end
obj
})
[{}, nil]
/tmp/marshal.rb:6:in `load': can't modify frozen Hash: {} (FrozenError)
from /tmp/marshal.rb:6:in `<main>
Actions
Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0