From bbde7ba366f7e8eba62f86287e5267085c03d7dc Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Tue, 6 Dec 2011 08:34:15 -0800 Subject: [PATCH 1/1] =?utf8?q?Don=E2=80=99t=20LEAVE=5Fwith=5Fname("evalcom?= =?utf8?q?p")=20for=20syntax=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit In S_doeval, if yystatus == 0 but there have been parser errors, then there will be an extra scope on the scope stack inside the evalcomp scope, causing an assertion failure with LEAVE_with_name("evalcomp"). This can happen with eval(q|""!=!~//|), which is a reduced version of an eval in SNMP::Trapinfo’s test suite. Under non-debugging builds, everything would have worked anyway, as the LEAVE_with_name("evalcomp") would have left the scope inside evalcomp. Since POPBLOCK pops away the savestack markers on the scope stack, it is not actually necessary to do LEAVE_with_name("evalcomp") at all when there is a syntax error. --- pp_ctl.c | 4 ++-- t/op/eval.t | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pp_ctl.c b/pp_ctl.c index 8e91ebd..b38e8e6 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -3588,8 +3588,6 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq, HV *hh) yystatus = (!in_require && CATCH_GET) ? S_try_yyparse(aTHX_ GRAMPROG) : yyparse(GRAMPROG); - if (!startop && yystatus != 3) LEAVE_with_name("evalcomp"); - if (yystatus || PL_parser->error_count || !PL_eval_root) { SV **newsp; /* Used by POPBLOCK. */ PERL_CONTEXT *cx; @@ -3615,6 +3613,7 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq, HV *hh) POPEVAL(cx); namesv = cx->blk_eval.old_namesv; } + /* POPBLOCK renders LEAVE_with_name("evalcomp") unnecessary. */ LEAVE_with_name("eval"); /* pp_entereval knows about this LEAVE. */ } @@ -3654,6 +3653,7 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq, HV *hh) PUTBACK; return FALSE; } + else if (!startop) LEAVE_with_name("evalcomp"); CopLINE_set(&PL_compiling, 0); if (startop) { *startop = PL_eval_root; diff --git a/t/op/eval.t b/t/op/eval.t index f8e23e3..78faa85 100644 --- a/t/op/eval.t +++ b/t/op/eval.t @@ -6,7 +6,7 @@ BEGIN { require './test.pl'; } -plan(tests => 120); +plan(tests => 121); eval 'pass();'; @@ -586,3 +586,8 @@ EOP BEGIN { eval 'require re; import re "/x"' } ok "ab" =~ /a b/, 'eval does not localise %^H at run time'; } + +# The fix for perl #70151 caused an assertion failure that broke +# SNMP::Trapinfo, when toke.c finds no syntax errors but perly.y fails. +eval(q|""!=!~//|); +pass("phew! dodged the assertion after a parsing (not lexing) error"); -- 1.8.3.1