From dba61f487cd7c1555f1187a2e2846506c1b143be Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 2 Dec 2022 09:44:10 -0600 Subject: [PATCH] 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] --- iseq.c | 8 ++++++++ test/ruby/test_iseq.rb | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/iseq.c b/iseq.c index f2a2bdedda..b16369e420 100644 --- a/iseq.c +++ b/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); diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb index 2a18ff02e1..563aeeeaea 100644 --- a/test/ruby/test_iseq.rb +++ b/test/ruby/test_iseq.rb @@ -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"