In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/7332835e5da7b7a793ef814a84e53003be1d0138?hp=32458de9a4322bd2e66c525d33720a42df7e0b56>
- Log ----------------------------------------------------------------- commit 7332835e5da7b7a793ef814a84e53003be1d0138 Author: David Mitchell <[email protected]> Date: Mon Nov 28 08:03:49 2016 +0000 crash on explicit return from s///e RT #130188 In sub f { my $x = 'a'; $x =~ s/./return;/e; } the 'return' triggers popping any contexts above the subroutine context: in this case, a CXt_SUBST context. In this case, Perl_dounwind() calls cx_popblock() for the bottom-most popped context, to restore any saved vars. However, CXt_SUBST is the one context type which *doesn't* use 'struct block' as part of its context struct union, so you can't cx_popblock() a CXt_SUBST context. This commit makes it skip the cx_popblock() in this case. Bug was introduced by me with v5.23.7-235-gfc6e609. ----------------------------------------------------------------------- Summary of changes: pp_ctl.c | 6 ++++++ t/re/subst.t | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/pp_ctl.c b/pp_ctl.c index 89a7521..ec0ad7d 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -1530,6 +1530,12 @@ Perl_dounwind(pTHX_ I32 cxix) switch (CxTYPE(cx)) { case CXt_SUBST: CX_POPSUBST(cx); + /* CXt_SUBST is not a block context type, so skip the + * cx_popblock(cx) below */ + if (cxstack_ix == cxix + 1) { + cxstack_ix--; + return; + } break; case CXt_SUB: cx_popsub(cx); diff --git a/t/re/subst.t b/t/re/subst.t index 334d6ad..b9b9939 100644 --- a/t/re/subst.t +++ b/t/re/subst.t @@ -11,7 +11,7 @@ BEGIN { require './loc_tools.pl'; } -plan( tests => 274 ); +plan(tests => 275); $_ = 'david'; $a = s/david/rules/r; @@ -1151,3 +1151,18 @@ SKIP: { undef *Tie::Prematch::FETCH; __EOF__ } + +# [perl #130188] crash on return from substitution in subroutine +# make sure returning from s///e doesn't SEGV +{ + my $f = sub { + my $x = 'a'; + $x =~ s/./return;/e; + }; + my $x = $f->(); + pass("RT #130188"); +} + + + + -- Perl5 Master Repository
