diff --git a/re.c b/re.c index 5d365edb63..96a3cbeaa9 100644 --- a/re.c +++ b/re.c @@ -1829,6 +1829,9 @@ rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_back if (NIL_P(match)) { match = match_alloc(rb_cMatch); } + else { + onig_region_free(&RMATCH_EXT(match)->regs, false); + } rb_matchext_t *rm = RMATCH_EXT(match); rm->regs = regs; diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb index f22128686e..be7c6761ca 100644 --- a/test/ruby/test_regexp.rb +++ b/test/ruby/test_regexp.rb @@ -999,6 +999,18 @@ class TestRegexp < Test::Unit::TestCase assert_equal('foobazquux/foobazquux', result, bug8856) end + def test_regsub_no_memory_leak + assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~"end;"}", rss: true) + code = proc do + "aaaaaaaaaaa".gsub(/a/, "") + end + + 1_000.times(&code) + begin; + 100_000.times(&code) + end; + end + def test_ignorecase v = assert_deprecated_warning(/variable \$= is no longer effective/) { $= } assert_equal(false, v)