return early if there is no is_entries buffer

If there is a compilation error, is_entries may not be allocated, but
ic_size could be greater than 0.  If we don't have a buffer to iterate
over, just return early.  Otherwise GC could segv

[Bug #19173]
This commit is contained in:
Aaron Patterson 2022-12-02 09:44:10 -06:00 коммит произвёл Aaron Patterson
Родитель b8a73e704d
Коммит dba61f487c
2 изменённых файлов: 15 добавлений и 0 удалений

8
iseq.c
Просмотреть файл

@ -126,6 +126,14 @@ remove_from_constant_cache(ID id, IC ic)
static void
iseq_clear_ic_references(const rb_iseq_t *iseq)
{
// In some cases (when there is a compilation error), we end up with
// ic_size greater than 0, but no allocated is_entries buffer.
// If there's no is_entries buffer to loop through, return early.
// [Bug #19173]
if (!ISEQ_BODY(iseq)->is_entries) {
return;
}
for (unsigned int ic_idx = 0; ic_idx < ISEQ_BODY(iseq)->ic_size; ic_idx++) {
IC ic = &ISEQ_IS_IC_ENTRY(ISEQ_BODY(iseq), ic_idx);

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

@ -355,6 +355,13 @@ class TestISeq < Test::Unit::TestCase
end
end
# [Bug #19173]
def test_compile_error
assert_raise SyntaxError do
RubyVM::InstructionSequence.compile 'using Module.new; yield'
end
end
def test_compile_file_error
Tempfile.create(%w"test_iseq .rb") do |f|
f.puts "end"