Stop the glob operator from leaking GVs
authorFather Chrysostomos <sprout@cpan.org>
Mon, 5 Nov 2012 04:18:51 +0000 (20:18 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 5 Nov 2012 06:45:36 +0000 (22:45 -0800)
It was adding GVs to the symbol table (via newGVgen), so they
would never be freed, even after the op was freed, unless done so
explicitly.

There is no reason for these GVs to be exposed.

op.c
t/op/svleak.t

diff --git a/op.c b/op.c
index 93b71bd..b67d4cb 100644 (file)
--- a/op.c
+++ b/op.c
@@ -9015,12 +9015,14 @@ Perl_ck_glob(pTHX_ OP *o)
        LEAVE;
     }
 #endif /* !PERL_EXTERNAL_GLOB */
-    gv = newGVgen("main");
+    gv = (GV *)newSV(0);
+    gv_init(gv, 0, "", 0, 0);
     gv_IOadd(gv);
 #ifndef PERL_EXTERNAL_GLOB
     sv_setiv(GvSVn(gv),PL_glob_index++);
 #endif
     op_append_elem(OP_GLOB, o, newGVOP(OP_GV, 0, gv));
+    SvREFCNT_dec(gv); /* newGVOP increased it */
     scalarkids(o);
     return o;
 }
index f6d93fe..b74967f 100644 (file)
@@ -15,7 +15,7 @@ BEGIN {
 
 use Config;
 
-plan tests => 54;
+plan tests => 55;
 
 # 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
@@ -69,6 +69,8 @@ leak(5, 0, sub {},                 "basic check 1 of leak test infrastructure");
 leak(5, 0, sub {push @a,1;pop @a}, "basic check 2 of leak test infrastructure");
 leak(5, 1, sub {push @a,1;},       "basic check 3 of leak test infrastructure");
 
+eleak(2, 0, 'sub{<*>}');
+
 sub TIEARRAY   { bless [], $_[0] }
 sub FETCH      { $_[0]->[$_[1]] }
 sub STORE      { $_[0]->[$_[1]] = $_[2] }