summaryrefslogtreecommitdiff
path: root/scope.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-08-26 23:31:36 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-08-26 23:44:38 -0700
commit014333460b4235140c1e4ad346b2581af7ff6592 (patch)
tree4ed94798dab023f1bca2f207449015cde5245edc /scope.c
parent17008668bc1759e4a1ff55f42c3d738e5534b5dc (diff)
downloadperl-014333460b4235140c1e4ad346b2581af7ff6592.tar.gz
GVs of localised arrays and hashes should be refcounted
Otherwise the GV can be freed before the scope-popping code can put the old entry back in it: $ perl -le 'local @{"x"}; delete $::{x}' Bus error $ perl -le 'local %{"x"}; delete $::{x}' Bus error
Diffstat (limited to 'scope.c')
-rw-r--r--scope.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/scope.c b/scope.c
index 9a43eb0ebb..b9051d5c63 100644
--- a/scope.c
+++ b/scope.c
@@ -317,7 +317,7 @@ Perl_save_ary(pTHX_ GV *gv)
if (!AvREAL(oav) && AvREIFY(oav))
av_reify(oav);
- save_pushptrptr(gv, oav, SAVEt_AV);
+ save_pushptrptr(SvREFCNT_inc_simple_NN(gv), oav, SAVEt_AV);
GvAV(gv) = NULL;
av = GvAVn(gv);
@@ -334,7 +334,9 @@ Perl_save_hash(pTHX_ GV *gv)
PERL_ARGS_ASSERT_SAVE_HASH;
- save_pushptrptr(gv, (ohv = GvHVn(gv)), SAVEt_HV);
+ save_pushptrptr(
+ SvREFCNT_inc_simple_NN(gv), (ohv = GvHVn(gv)), SAVEt_HV
+ );
GvHV(gv) = NULL;
hv = GvHVn(gv);
@@ -786,6 +788,7 @@ Perl_leave_scope(pTHX_ I32 base)
SvSETMAGIC(MUTABLE_SV(av));
PL_localizing = 0;
}
+ SvREFCNT_dec(gv);
break;
case SAVEt_HV: /* hash reference */
hv = MUTABLE_HV(SSPOPPTR);
@@ -797,6 +800,7 @@ Perl_leave_scope(pTHX_ I32 base)
SvSETMAGIC(MUTABLE_SV(hv));
PL_localizing = 0;
}
+ SvREFCNT_dec(gv);
break;
case SAVEt_INT_SMALL:
ptr = SSPOPPTR;