Stop invalid y/// ranges from leaking
authorFather Chrysostomos <sprout@cpan.org>
Mon, 27 Aug 2012 06:46:09 +0000 (23:46 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 28 Aug 2012 06:24:01 +0000 (23:24 -0700)
t/op/svleak.t
toke.c

index 3a3d052..04ba35c 100644 (file)
@@ -15,7 +15,7 @@ BEGIN {
 
 use Config;
 
-plan tests => 25;
+plan tests => 27;
 
 # run some code N times. If the number of SVs at the end of loop N is
 # greater than (N-1)*delta at the end of loop 1, we've got a leak
@@ -180,4 +180,6 @@ SKIP: {
                }"' }, 'unterminated here-doc in multiline quotes in eval');
     leak(2, 0, sub { eval { do './op/svleak.pl' } },
         'unterminated here-doc in file');
+    leak(2, 0, sub { eval 'tr/9-0//' }, 'tr/9-0//');
+    leak(2, 0, sub { eval 'tr/a-z-0//' }, 'tr/a-z-0//');
 }
diff --git a/toke.c b/toke.c
index 5174f89..f0619d4 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -2518,6 +2518,7 @@ S_sublex_push(pTHX)
     PL_bufend += SvCUR(PL_linestr);
     PL_last_lop = PL_last_uni = NULL;
     SAVEFREESV(PL_linestr);
+    if (PL_lex_repl) SAVEFREESV(PL_lex_repl);
 
     PL_lex_dojoin = FALSE;
     PL_lex_brackets = PL_lex_formbrack = 0;
@@ -2574,7 +2575,6 @@ S_sublex_done(pTHX)
        PL_bufend = PL_bufptr = PL_oldbufptr = PL_oldoldbufptr = PL_linestart = SvPVX(PL_linestr);
        PL_bufend += SvCUR(PL_linestr);
        PL_last_lop = PL_last_uni = NULL;
-       SAVEFREESV(PL_linestr);
        PL_lex_dojoin = FALSE;
        PL_lex_brackets = 0;
        PL_lex_allbrackets = 0;
@@ -2826,6 +2826,7 @@ S_scan_const(pTHX_ char *start)
 #endif
 
                 if (min > max) {
+                   SvREFCNT_dec(sv);
                    Perl_croak(aTHX_
                               "Invalid range \"%c-%c\" in transliteration operator",
                               (char)min, (char)max);
@@ -2884,6 +2885,7 @@ S_scan_const(pTHX_ char *start)
            /* range begins (ignore - as first or last char) */
            else if (*s == '-' && s+1 < send  && s != start) {
                if (didrange) {
+                   SvREFCNT_dec(sv);
                    Perl_croak(aTHX_ "Ambiguous range in transliteration operator");
                }
                if (has_utf8