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