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