diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-08-26 23:31:36 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-08-26 23:44:38 -0700 |
commit | 014333460b4235140c1e4ad346b2581af7ff6592 (patch) | |
tree | 4ed94798dab023f1bca2f207449015cde5245edc /scope.c | |
parent | 17008668bc1759e4a1ff55f42c3d738e5534b5dc (diff) | |
download | perl-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.c | 8 |
1 files changed, 6 insertions, 2 deletions
@@ -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; |