This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix CvFILE() leak in Perl_newMYSUB()
authorDavid Mitchell <davem@iabyn.com>
Tue, 26 Mar 2019 12:33:46 +0000 (12:33 +0000)
committerDavid Mitchell <davem@iabyn.com>
Tue, 26 Mar 2019 12:49:25 +0000 (12:49 +0000)
This is basically the same as my recent fix for Perl_newATTRSUB_x(),
v5.29.8-46-gb37d10f658.

When overwriting cv with the contents of PL_compcv, it was checking the
CvDYNFILE(cv) flag (to see if CvFILE(cv) needed freeing) *after*
overwriting cv's flags with PL_compcv's flag.

op.c

diff --git a/op.c b/op.c
index 95a3061..ce769c5 100644 (file)
--- a/op.c
+++ b/op.c
@@ -9671,6 +9671,7 @@ Perl_newMYSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
     if (cv) {  /* must reuse cv in case stub is referenced elsewhere */
        /* transfer PL_compcv to cv */
        if (block) {
+            bool free_file = CvFILE(cv) && CvDYNFILE(cv);
            cv_flags_t preserved_flags =
                CvFLAGS(cv) & (CVf_BUILTIN_ATTRS|CVf_NAMED);
            PADLIST *const temp_padl = CvPADLIST(cv);
@@ -9692,8 +9693,9 @@ Perl_newMYSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
            CvFLAGS(compcv) &= ~(CVf_SLABBED|CVf_WEAKOUTSIDE);
            CvFLAGS(compcv) |= other_flags;
 
-           if (CvFILE(cv) && CvDYNFILE(cv)) {
+           if (free_file) {
                Safefree(CvFILE(cv));
+               CvFILE(cv) = NULL;
            }
 
            /* inner references to compcv must be fixed up ... */
@@ -9732,6 +9734,8 @@ Perl_newMYSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
     if (const_sv)
         goto clone;
 
+    if (CvFILE(cv) && CvDYNFILE(cv))
+        Safefree(CvFILE(cv));
     CvFILE_set_from_cop(cv, PL_curcop);
     CvSTASH_set(cv, PL_curstash);