summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2001-01-11 17:11:01 +0000
committerJarkko Hietaniemi <jhi@iki.fi>2001-01-11 17:11:01 +0000
commit075a4a2b17419f90b0888605cbb91ee4b236f645 (patch)
tree13022ad233f9ffbfa26a8a2735683b4535c07143 /mg.c
parent31a5f8c19f13755530c6e4a19d7486278a19ea61 (diff)
downloadperl-075a4a2b17419f90b0888605cbb91ee4b236f645.tar.gz
Fix UTF-8 lval substr().
p4raw-id: //depot/perl@8405
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/mg.c b/mg.c
index 3a61655678..ca06b891fc 100644
--- a/mg.c
+++ b/mg.c
@@ -1417,15 +1417,25 @@ Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg)
int
Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
{
- STRLEN len;
- char *tmps = SvPV(sv,len);
+ STRLEN littlelen;
+ char *tmps = SvPV(sv, littlelen);
+
if (DO_UTF8(sv)) {
+ I32 bigoff = LvTARGOFF(sv);
+ I32 biglen = LvTARGLEN(sv);
+ U8 *s, *a, *b;
+
sv_utf8_upgrade(LvTARG(sv));
- sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
+ /* sv_utf8_upgrade() might have moved and/or resized
+ * the string to be replaced, we must rediscover it. --jhi */
+ s = (U8*)SvPVX(LvTARG(sv));
+ a = utf8_hop(s, bigoff);
+ b = utf8_hop(a, biglen);
+ sv_insert(LvTARG(sv), a - s, b - a, tmps, littlelen);
SvUTF8_on(LvTARG(sv));
}
else
- sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
+ sv_insert(LvTARG(sv), LvTARGOFF(sv), LvTARGLEN(sv), tmps, littlelen);
return 0;
}