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

Reply via email to