• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ******************************************************************************
3 *
4 *   Copyright (C) 1999-2012, International Business Machines
5 *   Corporation and others.  All Rights Reserved.
6 *
7 ******************************************************************************
8 *   file name:  utf_impl.c
9 *   encoding:   US-ASCII
10 *   tab size:   8 (not used)
11 *   indentation:4
12 *
13 *   created on: 1999sep13
14 *   created by: Markus W. Scherer
15 *
16 *   This file provides implementation functions for macros in the utfXX.h
17 *   that would otherwise be too long as macros.
18 */
19 
20 /* set import/export definitions */
21 #ifndef U_UTF8_IMPL
22 #   define U_UTF8_IMPL
23 #endif
24 
25 #include "unicode/utypes.h"
26 #include "unicode/utf.h"
27 #include "unicode/utf8.h"
28 #include "unicode/utf_old.h"
29 #include "uassert.h"
30 
31 /*
32  * This table could be replaced on many machines by
33  * a few lines of assembler code using an
34  * "index of first 0-bit from msb" instruction and
35  * one or two more integer instructions.
36  *
37  * For example, on an i386, do something like
38  * - MOV AL, leadByte
39  * - NOT AL         (8-bit, leave b15..b8==0..0, reverse only b7..b0)
40  * - MOV AH, 0
41  * - BSR BX, AX     (16-bit)
42  * - MOV AX, 6      (result)
43  * - JZ finish      (ZF==1 if leadByte==0xff)
44  * - SUB AX, BX (result)
45  * -finish:
46  * (BSR: Bit Scan Reverse, scans for a 1-bit, starting from the MSB)
47  *
48  * In Unicode, all UTF-8 byte sequences with more than 4 bytes are illegal;
49  * lead bytes above 0xf4 are illegal.
50  * We keep them in this table for skipping long ISO 10646-UTF-8 sequences.
51  */
52 U_EXPORT const uint8_t
53 utf8_countTrailBytes[256]={
54     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 
59     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 
64     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68 
69     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
70     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
71 
72     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
73     3, 3, 3, 3, 3,
74     3, 3, 3,    /* illegal in Unicode */
75     4, 4, 4, 4, /* illegal in Unicode */
76     5, 5,       /* illegal in Unicode */
77     0, 0        /* illegal bytes 0xfe and 0xff */
78 };
79 
80 static const UChar32
81 utf8_minLegal[4]={ 0, 0x80, 0x800, 0x10000 };
82 
83 static const UChar32
84 utf8_errorValue[6]={
85     UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_2, UTF_ERROR_VALUE, 0x10ffff,
86     0x3ffffff, 0x7fffffff
87 };
88 
89 /*
90  * Handle the non-inline part of the U8_NEXT() macro and its obsolete sibling
91  * UTF8_NEXT_CHAR_SAFE().
92  *
93  * The "strict" parameter controls the error behavior:
94  * <0  "Safe" behavior of U8_NEXT(): All illegal byte sequences yield a negative
95  *     code point result.
96  *  0  Obsolete "safe" behavior of UTF8_NEXT_CHAR_SAFE(..., FALSE):
97  *     All illegal byte sequences yield a positive code point such that this
98  *     result code point would be encoded with the same number of bytes as
99  *     the illegal sequence.
100  * >0  Obsolete "strict" behavior of UTF8_NEXT_CHAR_SAFE(..., TRUE):
101  *     Same as the obsolete "safe" behavior, but non-characters are also treated
102  *     like illegal sequences.
103  *
104  * The special negative (<0) value -2 is used for lenient treatment of surrogate
105  * code points as legal. Some implementations use this for roundtripping of
106  * Unicode 16-bit strings that are not well-formed UTF-16, that is, they
107  * contain unpaired surrogates.
108  *
109  * Note that a UBool is the same as an int8_t.
110  */
111 U_CAPI UChar32 U_EXPORT2
utf8_nextCharSafeBody(const uint8_t * s,int32_t * pi,int32_t length,UChar32 c,UBool strict)112 utf8_nextCharSafeBody(const uint8_t *s, int32_t *pi, int32_t length, UChar32 c, UBool strict) {
113     int32_t i=*pi;
114     uint8_t count=U8_COUNT_TRAIL_BYTES(c);
115     U_ASSERT(count <= 5); /* U8_COUNT_TRAIL_BYTES returns value 0...5 */
116     if((i)+count<=(length)) {
117         uint8_t trail, illegal=0;
118 
119         U8_MASK_LEAD_BYTE((c), count);
120         /* count==0 for illegally leading trail bytes and the illegal bytes 0xfe and 0xff */
121         switch(count) {
122         /* each branch falls through to the next one */
123         case 5:
124         case 4:
125             /* count>=4 is always illegal: no more than 3 trail bytes in Unicode's UTF-8 */
126             illegal=1;
127             break;
128         case 3:
129             trail=s[(i)++];
130             (c)=((c)<<6)|(trail&0x3f);
131             if(c<0x110) {
132                 illegal|=(trail&0xc0)^0x80;
133             } else {
134                 /* code point>0x10ffff, outside Unicode */
135                 illegal=1;
136                 break;
137             }
138         case 2:
139             trail=s[(i)++];
140             (c)=((c)<<6)|(trail&0x3f);
141             illegal|=(trail&0xc0)^0x80;
142         case 1:
143             trail=s[(i)++];
144             (c)=((c)<<6)|(trail&0x3f);
145             illegal|=(trail&0xc0)^0x80;
146             break;
147         case 0:
148             if(strict>=0) {
149                 return UTF8_ERROR_VALUE_1;
150             } else {
151                 return U_SENTINEL;
152             }
153         /* no default branch to optimize switch()  - all values are covered */
154         }
155 
156         /*
157          * All the error handling should return a value
158          * that needs count bytes so that UTF8_GET_CHAR_SAFE() works right.
159          *
160          * Starting with Unicode 3.0.1, non-shortest forms are illegal.
161          * Starting with Unicode 3.2, surrogate code points must not be
162          * encoded in UTF-8, and there are no irregular sequences any more.
163          *
164          * U8_ macros (new in ICU 2.4) return negative values for error conditions.
165          */
166 
167         /* correct sequence - all trail bytes have (b7..b6)==(10)? */
168         /* illegal is also set if count>=4 */
169         if(illegal || (c)<utf8_minLegal[count] || (U_IS_SURROGATE(c) && strict!=-2)) {
170             /* error handling */
171             uint8_t errorCount=count;
172             /* don't go beyond this sequence */
173             i=*pi;
174             while(count>0 && U8_IS_TRAIL(s[i])) {
175                 ++(i);
176                 --count;
177             }
178             if(strict>=0) {
179                 c=utf8_errorValue[errorCount-count];
180             } else {
181                 c=U_SENTINEL;
182             }
183         } else if((strict)>0 && U_IS_UNICODE_NONCHAR(c)) {
184             /* strict: forbid non-characters like U+fffe */
185             c=utf8_errorValue[count];
186         }
187     } else /* too few bytes left */ {
188         /* error handling */
189         int32_t i0=i;
190         /* don't just set (i)=(length) in case there is an illegal sequence */
191         while((i)<(length) && U8_IS_TRAIL(s[i])) {
192             ++(i);
193         }
194         if(strict>=0) {
195             c=utf8_errorValue[i-i0];
196         } else {
197             c=U_SENTINEL;
198         }
199     }
200     *pi=i;
201     return c;
202 }
203 
204 U_CAPI int32_t U_EXPORT2
utf8_appendCharSafeBody(uint8_t * s,int32_t i,int32_t length,UChar32 c,UBool * pIsError)205 utf8_appendCharSafeBody(uint8_t *s, int32_t i, int32_t length, UChar32 c, UBool *pIsError) {
206     if((uint32_t)(c)<=0x7ff) {
207         if((i)+1<(length)) {
208             (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0);
209             (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80);
210             return i;
211         }
212     } else if((uint32_t)(c)<=0xffff) {
213         /* Starting with Unicode 3.2, surrogate code points must not be encoded in UTF-8. */
214         if((i)+2<(length) && !U_IS_SURROGATE(c)) {
215             (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0);
216             (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80);
217             (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80);
218             return i;
219         }
220     } else if((uint32_t)(c)<=0x10ffff) {
221         if((i)+3<(length)) {
222             (s)[(i)++]=(uint8_t)(((c)>>18)|0xf0);
223             (s)[(i)++]=(uint8_t)((((c)>>12)&0x3f)|0x80);
224             (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80);
225             (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80);
226             return i;
227         }
228     }
229     /* c>0x10ffff or not enough space, write an error value */
230     if(pIsError!=NULL) {
231         *pIsError=TRUE;
232     } else {
233         length-=i;
234         if(length>0) {
235             int32_t offset;
236             if(length>3) {
237                 length=3;
238             }
239             s+=i;
240             offset=0;
241             c=utf8_errorValue[length-1];
242             UTF8_APPEND_CHAR_UNSAFE(s, offset, c);
243             i=i+offset;
244         }
245     }
246     return i;
247 }
248 
249 U_CAPI UChar32 U_EXPORT2
utf8_prevCharSafeBody(const uint8_t * s,int32_t start,int32_t * pi,UChar32 c,UBool strict)250 utf8_prevCharSafeBody(const uint8_t *s, int32_t start, int32_t *pi, UChar32 c, UBool strict) {
251     int32_t i=*pi;
252     uint8_t b, count=1, shift=6;
253 
254     /* extract value bits from the last trail byte */
255     c&=0x3f;
256 
257     for(;;) {
258         if(i<=start) {
259             /* no lead byte at all */
260             if(strict>=0) {
261                 return UTF8_ERROR_VALUE_1;
262             } else {
263                 return U_SENTINEL;
264             }
265             /*break;*/
266         }
267 
268         /* read another previous byte */
269         b=s[--i];
270         if((uint8_t)(b-0x80)<0x7e) { /* 0x80<=b<0xfe */
271             if(b&0x40) {
272                 /* lead byte, this will always end the loop */
273                 uint8_t shouldCount=U8_COUNT_TRAIL_BYTES(b);
274 
275                 if(count==shouldCount) {
276                     /* set the new position */
277                     *pi=i;
278                     U8_MASK_LEAD_BYTE(b, count);
279                     c|=(UChar32)b<<shift;
280                     if(count>=4 || c>0x10ffff || c<utf8_minLegal[count] || (U_IS_SURROGATE(c) && strict!=-2) || (strict>0 && U_IS_UNICODE_NONCHAR(c))) {
281                         /* illegal sequence or (strict and non-character) */
282                         if(count>=4) {
283                             count=3;
284                         }
285                         if(strict>=0) {
286                             c=utf8_errorValue[count];
287                         } else {
288                             c=U_SENTINEL;
289                         }
290                     } else {
291                         /* exit with correct c */
292                     }
293                 } else {
294                     /* the lead byte does not match the number of trail bytes */
295                     /* only set the position to the lead byte if it would
296                        include the trail byte that we started with */
297                     if(count<shouldCount) {
298                         *pi=i;
299                         if(strict>=0) {
300                             c=utf8_errorValue[count];
301                         } else {
302                             c=U_SENTINEL;
303                         }
304                     } else {
305                         if(strict>=0) {
306                             c=UTF8_ERROR_VALUE_1;
307                         } else {
308                             c=U_SENTINEL;
309                         }
310                     }
311                 }
312                 break;
313             } else if(count<5) {
314                 /* trail byte */
315                 c|=(UChar32)(b&0x3f)<<shift;
316                 ++count;
317                 shift+=6;
318             } else {
319                 /* more than 5 trail bytes is illegal */
320                 if(strict>=0) {
321                     c=UTF8_ERROR_VALUE_1;
322                 } else {
323                     c=U_SENTINEL;
324                 }
325                 break;
326             }
327         } else {
328             /* single-byte character precedes trailing bytes */
329             if(strict>=0) {
330                 c=UTF8_ERROR_VALUE_1;
331             } else {
332                 c=U_SENTINEL;
333             }
334             break;
335         }
336     }
337     return c;
338 }
339 
340 U_CAPI int32_t U_EXPORT2
utf8_back1SafeBody(const uint8_t * s,int32_t start,int32_t i)341 utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i) {
342     /* i had been decremented once before the function call */
343     int32_t I=i, Z;
344     uint8_t b;
345 
346     /* read at most the 6 bytes s[Z] to s[i], inclusively */
347     if(I-5>start) {
348         Z=I-5;
349     } else {
350         Z=start;
351     }
352 
353     /* return I if the sequence starting there is long enough to include i */
354     do {
355         b=s[I];
356         if((uint8_t)(b-0x80)>=0x7e) { /* not 0x80<=b<0xfe */
357             break;
358         } else if(b>=0xc0) {
359             if(U8_COUNT_TRAIL_BYTES(b)>=(i-I)) {
360                 return I;
361             } else {
362                 break;
363             }
364         }
365     } while(Z<=--I);
366 
367     /* return i itself to be consistent with the FWD_1 macro */
368     return i;
369 }
370