diff options
author | Zefram <zefram@fysh.org> | 2010-10-24 14:57:21 +0100 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2010-10-24 11:40:00 -0700 |
commit | 8f89e5a94a208b4017fb2fb80d6a0e23cd552ed9 (patch) | |
tree | 908f1376e69a56debccf3bfbc36f5cbd37743312 /pp_ctl.c | |
parent | ccbfef1989966a87df0683fb781de40d0fad1f84 (diff) | |
download | perl-8f89e5a94a208b4017fb2fb80d6a0e23cd552ed9.tar.gz |
don't rely on ghost contexts being unmolested
Dying and returning from a format both relied on the state of a
just-popped context frame being preserved across a LEAVE. Don't rely
on it. Test using an operator ripped off from Scope::Cleanup, which makes
it easy to run arbitrary Perl code during cleanup, without isolating it
on a separate context stack as the DESTROY mechanism does.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 13 |
1 files changed, 9 insertions, 4 deletions
@@ -1653,6 +1653,9 @@ Perl_die_unwind(pTHX_ SV *msv) SV *namesv; register PERL_CONTEXT *cx; SV **newsp; + COP *oldcop; + JMPENV *restartjmpenv; + OP *restartop; if (cxix < cxstack_ix) dounwind(cxix); @@ -1667,6 +1670,9 @@ Perl_die_unwind(pTHX_ SV *msv) } POPEVAL(cx); namesv = cx->blk_eval.old_namesv; + oldcop = cx->blk_oldcop; + restartjmpenv = cx->blk_eval.cur_top_env; + restartop = cx->blk_eval.retop; if (gimme == G_SCALAR) *++newsp = &PL_sv_undef; @@ -1678,7 +1684,7 @@ Perl_die_unwind(pTHX_ SV *msv) * XXX it might be better to find a way to avoid messing with * PL_curcop in save_re_context() instead, but this is a more * minimal fix --GSAR */ - PL_curcop = cx->blk_oldcop; + PL_curcop = oldcop; if (optype == OP_REQUIRE) { const char* const msg = SvPVx_nolen_const(exceptsv); @@ -1699,9 +1705,8 @@ Perl_die_unwind(pTHX_ SV *msv) else { sv_setsv(ERRSV, exceptsv); } - assert(CxTYPE(cx) == CXt_EVAL); - PL_restartjmpenv = cx->blk_eval.cur_top_env; - PL_restartop = cx->blk_eval.retop; + PL_restartjmpenv = restartjmpenv; + PL_restartop = restartop; JMPENV_JUMP(3); /* NOTREACHED */ } |