summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/ruby/test_marshal.rb24
-rw-r--r--variable.c3
2 files changed, 27 insertions, 0 deletions
diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb
index bfb4a9056e..eb66994801 100644
--- a/test/ruby/test_marshal.rb
+++ b/test/ruby/test_marshal.rb
@@ -469,6 +469,30 @@ class TestMarshal < Test::Unit::TestCase
assert_equal(o1.foo, o2.foo)
end
+ class TooComplex
+ def initialize
+ @marshal_too_complex = 1
+ end
+ end
+
+ def test_complex_shape_object_id_not_dumped
+ if defined?(RubyVM::Shape::SHAPE_MAX_VARIATIONS)
+ assert_equal 8, RubyVM::Shape::SHAPE_MAX_VARIATIONS
+ end
+ 8.times do |i|
+ TooComplex.new.instance_variable_set("@TestObjectIdTooComplex#{i}", 1)
+ end
+ obj = TooComplex.new
+ ivar = "@a#{rand(10_000).to_s.rjust(5, '0')}"
+ obj.instance_variable_set(ivar, 1)
+
+ if defined?(RubyVM::Shape)
+ assert_predicate(RubyVM::Shape.of(obj), :too_complex?)
+ end
+ obj.object_id
+ assert_equal "\x04\bo:\x1CTestMarshal::TooComplex\a:\x19@marshal_too_complexi\x06:\f#{ivar}i\x06".b, Marshal.dump(obj)
+ end
+
def test_marshal_complex
assert_raise(ArgumentError){Marshal.load("\x04\bU:\fComplex[\x05")}
assert_raise(ArgumentError){Marshal.load("\x04\bU:\fComplex[\x06i\x00")}
diff --git a/variable.c b/variable.c
index 4f924813fa..5ae2d3e3b0 100644
--- a/variable.c
+++ b/variable.c
@@ -2255,6 +2255,9 @@ each_hash_iv(st_data_t id, st_data_t val, st_data_t data)
{
struct iv_itr_data * itr_data = (struct iv_itr_data *)data;
rb_ivar_foreach_callback_func *callback = itr_data->func;
+ if (is_internal_id((ID)id)) {
+ return ST_CONTINUE;
+ }
return callback((ID)id, (VALUE)val, itr_data->arg);
}