diff options
author | Mike Guy <mjtg@cam.ac.uk> | 2000-09-01 18:43:33 +0100 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2000-09-01 19:37:40 +0000 |
commit | 246fae53ea6ae12991e7653f136a0f797ce002d4 (patch) | |
tree | 217a07ca92ca48618ff14c8cead58f88b284fbb3 /utf8.c | |
parent | 93d73c42a7dc0b497a6a2eb40edcb6429896653c (diff) | |
download | perl-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.c | 33 |
1 files changed, 20 insertions, 13 deletions
@@ -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; } |