avoid tainting boolean return value of s///
authorDavid Mitchell <davem@iabyn.com>
Tue, 19 Dec 2017 14:52:49 +0000 (14:52 +0000)
committerDavid Mitchell <davem@iabyn.com>
Tue, 19 Dec 2017 15:15:02 +0000 (15:15 +0000)
RT #132385

s/// normally returns an integer count, but sometimes for efficiency it
will return a boolean instead (PL_sv_yes/PL_sv_zero).

In these cases, don't try to taint the return value, since it will die
with 'Modification of a read-only value'.

pp_hot.c
t/op/taint.t

index 958aa6e..bba90a8 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -4190,8 +4190,8 @@ PP(pp_subst)
            (SvTAINTED(TARG) ? SUBST_TAINT_STR : 0)
          | (RXp_ISTAINTED(prog) ? SUBST_TAINT_PAT : 0)
          | ((pm->op_pmflags & PMf_RETAINT) ? SUBST_TAINT_RETAINT : 0)
-         | ((once && !(rpm->op_pmflags & PMf_NONDESTRUCT))
-               ? SUBST_TAINT_BOOLRET : 0));
+         | ((  (once && !(rpm->op_pmflags & PMf_NONDESTRUCT))
+             || (PL_op->op_private & OPpTRUEBOOL)) ? SUBST_TAINT_BOOLRET : 0));
        TAINT_NOT;
     }
 
index 912be0e..e5a4799 100644 (file)
@@ -17,7 +17,7 @@ BEGIN {
 use strict;
 use Config;
 
-plan tests => 1038;
+plan tests => 1039;
 
 $| = 1;
 
@@ -2855,6 +2855,15 @@ is_tainted("$ovtaint", "overload preserves taint");
     is($one, 'd',      "$desc: \$1 value");
 }
 
+# RT #132385
+# It was trying to taint a boolean return from s/// (e.g. PL_sv_yes)
+# and was thus crashing with 'Modification of a read-only value'.
+
+{
+    my $s = "abcd" . $TAINT;
+    ok(!!($s =~ s/a/x/g), "RT #132385");
+}
+
 # This may bomb out with the alarm signal so keep it last
 SKIP: {
     skip "No alarm()"  unless $Config{d_alarm};