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