RETURN;
}
+ PL_curpm = pm;
+
/* known replacement string? */
if (dstr) {
if (SvTAINTED(dstr))
#endif
&& (I32)clen <= RX_MINLENRET(rx)
&& (once || !(r_flags & REXEC_COPY_STR))
- && !(RX_EXTFLAGS(rx) & RXf_LOOKBEHIND_SEEN)
+ && !(RX_EXTFLAGS(rx) & (RXf_LOOKBEHIND_SEEN|RXf_MODIFIES_VARS))
&& (!doutf8 || SvUTF8(TARG))
&& !(rpm->op_pmflags & PMf_NONDESTRUCT))
{
goto force_it;
}
d = s;
- PL_curpm = pm;
if (once) {
if (RX_MATCH_TAINTED(rx)) /* run time pattern taint, eg locale */
rxtainted |= SUBST_TAINT_PAT;
}
}
else {
+ bool first;
+ SV *repl;
if (force_on_match) {
force_on_match = 0;
if (rpm->op_pmflags & PMf_NONDESTRUCT) {
#endif
if (RX_MATCH_TAINTED(rx)) /* run time pattern taint, eg locale */
rxtainted |= SUBST_TAINT_PAT;
+ repl = dstr;
dstr = newSVpvn_flags(m, s-m, SVs_TEMP | (DO_UTF8(TARG) ? SVf_UTF8 : 0));
- PL_curpm = pm;
if (!c) {
PERL_CONTEXT *cx;
SPAGAIN;
RETURNOP(cPMOP->op_pmreplrootu.op_pmreplroot);
}
r_flags |= REXEC_IGNOREPOS | REXEC_NOT_FIRST;
+ first = TRUE;
do {
if (iters++ > maxiters)
DIE(aTHX_ "Substitution loop");
m = RX_OFFS(rx)[0].start + orig;
sv_catpvn_nomg_maybeutf8(dstr, s, m - s, DO_UTF8(TARG));
s = RX_OFFS(rx)[0].end + orig;
- if (clen)
+ if (first) {
+ /* replacement already stringified */
+ if (clen)
sv_catpvn_nomg_maybeutf8(dstr, c, clen, doutf8);
+ first = FALSE;
+ }
+ else {
+ if (SvTAINTED(dstr))
+ rxtainted |= SUBST_TAINT_REPL;
+ if (PL_encoding) {
+ if (!nsv) nsv = sv_newmortal();
+ sv_copypv(nsv, repl);
+ if (!DO_UTF8(nsv)) sv_recode_to_utf8(nsv, PL_encoding);
+ sv_catsv(dstr, nsv);
+ }
+ else sv_catsv(dstr, repl);
+ }
if (once)
break;
} while (CALLREGEXEC(rx, s, strend, orig, s == m,
}
-plan tests => 2525; # Update this when adding/deleting tests.
+plan tests => 2527; # Update this when adding/deleting tests.
run_tests() unless caller;
$_ = "CCCCBAA";
ok(s/(*:X)A+|(*:Y)B+|(*:Z)C+/$REGMARK/g, $message);
is($_, "ZYX", $message);
+ # Use a longer name to force reallocation of $REGMARK.
+ $_ = "CCCCBAA";
+ ok(s/(*:X)A+|(*:YYYYYYYYYYYYYYYY)B+|(*:Z)C+/$REGMARK/g, $message);
+ is($_, "ZYYYYYYYYYYYYYYYYX", $message);
}
{
require './test.pl';
}
-plan( tests => 202 );
+plan( tests => 203 );
$_ = 'david';
$a = s/david/rules/r;
}
+# Test problems with constant replacement optimisation
# [perl #26986] logop in repl resulting in incorrect optimisation
"g" =~ /(.)/;
@l{'a'..'z'} = 'A'..':';
{ s/(.)/$l{my $a||$1}/g }
is $_, "HELLO",
'logop in s/// repl does not result in "constant" repl optimisation';
+# Aliases to match vars
+"g" =~ /(.)/;
+$_ = "hello";
+{
+ local *a = *1;
+ s/(.)\1/$a/g;
+}
+is $_, 'helo', 's/pat/$alias_to_match_var/';
+
$_ = "\xc4\x80";
$a = "";