[perl #32332] Perl segfaults; test case available
Dave Mitchell [Sat, 20 May 2006 11:58:07 +0000 (11:58 +0000)]
sub f { s/$var/f()/e } could free the wrong RE

p4raw-id: //depot/perl@28251

cop.h
pp_ctl.c
pp_hot.c

diff --git a/cop.h b/cop.h
index 749b128..b1273ac 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -576,10 +576,12 @@ struct subst {
        cx->sb_rxres            = NULL,                                 \
        cx->sb_rx               = rx,                                   \
        cx->cx_type             = CXt_SUBST;                            \
-       rxres_save(&cx->sb_rxres, rx)
+       rxres_save(&cx->sb_rxres, rx);                                  \
+       ReREFCNT_inc(rx)
 
 #define POPSUBST(cx) cx = &cxstack[cxstack_ix--];                      \
-       rxres_free(&cx->sb_rxres)
+       rxres_free(&cx->sb_rxres);                                      \
+       ReREFCNT_dec(cx->sb_rx)
 
 struct context {
     U32                cx_type;        /* what kind of context this is */
index 55ffb19..baed3fd 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -197,7 +197,7 @@ PP(pp_substcont)
     if(old != rx) {
        if(old)
            ReREFCNT_dec(old);
-       PM_SETRE(pm,rx);
+       PM_SETRE(pm,ReREFCNT_inc(rx));
     }
 
     rxres_restore(&cx->sb_rxres, rx);
@@ -256,7 +256,6 @@ PP(pp_substcont)
            SvTAINT(targ);
 
            LEAVE_SCOPE(cx->sb_oldsave);
-           ReREFCNT_dec(rx);
            POPSUBST(cx);
            RETURNOP(pm->op_next);
        }
index 6a879d7..7b0c128 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2303,7 +2303,6 @@ PP(pp_subst)
        if (!c) {
            register PERL_CONTEXT *cx;
            SPAGAIN;
-           (void)ReREFCNT_inc(rx);
            PUSHSUBST(cx);
            RETURNOP(cPMOP->op_pmreplroot);
        }