summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-12-19 15:40:41 +0000
committerDavid Mitchell <davem@iabyn.com>2017-12-19 15:40:41 +0000
commitbae26b955e9b17fa91cd0958f2da36b55ff26d45 (patch)
tree9ef1c3a2b2f187c5a9192e4614d0893a4ccad5d4
parent159675014fd98cba9a4bb64961c8cec02dfec87d (diff)
parent04d596853d450fae95e059c4d4d15f6750beea34 (diff)
downloadperl-bae26b955e9b17fa91cd0958f2da36b55ff26d45.tar.gz
[MERGE] s/// return value fixups
-rw-r--r--pp_hot.c12
-rw-r--r--t/op/taint.t11
2 files changed, 18 insertions, 5 deletions
diff --git a/pp_hot.c b/pp_hot.c
index 100ae39b07..21b1f16a28 100644
--- 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;
}
@@ -4361,8 +4361,9 @@ PP(pp_subst)
Move(s, d, i+1, char); /* include the NUL */
}
SPAGAIN;
+ assert(iters);
if (PL_op->op_private & OPpTRUEBOOL)
- PUSHs(iters ? &PL_sv_yes : &PL_sv_zero);
+ PUSHs(&PL_sv_yes);
else
mPUSHi(iters);
}
@@ -4470,7 +4471,10 @@ PP(pp_subst)
SvPV_set(dstr, NULL);
SPAGAIN;
- mPUSHi(iters);
+ if (PL_op->op_private & OPpTRUEBOOL)
+ PUSHs(&PL_sv_yes);
+ else
+ mPUSHi(iters);
}
}
diff --git a/t/op/taint.t b/t/op/taint.t
index 912be0e659..e5a47996c5 100644
--- a/t/op/taint.t
+++ b/t/op/taint.t
@@ -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};