xref: /titanic_50/usr/src/common/unicode/u8_textprep.c (revision c9a6ea2e938727c95af7108c5e00eee4c890c7ae)
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 }
2133