diff options
author | Dave Mitchell <davem@fdisolutions.com> | 2004-06-08 22:20:40 +0000 |
---|---|---|
committer | Dave Mitchell <davem@fdisolutions.com> | 2004-06-08 22:20:40 +0000 |
commit | dc09a129f20ae03853f77ccff57c311a4bae0f77 (patch) | |
tree | 663489bac3cd83eb94bbc18948f71b8f67ca0bb2 /pp_hot.c | |
parent | 72e5dea67722deb16f01b7f031b918a1919efc18 (diff) | |
download | perl-dc09a129f20ae03853f77ccff57c311a4bae0f77.tar.gz |
[perl #30061] double DESTROY in for loop
pp_iter decremented the ref count of the previous iterant before
unaliasing it. This could lead to DESTROY being called with the
loop variable still aliased to the freed value. If the DESTROY
also contained a for loop with the same iterator variable, the
freed value would get resurrected then freed for a second time.
p4raw-id: //depot/perl@22913
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 13 |
1 files changed, 8 insertions, 5 deletions
@@ -1824,7 +1824,7 @@ PP(pp_iter) { dSP; register PERL_CONTEXT *cx; - SV* sv; + SV *sv, *oldsv; AV* av; SV **itersvp; @@ -1852,8 +1852,9 @@ PP(pp_iter) /* we need a fresh SV every time so that loop body sees a * completely new SV for closures/references to work as * they used to */ - SvREFCNT_dec(*itersvp); + oldsv = *itersvp; *itersvp = newSVsv(cur); + SvREFCNT_dec(oldsv); } if (strEQ(SvPVX(cur), max)) sv_setiv(cur, 0); /* terminate next time */ @@ -1877,8 +1878,9 @@ PP(pp_iter) /* we need a fresh SV every time so that loop body sees a * completely new SV for closures/references to work as they * used to */ - SvREFCNT_dec(*itersvp); + oldsv = *itersvp; *itersvp = newSViv(cx->blk_loop.iterix++); + SvREFCNT_dec(oldsv); } RETPUSHYES; } @@ -1887,8 +1889,6 @@ PP(pp_iter) if (cx->blk_loop.iterix >= (av == PL_curstack ? cx->blk_oldsp : AvFILL(av))) RETPUSHNO; - SvREFCNT_dec(*itersvp); - if (SvMAGICAL(av) || AvREIFY(av)) { SV **svp = av_fetch(av, ++cx->blk_loop.iterix, FALSE); if (svp) @@ -1928,7 +1928,10 @@ PP(pp_iter) sv = (SV*)lv; } + oldsv = *itersvp; *itersvp = SvREFCNT_inc(sv); + SvREFCNT_dec(oldsv); + RETPUSHYES; } |