This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix lvalue context for 4-arg substr
authorZefram <zefram@fysh.org>
Thu, 16 Nov 2017 14:56:11 +0000 (14:56 +0000)
committerZefram <zefram@fysh.org>
Thu, 16 Nov 2017 14:59:22 +0000 (14:59 +0000)
4-arg substr uses its first arg as an lvalue, but wasn't lvaluifying
it properly.  [perl #115258]

op.c
t/op/substr.t

diff --git a/op.c b/op.c
index c617ad2..2e4dae4 100644 (file)
--- a/op.c
+++ b/op.c
@@ -13385,7 +13385,7 @@ Perl_ck_substr(pTHX_ OP *o)
        if (kid->op_type == OP_NULL)
            kid = OpSIBLING(kid);
        if (kid)
-           kid->op_flags |= OPf_MOD;
+           op_lvalue(kid, o->op_type);
 
     }
     return o;
index 3d850f5..dade46d 100644 (file)
@@ -22,7 +22,7 @@ $SIG{__WARN__} = sub {
      }
 };
 
-plan(392);
+plan(399);
 
 run_tests() unless caller;
 
@@ -883,4 +883,30 @@ fresh_perl_is('$0 = "/usr/bin/perl"; substr($0, 0, 0, $0)', '', {}, "(perl #1293
     is $x, "\x{100}zzzz", "RT#130624: heap-use-after-free in 4-arg substr (targ)";
 }
 
+{
+    our @ta;
+    $#ta = -1;
+    substr($#ta, 0, 2) = 23;
+    is $#ta, 23;
+    $#ta = -1;
+    substr($#ta, 0, 2) =~ s/\A..\z/23/s;
+    is $#ta, 23;
+    $#ta = -1;
+    substr($#ta, 0, 2, 23);
+    is $#ta, 23;
+    sub ta_tindex :lvalue { $#ta }
+    $#ta = -1;
+    ta_tindex() = 23;
+    is $#ta, 23;
+    $#ta = -1;
+    substr(ta_tindex(), 0, 2) = 23;
+    is $#ta, 23;
+    $#ta = -1;
+    substr(ta_tindex(), 0, 2) =~ s/\A..\z/23/s;
+    is $#ta, 23;
+    $#ta = -1;
+    substr(ta_tindex(), 0, 2, 23);
+    is $#ta, 23;
+}
 
+1;