Files
ruby/marshal.rb
T
Hiroshi SHIBATAandClaude Opus 5 111cc79210 Look up the nearest user box for :caller_user_box
The box of the immediately previous frame can be the root box, e.g. when
a proc made in the root box calls Marshal.load, and the classes of the
caller's data are invisible there. Walk the caller frames up to the
nearest user box instead, and rename the attribute after what it finds.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:39:17 +09:00

42 lines
1.5 KiB
Ruby

module Marshal
# call-seq:
# load(source, proc = nil, freeze: false) -> obj
# restore(source, proc = nil, freeze: false) -> obj
#
# Returns the result of converting the serialized data in source into a
# Ruby object (possibly with associated subordinate objects). source
# may be either an instance of IO or an object that responds to
# to_str. If proc is specified, each object will be passed to the proc, as the object
# is being deserialized.
#
# Never pass untrusted data (including user supplied input) to this method.
# Please see the overview for further details.
#
# If the <tt>freeze: true</tt> argument is passed, deserialized object would
# be deeply frozen. Note that it may lead to more efficient memory usage due to
# frozen strings deduplication:
#
# serialized = Marshal.dump(['value1', 'value2', 'value1', 'value2'])
#
# deserialized = Marshal.load(serialized)
# deserialized.map(&:frozen?)
# # => [false, false, false, false]
# deserialized.map(&:object_id)
# # => [1023900, 1023920, 1023940, 1023960] -- 4 different objects
#
# deserialized = Marshal.load(serialized, freeze: true)
# deserialized.map(&:frozen?)
# # => [true, true, true, true]
# deserialized.map(&:object_id)
# # => [1039360, 1039380, 1039360, 1039380] -- only 2 different objects, object_ids repeating
#
def self.load(source, proc = nil, freeze: false)
Primitive.attr! :caller_user_box
Primitive.marshal_load(source, proc, freeze)
end
class << self
alias restore load
end
end