提交 aa0fad51 编写于 作者: O Olek Janiszewski

Prevent `Marshal.load` from looping infinitely

Fix a bug in `Marshal.load` that caused it to loop indefinitely when
trying to autoload a constant that resolved to a different name.

This could occur when marshalling an ActiveRecord 4.0 object (e.g. into
memcached) and then trying to unmarshal it with Rails 4.2. The
marshalled payload contains a reference to
`ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column`, which in
Rails 4.2 resolves to
`ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::Column`.
上级 a101115d
* Prevent `Marshal.load` from looping infinitely when trying to autoload a constant
which resolves to a different name.
*Olek Janiszewski*
* Deprecate `Module.local_constants`. Please use `Module.constants(false)` instead.
*Yuichiro Kaneko*
......
......@@ -5,7 +5,10 @@ def load(source)
rescue ArgumentError, NameError => exc
if exc.message.match(%r|undefined class/module (.+)|)
# try loading the class/module
$1.constantize
loaded = $1.constantize
raise unless $1 == loaded.name
# if it is an IO we need to go back to read the object
source.rewind if source.respond_to?(:rewind)
retry
......
......@@ -64,6 +64,17 @@ def teardown
end
end
test "when one constant resolves to another" do
class Parent; C = Class.new; end
class Child < Parent; C = Class.new; end
dump = Marshal.dump(Child::C.new)
Child.send(:remove_const, :C)
assert_raise(ArgumentError) { Marshal.load(dump) }
end
test "that a real missing class is causing an exception" do
dumped = nil
with_autoloading_fixtures do
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册