summaryrefslogtreecommitdiff
path: root/utf8.c
diff options
context:
space:
mode:
authorMike Guy <mjtg@cam.ac.uk>2000-09-01 18:43:33 +0100
committerJarkko Hietaniemi <jhi@iki.fi>2000-09-01 19:37:40 +0000
commit246fae53ea6ae12991e7653f136a0f797ce002d4 (patch)
tree217a07ca92ca48618ff14c8cead58f88b284fbb3 /utf8.c
parent93d73c42a7dc0b497a6a2eb40edcb6429896653c (diff)
downloadperl-246fae53ea6ae12991e7653f136a0f797ce002d4.tar.gz
Fix vec() / utf8 (was Re: bitvec ops still broken with utf8 -- or not?)
Message-Id: <E13Utuf-0004Bw-00@draco.cus.cam.ac.uk> p4raw-id: //depot/perl@6988
Diffstat (limited to 'utf8.c')
-rw-r--r--utf8.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/utf8.c b/utf8.c
index e86c49fdcf..c109f6529f 100644
--- a/utf8.c
+++ b/utf8.c
@@ -204,7 +204,8 @@ Perl_utf8_to_uv(pTHX_ U8* s, I32* retlen)
return uv;
}
-/* utf8_distance(a,b) is intended to be a - b in pointer arithmetic */
+/* utf8_distance(a,b) returns the number of UTF8 characters between
+ the pointers a and b */
I32
Perl_utf8_distance(pTHX_ U8 *a, U8 *b)
@@ -247,40 +248,46 @@ Perl_utf8_hop(pTHX_ U8 *s, I32 off)
}
/*
-=for apidoc Am|U8 *|utf8_to_bytes|U8 *s|STRLEN len
+=for apidoc Am|U8 *|utf8_to_bytes|U8 *s|STRLEN *len
-Converts a string C<s> of length C<len> from UTF8 into ASCII encoding.
-Unlike C<bytes_to_utf8>, this over-writes the original string.
-Returns zero on failure after converting as much as possible.
+Converts a string C<s> of length C<len> from UTF8 into byte encoding.
+Unlike C<bytes_to_utf8>, this over-writes the original string, and
+updates len to contain the new length.
+Returns zero on failure leaving the string and len unchanged
=cut
*/
U8 *
-Perl_utf8_to_bytes(pTHX_ U8* s, STRLEN len)
+Perl_utf8_to_bytes(pTHX_ U8* s, STRLEN *len)
{
dTHR;
U8 *send;
U8 *d;
U8 *save;
- send = s + len;
+ send = s + *len;
d = save = s;
+
+ /* ensure valid UTF8 and chars < 256 before updating string */
+ while (s < send) {
+ U8 c = *s++;
+ if (c >= 0x80 &&
+ ( (s >= send) || ((*s++ & 0xc0) != 0x80) || ((c & 0xfe) != 0xc2)))
+ return 0;
+ }
+ s = save;
while (s < send) {
if (*s < 0x80)
*d++ = *s++;
else {
I32 ulen;
- UV uv = utf8_to_uv(s, &ulen);
- if (uv > 255) {
- *d = '\0';
- return 0;
- }
+ *d++ = (U8)utf8_to_uv(s, &ulen);
s += ulen;
- *d++ = (U8)uv;
}
}
*d = '\0';
+ *len = d - save;
return save;
}