Stop /(?{})+/ from leaking under fatal warnings
authorFather Chrysostomos <sprout@cpan.org>
Mon, 3 Dec 2012 01:40:36 +0000 (17:40 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 3 Dec 2012 16:53:44 +0000 (08:53 -0800)
This commit arranges for the regexp to be freed in case the ‘blah blah
blah matches null string many times in regex’ warning proves fatal.

regcomp.c
t/op/svleak.t

index 46b9802..51b3e2a 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -9653,10 +9653,12 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
     }
   nest_check:
     if (!SIZE_ONLY && !(flags&(HASWIDTH|POSTPONED)) && max > REG_INFTY/3) {
+       SAVEFREESV(RExC_rx_sv); /* in case of fatal warnings */
        ckWARN3reg(RExC_parse,
                   "%.*s matches null string many times",
                   (int)(RExC_parse >= origparse ? RExC_parse - origparse : 0),
                   origparse);
+       ReREFCNT_inc(RExC_rx_sv);
     }
 
     if (RExC_parse < RExC_end && *RExC_parse == '?') {
index bbccfa9..f4abbdb 100644 (file)
@@ -99,8 +99,8 @@ eleak(2, 0, "$f 'closure';
              sub foo { my \$x; format=\n\@\n\$x\n.\n} write; ",
      'format closing over unavailable var with fatal warnings');
 eleak(2, 0, "$all /(?{})?/ ", '(?{})? with fatal warnings');
-$::TODO = 'still leaks';
 eleak(2, 0, "$all /(?{})+/ ", '(?{})+ with fatal warnings');
+$::TODO = 'still leaks';
 eleak(2, 0, "$all /[\\i]/ ", 'invalid charclass escape with fatal warns');
 eleak(2, 0, "$all /[:foo:]/ ", '/[:foo:]/ with fatal warnings');
 eleak(2, 0, "$all /[a-\\d]/ ", '[a-\d] char class with fatal warnings');