Assigning to DEFSV leaks if PL_defgv's gp_sv isn't set.
Marcus Holland-Moritz [Sat, 8 Nov 2008 12:38:36 +0000 (12:38 +0000)]
As Nicholas already noted in a FIXME, assigning to DEFSV should
use GvSV instead of GvSVn. This change ensures that, at least
under -DPERL_CORE, DEFSV cannot be assigned to and introduces
a DEFSV_set macro to allow setting DEFSV.
This fixes #53038: map leaks memory.

p4raw-id: //depot/perl@34776

XSUB.h
ext/Filter/Util/Call/Call.pm
ext/Filter/Util/Call/Call.xs
perl.h
pp_ctl.c
pp_hot.c
regexec.c

diff --git a/XSUB.h b/XSUB.h
index 46e9c29..2d95b1e 100644 (file)
--- a/XSUB.h
+++ b/XSUB.h
@@ -364,10 +364,10 @@ Rethrows a previously caught exception.  See L<perlguts/"Exception Handling">.
            SAVETMPS ;                                          \
            SAVEINT(db->filtering) ;                            \
            db->filtering = TRUE ;                              \
-           SAVESPTR(DEFSV) ;                                   \
+           SAVE_DEFSV ;                                        \
             if (name[7] == 's')                                 \
                 arg = newSVsv(arg);                             \
-           DEFSV = arg ;                                       \
+           DEFSV_set(arg) ;                                    \
            SvTEMP_off(arg) ;                                   \
            PUSHMARK(SP) ;                                      \
            PUTBACK ;                                           \
index 6522edc..46f0b81 100644 (file)
@@ -18,7 +18,7 @@ use vars qw($VERSION @ISA @EXPORT) ;
 
 @ISA = qw(Exporter DynaLoader);
 @EXPORT = qw( filter_add filter_del filter_read filter_read_exact) ;
-$VERSION = "1.07_01" ;
+$VERSION = "1.07_02" ;
 
 sub filter_read_exact($)
 {
index 2df81d8..2380b14 100644 (file)
@@ -125,9 +125,9 @@ filter_call(pTHX_ int idx, SV *buf_sv, int maxlen)
            SAVEINT(current_idx) ;      /* save current idx */
            current_idx = idx ;
 
-           SAVESPTR(DEFSV) ;   /* save $_ */
+           SAVE_DEFSV ;        /* save $_ */
            /* make $_ use our buffer */
-           DEFSV = newSVpv("", 0) ; 
+           DEFSV_set(newSVpv("", 0)) ; 
 
            PUSHMARK(sp) ;
 
diff --git a/perl.h b/perl.h
index e07416e..526155b 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1306,8 +1306,12 @@ EXTERN_C char *crypt(const char *, const char *);
 #endif
 
 #define ERRSV GvSV(PL_errgv)
-/* FIXME? Change the assignments to PL_defgv to instantiate GvSV?  */
-#define DEFSV GvSVn(PL_defgv)
+#ifdef PERL_CORE
+# define DEFSV (0 + GvSVn(PL_defgv))
+#else
+# define DEFSV GvSVn(PL_defgv)
+#endif
+#define DEFSV_set(sv) (GvSV(PL_defgv) = (sv))
 #define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv))
 
 #define ERRHV GvHV(PL_errgv)   /* XXX unused, here for compatibility */
index 08b14c6..3ef7e32 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -988,7 +988,7 @@ PP(pp_grepstart)
     if (PL_op->op_private & OPpGREP_LEX)
        PAD_SVl(PL_op->op_targ) = src;
     else
-       DEFSV = src;
+       DEFSV_set(src);
 
     PUTBACK;
     if (PL_op->op_type == OP_MAPSTART)
@@ -1099,7 +1099,7 @@ PP(pp_mapwhile)
        if (PL_op->op_private & OPpGREP_LEX)
            PAD_SVl(PL_op->op_targ) = src;
        else
-           DEFSV = src;
+           DEFSV_set(src);
 
        RETURNOP(cLOGOP->op_other);
     }
@@ -4822,7 +4822,7 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
        SAVETMPS;
        EXTEND(SP, 2);
 
-       DEFSV = upstream;
+       DEFSV_set(upstream);
        PUSHMARK(SP);
        mPUSHi(0);
        if (filter_state) {
index eeedc5b..6450e25 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2424,7 +2424,7 @@ PP(pp_grepwhile)
        if (PL_op->op_private & OPpGREP_LEX)
            PAD_SVl(PL_op->op_targ) = src;
        else
-           DEFSV = src;
+           DEFSV_set(src);
 
        RETURNOP(cLOGOP->op_other);
     }
index 025d159..6c0923f 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -2250,7 +2250,7 @@ S_regtry(pTHX_ regmatch_info *reginfo, char **startpos)
            /* Make $_ available to executed code. */
            if (reginfo->sv != DEFSV) {
                SAVE_DEFSV;
-               DEFSV = reginfo->sv;
+               DEFSV_set(reginfo->sv);
            }
        
            if (!(SvTYPE(reginfo->sv) >= SVt_PVMG && SvMAGIC(reginfo->sv)