summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2001-11-13 22:50:27 +0000
committerJarkko Hietaniemi <jhi@iki.fi>2001-11-13 22:50:27 +0000
commitd09651054f608b613dc2d41d0267898bf3d676f8 (patch)
tree3c6ed3dc81fbd5d917307d6a2889f92d6811c6d0 /pp_sys.c
parent72d9590d7f2276007a1ce30193936901e22250e1 (diff)
downloadperl-d09651054f608b613dc2d41d0267898bf3d676f8.tar.gz
Fix for the :utf8 read() bug noticed by Matt Sergeant:
"large enough" Unicode characters returned more than one as their "Unicode size". p4raw-id: //depot/perl@12981
Diffstat (limited to 'pp_sys.c')
-rw-r--r--pp_sys.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/pp_sys.c b/pp_sys.c
index ea35136f8e..ed7030700a 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1517,6 +1517,9 @@ PP(pp_sysread)
int fp_utf8;
Size_t got = 0;
Size_t wanted;
+ bool charstart = NULL;
+ STRLEN skip;
+ STRLEN charskip;
gv = (GV*)*++MARK;
if ((PL_op->op_type == OP_READ || PL_op->op_type == OP_SYSREAD)
@@ -1563,6 +1566,9 @@ PP(pp_sysread)
DIE(aTHX_ "Negative length");
wanted = length;
+ charstart = TRUE;
+ charskip = 0;
+
#ifdef HAS_SOCKET
if (PL_op->op_type == OP_RECV) {
char namebuf[MAXPATHLEN];
@@ -1683,23 +1689,30 @@ PP(pp_sysread)
/* Look at utf8 we got back and count the characters */
char *bend = buffer + count;
while (buffer < bend) {
- STRLEN skip = UTF8SKIP(buffer);
- if (buffer+skip > bend) {
+ if (charstart) {
+ skip = UTF8SKIP(buffer);
+ charskip = 0;
+ }
+ if (buffer - charskip + skip > bend) {
/* partial character - try for rest of it */
length = skip - (bend-buffer);
offset = bend - SvPVX(bufsv);
+ charstart = FALSE;
+ charskip += count;
goto more_bytes;
}
else {
got++;
buffer += skip;
+ charstart = TRUE;
+ charskip = 0;
}
}
/* If we have not 'got' the number of _characters_ we 'wanted' get some more
provided amount read (count) was what was requested (length)
*/
if (got < wanted && count == length) {
- length = (wanted-got);
+ length = wanted - got;
offset = bend - SvPVX(bufsv);
goto more_bytes;
}