diff options
-rw-r--r-- | re.c | 9 | ||||
-rw-r--r-- | test/ruby/test_regexp.rb | 12 | ||||
-rw-r--r-- | tool/lib/envutil.rb | 8 |
3 files changed, 26 insertions, 3 deletions
@@ -1747,15 +1747,18 @@ rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_back .range = reverse ? 0 : len, }; - VALUE match = match_alloc(rb_cMatch); - struct re_registers *regs = RMATCH_REGS(match); + struct re_registers regs = {0}; - OnigPosition result = rb_reg_onig_match(re, str, reg_onig_search, &args, regs); + OnigPosition result = rb_reg_onig_match(re, str, reg_onig_search, &args, ®s); if (result == ONIG_MISMATCH) { rb_backref_set(Qnil); return ONIG_MISMATCH; } + VALUE match = match_alloc(rb_cMatch); + rb_matchext_t *rm = RMATCH_EXT(match); + rm->regs = regs; + if (set_backref_str) { RB_OBJ_WRITE(match, &RMATCH(match)->str, rb_str_new4(str)); } diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb index be563dfa52..6973e21c7a 100644 --- a/test/ruby/test_regexp.rb +++ b/test/ruby/test_regexp.rb @@ -711,6 +711,18 @@ class TestRegexp < Test::Unit::TestCase } end + def test_match_no_match_no_matchdata + EnvUtil.without_gc do + h = {} + ObjectSpace.count_objects(h) + prev_matches = h[:T_MATCH] || 0 + md = /[A-Z]/.match('1') # no match + ObjectSpace.count_objects(h) + new_matches = h[:T_MATCH] || 0 + assert_equal prev_matches, new_matches, "Bug [#20104]" + end + end + def test_initialize assert_raise(ArgumentError) { Regexp.new } assert_equal(/foo/, assert_warning(/ignored/) {Regexp.new(/foo/, Regexp::IGNORECASE)}) diff --git a/tool/lib/envutil.rb b/tool/lib/envutil.rb index 9be0aac479..309a6af40f 100644 --- a/tool/lib/envutil.rb +++ b/tool/lib/envutil.rb @@ -254,6 +254,14 @@ module EnvUtil end module_function :under_gc_compact_stress + def without_gc + prev_disabled = GC.disable + yield + ensure + GC.enable unless prev_disabled + end + module_function :without_gc + def with_default_external(enc) suppress_warning { Encoding.default_external = enc } yield |