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.
This commit is contained in:
Alan Wu 2020-09-01 23:13:54 -04:00 коммит произвёл Aaron Patterson
Родитель 3a00f2a0f4
Коммит 24820d508b
2 изменённых файлов: 12 добавлений и 2 удалений

Просмотреть файл

@ -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);
}
}
/*

Просмотреть файл

@ -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)