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