Add unicode library
[zfs.git] / module / unicode / u8_textprep.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25
26 #pragma ident   "%Z%%M% %I%     %E% SMI"
27
28
29 /*
30  * UTF-8 text preparation functions (PSARC/2007/149, PSARC/2007/458).
31  *
32  * Man pages: u8_textprep_open(9F), u8_textprep_buf(9F), u8_textprep_close(9F),
33  * u8_textprep_str(9F), u8_strcmp(9F), and u8_validate(9F). See also
34  * the section 3C man pages.
35  * Interface stability: Committed.
36  */
37
38 #include <sys/types.h>
39 #ifdef  _KERNEL
40 #include <sys/param.h>
41 #include <sys/sysmacros.h>
42 #include <sys/systm.h>
43 #include <sys/debug.h>
44 #include <sys/kmem.h>
45 #include <sys/ddi.h>
46 #include <sys/sunddi.h>
47 #else
48 #include <sys/u8_textprep.h>
49 #include <strings.h>
50 #endif  /* _KERNEL */
51 #include <sys/byteorder.h>
52 #include <sys/errno.h>
53 #include <sys/u8_textprep_data.h>
54
55
56 /* The maximum possible number of bytes in a UTF-8 character. */
57 #define U8_MB_CUR_MAX                   (4)
58
59 /*
60  * The maximum number of bytes needed for a UTF-8 character to cover
61  * U+0000 - U+FFFF, i.e., the coding space of now deprecated UCS-2.
62  */
63 #define U8_MAX_BYTES_UCS2               (3)
64
65 /* The maximum possible number of bytes in a Stream-Safe Text. */
66 #define U8_STREAM_SAFE_TEXT_MAX         (128)
67
68 /*
69  * The maximum number of characters in a combining/conjoining sequence and
70  * the actual upperbound limit of a combining/conjoining sequence.
71  */
72 #define U8_MAX_CHARS_A_SEQ              (32)
73 #define U8_UPPER_LIMIT_IN_A_SEQ         (31)
74
75 /* The combining class value for Starter. */
76 #define U8_COMBINING_CLASS_STARTER      (0)
77
78 /*
79  * Some Hangul related macros at below.
80  *
81  * The first and the last of Hangul syllables, Hangul Jamo Leading consonants,
82  * Vowels, and optional Trailing consonants in Unicode scalar values.
83  *
84  * Please be noted that the U8_HANGUL_JAMO_T_FIRST is 0x11A7 at below not
85  * the actual U+11A8. This is due to that the trailing consonant is optional
86  * and thus we are doing a pre-calculation of subtracting one.
87  *
88  * Each of 19 modern leading consonants has total 588 possible syllables since
89  * Hangul has 21 modern vowels and 27 modern trailing consonants plus 1 for
90  * no trailing consonant case, i.e., 21 x 28 = 588.
91  *
92  * We also have bunch of Hangul related macros at below. Please bear in mind
93  * that the U8_HANGUL_JAMO_1ST_BYTE can be used to check whether it is
94  * a Hangul Jamo or not but the value does not guarantee that it is a Hangul
95  * Jamo; it just guarantee that it will be most likely.
96  */
97 #define U8_HANGUL_SYL_FIRST             (0xAC00U)
98 #define U8_HANGUL_SYL_LAST              (0xD7A3U)
99
100 #define U8_HANGUL_JAMO_L_FIRST          (0x1100U)
101 #define U8_HANGUL_JAMO_L_LAST           (0x1112U)
102 #define U8_HANGUL_JAMO_V_FIRST          (0x1161U)
103 #define U8_HANGUL_JAMO_V_LAST           (0x1175U)
104 #define U8_HANGUL_JAMO_T_FIRST          (0x11A7U)
105 #define U8_HANGUL_JAMO_T_LAST           (0x11C2U)
106
107 #define U8_HANGUL_V_COUNT               (21)
108 #define U8_HANGUL_VT_COUNT              (588)
109 #define U8_HANGUL_T_COUNT               (28)
110
111 #define U8_HANGUL_JAMO_1ST_BYTE         (0xE1U)
112
113 #define U8_SAVE_HANGUL_AS_UTF8(s, i, j, k, b) \
114         (s)[(i)] = (uchar_t)(0xE0U | ((uint32_t)(b) & 0xF000U) >> 12); \
115         (s)[(j)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x0FC0U) >> 6); \
116         (s)[(k)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x003FU));
117
118 #define U8_HANGUL_JAMO_L(u) \
119         ((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_L_LAST)
120
121 #define U8_HANGUL_JAMO_V(u) \
122         ((u) >= U8_HANGUL_JAMO_V_FIRST && (u) <= U8_HANGUL_JAMO_V_LAST)
123
124 #define U8_HANGUL_JAMO_T(u) \
125         ((u) > U8_HANGUL_JAMO_T_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
126
127 #define U8_HANGUL_JAMO(u) \
128         ((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
129
130 #define U8_HANGUL_SYLLABLE(u) \
131         ((u) >= U8_HANGUL_SYL_FIRST && (u) <= U8_HANGUL_SYL_LAST)
132
133 #define U8_HANGUL_COMPOSABLE_L_V(s, u) \
134         ((s) == U8_STATE_HANGUL_L && U8_HANGUL_JAMO_V((u)))
135
136 #define U8_HANGUL_COMPOSABLE_LV_T(s, u) \
137         ((s) == U8_STATE_HANGUL_LV && U8_HANGUL_JAMO_T((u)))
138
139 /* The types of decomposition mappings. */
140 #define U8_DECOMP_BOTH                  (0xF5U)
141 #define U8_DECOMP_CANONICAL             (0xF6U)
142
143 /* The indicator for 16-bit table. */
144 #define U8_16BIT_TABLE_INDICATOR        (0x8000U)
145
146 /* The following are some convenience macros. */
147 #define U8_PUT_3BYTES_INTO_UTF32(u, b1, b2, b3) \
148         (u) = ((uint32_t)(b1) & 0x0F) << 12 | ((uint32_t)(b2) & 0x3F) << 6 | \
149                 (uint32_t)(b3) & 0x3F;
150
151 #define U8_SIMPLE_SWAP(a, b, t) \
152         (t) = (a); \
153         (a) = (b); \
154         (b) = (t);
155
156 #define U8_ASCII_TOUPPER(c) \
157         (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c))
158
159 #define U8_ASCII_TOLOWER(c) \
160         (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
161
162 #define U8_ISASCII(c)                   (((uchar_t)(c)) < 0x80U)
163 /*
164  * The following macro assumes that the two characters that are to be
165  * swapped are adjacent to each other and 'a' comes before 'b'.
166  *
167  * If the assumptions are not met, then, the macro will fail.
168  */
169 #define U8_SWAP_COMB_MARKS(a, b) \
170         for (k = 0; k < disp[(a)]; k++) \
171                 u8t[k] = u8s[start[(a)] + k]; \
172         for (k = 0; k < disp[(b)]; k++) \
173                 u8s[start[(a)] + k] = u8s[start[(b)] + k]; \
174         start[(b)] = start[(a)] + disp[(b)]; \
175         for (k = 0; k < disp[(a)]; k++) \
176                 u8s[start[(b)] + k] = u8t[k]; \
177         U8_SIMPLE_SWAP(comb_class[(a)], comb_class[(b)], tc); \
178         U8_SIMPLE_SWAP(disp[(a)], disp[(b)], tc);
179
180 /* The possible states during normalization. */
181 typedef enum {
182         U8_STATE_START = 0,
183         U8_STATE_HANGUL_L = 1,
184         U8_STATE_HANGUL_LV = 2,
185         U8_STATE_HANGUL_LVT = 3,
186         U8_STATE_HANGUL_V = 4,
187         U8_STATE_HANGUL_T = 5,
188         U8_STATE_COMBINING_MARK = 6
189 } u8_normalization_states_t;
190
191 /*
192  * The three vectors at below are used to check bytes of a given UTF-8
193  * character are valid and not containing any malformed byte values.
194  *
195  * We used to have a quite relaxed UTF-8 binary representation but then there
196  * was some security related issues and so the Unicode Consortium defined
197  * and announced the UTF-8 Corrigendum at Unicode 3.1 and then refined it
198  * one more time at the Unicode 3.2. The following three tables are based on
199  * that.
200  */
201
202 #define U8_ILLEGAL_NEXT_BYTE_COMMON(c)  ((c) < 0x80 || (c) > 0xBF)
203
204 #define I_                              U8_ILLEGAL_CHAR
205 #define O_                              U8_OUT_OF_RANGE_CHAR
206
207 const int8_t u8_number_of_bytes[0x100] = {
208         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
209         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
210         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
211         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
212         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
213         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
214         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
215         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
216
217 /*      80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F  */
218         I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
219
220 /*      90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F  */
221         I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
222
223 /*      A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF  */
224         I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
225
226 /*      B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF  */
227         I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
228
229 /*      C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF  */
230         I_, I_, 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
231
232 /*      D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF  */
233         2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
234
235 /*      E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF  */
236         3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
237
238 /*      F0  F1  F2  F3  F4  F5  F6  F7  F8  F9  FA  FB  FC  FD  FE  FF  */
239         4,  4,  4,  4,  4,  O_, O_, O_, O_, O_, O_, O_, O_, O_, O_, O_,
240 };
241
242 #undef  I_
243 #undef  O_
244
245 const uint8_t u8_valid_min_2nd_byte[0x100] = {
246         0,    0,    0,    0,    0,    0,    0,    0,
247         0,    0,    0,    0,    0,    0,    0,    0,
248         0,    0,    0,    0,    0,    0,    0,    0,
249         0,    0,    0,    0,    0,    0,    0,    0,
250         0,    0,    0,    0,    0,    0,    0,    0,
251         0,    0,    0,    0,    0,    0,    0,    0,
252         0,    0,    0,    0,    0,    0,    0,    0,
253         0,    0,    0,    0,    0,    0,    0,    0,
254         0,    0,    0,    0,    0,    0,    0,    0,
255         0,    0,    0,    0,    0,    0,    0,    0,
256         0,    0,    0,    0,    0,    0,    0,    0,
257         0,    0,    0,    0,    0,    0,    0,    0,
258         0,    0,    0,    0,    0,    0,    0,    0,
259         0,    0,    0,    0,    0,    0,    0,    0,
260         0,    0,    0,    0,    0,    0,    0,    0,
261         0,    0,    0,    0,    0,    0,    0,    0,
262         0,    0,    0,    0,    0,    0,    0,    0,
263         0,    0,    0,    0,    0,    0,    0,    0,
264         0,    0,    0,    0,    0,    0,    0,    0,
265         0,    0,    0,    0,    0,    0,    0,    0,
266         0,    0,    0,    0,    0,    0,    0,    0,
267         0,    0,    0,    0,    0,    0,    0,    0,
268         0,    0,    0,    0,    0,    0,    0,    0,
269         0,    0,    0,    0,    0,    0,    0,    0,
270 /*      C0    C1    C2    C3    C4    C5    C6    C7    */
271         0,    0,    0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
272 /*      C8    C9    CA    CB    CC    CD    CE    CF    */
273         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
274 /*      D0    D1    D2    D3    D4    D5    D6    D7    */
275         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
276 /*      D8    D9    DA    DB    DC    DD    DE    DF    */
277         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
278 /*      E0    E1    E2    E3    E4    E5    E6    E7    */
279         0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
280 /*      E8    E9    EA    EB    EC    ED    EE    EF    */
281         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
282 /*      F0    F1    F2    F3    F4    F5    F6    F7    */
283         0x90, 0x80, 0x80, 0x80, 0x80, 0,    0,    0,
284         0,    0,    0,    0,    0,    0,    0,    0,
285 };
286
287 const uint8_t u8_valid_max_2nd_byte[0x100] = {
288         0,    0,    0,    0,    0,    0,    0,    0,
289         0,    0,    0,    0,    0,    0,    0,    0,
290         0,    0,    0,    0,    0,    0,    0,    0,
291         0,    0,    0,    0,    0,    0,    0,    0,
292         0,    0,    0,    0,    0,    0,    0,    0,
293         0,    0,    0,    0,    0,    0,    0,    0,
294         0,    0,    0,    0,    0,    0,    0,    0,
295         0,    0,    0,    0,    0,    0,    0,    0,
296         0,    0,    0,    0,    0,    0,    0,    0,
297         0,    0,    0,    0,    0,    0,    0,    0,
298         0,    0,    0,    0,    0,    0,    0,    0,
299         0,    0,    0,    0,    0,    0,    0,    0,
300         0,    0,    0,    0,    0,    0,    0,    0,
301         0,    0,    0,    0,    0,    0,    0,    0,
302         0,    0,    0,    0,    0,    0,    0,    0,
303         0,    0,    0,    0,    0,    0,    0,    0,
304         0,    0,    0,    0,    0,    0,    0,    0,
305         0,    0,    0,    0,    0,    0,    0,    0,
306         0,    0,    0,    0,    0,    0,    0,    0,
307         0,    0,    0,    0,    0,    0,    0,    0,
308         0,    0,    0,    0,    0,    0,    0,    0,
309         0,    0,    0,    0,    0,    0,    0,    0,
310         0,    0,    0,    0,    0,    0,    0,    0,
311         0,    0,    0,    0,    0,    0,    0,    0,
312 /*      C0    C1    C2    C3    C4    C5    C6    C7    */
313         0,    0,    0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
314 /*      C8    C9    CA    CB    CC    CD    CE    CF    */
315         0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
316 /*      D0    D1    D2    D3    D4    D5    D6    D7    */
317         0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
318 /*      D8    D9    DA    DB    DC    DD    DE    DF    */
319         0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
320 /*      E0    E1    E2    E3    E4    E5    E6    E7    */
321         0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
322 /*      E8    E9    EA    EB    EC    ED    EE    EF    */
323         0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x9f, 0xbf, 0xbf,
324 /*      F0    F1    F2    F3    F4    F5    F6    F7    */
325         0xbf, 0xbf, 0xbf, 0xbf, 0x8f, 0,    0,    0,
326         0,    0,    0,    0,    0,    0,    0,    0,
327 };
328
329
330 /*
331  * The u8_validate() validates on the given UTF-8 character string and
332  * calculate the byte length. It is quite similar to mblen(3C) except that
333  * this will validate against the list of characters if required and
334  * specific to UTF-8 and Unicode.
335  */
336 int
337 u8_validate(char *u8str, size_t n, char **list, int flag, int *errnum)
338 {
339         uchar_t *ib;
340         uchar_t *ibtail;
341         uchar_t **p;
342         uchar_t *s1;
343         uchar_t *s2;
344         uchar_t f;
345         int sz;
346         size_t i;
347         int ret_val;
348         boolean_t second;
349         boolean_t no_need_to_validate_entire;
350         boolean_t check_additional;
351         boolean_t validate_ucs2_range_only;
352
353         if (! u8str)
354                 return (0);
355
356         ib = (uchar_t *)u8str;
357         ibtail = ib + n;
358
359         ret_val = 0;
360
361         no_need_to_validate_entire = ! (flag & U8_VALIDATE_ENTIRE);
362         check_additional = flag & U8_VALIDATE_CHECK_ADDITIONAL;
363         validate_ucs2_range_only = flag & U8_VALIDATE_UCS2_RANGE;
364
365         while (ib < ibtail) {
366                 /*
367                  * The first byte of a UTF-8 character tells how many
368                  * bytes will follow for the character. If the first byte
369                  * is an illegal byte value or out of range value, we just
370                  * return -1 with an appropriate error number.
371                  */
372                 sz = u8_number_of_bytes[*ib];
373                 if (sz == U8_ILLEGAL_CHAR) {
374                         *errnum = EILSEQ;
375                         return (-1);
376                 }
377
378                 if (sz == U8_OUT_OF_RANGE_CHAR ||
379                     (validate_ucs2_range_only && sz > U8_MAX_BYTES_UCS2)) {
380                         *errnum = ERANGE;
381                         return (-1);
382                 }
383
384                 /*
385                  * If we don't have enough bytes to check on, that's also
386                  * an error. As you can see, we give illegal byte sequence
387                  * checking higher priority then EINVAL cases.
388                  */
389                 if ((ibtail - ib) < sz) {
390                         *errnum = EINVAL;
391                         return (-1);
392                 }
393
394                 if (sz == 1) {
395                         ib++;
396                         ret_val++;
397                 } else {
398                         /*
399                          * Check on the multi-byte UTF-8 character. For more
400                          * details on this, see comment added for the used
401                          * data structures at the beginning of the file.
402                          */
403                         f = *ib++;
404                         ret_val++;
405                         second = B_TRUE;
406                         for (i = 1; i < sz; i++) {
407                                 if (second) {
408                                         if (*ib < u8_valid_min_2nd_byte[f] ||
409                                             *ib > u8_valid_max_2nd_byte[f]) {
410                                                 *errnum = EILSEQ;
411                                                 return (-1);
412                                         }
413                                         second = B_FALSE;
414                                 } else if (U8_ILLEGAL_NEXT_BYTE_COMMON(*ib)) {
415                                         *errnum = EILSEQ;
416                                         return (-1);
417                                 }
418                                 ib++;
419                                 ret_val++;
420                         }
421                 }
422
423                 if (check_additional) {
424                         for (p = (uchar_t **)list, i = 0; p[i]; i++) {
425                                 s1 = ib - sz;
426                                 s2 = p[i];
427                                 while (s1 < ib) {
428                                         if (*s1 != *s2 || *s2 == '\0')
429                                                 break;
430                                         s1++;
431                                         s2++;
432                                 }
433
434                                 if (s1 >= ib && *s2 == '\0') {
435                                         *errnum = EBADF;
436                                         return (-1);
437                                 }
438                         }
439                 }
440
441                 if (no_need_to_validate_entire)
442                         break;
443         }
444
445         return (ret_val);
446 }
447
448 /*
449  * The do_case_conv() looks at the mapping tables and returns found
450  * bytes if any. If not found, the input bytes are returned. The function
451  * always terminate the return bytes with a null character assuming that
452  * there are plenty of room to do so.
453  *
454  * The case conversions are simple case conversions mapping a character to
455  * another character as specified in the Unicode data. The byte size of
456  * the mapped character could be different from that of the input character.
457  *
458  * The return value is the byte length of the returned character excluding
459  * the terminating null byte.
460  */
461 static size_t
462 do_case_conv(int uv, uchar_t *u8s, uchar_t *s, int sz, boolean_t is_it_toupper)
463 {
464         size_t i;
465         uint16_t b1 = 0;
466         uint16_t b2 = 0;
467         uint16_t b3 = 0;
468         uint16_t b3_tbl;
469         uint16_t b3_base;
470         uint16_t b4 = 0;
471         size_t start_id;
472         size_t end_id;
473
474         /*
475          * At this point, the only possible values for sz are 2, 3, and 4.
476          * The u8s should point to a vector that is well beyond the size of
477          * 5 bytes.
478          */
479         if (sz == 2) {
480                 b3 = u8s[0] = s[0];
481                 b4 = u8s[1] = s[1];
482         } else if (sz == 3) {
483                 b2 = u8s[0] = s[0];
484                 b3 = u8s[1] = s[1];
485                 b4 = u8s[2] = s[2];
486         } else if (sz == 4) {
487                 b1 = u8s[0] = s[0];
488                 b2 = u8s[1] = s[1];
489                 b3 = u8s[2] = s[2];
490                 b4 = u8s[3] = s[3];
491         } else {
492                 /* This is not possible but just in case as a fallback. */
493                 if (is_it_toupper)
494                         *u8s = U8_ASCII_TOUPPER(*s);
495                 else
496                         *u8s = U8_ASCII_TOLOWER(*s);
497                 u8s[1] = '\0';
498
499                 return (1);
500         }
501         u8s[sz] = '\0';
502
503         /*
504          * Let's find out if we have a corresponding character.
505          */
506         b1 = u8_common_b1_tbl[uv][b1];
507         if (b1 == U8_TBL_ELEMENT_NOT_DEF)
508                 return ((size_t)sz);
509
510         b2 = u8_case_common_b2_tbl[uv][b1][b2];
511         if (b2 == U8_TBL_ELEMENT_NOT_DEF)
512                 return ((size_t)sz);
513
514         if (is_it_toupper) {
515                 b3_tbl = u8_toupper_b3_tbl[uv][b2][b3].tbl_id;
516                 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
517                         return ((size_t)sz);
518
519                 start_id = u8_toupper_b4_tbl[uv][b3_tbl][b4];
520                 end_id = u8_toupper_b4_tbl[uv][b3_tbl][b4 + 1];
521
522                 /* Either there is no match or an error at the table. */
523                 if (start_id >= end_id || (end_id - start_id) > U8_MB_CUR_MAX)
524                         return ((size_t)sz);
525
526                 b3_base = u8_toupper_b3_tbl[uv][b2][b3].base;
527
528                 for (i = 0; start_id < end_id; start_id++)
529                         u8s[i++] = u8_toupper_final_tbl[uv][b3_base + start_id];
530         } else {
531                 b3_tbl = u8_tolower_b3_tbl[uv][b2][b3].tbl_id;
532                 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
533                         return ((size_t)sz);
534
535                 start_id = u8_tolower_b4_tbl[uv][b3_tbl][b4];
536                 end_id = u8_tolower_b4_tbl[uv][b3_tbl][b4 + 1];
537
538                 if (start_id >= end_id || (end_id - start_id) > U8_MB_CUR_MAX)
539                         return ((size_t)sz);
540
541                 b3_base = u8_tolower_b3_tbl[uv][b2][b3].base;
542
543                 for (i = 0; start_id < end_id; start_id++)
544                         u8s[i++] = u8_tolower_final_tbl[uv][b3_base + start_id];
545         }
546
547         /*
548          * If i is still zero, that means there is no corresponding character.
549          */
550         if (i == 0)
551                 return ((size_t)sz);
552
553         u8s[i] = '\0';
554
555         return (i);
556 }
557
558 /*
559  * The do_case_compare() function compares the two input strings, s1 and s2,
560  * one character at a time doing case conversions if applicable and return
561  * the comparison result as like strcmp().
562  *
563  * Since, in empirical sense, most of text data are 7-bit ASCII characters,
564  * we treat the 7-bit ASCII characters as a special case trying to yield
565  * faster processing time.
566  */
567 static int
568 do_case_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1,
569         size_t n2, boolean_t is_it_toupper, int *errnum)
570 {
571         int f;
572         int sz1;
573         int sz2;
574         size_t j;
575         size_t i1;
576         size_t i2;
577         uchar_t u8s1[U8_MB_CUR_MAX + 1];
578         uchar_t u8s2[U8_MB_CUR_MAX + 1];
579
580         i1 = i2 = 0;
581         while (i1 < n1 && i2 < n2) {
582                 /*
583                  * Find out what would be the byte length for this UTF-8
584                  * character at string s1 and also find out if this is
585                  * an illegal start byte or not and if so, issue a proper
586                  * error number and yet treat this byte as a character.
587                  */
588                 sz1 = u8_number_of_bytes[*s1];
589                 if (sz1 < 0) {
590                         *errnum = EILSEQ;
591                         sz1 = 1;
592                 }
593
594                 /*
595                  * For 7-bit ASCII characters mainly, we do a quick case
596                  * conversion right at here.
597                  *
598                  * If we don't have enough bytes for this character, issue
599                  * an EINVAL error and use what are available.
600                  *
601                  * If we have enough bytes, find out if there is
602                  * a corresponding uppercase character and if so, copy over
603                  * the bytes for a comparison later. If there is no
604                  * corresponding uppercase character, then, use what we have
605                  * for the comparison.
606                  */
607                 if (sz1 == 1) {
608                         if (is_it_toupper)
609                                 u8s1[0] = U8_ASCII_TOUPPER(*s1);
610                         else
611                                 u8s1[0] = U8_ASCII_TOLOWER(*s1);
612                         s1++;
613                         u8s1[1] = '\0';
614                 } else if ((i1 + sz1) > n1) {
615                         *errnum = EINVAL;
616                         for (j = 0; (i1 + j) < n1; )
617                                 u8s1[j++] = *s1++;
618                         u8s1[j] = '\0';
619                 } else {
620                         (void) do_case_conv(uv, u8s1, s1, sz1, is_it_toupper);
621                         s1 += sz1;
622                 }
623
624                 /* Do the same for the string s2. */
625                 sz2 = u8_number_of_bytes[*s2];
626                 if (sz2 < 0) {
627                         *errnum = EILSEQ;
628                         sz2 = 1;
629                 }
630
631                 if (sz2 == 1) {
632                         if (is_it_toupper)
633                                 u8s2[0] = U8_ASCII_TOUPPER(*s2);
634                         else
635                                 u8s2[0] = U8_ASCII_TOLOWER(*s2);
636                         s2++;
637                         u8s2[1] = '\0';
638                 } else if ((i2 + sz2) > n2) {
639                         *errnum = EINVAL;
640                         for (j = 0; (i2 + j) < n2; )
641                                 u8s2[j++] = *s2++;
642                         u8s2[j] = '\0';
643                 } else {
644                         (void) do_case_conv(uv, u8s2, s2, sz2, is_it_toupper);
645                         s2 += sz2;
646                 }
647
648                 /* Now compare the two characters. */
649                 if (sz1 == 1 && sz2 == 1) {
650                         if (*u8s1 > *u8s2)
651                                 return (1);
652                         if (*u8s1 < *u8s2)
653                                 return (-1);
654                 } else {
655                         f = strcmp((const char *)u8s1, (const char *)u8s2);
656                         if (f != 0)
657                                 return (f);
658                 }
659
660                 /*
661                  * They were the same. Let's move on to the next
662                  * characters then.
663                  */
664                 i1 += sz1;
665                 i2 += sz2;
666         }
667
668         /*
669          * We compared until the end of either or both strings.
670          *
671          * If we reached to or went over the ends for the both, that means
672          * they are the same.
673          *
674          * If we reached only one of the two ends, that means the other string
675          * has something which then the fact can be used to determine
676          * the return value.
677          */
678         if (i1 >= n1) {
679                 if (i2 >= n2)
680                         return (0);
681                 return (-1);
682         }
683         return (1);
684 }
685
686 /*
687  * The combining_class() function checks on the given bytes and find out
688  * the corresponding Unicode combining class value. The return value 0 means
689  * it is a Starter. Any illegal UTF-8 character will also be treated as
690  * a Starter.
691  */
692 static uchar_t
693 combining_class(size_t uv, uchar_t *s, size_t sz)
694 {
695         uint16_t b1 = 0;
696         uint16_t b2 = 0;
697         uint16_t b3 = 0;
698         uint16_t b4 = 0;
699
700         if (sz == 1 || sz > 4)
701                 return (0);
702
703         if (sz == 2) {
704                 b3 = s[0];
705                 b4 = s[1];
706         } else if (sz == 3) {
707                 b2 = s[0];
708                 b3 = s[1];
709                 b4 = s[2];
710         } else if (sz == 4) {
711                 b1 = s[0];
712                 b2 = s[1];
713                 b3 = s[2];
714                 b4 = s[3];
715         }
716
717         b1 = u8_common_b1_tbl[uv][b1];
718         if (b1 == U8_TBL_ELEMENT_NOT_DEF)
719                 return (0);
720
721         b2 = u8_combining_class_b2_tbl[uv][b1][b2];
722         if (b2 == U8_TBL_ELEMENT_NOT_DEF)
723                 return (0);
724
725         b3 = u8_combining_class_b3_tbl[uv][b2][b3];
726         if (b3 == U8_TBL_ELEMENT_NOT_DEF)
727                 return (0);
728
729         return (u8_combining_class_b4_tbl[uv][b3][b4]);
730 }
731
732 /*
733  * The do_decomp() function finds out a matching decomposition if any
734  * and return. If there is no match, the input bytes are copied and returned.
735  * The function also checks if there is a Hangul, decomposes it if necessary
736  * and returns.
737  *
738  * To save time, a single byte 7-bit ASCII character should be handled by
739  * the caller.
740  *
741  * The function returns the number of bytes returned sans always terminating
742  * the null byte. It will also return a state that will tell if there was
743  * a Hangul character decomposed which then will be used by the caller.
744  */
745 static size_t
746 do_decomp(size_t uv, uchar_t *u8s, uchar_t *s, int sz,
747         boolean_t canonical_decomposition, u8_normalization_states_t *state)
748 {
749         uint16_t b1 = 0;
750         uint16_t b2 = 0;
751         uint16_t b3 = 0;
752         uint16_t b3_tbl;
753         uint16_t b3_base;
754         uint16_t b4 = 0;
755         size_t start_id;
756         size_t end_id;
757         size_t i;
758         uint32_t u1;
759
760         if (sz == 2) {
761                 b3 = u8s[0] = s[0];
762                 b4 = u8s[1] = s[1];
763                 u8s[2] = '\0';
764         } else if (sz == 3) {
765                 /* Convert it to a Unicode scalar value. */
766                 U8_PUT_3BYTES_INTO_UTF32(u1, s[0], s[1], s[2]);
767
768                 /*
769                  * If this is a Hangul syllable, we decompose it into
770                  * a leading consonant, a vowel, and an optional trailing
771                  * consonant and then return.
772                  */
773                 if (U8_HANGUL_SYLLABLE(u1)) {
774                         u1 -= U8_HANGUL_SYL_FIRST;
775
776                         b1 = U8_HANGUL_JAMO_L_FIRST + u1 / U8_HANGUL_VT_COUNT;
777                         b2 = U8_HANGUL_JAMO_V_FIRST + (u1 % U8_HANGUL_VT_COUNT)
778                             / U8_HANGUL_T_COUNT;
779                         b3 = u1 % U8_HANGUL_T_COUNT;
780
781                         U8_SAVE_HANGUL_AS_UTF8(u8s, 0, 1, 2, b1);
782                         U8_SAVE_HANGUL_AS_UTF8(u8s, 3, 4, 5, b2);
783                         if (b3) {
784                                 b3 += U8_HANGUL_JAMO_T_FIRST;
785                                 U8_SAVE_HANGUL_AS_UTF8(u8s, 6, 7, 8, b3);
786
787                                 u8s[9] = '\0';
788                                 *state = U8_STATE_HANGUL_LVT;
789                                 return (9);
790                         }
791
792                         u8s[6] = '\0';
793                         *state = U8_STATE_HANGUL_LV;
794                         return (6);
795                 }
796
797                 b2 = u8s[0] = s[0];
798                 b3 = u8s[1] = s[1];
799                 b4 = u8s[2] = s[2];
800                 u8s[3] = '\0';
801
802                 /*
803                  * If this is a Hangul Jamo, we know there is nothing
804                  * further that we can decompose.
805                  */
806                 if (U8_HANGUL_JAMO_L(u1)) {
807                         *state = U8_STATE_HANGUL_L;
808                         return (3);
809                 }
810
811                 if (U8_HANGUL_JAMO_V(u1)) {
812                         if (*state == U8_STATE_HANGUL_L)
813                                 *state = U8_STATE_HANGUL_LV;
814                         else
815                                 *state = U8_STATE_HANGUL_V;
816                         return (3);
817                 }
818
819                 if (U8_HANGUL_JAMO_T(u1)) {
820                         if (*state == U8_STATE_HANGUL_LV)
821                                 *state = U8_STATE_HANGUL_LVT;
822                         else
823                                 *state = U8_STATE_HANGUL_T;
824                         return (3);
825                 }
826         } else if (sz == 4) {
827                 b1 = u8s[0] = s[0];
828                 b2 = u8s[1] = s[1];
829                 b3 = u8s[2] = s[2];
830                 b4 = u8s[3] = s[3];
831                 u8s[4] = '\0';
832         } else {
833                 /*
834                  * This is a fallback and should not happen if the function
835                  * was called properly.
836                  */
837                 u8s[0] = s[0];
838                 u8s[1] = '\0';
839                 *state = U8_STATE_START;
840                 return (1);
841         }
842
843         /*
844          * At this point, this rountine does not know what it would get.
845          * The caller should sort it out if the state isn't a Hangul one.
846          */
847         *state = U8_STATE_START;
848
849         /* Try to find matching decomposition mapping byte sequence. */
850         b1 = u8_common_b1_tbl[uv][b1];
851         if (b1 == U8_TBL_ELEMENT_NOT_DEF)
852                 return ((size_t)sz);
853
854         b2 = u8_decomp_b2_tbl[uv][b1][b2];
855         if (b2 == U8_TBL_ELEMENT_NOT_DEF)
856                 return ((size_t)sz);
857
858         b3_tbl = u8_decomp_b3_tbl[uv][b2][b3].tbl_id;
859         if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
860                 return ((size_t)sz);
861
862         /*
863          * If b3_tbl is bigger than or equal to U8_16BIT_TABLE_INDICATOR
864          * which is 0x8000, this means we couldn't fit the mappings into
865          * the cardinality of a unsigned byte.
866          */
867         if (b3_tbl >= U8_16BIT_TABLE_INDICATOR) {
868                 b3_tbl -= U8_16BIT_TABLE_INDICATOR;
869                 start_id = u8_decomp_b4_16bit_tbl[uv][b3_tbl][b4];
870                 end_id = u8_decomp_b4_16bit_tbl[uv][b3_tbl][b4 + 1];
871         } else {
872                 start_id = u8_decomp_b4_tbl[uv][b3_tbl][b4];
873                 end_id = u8_decomp_b4_tbl[uv][b3_tbl][b4 + 1];
874         }
875
876         /* This also means there wasn't any matching decomposition. */
877         if (start_id >= end_id)
878                 return ((size_t)sz);
879
880         /*
881          * The final table for decomposition mappings has three types of
882          * byte sequences depending on whether a mapping is for compatibility
883          * decomposition, canonical decomposition, or both like the following:
884          *
885          * (1) Compatibility decomposition mappings:
886          *
887          *      +---+---+-...-+---+
888          *      | B0| B1| ... | Bm|
889          *      +---+---+-...-+---+
890          *
891          *      The first byte, B0, is always less then 0xF5 (U8_DECOMP_BOTH).
892          *
893          * (2) Canonical decomposition mappings:
894          *
895          *      +---+---+---+-...-+---+
896          *      | T | b0| b1| ... | bn|
897          *      +---+---+---+-...-+---+
898          *
899          *      where the first byte, T, is 0xF6 (U8_DECOMP_CANONICAL).
900          *
901          * (3) Both mappings:
902          *
903          *      +---+---+---+---+-...-+---+---+---+-...-+---+
904          *      | T | D | b0| b1| ... | bn| B0| B1| ... | Bm|
905          *      +---+---+---+---+-...-+---+---+---+-...-+---+
906          *
907          *      where T is 0xF5 (U8_DECOMP_BOTH) and D is a displacement
908          *      byte, b0 to bn are canonical mapping bytes and B0 to Bm are
909          *      compatibility mapping bytes.
910          *
911          * Note that compatibility decomposition means doing recursive
912          * decompositions using both compatibility decomposition mappings and
913          * canonical decomposition mappings. On the other hand, canonical
914          * decomposition means doing recursive decompositions using only
915          * canonical decomposition mappings. Since the table we have has gone
916          * through the recursions already, we do not need to do so during
917          * runtime, i.e., the table has been completely flattened out
918          * already.
919          */
920
921         b3_base = u8_decomp_b3_tbl[uv][b2][b3].base;
922
923         /* Get the type, T, of the byte sequence. */
924         b1 = u8_decomp_final_tbl[uv][b3_base + start_id];
925
926         /*
927          * If necessary, adjust start_id, end_id, or both. Note that if
928          * this is compatibility decomposition mapping, there is no
929          * adjustment.
930          */
931         if (canonical_decomposition) {
932                 /* Is the mapping only for compatibility decomposition? */
933                 if (b1 < U8_DECOMP_BOTH)
934                         return ((size_t)sz);
935
936                 start_id++;
937
938                 if (b1 == U8_DECOMP_BOTH) {
939                         end_id = start_id +
940                             u8_decomp_final_tbl[uv][b3_base + start_id];
941                         start_id++;
942                 }
943         } else {
944                 /*
945                  * Unless this is a compatibility decomposition mapping,
946                  * we adjust the start_id.
947                  */
948                 if (b1 == U8_DECOMP_BOTH) {
949                         start_id++;
950                         start_id += u8_decomp_final_tbl[uv][b3_base + start_id];
951                 } else if (b1 == U8_DECOMP_CANONICAL) {
952                         start_id++;
953                 }
954         }
955
956         for (i = 0; start_id < end_id; start_id++)
957                 u8s[i++] = u8_decomp_final_tbl[uv][b3_base + start_id];
958         u8s[i] = '\0';
959
960         return (i);
961 }
962
963 /*
964  * The find_composition_start() function uses the character bytes given and
965  * find out the matching composition mappings if any and return the address
966  * to the composition mappings as explained in the do_composition().
967  */
968 static uchar_t *
969 find_composition_start(size_t uv, uchar_t *s, size_t sz)
970 {
971         uint16_t b1 = 0;
972         uint16_t b2 = 0;
973         uint16_t b3 = 0;
974         uint16_t b3_tbl;
975         uint16_t b3_base;
976         uint16_t b4 = 0;
977         size_t start_id;
978         size_t end_id;
979
980         if (sz == 1) {
981                 b4 = s[0];
982         } else if (sz == 2) {
983                 b3 = s[0];
984                 b4 = s[1];
985         } else if (sz == 3) {
986                 b2 = s[0];
987                 b3 = s[1];
988                 b4 = s[2];
989         } else if (sz == 4) {
990                 b1 = s[0];
991                 b2 = s[1];
992                 b3 = s[2];
993                 b4 = s[3];
994         } else {
995                 /*
996                  * This is a fallback and should not happen if the function
997                  * was called properly.
998                  */
999                 return (NULL);
1000         }
1001
1002         b1 = u8_composition_b1_tbl[uv][b1];
1003         if (b1 == U8_TBL_ELEMENT_NOT_DEF)
1004                 return (NULL);
1005
1006         b2 = u8_composition_b2_tbl[uv][b1][b2];
1007         if (b2 == U8_TBL_ELEMENT_NOT_DEF)
1008                 return (NULL);
1009
1010         b3_tbl = u8_composition_b3_tbl[uv][b2][b3].tbl_id;
1011         if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
1012                 return (NULL);
1013
1014         if (b3_tbl >= U8_16BIT_TABLE_INDICATOR) {
1015                 b3_tbl -= U8_16BIT_TABLE_INDICATOR;
1016                 start_id = u8_composition_b4_16bit_tbl[uv][b3_tbl][b4];
1017                 end_id = u8_composition_b4_16bit_tbl[uv][b3_tbl][b4 + 1];
1018         } else {
1019                 start_id = u8_composition_b4_tbl[uv][b3_tbl][b4];
1020                 end_id = u8_composition_b4_tbl[uv][b3_tbl][b4 + 1];
1021         }
1022
1023         if (start_id >= end_id)
1024                 return (NULL);
1025
1026         b3_base = u8_composition_b3_tbl[uv][b2][b3].base;
1027
1028         return ((uchar_t *)&(u8_composition_final_tbl[uv][b3_base + start_id]));
1029 }
1030
1031 /*
1032  * The blocked() function checks on the combining class values of previous
1033  * characters in this sequence and return whether it is blocked or not.
1034  */
1035 static boolean_t
1036 blocked(uchar_t *comb_class, size_t last)
1037 {
1038         uchar_t my_comb_class;
1039         size_t i;
1040
1041         my_comb_class = comb_class[last];
1042         for (i = 1; i < last; i++)
1043                 if (comb_class[i] >= my_comb_class ||
1044                     comb_class[i] == U8_COMBINING_CLASS_STARTER)
1045                         return (B_TRUE);
1046
1047         return (B_FALSE);
1048 }
1049
1050 /*
1051  * The do_composition() reads the character string pointed by 's' and
1052  * do necessary canonical composition and then copy over the result back to
1053  * the 's'.
1054  *
1055  * The input argument 's' cannot contain more than 32 characters.
1056  */
1057 static size_t
1058 do_composition(size_t uv, uchar_t *s, uchar_t *comb_class, uchar_t *start,
1059         uchar_t *disp, size_t last, uchar_t **os, uchar_t *oslast)
1060 {
1061         uchar_t t[U8_STREAM_SAFE_TEXT_MAX + 1];
1062         uchar_t tc[U8_MB_CUR_MAX];
1063         uint8_t saved_marks[U8_MAX_CHARS_A_SEQ];
1064         size_t saved_marks_count;
1065         uchar_t *p;
1066         uchar_t *saved_p;
1067         uchar_t *q;
1068         size_t i;
1069         size_t saved_i;
1070         size_t j;
1071         size_t k;
1072         size_t l;
1073         size_t C;
1074         size_t saved_l;
1075         size_t size;
1076         uint32_t u1;
1077         uint32_t u2;
1078         boolean_t match_not_found = B_TRUE;
1079
1080         /*
1081          * This should never happen unless the callers are doing some strange
1082          * and unexpected things.
1083          *
1084          * The "last" is the index pointing to the last character not last + 1.
1085          */
1086         if (last >= U8_MAX_CHARS_A_SEQ)
1087                 last = U8_UPPER_LIMIT_IN_A_SEQ;
1088
1089         for (i = l = 0; i <= last; i++) {
1090                 /*
1091                  * The last or any non-Starters at the beginning, we don't
1092                  * have any chance to do composition and so we just copy them
1093                  * to the temporary buffer.
1094                  */
1095                 if (i >= last || comb_class[i] != U8_COMBINING_CLASS_STARTER) {
1096 SAVE_THE_CHAR:
1097                         p = s + start[i];
1098                         size = disp[i];
1099                         for (k = 0; k < size; k++)
1100                                 t[l++] = *p++;
1101                         continue;
1102                 }
1103
1104                 /*
1105                  * If this could be a start of Hangul Jamos, then, we try to
1106                  * conjoin them.
1107                  */
1108                 if (s[start[i]] == U8_HANGUL_JAMO_1ST_BYTE) {
1109                         U8_PUT_3BYTES_INTO_UTF32(u1, s[start[i]],
1110                             s[start[i] + 1], s[start[i] + 2]);
1111                         U8_PUT_3BYTES_INTO_UTF32(u2, s[start[i] + 3],
1112                             s[start[i] + 4], s[start[i] + 5]);
1113
1114                         if (U8_HANGUL_JAMO_L(u1) && U8_HANGUL_JAMO_V(u2)) {
1115                                 u1 -= U8_HANGUL_JAMO_L_FIRST;
1116                                 u2 -= U8_HANGUL_JAMO_V_FIRST;
1117                                 u1 = U8_HANGUL_SYL_FIRST +
1118                                     (u1 * U8_HANGUL_V_COUNT + u2) *
1119                                     U8_HANGUL_T_COUNT;
1120
1121                                 i += 2;
1122                                 if (i <= last) {
1123                                         U8_PUT_3BYTES_INTO_UTF32(u2,
1124                                             s[start[i]], s[start[i] + 1],
1125                                             s[start[i] + 2]);
1126
1127                                         if (U8_HANGUL_JAMO_T(u2)) {
1128                                                 u1 += u2 -
1129                                                     U8_HANGUL_JAMO_T_FIRST;
1130                                                 i++;
1131                                         }
1132                                 }
1133
1134                                 U8_SAVE_HANGUL_AS_UTF8(t + l, 0, 1, 2, u1);
1135                                 i--;
1136                                 l += 3;
1137                                 continue;
1138                         }
1139                 }
1140
1141                 /*
1142                  * Let's then find out if this Starter has composition
1143                  * mapping.
1144                  */
1145                 p = find_composition_start(uv, s + start[i], disp[i]);
1146                 if (p == NULL)
1147                         goto SAVE_THE_CHAR;
1148
1149                 /*
1150                  * We have a Starter with composition mapping and the next
1151                  * character is a non-Starter. Let's try to find out if
1152                  * we can do composition.
1153                  */
1154
1155                 saved_p = p;
1156                 saved_i = i;
1157                 saved_l = l;
1158                 saved_marks_count = 0;
1159
1160 TRY_THE_NEXT_MARK:
1161                 q = s + start[++i];
1162                 size = disp[i];
1163
1164                 /*
1165                  * The next for() loop compares the non-Starter pointed by
1166                  * 'q' with the possible (joinable) characters pointed by 'p'.
1167                  *
1168                  * The composition final table entry pointed by the 'p'
1169                  * looks like the following:
1170                  *
1171                  * +---+---+---+-...-+---+---+---+---+-...-+---+---+
1172                  * | C | b0| b2| ... | bn| F | B0| B1| ... | Bm| F |
1173                  * +---+---+---+-...-+---+---+---+---+-...-+---+---+
1174                  *
1175                  * where C is the count byte indicating the number of
1176                  * mapping pairs where each pair would be look like
1177                  * (b0-bn F, B0-Bm F). The b0-bn are the bytes of the second
1178                  * character of a canonical decomposition and the B0-Bm are
1179                  * the bytes of a matching composite character. The F is
1180                  * a filler byte after each character as the separator.
1181                  */
1182
1183                 match_not_found = B_TRUE;
1184
1185                 for (C = *p++; C > 0; C--) {
1186                         for (k = 0; k < size; p++, k++)
1187                                 if (*p != q[k])
1188                                         break;
1189
1190                         /* Have we found it? */
1191                         if (k >= size && *p == U8_TBL_ELEMENT_FILLER) {
1192                                 match_not_found = B_FALSE;
1193
1194                                 l = saved_l;
1195
1196                                 while (*++p != U8_TBL_ELEMENT_FILLER)
1197                                         t[l++] = *p;
1198
1199                                 break;
1200                         }
1201
1202                         /* We didn't find; skip to the next pair. */
1203                         if (*p != U8_TBL_ELEMENT_FILLER)
1204                                 while (*++p != U8_TBL_ELEMENT_FILLER)
1205                                         ;
1206                         while (*++p != U8_TBL_ELEMENT_FILLER)
1207                                 ;
1208                         p++;
1209                 }
1210
1211                 /*
1212                  * If there was no match, we will need to save the combining
1213                  * mark for later appending. After that, if the next one
1214                  * is a non-Starter and not blocked, then, we try once
1215                  * again to do composition with the next non-Starter.
1216                  *
1217                  * If there was no match and this was a Starter, then,
1218                  * this is a new start.
1219                  *
1220                  * If there was a match and a composition done and we have
1221                  * more to check on, then, we retrieve a new composition final
1222                  * table entry for the composite and then try to do the
1223                  * composition again.
1224                  */
1225
1226                 if (match_not_found) {
1227                         if (comb_class[i] == U8_COMBINING_CLASS_STARTER) {
1228                                 i--;
1229                                 goto SAVE_THE_CHAR;
1230                         }
1231
1232                         saved_marks[saved_marks_count++] = i;
1233                 }
1234
1235                 if (saved_l == l) {
1236                         while (i < last) {
1237                                 if (blocked(comb_class, i + 1))
1238                                         saved_marks[saved_marks_count++] = ++i;
1239                                 else
1240                                         break;
1241                         }
1242                         if (i < last) {
1243                                 p = saved_p;
1244                                 goto TRY_THE_NEXT_MARK;
1245                         }
1246                 } else if (i < last) {
1247                         p = find_composition_start(uv, t + saved_l,
1248                             l - saved_l);
1249                         if (p != NULL) {
1250                                 saved_p = p;
1251                                 goto TRY_THE_NEXT_MARK;
1252                         }
1253                 }
1254
1255                 /*
1256                  * There is no more composition possible.
1257                  *
1258                  * If there was no composition what so ever then we copy
1259                  * over the original Starter and then append any non-Starters
1260                  * remaining at the target string sequentially after that.
1261                  */
1262
1263                 if (saved_l == l) {
1264                         p = s + start[saved_i];
1265                         size = disp[saved_i];
1266                         for (j = 0; j < size; j++)
1267                                 t[l++] = *p++;
1268                 }
1269
1270                 for (k = 0; k < saved_marks_count; k++) {
1271                         p = s + start[saved_marks[k]];
1272                         size = disp[saved_marks[k]];
1273                         for (j = 0; j < size; j++)
1274                                 t[l++] = *p++;
1275                 }
1276         }
1277
1278         /*
1279          * If the last character is a Starter and if we have a character
1280          * (possibly another Starter) that can be turned into a composite,
1281          * we do so and we do so until there is no more of composition
1282          * possible.
1283          */
1284         if (comb_class[last] == U8_COMBINING_CLASS_STARTER) {
1285                 p = *os;
1286                 saved_l = l - disp[last];
1287
1288                 while (p < oslast) {
1289                         size = u8_number_of_bytes[*p];
1290                         if (size <= 1 || (p + size) > oslast)
1291                                 break;
1292
1293                         saved_p = p;
1294
1295                         for (i = 0; i < size; i++)
1296                                 tc[i] = *p++;
1297
1298                         q = find_composition_start(uv, t + saved_l,
1299                             l - saved_l);
1300                         if (q == NULL) {
1301                                 p = saved_p;
1302                                 break;
1303                         }
1304
1305                         match_not_found = B_TRUE;
1306
1307                         for (C = *q++; C > 0; C--) {
1308                                 for (k = 0; k < size; q++, k++)
1309                                         if (*q != tc[k])
1310                                                 break;
1311
1312                                 if (k >= size && *q == U8_TBL_ELEMENT_FILLER) {
1313                                         match_not_found = B_FALSE;
1314
1315                                         l = saved_l;
1316
1317                                         while (*++q != U8_TBL_ELEMENT_FILLER) {
1318                                                 /*
1319                                                  * This is practically
1320                                                  * impossible but we don't
1321                                                  * want to take any chances.
1322                                                  */
1323                                                 if (l >=
1324                                                     U8_STREAM_SAFE_TEXT_MAX) {
1325                                                         p = saved_p;
1326                                                         goto SAFE_RETURN;
1327                                                 }
1328                                                 t[l++] = *q;
1329                                         }
1330
1331                                         break;
1332                                 }
1333
1334                                 if (*q != U8_TBL_ELEMENT_FILLER)
1335                                         while (*++q != U8_TBL_ELEMENT_FILLER)
1336                                                 ;
1337                                 while (*++q != U8_TBL_ELEMENT_FILLER)
1338                                         ;
1339                                 q++;
1340                         }
1341
1342                         if (match_not_found) {
1343                                 p = saved_p;
1344                                 break;
1345                         }
1346                 }
1347 SAFE_RETURN:
1348                 *os = p;
1349         }
1350
1351         /*
1352          * Now we copy over the temporary string to the target string.
1353          * Since composition always reduces the number of characters or
1354          * the number of characters stay, we don't need to worry about
1355          * the buffer overflow here.
1356          */
1357         for (i = 0; i < l; i++)
1358                 s[i] = t[i];
1359         s[l] = '\0';
1360
1361         return (l);
1362 }
1363
1364 /*
1365  * The collect_a_seq() function checks on the given string s, collect
1366  * a sequence of characters at u8s, and return the sequence. While it collects
1367  * a sequence, it also applies case conversion, canonical or compatibility
1368  * decomposition, canonical decomposition, or some or all of them and
1369  * in that order.
1370  *
1371  * The collected sequence cannot be bigger than 32 characters since if
1372  * it is having more than 31 characters, the sequence will be terminated
1373  * with a U+034F COMBINING GRAPHEME JOINER (CGJ) character and turned into
1374  * a Stream-Safe Text. The collected sequence is always terminated with
1375  * a null byte and the return value is the byte length of the sequence
1376  * including 0. The return value does not include the terminating
1377  * null byte.
1378  */
1379 static size_t
1380 collect_a_seq(size_t uv, uchar_t *u8s, uchar_t **source, uchar_t *slast,
1381         boolean_t is_it_toupper,
1382         boolean_t is_it_tolower,
1383         boolean_t canonical_decomposition,
1384         boolean_t compatibility_decomposition,
1385         boolean_t canonical_composition,
1386         int *errnum, u8_normalization_states_t *state)
1387 {
1388         uchar_t *s;
1389         int sz;
1390         int saved_sz;
1391         size_t i;
1392         size_t j;
1393         size_t k;
1394         size_t l;
1395         uchar_t comb_class[U8_MAX_CHARS_A_SEQ];
1396         uchar_t disp[U8_MAX_CHARS_A_SEQ];
1397         uchar_t start[U8_MAX_CHARS_A_SEQ];
1398         uchar_t u8t[U8_MB_CUR_MAX];
1399         uchar_t uts[U8_STREAM_SAFE_TEXT_MAX + 1];
1400         uchar_t tc;
1401         size_t last;
1402         size_t saved_last;
1403         uint32_t u1;
1404
1405         /*
1406          * Save the source string pointer which we will return a changed
1407          * pointer if we do processing.
1408          */
1409         s = *source;
1410
1411         /*
1412          * The following is a fallback for just in case callers are not
1413          * checking the string boundaries before the calling.
1414          */
1415         if (s >= slast) {
1416                 u8s[0] = '\0';
1417
1418                 return (0);
1419         }
1420
1421         /*
1422          * As the first thing, let's collect a character and do case
1423          * conversion if necessary.
1424          */
1425
1426         sz = u8_number_of_bytes[*s];
1427
1428         if (sz < 0) {
1429                 *errnum = EILSEQ;
1430
1431                 u8s[0] = *s++;
1432                 u8s[1] = '\0';
1433
1434                 *source = s;
1435
1436                 return (1);
1437         }
1438
1439         if (sz == 1) {
1440                 if (is_it_toupper)
1441                         u8s[0] = U8_ASCII_TOUPPER(*s);
1442                 else if (is_it_tolower)
1443                         u8s[0] = U8_ASCII_TOLOWER(*s);
1444                 else
1445                         u8s[0] = *s;
1446                 s++;
1447                 u8s[1] = '\0';
1448         } else if ((s + sz) > slast) {
1449                 *errnum = EINVAL;
1450
1451                 for (i = 0; s < slast; )
1452                         u8s[i++] = *s++;
1453                 u8s[i] = '\0';
1454
1455                 *source = s;
1456
1457                 return (i);
1458         } else {
1459                 if (is_it_toupper || is_it_tolower) {
1460                         i = do_case_conv(uv, u8s, s, sz, is_it_toupper);
1461                         s += sz;
1462                         sz = i;
1463                 } else {
1464                         for (i = 0; i < sz; )
1465                                 u8s[i++] = *s++;
1466                         u8s[i] = '\0';
1467                 }
1468         }
1469
1470         /*
1471          * And then canonical/compatibility decomposition followed by
1472          * an optional canonical composition. Please be noted that
1473          * canonical composition is done only when a decomposition is
1474          * done.
1475          */
1476         if (canonical_decomposition || compatibility_decomposition) {
1477                 if (sz == 1) {
1478                         *state = U8_STATE_START;
1479
1480                         saved_sz = 1;
1481
1482                         comb_class[0] = 0;
1483                         start[0] = 0;
1484                         disp[0] = 1;
1485
1486                         last = 1;
1487                 } else {
1488                         saved_sz = do_decomp(uv, u8s, u8s, sz,
1489                             canonical_decomposition, state);
1490
1491                         last = 0;
1492
1493                         for (i = 0; i < saved_sz; ) {
1494                                 sz = u8_number_of_bytes[u8s[i]];
1495
1496                                 comb_class[last] = combining_class(uv,
1497                                     u8s + i, sz);
1498                                 start[last] = i;
1499                                 disp[last] = sz;
1500
1501                                 last++;
1502                                 i += sz;
1503                         }
1504
1505                         /*
1506                          * Decomposition yields various Hangul related
1507                          * states but not on combining marks. We need to
1508                          * find out at here by checking on the last
1509                          * character.
1510                          */
1511                         if (*state == U8_STATE_START) {
1512                                 if (comb_class[last - 1])
1513                                         *state = U8_STATE_COMBINING_MARK;
1514                         }
1515                 }
1516
1517                 saved_last = last;
1518
1519                 while (s < slast) {
1520                         sz = u8_number_of_bytes[*s];
1521
1522                         /*
1523                          * If this is an illegal character, an incomplete
1524                          * character, or an 7-bit ASCII Starter character,
1525                          * then we have collected a sequence; break and let
1526                          * the next call deal with the two cases.
1527                          *
1528                          * Note that this is okay only if you are using this
1529                          * function with a fixed length string, not on
1530                          * a buffer with multiple calls of one chunk at a time.
1531                          */
1532                         if (sz <= 1) {
1533                                 break;
1534                         } else if ((s + sz) > slast) {
1535                                 break;
1536                         } else {
1537                                 /*
1538                                  * If the previous character was a Hangul Jamo
1539                                  * and this character is a Hangul Jamo that
1540                                  * can be conjoined, we collect the Jamo.
1541                                  */
1542                                 if (*s == U8_HANGUL_JAMO_1ST_BYTE) {
1543                                         U8_PUT_3BYTES_INTO_UTF32(u1,
1544                                             *s, *(s + 1), *(s + 2));
1545
1546                                         if (U8_HANGUL_COMPOSABLE_L_V(*state,
1547                                             u1)) {
1548                                                 i = 0;
1549                                                 *state = U8_STATE_HANGUL_LV;
1550                                                 goto COLLECT_A_HANGUL;
1551                                         }
1552
1553                                         if (U8_HANGUL_COMPOSABLE_LV_T(*state,
1554                                             u1)) {
1555                                                 i = 0;
1556                                                 *state = U8_STATE_HANGUL_LVT;
1557                                                 goto COLLECT_A_HANGUL;
1558                                         }
1559                                 }
1560
1561                                 /*
1562                                  * Regardless of whatever it was, if this is
1563                                  * a Starter, we don't collect the character
1564                                  * since that's a new start and we will deal
1565                                  * with it at the next time.
1566                                  */
1567                                 i = combining_class(uv, s, sz);
1568                                 if (i == U8_COMBINING_CLASS_STARTER)
1569                                         break;
1570
1571                                 /*
1572                                  * We know the current character is a combining
1573                                  * mark. If the previous character wasn't
1574                                  * a Starter (not Hangul) or a combining mark,
1575                                  * then, we don't collect this combining mark.
1576                                  */
1577                                 if (*state != U8_STATE_START &&
1578                                     *state != U8_STATE_COMBINING_MARK)
1579                                         break;
1580
1581                                 *state = U8_STATE_COMBINING_MARK;
1582 COLLECT_A_HANGUL:
1583                                 /*
1584                                  * If we collected a Starter and combining
1585                                  * marks up to 30, i.e., total 31 characters,
1586                                  * then, we terminate this degenerately long
1587                                  * combining sequence with a U+034F COMBINING
1588                                  * GRAPHEME JOINER (CGJ) which is 0xCD 0x8F in
1589                                  * UTF-8 and turn this into a Stream-Safe
1590                                  * Text. This will be extremely rare but
1591                                  * possible.
1592                                  *
1593                                  * The following will also guarantee that
1594                                  * we are not writing more than 32 characters
1595                                  * plus a NULL at u8s[].
1596                                  */
1597                                 if (last >= U8_UPPER_LIMIT_IN_A_SEQ) {
1598 TURN_STREAM_SAFE:
1599                                         *state = U8_STATE_START;
1600                                         comb_class[last] = 0;
1601                                         start[last] = saved_sz;
1602                                         disp[last] = 2;
1603                                         last++;
1604
1605                                         u8s[saved_sz++] = 0xCD;
1606                                         u8s[saved_sz++] = 0x8F;
1607
1608                                         break;
1609                                 }
1610
1611                                 /*
1612                                  * Some combining marks also do decompose into
1613                                  * another combining mark or marks.
1614                                  */
1615                                 if (*state == U8_STATE_COMBINING_MARK) {
1616                                         k = last;
1617                                         l = sz;
1618                                         i = do_decomp(uv, uts, s, sz,
1619                                             canonical_decomposition, state);
1620                                         for (j = 0; j < i; ) {
1621                                                 sz = u8_number_of_bytes[uts[j]];
1622
1623                                                 comb_class[last] =
1624                                                     combining_class(uv,
1625                                                     uts + j, sz);
1626                                                 start[last] = saved_sz + j;
1627                                                 disp[last] = sz;
1628
1629                                                 last++;
1630                                                 if (last >=
1631                                                     U8_UPPER_LIMIT_IN_A_SEQ) {
1632                                                         last = k;
1633                                                         goto TURN_STREAM_SAFE;
1634                                                 }
1635                                                 j += sz;
1636                                         }
1637
1638                                         *state = U8_STATE_COMBINING_MARK;
1639                                         sz = i;
1640                                         s += l;
1641
1642                                         for (i = 0; i < sz; i++)
1643                                                 u8s[saved_sz++] = uts[i];
1644                                 } else {
1645                                         comb_class[last] = i;
1646                                         start[last] = saved_sz;
1647                                         disp[last] = sz;
1648                                         last++;
1649
1650                                         for (i = 0; i < sz; i++)
1651                                                 u8s[saved_sz++] = *s++;
1652                                 }
1653
1654                                 /*
1655                                  * If this is U+0345 COMBINING GREEK
1656                                  * YPOGEGRAMMENI (0xCD 0x85 in UTF-8), a.k.a.,
1657                                  * iota subscript, and need to be converted to
1658                                  * uppercase letter, convert it to U+0399 GREEK
1659                                  * CAPITAL LETTER IOTA (0xCE 0x99 in UTF-8),
1660                                  * i.e., convert to capital adscript form as
1661                                  * specified in the Unicode standard.
1662                                  *
1663                                  * This is the only special case of (ambiguous)
1664                                  * case conversion at combining marks and
1665                                  * probably the standard will never have
1666                                  * anything similar like this in future.
1667                                  */
1668                                 if (is_it_toupper && sz >= 2 &&
1669                                     u8s[saved_sz - 2] == 0xCD &&
1670                                     u8s[saved_sz - 1] == 0x85) {
1671                                         u8s[saved_sz - 2] = 0xCE;
1672                                         u8s[saved_sz - 1] = 0x99;
1673                                 }
1674                         }
1675                 }
1676
1677                 /*
1678                  * Let's try to ensure a canonical ordering for the collected
1679                  * combining marks. We do this only if we have collected
1680                  * at least one more non-Starter. (The decomposition mapping
1681                  * data tables have fully (and recursively) expanded and
1682                  * canonically ordered decompositions.)
1683                  *
1684                  * The U8_SWAP_COMB_MARKS() convenience macro has some
1685                  * assumptions and we are meeting the assumptions.
1686                  */
1687                 last--;
1688                 if (last >= saved_last) {
1689                         for (i = 0; i < last; i++)
1690                                 for (j = last; j > i; j--)
1691                                         if (comb_class[j] &&
1692                                             comb_class[j - 1] > comb_class[j]) {
1693                                                 U8_SWAP_COMB_MARKS(j - 1, j);
1694                                         }
1695                 }
1696
1697                 *source = s;
1698
1699                 if (! canonical_composition) {
1700                         u8s[saved_sz] = '\0';
1701                         return (saved_sz);
1702                 }
1703
1704                 /*
1705                  * Now do the canonical composition. Note that we do this
1706                  * only after a canonical or compatibility decomposition to
1707                  * finish up NFC or NFKC.
1708                  */
1709                 sz = do_composition(uv, u8s, comb_class, start, disp, last,
1710                     &s, slast);
1711         }
1712
1713         *source = s;
1714
1715         return ((size_t)sz);
1716 }
1717
1718 /*
1719  * The do_norm_compare() function does string comparion based on Unicode
1720  * simple case mappings and Unicode Normalization definitions.
1721  *
1722  * It does so by collecting a sequence of character at a time and comparing
1723  * the collected sequences from the strings.
1724  *
1725  * The meanings on the return values are the same as the usual strcmp().
1726  */
1727 static int
1728 do_norm_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, size_t n2,
1729         int flag, int *errnum)
1730 {
1731         int result;
1732         size_t sz1;
1733         size_t sz2;
1734         uchar_t u8s1[U8_STREAM_SAFE_TEXT_MAX + 1];
1735         uchar_t u8s2[U8_STREAM_SAFE_TEXT_MAX + 1];
1736         uchar_t *s1last;
1737         uchar_t *s2last;
1738         boolean_t is_it_toupper;
1739         boolean_t is_it_tolower;
1740         boolean_t canonical_decomposition;
1741         boolean_t compatibility_decomposition;
1742         boolean_t canonical_composition;
1743         u8_normalization_states_t state;
1744
1745         s1last = s1 + n1;
1746         s2last = s2 + n2;
1747
1748         is_it_toupper = flag & U8_TEXTPREP_TOUPPER;
1749         is_it_tolower = flag & U8_TEXTPREP_TOLOWER;
1750         canonical_decomposition = flag & U8_CANON_DECOMP;
1751         compatibility_decomposition = flag & U8_COMPAT_DECOMP;
1752         canonical_composition = flag & U8_CANON_COMP;
1753
1754         while (s1 < s1last && s2 < s2last) {
1755                 /*
1756                  * If the current character is a 7-bit ASCII and the last
1757                  * character, or, if the current character and the next
1758                  * character are both some 7-bit ASCII characters then
1759                  * we treat the current character as a sequence.
1760                  *
1761                  * In any other cases, we need to call collect_a_seq().
1762                  */
1763
1764                 if (U8_ISASCII(*s1) && ((s1 + 1) >= s1last ||
1765                     ((s1 + 1) < s1last && U8_ISASCII(*(s1 + 1))))) {
1766                         if (is_it_toupper)
1767                                 u8s1[0] = U8_ASCII_TOUPPER(*s1);
1768                         else if (is_it_tolower)
1769                                 u8s1[0] = U8_ASCII_TOLOWER(*s1);
1770                         else
1771                                 u8s1[0] = *s1;
1772                         u8s1[1] = '\0';
1773                         sz1 = 1;
1774                         s1++;
1775                 } else {
1776                         state = U8_STATE_START;
1777                         sz1 = collect_a_seq(uv, u8s1, &s1, s1last,
1778                             is_it_toupper, is_it_tolower,
1779                             canonical_decomposition,
1780                             compatibility_decomposition,
1781                             canonical_composition, errnum, &state);
1782                 }
1783
1784                 if (U8_ISASCII(*s2) && ((s2 + 1) >= s2last ||
1785                     ((s2 + 1) < s2last && U8_ISASCII(*(s2 + 1))))) {
1786                         if (is_it_toupper)
1787                                 u8s2[0] = U8_ASCII_TOUPPER(*s2);
1788                         else if (is_it_tolower)
1789                                 u8s2[0] = U8_ASCII_TOLOWER(*s2);
1790                         else
1791                                 u8s2[0] = *s2;
1792                         u8s2[1] = '\0';
1793                         sz2 = 1;
1794                         s2++;
1795                 } else {
1796                         state = U8_STATE_START;
1797                         sz2 = collect_a_seq(uv, u8s2, &s2, s2last,
1798                             is_it_toupper, is_it_tolower,
1799                             canonical_decomposition,
1800                             compatibility_decomposition,
1801                             canonical_composition, errnum, &state);
1802                 }
1803
1804                 /*
1805                  * Now compare the two characters. If they are the same,
1806                  * we move on to the next character sequences.
1807                  */
1808                 if (sz1 == 1 && sz2 == 1) {
1809                         if (*u8s1 > *u8s2)
1810                                 return (1);
1811                         if (*u8s1 < *u8s2)
1812                                 return (-1);
1813                 } else {
1814                         result = strcmp((const char *)u8s1, (const char *)u8s2);
1815                         if (result != 0)
1816                                 return (result);
1817                 }
1818         }
1819
1820         /*
1821          * We compared until the end of either or both strings.
1822          *
1823          * If we reached to or went over the ends for the both, that means
1824          * they are the same.
1825          *
1826          * If we reached only one end, that means the other string has
1827          * something which then can be used to determine the return value.
1828          */
1829         if (s1 >= s1last) {
1830                 if (s2 >= s2last)
1831                         return (0);
1832                 return (-1);
1833         }
1834         return (1);
1835 }
1836
1837 /*
1838  * The u8_strcmp() function compares two UTF-8 strings quite similar to
1839  * the strcmp(). For the comparison, however, Unicode Normalization specific
1840  * equivalency and Unicode simple case conversion mappings based equivalency
1841  * can be requested and checked against.
1842  */
1843 int
1844 u8_strcmp(const char *s1, const char *s2, size_t n, int flag, size_t uv,
1845                 int *errnum)
1846 {
1847         int f;
1848         size_t n1;
1849         size_t n2;
1850
1851         *errnum = 0;
1852
1853         /*
1854          * Check on the requested Unicode version, case conversion, and
1855          * normalization flag values.
1856          */
1857
1858         if (uv > U8_UNICODE_LATEST) {
1859                 *errnum = ERANGE;
1860                 uv = U8_UNICODE_LATEST;
1861         }
1862
1863         if (flag == 0) {
1864                 flag = U8_STRCMP_CS;
1865         } else {
1866                 f = flag & (U8_STRCMP_CS | U8_STRCMP_CI_UPPER |
1867                     U8_STRCMP_CI_LOWER);
1868                 if (f == 0) {
1869                         flag |= U8_STRCMP_CS;
1870                 } else if (f != U8_STRCMP_CS && f != U8_STRCMP_CI_UPPER &&
1871                     f != U8_STRCMP_CI_LOWER) {
1872                         *errnum = EBADF;
1873                         flag = U8_STRCMP_CS;
1874                 }
1875
1876                 f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP);
1877                 if (f && f != U8_STRCMP_NFD && f != U8_STRCMP_NFC &&
1878                     f != U8_STRCMP_NFKD && f != U8_STRCMP_NFKC) {
1879                         *errnum = EBADF;
1880                         flag = U8_STRCMP_CS;
1881                 }
1882         }
1883
1884         if (flag == U8_STRCMP_CS) {
1885                 return (n == 0 ? strcmp(s1, s2) : strncmp(s1, s2, n));
1886         }
1887
1888         n1 = strlen(s1);
1889         n2 = strlen(s2);
1890         if (n != 0) {
1891                 if (n < n1)
1892                         n1 = n;
1893                 if (n < n2)
1894                         n2 = n;
1895         }
1896
1897         /*
1898          * Simple case conversion can be done much faster and so we do
1899          * them separately here.
1900          */
1901         if (flag == U8_STRCMP_CI_UPPER) {
1902                 return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2,
1903                     n1, n2, B_TRUE, errnum));
1904         } else if (flag == U8_STRCMP_CI_LOWER) {
1905                 return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2,
1906                     n1, n2, B_FALSE, errnum));
1907         }
1908
1909         return (do_norm_compare(uv, (uchar_t *)s1, (uchar_t *)s2, n1, n2,
1910             flag, errnum));
1911 }
1912
1913 size_t
1914 u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen,
1915         int flag, size_t unicode_version, int *errnum)
1916 {
1917         int f;
1918         int sz;
1919         uchar_t *ib;
1920         uchar_t *ibtail;
1921         uchar_t *ob;
1922         uchar_t *obtail;
1923         boolean_t do_not_ignore_null;
1924         boolean_t do_not_ignore_invalid;
1925         boolean_t is_it_toupper;
1926         boolean_t is_it_tolower;
1927         boolean_t canonical_decomposition;
1928         boolean_t compatibility_decomposition;
1929         boolean_t canonical_composition;
1930         size_t ret_val;
1931         size_t i;
1932         size_t j;
1933         uchar_t u8s[U8_STREAM_SAFE_TEXT_MAX + 1];
1934         u8_normalization_states_t state;
1935
1936         if (unicode_version > U8_UNICODE_LATEST) {
1937                 *errnum = ERANGE;
1938                 return ((size_t)-1);
1939         }
1940
1941         f = flag & (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER);
1942         if (f == (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER)) {
1943                 *errnum = EBADF;
1944                 return ((size_t)-1);
1945         }
1946
1947         f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP);
1948         if (f && f != U8_TEXTPREP_NFD && f != U8_TEXTPREP_NFC &&
1949             f != U8_TEXTPREP_NFKD && f != U8_TEXTPREP_NFKC) {
1950                 *errnum = EBADF;
1951                 return ((size_t)-1);
1952         }
1953
1954         if (inarray == NULL || *inlen == 0)
1955                 return (0);
1956
1957         if (outarray == NULL) {
1958                 *errnum = E2BIG;
1959                 return ((size_t)-1);
1960         }
1961
1962         ib = (uchar_t *)inarray;
1963         ob = (uchar_t *)outarray;
1964         ibtail = ib + *inlen;
1965         obtail = ob + *outlen;
1966
1967         do_not_ignore_null = !(flag & U8_TEXTPREP_IGNORE_NULL);
1968         do_not_ignore_invalid = !(flag & U8_TEXTPREP_IGNORE_INVALID);
1969         is_it_toupper = flag & U8_TEXTPREP_TOUPPER;
1970         is_it_tolower = flag & U8_TEXTPREP_TOLOWER;
1971
1972         ret_val = 0;
1973
1974         /*
1975          * If we don't have a normalization flag set, we do the simple case
1976          * conversion based text preparation separately below. Text
1977          * preparation involving Normalization will be done in the false task
1978          * block, again, separately since it will take much more time and
1979          * resource than doing simple case conversions.
1980          */
1981         if (f == 0) {
1982                 while (ib < ibtail) {
1983                         if (*ib == '\0' && do_not_ignore_null)
1984                                 break;
1985
1986                         sz = u8_number_of_bytes[*ib];
1987
1988                         if (sz < 0) {
1989                                 if (do_not_ignore_invalid) {
1990                                         *errnum = EILSEQ;
1991                                         ret_val = (size_t)-1;
1992                                         break;
1993                                 }
1994
1995                                 sz = 1;
1996                                 ret_val++;
1997                         }
1998
1999                         if (sz == 1) {
2000                                 if (ob >= obtail) {
2001                                         *errnum = E2BIG;
2002                                         ret_val = (size_t)-1;
2003                                         break;
2004                                 }
2005
2006                                 if (is_it_toupper)
2007                                         *ob = U8_ASCII_TOUPPER(*ib);
2008                                 else if (is_it_tolower)
2009                                         *ob = U8_ASCII_TOLOWER(*ib);
2010                                 else
2011                                         *ob = *ib;
2012                                 ib++;
2013                                 ob++;
2014                         } else if ((ib + sz) > ibtail) {
2015                                 if (do_not_ignore_invalid) {
2016                                         *errnum = EINVAL;
2017                                         ret_val = (size_t)-1;
2018                                         break;
2019                                 }
2020
2021                                 if ((obtail - ob) < (ibtail - ib)) {
2022                                         *errnum = E2BIG;
2023                                         ret_val = (size_t)-1;
2024                                         break;
2025                                 }
2026
2027                                 /*
2028                                  * We treat the remaining incomplete character
2029                                  * bytes as a character.
2030                                  */
2031                                 ret_val++;
2032
2033                                 while (ib < ibtail)
2034                                         *ob++ = *ib++;
2035                         } else {
2036                                 if (is_it_toupper || is_it_tolower) {
2037                                         i = do_case_conv(unicode_version, u8s,
2038                                             ib, sz, is_it_toupper);
2039
2040                                         if ((obtail - ob) < i) {
2041                                                 *errnum = E2BIG;
2042                                                 ret_val = (size_t)-1;
2043                                                 break;
2044                                         }
2045
2046                                         ib += sz;
2047
2048                                         for (sz = 0; sz < i; sz++)
2049                                                 *ob++ = u8s[sz];
2050                                 } else {
2051                                         if ((obtail - ob) < sz) {
2052                                                 *errnum = E2BIG;
2053                                                 ret_val = (size_t)-1;
2054                                                 break;
2055                                         }
2056
2057                                         for (i = 0; i < sz; i++)
2058                                                 *ob++ = *ib++;
2059                                 }
2060                         }
2061                 }
2062         } else {
2063                 canonical_decomposition = flag & U8_CANON_DECOMP;
2064                 compatibility_decomposition = flag & U8_COMPAT_DECOMP;
2065                 canonical_composition = flag & U8_CANON_COMP;
2066
2067                 while (ib < ibtail) {
2068                         if (*ib == '\0' && do_not_ignore_null)
2069                                 break;
2070
2071                         /*
2072                          * If the current character is a 7-bit ASCII
2073                          * character and it is the last character, or,
2074                          * if the current character is a 7-bit ASCII
2075                          * character and the next character is also a 7-bit
2076                          * ASCII character, then, we copy over this
2077                          * character without going through collect_a_seq().
2078                          *
2079                          * In any other cases, we need to look further with
2080                          * the collect_a_seq() function.
2081                          */
2082                         if (U8_ISASCII(*ib) && ((ib + 1) >= ibtail ||
2083                             ((ib + 1) < ibtail && U8_ISASCII(*(ib + 1))))) {
2084                                 if (ob >= obtail) {
2085                                         *errnum = E2BIG;
2086                                         ret_val = (size_t)-1;
2087                                         break;
2088                                 }
2089
2090                                 if (is_it_toupper)
2091                                         *ob = U8_ASCII_TOUPPER(*ib);
2092                                 else if (is_it_tolower)
2093                                         *ob = U8_ASCII_TOLOWER(*ib);
2094                                 else
2095                                         *ob = *ib;
2096                                 ib++;
2097                                 ob++;
2098                         } else {
2099                                 *errnum = 0;
2100                                 state = U8_STATE_START;
2101
2102                                 j = collect_a_seq(unicode_version, u8s,
2103                                     &ib, ibtail,
2104                                     is_it_toupper,
2105                                     is_it_tolower,
2106                                     canonical_decomposition,
2107                                     compatibility_decomposition,
2108                                     canonical_composition,
2109                                     errnum, &state);
2110
2111                                 if (*errnum && do_not_ignore_invalid) {
2112                                         ret_val = (size_t)-1;
2113                                         break;
2114                                 }
2115
2116                                 if ((obtail - ob) < j) {
2117                                         *errnum = E2BIG;
2118                                         ret_val = (size_t)-1;
2119                                         break;
2120                                 }
2121
2122                                 for (i = 0; i < j; i++)
2123                                         *ob++ = u8s[i];
2124                         }
2125                 }
2126         }
2127
2128         *inlen = ibtail - ib;
2129         *outlen = obtail - ob;
2130
2131         return (ret_val);
2132 }