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