This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Stop invalid charnames from leaking
authorFather Chrysostomos <sprout@cpan.org>
Sat, 8 Dec 2012 14:36:59 +0000 (06:36 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 9 Dec 2012 02:46:54 +0000 (18:46 -0800)
The tests I added earlier were failing for a different reason than the
test names suggested.

Invalid charnames are not leaking because of the ‘too many errors’
that yyerror croakingly utters, but are leaking even when yyerror
doesn’t croak.

S_get_and_check_backslash_N_name just needs to free the returned SV
before returning if it is undefined.

t/op/svleak.t
toke.c

index c0672fc..13c800f 100644 (file)
@@ -284,18 +284,14 @@ eleak(2, 0, 'no warnings; 2 2;BEGIN{}',
 eleak(2, 0, "\"\$\0\356\"", 'qq containing $ <null> something');
 eleak(2, 0, 'END OF TERMS AND CONDITIONS', 'END followed by words');
 eleak(2, 0, "+ + +;qq|\\N{a}|"x10,'qq"\N{a}" after errors');
+eleak(2, 0, "qq|\\N{%}|",      'qq"\N{%}" (invalid charname)');
+eleak(2, 0, "qq|\\N{au}|;",    'qq"\N{invalid}"');
 eleak(2, 0, "qq|\\c|;"x10,     '"too many errors" from qq"\c"');
-$::TODO = 'still leaks';
-eleak(2, 0, "qq|\\N{%}|"x10,   '"too many errors" from qq"\N{%}"');
-undef $::TODO;
 eleak(2, 0, "qq|\\o|;"x10,     '"too many errors" from qq"\o"');
 eleak(2, 0, "qq|\\x{|;"x10,    '"too many errors" from qq"\x{"');
 eleak(2, 0, "qq|\\N|;"x10,     '"too many errors" from qq"\N"');
 eleak(2, 0, "qq|\\N{|;"x10,    '"too many errors" from qq"\N{"');
 eleak(2, 0, "qq|\\N{U+GETG}|;"x10,'"too many errors" from qq"\N{U+JUNK}"');
-$::TODO = 'still leaks';
-eleak(2, 0, "qq|\\N{au}|;"x10, '"too many errors" from qq"\N{invalid}"');
-undef $::TODO;
 
 
 # [perl #114764] Attributes leak scalars
diff --git a/toke.c b/toke.c
index 0d79a5b..16f359e 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -2689,6 +2689,7 @@ S_get_and_check_backslash_N_name(pTHX_ const char* s, const char* const e)
                         /* include the <}> */
                         e - backslash_ptr + 1);
     if (! SvPOK(res)) {
+        SvREFCNT_dec_NN(res);
         return NULL;
     }