This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Stop %! after syntax error from leaking the module name
authorFather Chrysostomos <sprout@cpan.org>
Sun, 4 Nov 2012 22:57:49 +0000 (14:57 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 5 Nov 2012 06:45:35 +0000 (22:45 -0800)
gv.c
t/op/svleak.t

diff --git a/gv.c b/gv.c
index 612b2ee..40f7c23 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -1239,12 +1239,12 @@ S_require_tie_mod(pTHX_ GV *gv, const char *varpv, SV* namesv, const char *methp
        const char type = varname == '[' ? '$' : '%';
        dSP;
        ENTER;
        const char type = varname == '[' ? '$' : '%';
        dSP;
        ENTER;
+       SAVEFREESV(namesv);
        if ( flags & 1 )
            save_scalar(gv);
        PUSHSTACKi(PERLSI_MAGIC);
        Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, module, NULL);
        POPSTACK;
        if ( flags & 1 )
            save_scalar(gv);
        PUSHSTACKi(PERLSI_MAGIC);
        Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, module, NULL);
        POPSTACK;
-       LEAVE;
        stash = gv_stashsv(namesv, 0);
        if (!stash)
            Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" is not available",
        stash = gv_stashsv(namesv, 0);
        if (!stash)
            Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" is not available",
@@ -1252,8 +1252,9 @@ S_require_tie_mod(pTHX_ GV *gv, const char *varpv, SV* namesv, const char *methp
        else if (!gv_fetchmethod(stash, methpv))
            Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" does not support method %s",
                    type, varname, SVfARG(namesv), methpv);
        else if (!gv_fetchmethod(stash, methpv))
            Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" does not support method %s",
                    type, varname, SVfARG(namesv), methpv);
+       LEAVE;
     }
     }
-    SvREFCNT_dec(namesv);
+    else SvREFCNT_dec(namesv);
     return stash;
 }
 
     return stash;
 }
 
index c8cf01b..f6d93fe 100644 (file)
@@ -15,7 +15,7 @@ BEGIN {
 
 use Config;
 
 
 use Config;
 
-plan tests => 53;
+plan tests => 54;
 
 # 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
 
 # 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
@@ -198,6 +198,11 @@ eleak(2, 0, 'no warnings; nonexistent_function 33838',
 eleak(2, 0, '//dd;'x20, '"too many errors" when parsing m// flags');
 eleak(2, 0, 's///dd;'x20, '"too many errors" when parsing s/// flags');
 eleak(2, 0, 'no warnings; 2 2;BEGIN{}', 'BEGIN block after syntax error');
 eleak(2, 0, '//dd;'x20, '"too many errors" when parsing m// flags');
 eleak(2, 0, 's///dd;'x20, '"too many errors" when parsing s/// flags');
 eleak(2, 0, 'no warnings; 2 2;BEGIN{}', 'BEGIN block after syntax error');
+{
+    local %INC; # in case Errno is already loaded
+    eleak(2, 0, 'no warnings; 2@!{',
+                'implicit "use Errno" after syntax error');
+}
 
 # [perl #114764] Attributes leak scalars
 leak(2, 0, sub { eval 'my $x : shared' }, 'my $x :shared used to leak');
 
 # [perl #114764] Attributes leak scalars
 leak(2, 0, sub { eval 'my $x : shared' }, 'my $x :shared used to leak');