From 24820d508bc89775e10e4e3e6e07e192540cb4a2 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Tue, 1 Sep 2020 23:13:54 -0400 Subject: Return nil when argument to ObjectSpace.internal_class_of is T_IMEMO The added test case crashes the interpreter because it makes ObjectSpace.internal_class_of return the second VALUE slot of an AST imemo object. The second VALUE slot of `struct rb_ast_struct` is not a VALUE and not a pointer to a Ruby object. --- ext/objspace/objspace.c | 9 +++++++-- test/objspace/test_objspace.rb | 5 +++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c index 262640d30c..3bfb79dc1f 100644 --- a/ext/objspace/objspace.c +++ b/ext/objspace/objspace.c @@ -895,8 +895,13 @@ objspace_internal_class_of(VALUE self, VALUE obj) obj = (VALUE)DATA_PTR(obj); } - klass = CLASS_OF(obj); - return wrap_klass_iow(klass); + if (RB_TYPE_P(obj, T_IMEMO)) { + return Qnil; + } + else { + klass = CLASS_OF(obj); + return wrap_klass_iow(klass); + } } /* diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb index f9e6e82e8f..b3f7a56e51 100644 --- a/test/objspace/test_objspace.rb +++ b/test/objspace/test_objspace.rb @@ -516,6 +516,11 @@ class TestObjSpace < Test::Unit::TestCase assert_operator i, :>, 0 end + def test_internal_class_of_on_ast + children = ObjectSpace.reachable_objects_from(RubyVM::AbstractSyntaxTree.parse("kadomatsu")) + children.each {|child| ObjectSpace.internal_class_of(child).itself} # this used to crash + end + def traverse_super_classes klass while klass klass = ObjectSpace.internal_super_of(klass) -- cgit v1.2.3