summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-09-28 05:52:53 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-10-01 12:51:54 -0700
commitcc02ebe5373ef9dc4ac786b90cb5db113958408e (patch)
tree11ff06e1d83186312a2bf211f7ebc725b4920fcc /mg.c
parent4ddea69a03520899f0beb1187b9ae3c69f278179 (diff)
downloadperl-cc02ebe5373ef9dc4ac786b90cb5db113958408e.tar.gz
Make magic_setsubstr check UTF8 flag after stringification
By checking it before, it can end up treating a UTF8 string as bytes when calculating offsets if the UTF8 flag is not turned on until the target is stringified. This can happen with overloading and typeglobs. This is a regression from 5.14. 5.14 itself was buggy, too, but one would have to modify the target after creating the substr lvalue but before assigning to it; and that because of another bug fixed by 83f78d1a27, which was cancelling out this one. package o { use overload '""' => sub { $_[0][0] } } my $refee = bless ["\x{100}a"], o::; my $substr = \substr $refee, -2; $$substr = "b"; warn $refee; That prints: Wide character in warn at - line 7. Āb at - line 7. In 5.14 it prints: b at - line 7.
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/mg.c b/mg.c
index d6561c9c66..7b13f615e3 100644
--- a/mg.c
+++ b/mg.c
@@ -2246,6 +2246,7 @@ Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
dVAR;
STRLEN len, lsv_len, oldtarglen, newtarglen;
const char * const tmps = SvPV_const(sv, len);
+ const char *targs;
SV * const lsv = LvTARG(sv);
STRLEN lvoff = LvTARGOFF(sv);
STRLEN lvlen = LvTARGLEN(sv);
@@ -2260,8 +2261,8 @@ Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
Perl_ck_warner(aTHX_ packWARN(WARN_SUBSTR),
"Attempt to use reference as lvalue in substr"
);
- if (SvUTF8(lsv)) lsv_len = sv_len_utf8_nomg(lsv);
- else (void)SvPV_nomg(lsv,lsv_len);
+ targs = SvPV_nomg(lsv,lsv_len);
+ if (SvUTF8(lsv)) lsv_len = sv_or_pv_len_utf8(lsv,targs,lsv_len);
if (!translate_substr_offsets(
lsv_len,
negoff ? -(IV)lvoff : (IV)lvoff, !negoff,