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