Perl_croak_no_modify(aTHX);
PUTBACK;
- setup_match:
s = SvPV_mutable(TARG, len);
+ setup_match:
if (!SvPOKp(TARG) || SvTYPE(TARG) == SVt_PVGV || SvVOK(TARG))
force_on_match = 1;
* http://www.nntp.perl.org/group/perl.perl5.porters/2010/04/msg158809.html
*/
if (DO_UTF8(dstr) && ! DO_UTF8(TARG)) {
- char * const orig_pvx = SvPVX(TARG);
+ char * const orig_pvx = SvPOKp(TARG) ? SvPVX(TARG) : NULL;
const STRLEN new_len = sv_utf8_upgrade_nomg(TARG);
/* If the lengths are the same, the pattern contains only
* invariants, can keep going; otherwise, various internal markers
* could be off, so redo */
if (new_len != len || orig_pvx != SvPVX(TARG)) {
+ /* Do this here, to avoid multiple FETCHes. */
+ s = SvPV_nomg(TARG, len);
goto setup_match;
}
}
#endif
if (force_on_match) {
force_on_match = 0;
- s = SvPV_force(TARG, len);
+ s = SvPV_force_nomg(TARG, len);
goto force_it;
}
d = s;
cases where it would be viable to drop into the copy code. */
TARG = sv_2mortal(newSVsv(TARG));
}
- s = SvPV_force(TARG, len);
+ s = SvPV_force_nomg(TARG, len);
goto force_it;
}
#ifdef PERL_OLD_COPY_ON_WRITE
}
require './test.pl';
-plan( tests => 190 );
+plan( tests => 200 );
$_ = 'david';
$a = s/david/rules/r;
# when substituted with a UTF8 replacement string, due to
# magic getting called multiple times, and pointers now pointing
# to stale/freed strings
+ # The original fix for this caused infinite loops for non- or cow-
+ # strings, so we test those, too.
package FOO;
my $fc;
sub TIESCALAR { bless [ "abcdefgh" ] }
$s =~ s/..../\x{101}/;
::is($fc, 1, "tied UTF8 stuff FETCH count");
::is("$s", "\x{101}efgh", "tied UTF8 stuff");
+
+ ::watchdog(300);
+ $fc = 0;
+ $s = *foo;
+ $s =~ s/..../\x{101}/;
+ ::is($fc, 1, '$tied_glob =~ s/non-utf8/utf8/ fetch count');
+ ::is("$s", "\x{101}::foo", '$tied_glob =~ s/non-utf8/utf8/ result');
+ $fc = 0;
+ $s = *foo;
+ $s =~ s/(....)/\x{101}/g;
+ ::is($fc, 1, '$tied_glob =~ s/(non-utf8)/utf8/g fetch count');
+ ::is("$s", "\x{101}\x{101}o",
+ '$tied_glob =~ s/(non-utf8)/utf8/g result');
+ $fc = 0;
+ $s = "\xff\xff\xff\xff\xff";
+ $s =~ s/..../\x{101}/;
+ ::is($fc, 1, '$tied_latin1 =~ s/non-utf8/utf8/ fetch count');
+ ::is("$s", "\x{101}\xff", '$tied_latin1 =~ s/non-utf8/utf8/ result');
+ $fc = 0;
+ { package package_name; tied($s)->[0] = __PACKAGE__ };
+ $s =~ s/..../\x{101}/;
+ ::is($fc, 1, '$tied_cow =~ s/non-utf8/utf8/ fetch count');
+ ::is("$s", "\x{101}age_name", '$tied_cow =~ s/non-utf8/utf8/ result');
+ $fc = 0;
+ $s = \1;
+ $s =~ s/..../\x{101}/;
+ ::is($fc, 1, '$tied_ref =~ s/non-utf8/utf8/ fetch count');
+ ::like("$s", qr/^\x{101}AR\(0x.*\)\z/,
+ '$tied_ref =~ s/non-utf8/utf8/ result');
}
# RT #97954