From: Robin Houston Date: Tue, 24 Feb 1998 11:15:57 +0000 (+0000) Subject: Re: [PATCH 5.004_60] Fix goto-in-eval segfault (unwrapped!) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b150fb22188cba2cc0808878ec299d4f0e8c70ea;p=p5sagit%2Fp5-mst-13.2.git Re: [PATCH 5.004_60] Fix goto-in-eval segfault (unwrapped!) p4raw-id: //depot/perl@582 --- diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 4ed7041..5f2876b 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -638,6 +638,11 @@ call for another. It can't manufacture one out of whole cloth. In general you should be calling it out of only an AUTOLOAD routine anyway. See L. +=item Can't goto subroutine from an eval-string + +(F) The "goto subroutine" call can't be used to jump out of an eval "string". +(You can use it to jump out of an eval {BLOCK}, but you probably don't want to.) + =item Can't localize through a reference (F) You said something like C, which Perl can't currently diff --git a/pp_ctl.c b/pp_ctl.c index 2cfe854..9753fcf 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -1722,8 +1722,11 @@ PP(pp_goto) if (cxix < cxstack_ix) dounwind(cxix); TOPBLOCK(cx); + if (cx->cx_type == CXt_EVAL && cx->blk_eval.old_op_type == OP_ENTEREVAL) + DIE("Can't goto subroutine from an eval-string"); mark = stack_sp; - if (cx->blk_sub.hasargs) { /* put @_ back onto stack */ + if (cx->cx_type == CXt_SUB && + cx->blk_sub.hasargs) { /* put @_ back onto stack */ AV* av = cx->blk_sub.argarray; items = AvFILLp(av) + 1; @@ -1738,7 +1741,8 @@ PP(pp_goto) AvREAL_off(av); av_clear(av); } - if (!(CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth)) + if (cx->cx_type == CXt_SUB && + !(CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth)) SvREFCNT_dec(cx->blk_sub.cv); oldsave = scopestack[scopestack_ix - 1]; LEAVE_SCOPE(oldsave); @@ -1768,6 +1772,12 @@ PP(pp_goto) else { AV* padlist = CvPADLIST(cv); SV** svp = AvARRAY(padlist); + if (cx->cx_type == CXt_EVAL) { + in_eval = cx->blk_eval.old_in_eval; + eval_root = cx->blk_eval.old_eval_root; + cx->cx_type = CXt_SUB; + cx->blk_sub.hasargs = 0; + } cx->blk_sub.cv = cv; cx->blk_sub.olddepth = CvDEPTH(cv); CvDEPTH(cv)++;