summaryrefslogtreecommitdiff
path: root/pp_sort.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-10-26 13:49:40 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-10-28 16:15:07 -0700
commit8465ba45245d0c78b43d10c2436bd926a67c99e9 (patch)
treea90192623441af8e112a541c007d5411ead9f783 /pp_sort.c
parent538c5178ddc0470ec56edd6c1ef5416c46f217c7 (diff)
downloadperl-8465ba45245d0c78b43d10c2436bd926a67c99e9.tar.gz
Make PL_firstgv and PL_secondgv refcounted
Otherwise freeing *a or *b in a sort block will result in a crash: $ perl -e '@_=sort { delete $::{a}; 3 } 1..3' Segmentation fault: 11
Diffstat (limited to 'pp_sort.c')
-rw-r--r--pp_sort.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/pp_sort.c b/pp_sort.c
index 1bb0cd8031..e517bc42c0 100644
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1656,10 +1656,14 @@ PP(pp_sort)
CATCH_SET(TRUE);
PUSHSTACKi(PERLSI_SORT);
if (!hasargs && !is_xsub) {
- SAVESPTR(PL_firstgv);
- SAVESPTR(PL_secondgv);
- PL_firstgv = gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV);
- PL_secondgv = gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV);
+ SAVEGENERICSV(PL_firstgv);
+ SAVEGENERICSV(PL_secondgv);
+ PL_firstgv = MUTABLE_GV(SvREFCNT_inc(
+ gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV)
+ ));
+ PL_secondgv = MUTABLE_GV(SvREFCNT_inc(
+ gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV)
+ ));
SAVESPTR(GvSV(PL_firstgv));
SAVESPTR(GvSV(PL_secondgv));
}