Prevent double frees with lexical constants
authorFather Chrysostomos <sprout@cpan.org>
Sat, 24 Nov 2012 07:32:55 +0000 (23:32 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 24 Nov 2012 15:35:50 +0000 (07:35 -0800)
my sub foo() { 2 }

This produces a double free, because SAVEPADSVANDMORTALIZE causes the
reference count to go down on scope exit, and nothing was increment-
ing it to compensate.

pp.c
t/cmd/lexsub.t

diff --git a/pp.c b/pp.c
index 8e4c4a6..e1c9d75 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -174,7 +174,7 @@ PP(pp_clonecv)
        /* If this changes to use SAVECLEARSV, we can move the SAVECLEARSV
           to introcv and remove the SvPADSTALE_off. */
        SAVEPADSVANDMORTALIZE(ARGTARG);
-       PAD_SVl(ARGTARG) = mg->mg_obj;
+       PAD_SVl(ARGTARG) = SvREFCNT_inc_simple_NN(mg->mg_obj);
     }
     else {
        if (CvROOT(mg->mg_obj)) {
index 06ee24c..f52951d 100644 (file)
@@ -8,7 +8,7 @@ BEGIN {
     *bar::like = *like;
 }
 no warnings 'deprecated';
-plan 127;
+plan 128;
 
 # -------------------- Errors with feature disabled -------------------- #
 
@@ -601,6 +601,13 @@ not_lexical11();
   is x, 3, 'my sub defined inside eval';
 }
 
+{
+  state $w;
+  local $SIG{__WARN__} = sub { $w .= shift };
+  eval q{ my sub george () { 2 } };
+  is $w, undef, 'no double free from constant my subs';
+}
+
 # -------------------- Interactions (and misc tests) -------------------- #
 
 is sub {