summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2006-05-20 11:58:07 +0000
committerDave Mitchell <davem@fdisolutions.com>2006-05-20 11:58:07 +0000
commite22ae1e278fa878ce0da6700e97da49f0dacf636 (patch)
tree4dd43a78d3f3555b2c2db1e6e0e3cbc41e080d5e
parent7b0bddfae402018e486a2f1fa0daf4581b85b65b (diff)
downloadperl-e22ae1e278fa878ce0da6700e97da49f0dacf636.tar.gz
[perl #32332] Perl segfaults; test case available
sub f { s/$var/f()/e } could free the wrong RE p4raw-id: //depot/perl@28251
-rw-r--r--cop.h6
-rw-r--r--pp_ctl.c3
-rw-r--r--pp_hot.c1
3 files changed, 5 insertions, 5 deletions
diff --git a/cop.h b/cop.h
index 749b128870..b1273ac2ff 100644
--- 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 */
diff --git a/pp_ctl.c b/pp_ctl.c
index 55ffb1933b..baed3fda58 100644
--- 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);
}
diff --git a/pp_hot.c b/pp_hot.c
index 6a879d77f7..7b0c128c61 100644
--- 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);
}