diff options
author | Nicholas Clark <nick@ccl4.org> | 2011-08-29 15:25:23 +0200 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2011-08-29 16:01:38 +0200 |
commit | 0c1438a1f54e0a813029e14b554e904c360b046a (patch) | |
tree | 4f9b8763d4792c0d34f9fc52c11d06c2cdcd207d /pp_hot.c | |
parent | b1e878f6dbf2d7092691a3ba0fc5d369ae48aa8c (diff) | |
download | perl-0c1438a1f54e0a813029e14b554e904c360b046a.tar.gz |
For s///r, don't call SvPV_force() on the original value. Resolves #97954.
8ca8a454f60a417f optimised the implementation of s///r by avoiding an
unconditional copy of the original value. However, it introduced a behaviour
regression where if original value happened to be one of a few particular
types, it could be modified by being forced to a string using SvPV_force().
The substitution was (correctly) performed on a copy of this string.
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 8 |
1 files changed, 8 insertions, 0 deletions
@@ -2294,6 +2294,14 @@ PP(pp_subst) else { if (force_on_match) { force_on_match = 0; + if (rpm->op_pmflags & PMf_NONDESTRUCT) { + /* I feel that it should be possible to avoid this mortal copy + given that the code below copies into a new destination. + However, I suspect it isn't worth the complexity of + unravelling the C<goto force_it> for the small number of + cases where it would be viable to drop into the copy code. */ + TARG = sv_2mortal(newSVsv(TARG)); + } s = SvPV_force(TARG, len); goto force_it; } |