mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 23:00:07 +00:00
ChangeLog for libidn.
2004-03-07 Simon Josefsson <jas@extundo.com> * Banner: New file. * Makefile: New file. * Version: New file. * configure: New file. * idn-stub.c: New file. * gunibreak.h: New file. Copied from Libidn. * gunicomp.h: New file. Copied from Libidn. * gunidecomp.h: New file. Copied from Libidn. * idna.h: New file. Copied from Libidn. * idna.c: New file. Copied from Libidn. * nfkc.c: New file. Copied from Libidn. * profiles.c: New file. Copied from Libidn. * punycode.c: New file. Copied from Libidn. * punycode.h: New file. Copied from Libidn. * rfc3454.c: New file. Copied from Libidn. * stringprep.c: New file. Copied from Libidn. * stringprep.h: New file. Copied from Libidn. * toutf8.c: New file. Copied from Libidn. Modified for use in glibc.
This commit is contained in:
parent
001836c8c1
commit
01859b1c24
1
libidn/Banner
Normal file
1
libidn/Banner
Normal file
@ -0,0 +1 @@
|
|||||||
|
GNU Libidn by Simon Josefsson
|
20
libidn/ChangeLog
Normal file
20
libidn/ChangeLog
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
2004-03-07 Simon Josefsson <jas@extundo.com>
|
||||||
|
|
||||||
|
* Banner: New file.
|
||||||
|
* Makefile: New file.
|
||||||
|
* Version: New file.
|
||||||
|
* configure: New file.
|
||||||
|
* idn-stub.c: New file.
|
||||||
|
* gunibreak.h: New file. Copied from Libidn.
|
||||||
|
* gunicomp.h: New file. Copied from Libidn.
|
||||||
|
* gunidecomp.h: New file. Copied from Libidn.
|
||||||
|
* idna.h: New file. Copied from Libidn.
|
||||||
|
* idna.c: New file. Copied from Libidn.
|
||||||
|
* nfkc.c: New file. Copied from Libidn.
|
||||||
|
* profiles.c: New file. Copied from Libidn.
|
||||||
|
* punycode.c: New file. Copied from Libidn.
|
||||||
|
* punycode.h: New file. Copied from Libidn.
|
||||||
|
* rfc3454.c: New file. Copied from Libidn.
|
||||||
|
* stringprep.c: New file. Copied from Libidn.
|
||||||
|
* stringprep.h: New file. Copied from Libidn.
|
||||||
|
* toutf8.c: New file. Copied from Libidn. Modified for use in glibc.
|
34
libidn/Makefile
Normal file
34
libidn/Makefile
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||||
|
# This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
# The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
# The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with the GNU C Library; if not, write to the Free
|
||||||
|
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
# 02111-1307 USA.
|
||||||
|
|
||||||
|
# Makefile for libidn subdirectory of GNU C Library.
|
||||||
|
|
||||||
|
subdir := libidn
|
||||||
|
|
||||||
|
distribute := punycode.h stringprep.h idna.h
|
||||||
|
|
||||||
|
routines = idn-stub
|
||||||
|
|
||||||
|
extra-libs = libcidn
|
||||||
|
extra-libs-others = $(extra-libs)
|
||||||
|
|
||||||
|
libcidn-routines := punycode toutf8 nfkc stringprep rfc3454 profiles idna
|
||||||
|
|
||||||
|
include ../Rules
|
||||||
|
|
||||||
|
$(objpfx)libcidn.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a
|
5
libidn/Versions
Normal file
5
libidn/Versions
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
libcidn {
|
||||||
|
GLIBC_PRIVATE {
|
||||||
|
idna_to_ascii_lz;
|
||||||
|
}
|
||||||
|
}
|
2
libidn/configure
vendored
Normal file
2
libidn/configure
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# This is only to keep the GNU C library configure mechanism happy.
|
||||||
|
exit 0
|
658
libidn/gunicomp.h
Normal file
658
libidn/gunicomp.h
Normal file
@ -0,0 +1,658 @@
|
|||||||
|
#define COMPOSE_FIRST_START 1
|
||||||
|
#define COMPOSE_FIRST_SINGLE_START 147
|
||||||
|
#define COMPOSE_SECOND_START 357
|
||||||
|
#define COMPOSE_SECOND_SINGLE_START 388
|
||||||
|
|
||||||
|
#define COMPOSE_TABLE_LAST 48
|
||||||
|
|
||||||
|
static const guint16 compose_data[][256] = {
|
||||||
|
{ /* page 0, index 0 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 148, 149, 0, 0, 1, 2, 3, 4, 5,
|
||||||
|
150, 6, 7, 8, 151, 9, 10, 11, 12, 13, 14, 0, 15, 16, 17, 18, 19, 20, 21,
|
||||||
|
22, 23, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 152, 29, 30, 31, 32, 33,
|
||||||
|
34, 35, 36, 37, 38, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 153, 154,
|
||||||
|
50, 155, 0, 0, 51, 0, 0, 0, 0, 156, 0, 0, 0, 0, 52, 53, 157, 0, 158, 0,
|
||||||
|
0, 0, 54, 0, 0, 0, 0, 0, 55, 0, 159, 160, 56, 161, 0, 0, 57, 0, 0, 0, 0,
|
||||||
|
162, 0, 0, 0, 0, 58, 59, 163, 0, 164, 0, 0, 0, 60, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 1, index 1 */
|
||||||
|
0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 65, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 166, 0,
|
||||||
|
0, 0, 0, 167, 168, 0, 0, 0, 0, 0, 0, 169, 170, 171, 172, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,
|
||||||
|
68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, 0, 174,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{ /* page 2, index 2 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 178, 179, 180, 0, 0, 0, 0,
|
||||||
|
181, 182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 3, index 3 */
|
||||||
|
357, 358, 359, 360, 361, 0, 362, 363, 364, 365, 366, 367, 368, 0, 0, 369,
|
||||||
|
0, 370, 0, 371, 372, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 374,
|
||||||
|
375, 376, 377, 378, 379, 0, 0, 0, 0, 380, 381, 0, 382, 383, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 384, 0, 0, 385, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0,
|
||||||
|
72, 0, 73, 0, 74, 0, 0, 0, 0, 0, 75, 0, 184, 0, 0, 0, 76, 0, 0, 0, 77, 0,
|
||||||
|
0, 185, 0, 186, 0, 0, 78, 0, 0, 0, 79, 0, 80, 0, 81, 0, 0, 0, 0, 0, 82,
|
||||||
|
0, 83, 0, 0, 0, 84, 0, 0, 0, 85, 86, 87, 0, 0, 187, 0, 0, 0, 88, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 4, index 4 */
|
||||||
|
0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 189, 0, 90,
|
||||||
|
91, 190, 92, 0, 191, 0, 0, 0, 192, 0, 0, 0, 0, 93, 0, 0, 0, 193, 0, 0, 0,
|
||||||
|
194, 0, 195, 0, 0, 94, 0, 0, 196, 0, 95, 96, 197, 97, 0, 198, 0, 0, 0,
|
||||||
|
199, 0, 0, 0, 0, 98, 0, 0, 0, 200, 0, 0, 0, 201, 0, 202, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 207, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 208, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 6, index 5 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
210, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 388, 389, 390, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0,
|
||||||
|
0, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 9, index 6 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
216, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 391,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 11, index 7 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 394, 395, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 396, 0, 0, 0, 0, 0, 0, 0, 102, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 12, index 8 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221,
|
||||||
|
0, 0, 398, 0, 0, 0, 103, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399,
|
||||||
|
400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 13, index 9 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 0, 0, 0, 0, 0, 0, 0, 104,
|
||||||
|
223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 404, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 105, 0, 0, 224, 0, 0, 405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 16, index 10 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 30, index 11 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 226, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 229, 0, 0,
|
||||||
|
0, 0, 0, 0, 230, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 233, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 235, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 31, index 12 */
|
||||||
|
108, 109, 236, 237, 238, 239, 240, 241, 110, 111, 242, 243, 244, 245,
|
||||||
|
246, 247, 112, 113, 0, 0, 0, 0, 0, 0, 114, 115, 0, 0, 0, 0, 0, 0, 116,
|
||||||
|
117, 248, 249, 250, 251, 252, 253, 118, 119, 254, 255, 256, 257, 258,
|
||||||
|
259, 120, 121, 0, 0, 0, 0, 0, 0, 122, 123, 0, 0, 0, 0, 0, 0, 124, 125, 0,
|
||||||
|
0, 0, 0, 0, 0, 126, 127, 0, 0, 0, 0, 0, 0, 128, 129, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
130, 0, 0, 0, 0, 0, 0, 131, 132, 260, 261, 262, 263, 264, 265, 133, 134,
|
||||||
|
266, 267, 268, 269, 270, 271, 272, 0, 0, 0, 273, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0,
|
||||||
|
0, 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 277, 0, 0, 0, 0, 0, 0, 0, 136, 0
|
||||||
|
},
|
||||||
|
{ /* page 33, index 13 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
278, 0, 279, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 0, 282, 0,
|
||||||
|
283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 34, index 14 */
|
||||||
|
0, 0, 0, 284, 0, 0, 0, 0, 285, 0, 0, 286, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 287, 0, 288, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 0, 0, 0, 0, 0, 0, 290,
|
||||||
|
0, 291, 0, 0, 292, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 294, 0, 0, 295, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 297, 298, 0, 0, 299, 300, 0, 0, 301, 302, 303, 304, 0, 0, 0, 0,
|
||||||
|
305, 306, 0, 0, 307, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 309, 310, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, 312, 313, 0, 314,
|
||||||
|
0, 0, 0, 0, 0, 0, 315, 316, 317, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ /* page 48, index 15 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319, 0,
|
||||||
|
0, 0, 0, 320, 0, 321, 0, 322, 0, 323, 0, 324, 0, 325, 0, 326, 0, 327, 0,
|
||||||
|
328, 0, 329, 0, 330, 0, 331, 0, 0, 332, 0, 333, 0, 334, 0, 0, 0, 0, 0, 0,
|
||||||
|
137, 0, 0, 138, 0, 0, 139, 0, 0, 140, 0, 0, 141, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 386, 387,
|
||||||
|
0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 0, 336, 0, 0, 0, 0, 337, 0, 338, 0, 339,
|
||||||
|
0, 340, 0, 341, 0, 342, 0, 343, 0, 344, 0, 345, 0, 346, 0, 347, 0, 348,
|
||||||
|
0, 0, 349, 0, 350, 0, 351, 0, 0, 0, 0, 0, 0, 142, 0, 0, 143, 0, 0, 144,
|
||||||
|
0, 0, 145, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 352, 353, 354, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 356, 0, 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const gint16 compose_table[COMPOSE_TABLE_LAST + 1] = {
|
||||||
|
0 /* page 0 */,
|
||||||
|
1 /* page 1 */,
|
||||||
|
2 /* page 2 */,
|
||||||
|
3 /* page 3 */,
|
||||||
|
4 /* page 4 */,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
5 /* page 6 */,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
6 /* page 9 */,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
7 /* page 11 */,
|
||||||
|
8 /* page 12 */,
|
||||||
|
9 /* page 13 */,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
10 /* page 16 */,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
11 /* page 30 */,
|
||||||
|
12 /* page 31 */,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
13 /* page 33 */,
|
||||||
|
14 /* page 34 */,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
0 + G_UNICODE_MAX_TABLE_INDEX,
|
||||||
|
15 /* page 48 */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const guint16 compose_first_single[][2] = {
|
||||||
|
{ 0x0338, 0x226e },
|
||||||
|
{ 0x0338, 0x2260 },
|
||||||
|
{ 0x0338, 0x226f },
|
||||||
|
{ 0x0307, 0x1e1e },
|
||||||
|
{ 0x0302, 0x0134 },
|
||||||
|
{ 0x0307, 0x1e1f },
|
||||||
|
{ 0x0304, 0x01de },
|
||||||
|
{ 0x0301, 0x01fa },
|
||||||
|
{ 0x0301, 0x1e08 },
|
||||||
|
{ 0x0301, 0x1e2e },
|
||||||
|
{ 0x0304, 0x022a },
|
||||||
|
{ 0x0301, 0x01fe },
|
||||||
|
{ 0x0304, 0x01df },
|
||||||
|
{ 0x0301, 0x01fb },
|
||||||
|
{ 0x0301, 0x1e09 },
|
||||||
|
{ 0x0301, 0x1e2f },
|
||||||
|
{ 0x0304, 0x022b },
|
||||||
|
{ 0x0301, 0x01ff },
|
||||||
|
{ 0x0307, 0x1e64 },
|
||||||
|
{ 0x0307, 0x1e65 },
|
||||||
|
{ 0x0307, 0x1e66 },
|
||||||
|
{ 0x0307, 0x1e67 },
|
||||||
|
{ 0x0301, 0x1e78 },
|
||||||
|
{ 0x0301, 0x1e79 },
|
||||||
|
{ 0x0308, 0x1e7a },
|
||||||
|
{ 0x0308, 0x1e7b },
|
||||||
|
{ 0x0307, 0x1e9b },
|
||||||
|
{ 0x030c, 0x01ee },
|
||||||
|
{ 0x0304, 0x01ec },
|
||||||
|
{ 0x0304, 0x01ed },
|
||||||
|
{ 0x0304, 0x01e0 },
|
||||||
|
{ 0x0304, 0x01e1 },
|
||||||
|
{ 0x0306, 0x1e1c },
|
||||||
|
{ 0x0306, 0x1e1d },
|
||||||
|
{ 0x0304, 0x0230 },
|
||||||
|
{ 0x0304, 0x0231 },
|
||||||
|
{ 0x030c, 0x01ef },
|
||||||
|
{ 0x0314, 0x1fec },
|
||||||
|
{ 0x0345, 0x1fb4 },
|
||||||
|
{ 0x0345, 0x1fc4 },
|
||||||
|
{ 0x0345, 0x1ff4 },
|
||||||
|
{ 0x0308, 0x0407 },
|
||||||
|
{ 0x0301, 0x0403 },
|
||||||
|
{ 0x0308, 0x04de },
|
||||||
|
{ 0x0301, 0x040c },
|
||||||
|
{ 0x0308, 0x04e6 },
|
||||||
|
{ 0x0308, 0x04f4 },
|
||||||
|
{ 0x0308, 0x04f8 },
|
||||||
|
{ 0x0308, 0x04ec },
|
||||||
|
{ 0x0301, 0x0453 },
|
||||||
|
{ 0x0308, 0x04df },
|
||||||
|
{ 0x0301, 0x045c },
|
||||||
|
{ 0x0308, 0x04e7 },
|
||||||
|
{ 0x0308, 0x04f5 },
|
||||||
|
{ 0x0308, 0x04f9 },
|
||||||
|
{ 0x0308, 0x04ed },
|
||||||
|
{ 0x0308, 0x0457 },
|
||||||
|
{ 0x030f, 0x0476 },
|
||||||
|
{ 0x030f, 0x0477 },
|
||||||
|
{ 0x0308, 0x04da },
|
||||||
|
{ 0x0308, 0x04db },
|
||||||
|
{ 0x0308, 0x04ea },
|
||||||
|
{ 0x0308, 0x04eb },
|
||||||
|
{ 0x0654, 0x0624 },
|
||||||
|
{ 0x0654, 0x0626 },
|
||||||
|
{ 0x0654, 0x06c2 },
|
||||||
|
{ 0x0654, 0x06d3 },
|
||||||
|
{ 0x0654, 0x06c0 },
|
||||||
|
{ 0x093c, 0x0929 },
|
||||||
|
{ 0x093c, 0x0931 },
|
||||||
|
{ 0x093c, 0x0934 },
|
||||||
|
{ 0x0bd7, 0x0b94 },
|
||||||
|
{ 0x0bbe, 0x0bcb },
|
||||||
|
{ 0x0c56, 0x0c48 },
|
||||||
|
{ 0x0cd5, 0x0cc0 },
|
||||||
|
{ 0x0cd5, 0x0ccb },
|
||||||
|
{ 0x0d3e, 0x0d4b },
|
||||||
|
{ 0x0dca, 0x0ddd },
|
||||||
|
{ 0x102e, 0x1026 },
|
||||||
|
{ 0x0304, 0x1e38 },
|
||||||
|
{ 0x0304, 0x1e39 },
|
||||||
|
{ 0x0304, 0x1e5c },
|
||||||
|
{ 0x0304, 0x1e5d },
|
||||||
|
{ 0x0307, 0x1e68 },
|
||||||
|
{ 0x0307, 0x1e69 },
|
||||||
|
{ 0x0302, 0x1ec6 },
|
||||||
|
{ 0x0302, 0x1ec7 },
|
||||||
|
{ 0x0302, 0x1ed8 },
|
||||||
|
{ 0x0302, 0x1ed9 },
|
||||||
|
{ 0x0345, 0x1f82 },
|
||||||
|
{ 0x0345, 0x1f83 },
|
||||||
|
{ 0x0345, 0x1f84 },
|
||||||
|
{ 0x0345, 0x1f85 },
|
||||||
|
{ 0x0345, 0x1f86 },
|
||||||
|
{ 0x0345, 0x1f87 },
|
||||||
|
{ 0x0345, 0x1f8a },
|
||||||
|
{ 0x0345, 0x1f8b },
|
||||||
|
{ 0x0345, 0x1f8c },
|
||||||
|
{ 0x0345, 0x1f8d },
|
||||||
|
{ 0x0345, 0x1f8e },
|
||||||
|
{ 0x0345, 0x1f8f },
|
||||||
|
{ 0x0345, 0x1f92 },
|
||||||
|
{ 0x0345, 0x1f93 },
|
||||||
|
{ 0x0345, 0x1f94 },
|
||||||
|
{ 0x0345, 0x1f95 },
|
||||||
|
{ 0x0345, 0x1f96 },
|
||||||
|
{ 0x0345, 0x1f97 },
|
||||||
|
{ 0x0345, 0x1f9a },
|
||||||
|
{ 0x0345, 0x1f9b },
|
||||||
|
{ 0x0345, 0x1f9c },
|
||||||
|
{ 0x0345, 0x1f9d },
|
||||||
|
{ 0x0345, 0x1f9e },
|
||||||
|
{ 0x0345, 0x1f9f },
|
||||||
|
{ 0x0345, 0x1fa2 },
|
||||||
|
{ 0x0345, 0x1fa3 },
|
||||||
|
{ 0x0345, 0x1fa4 },
|
||||||
|
{ 0x0345, 0x1fa5 },
|
||||||
|
{ 0x0345, 0x1fa6 },
|
||||||
|
{ 0x0345, 0x1fa7 },
|
||||||
|
{ 0x0345, 0x1faa },
|
||||||
|
{ 0x0345, 0x1fab },
|
||||||
|
{ 0x0345, 0x1fac },
|
||||||
|
{ 0x0345, 0x1fad },
|
||||||
|
{ 0x0345, 0x1fae },
|
||||||
|
{ 0x0345, 0x1faf },
|
||||||
|
{ 0x0345, 0x1fb2 },
|
||||||
|
{ 0x0345, 0x1fc2 },
|
||||||
|
{ 0x0345, 0x1ff2 },
|
||||||
|
{ 0x0345, 0x1fb7 },
|
||||||
|
{ 0x0345, 0x1fc7 },
|
||||||
|
{ 0x0345, 0x1ff7 },
|
||||||
|
{ 0x0338, 0x219a },
|
||||||
|
{ 0x0338, 0x219b },
|
||||||
|
{ 0x0338, 0x21ae },
|
||||||
|
{ 0x0338, 0x21cd },
|
||||||
|
{ 0x0338, 0x21cf },
|
||||||
|
{ 0x0338, 0x21ce },
|
||||||
|
{ 0x0338, 0x2204 },
|
||||||
|
{ 0x0338, 0x2209 },
|
||||||
|
{ 0x0338, 0x220c },
|
||||||
|
{ 0x0338, 0x2224 },
|
||||||
|
{ 0x0338, 0x2226 },
|
||||||
|
{ 0x0338, 0x2241 },
|
||||||
|
{ 0x0338, 0x2244 },
|
||||||
|
{ 0x0338, 0x2247 },
|
||||||
|
{ 0x0338, 0x2249 },
|
||||||
|
{ 0x0338, 0x226d },
|
||||||
|
{ 0x0338, 0x2262 },
|
||||||
|
{ 0x0338, 0x2270 },
|
||||||
|
{ 0x0338, 0x2271 },
|
||||||
|
{ 0x0338, 0x2274 },
|
||||||
|
{ 0x0338, 0x2275 },
|
||||||
|
{ 0x0338, 0x2278 },
|
||||||
|
{ 0x0338, 0x2279 },
|
||||||
|
{ 0x0338, 0x2280 },
|
||||||
|
{ 0x0338, 0x2281 },
|
||||||
|
{ 0x0338, 0x22e0 },
|
||||||
|
{ 0x0338, 0x22e1 },
|
||||||
|
{ 0x0338, 0x2284 },
|
||||||
|
{ 0x0338, 0x2285 },
|
||||||
|
{ 0x0338, 0x2288 },
|
||||||
|
{ 0x0338, 0x2289 },
|
||||||
|
{ 0x0338, 0x22e2 },
|
||||||
|
{ 0x0338, 0x22e3 },
|
||||||
|
{ 0x0338, 0x22ac },
|
||||||
|
{ 0x0338, 0x22ad },
|
||||||
|
{ 0x0338, 0x22ae },
|
||||||
|
{ 0x0338, 0x22af },
|
||||||
|
{ 0x0338, 0x22ea },
|
||||||
|
{ 0x0338, 0x22eb },
|
||||||
|
{ 0x0338, 0x22ec },
|
||||||
|
{ 0x0338, 0x22ed },
|
||||||
|
{ 0x3099, 0x3094 },
|
||||||
|
{ 0x3099, 0x304c },
|
||||||
|
{ 0x3099, 0x304e },
|
||||||
|
{ 0x3099, 0x3050 },
|
||||||
|
{ 0x3099, 0x3052 },
|
||||||
|
{ 0x3099, 0x3054 },
|
||||||
|
{ 0x3099, 0x3056 },
|
||||||
|
{ 0x3099, 0x3058 },
|
||||||
|
{ 0x3099, 0x305a },
|
||||||
|
{ 0x3099, 0x305c },
|
||||||
|
{ 0x3099, 0x305e },
|
||||||
|
{ 0x3099, 0x3060 },
|
||||||
|
{ 0x3099, 0x3062 },
|
||||||
|
{ 0x3099, 0x3065 },
|
||||||
|
{ 0x3099, 0x3067 },
|
||||||
|
{ 0x3099, 0x3069 },
|
||||||
|
{ 0x3099, 0x309e },
|
||||||
|
{ 0x3099, 0x30f4 },
|
||||||
|
{ 0x3099, 0x30ac },
|
||||||
|
{ 0x3099, 0x30ae },
|
||||||
|
{ 0x3099, 0x30b0 },
|
||||||
|
{ 0x3099, 0x30b2 },
|
||||||
|
{ 0x3099, 0x30b4 },
|
||||||
|
{ 0x3099, 0x30b6 },
|
||||||
|
{ 0x3099, 0x30b8 },
|
||||||
|
{ 0x3099, 0x30ba },
|
||||||
|
{ 0x3099, 0x30bc },
|
||||||
|
{ 0x3099, 0x30be },
|
||||||
|
{ 0x3099, 0x30c0 },
|
||||||
|
{ 0x3099, 0x30c2 },
|
||||||
|
{ 0x3099, 0x30c5 },
|
||||||
|
{ 0x3099, 0x30c7 },
|
||||||
|
{ 0x3099, 0x30c9 },
|
||||||
|
{ 0x3099, 0x30f7 },
|
||||||
|
{ 0x3099, 0x30f8 },
|
||||||
|
{ 0x3099, 0x30f9 },
|
||||||
|
{ 0x3099, 0x30fa },
|
||||||
|
{ 0x3099, 0x30fe }
|
||||||
|
};
|
||||||
|
static const guint16 compose_second_single[][2] = {
|
||||||
|
{ 0x0627, 0x0622 },
|
||||||
|
{ 0x0627, 0x0623 },
|
||||||
|
{ 0x0627, 0x0625 },
|
||||||
|
{ 0x09c7, 0x09cb },
|
||||||
|
{ 0x09c7, 0x09cc },
|
||||||
|
{ 0x0b47, 0x0b4b },
|
||||||
|
{ 0x0b47, 0x0b48 },
|
||||||
|
{ 0x0b47, 0x0b4c },
|
||||||
|
{ 0x0bc6, 0x0bca },
|
||||||
|
{ 0x0bc6, 0x0bcc },
|
||||||
|
{ 0x0cc6, 0x0cca },
|
||||||
|
{ 0x0cc6, 0x0cc7 },
|
||||||
|
{ 0x0cc6, 0x0cc8 },
|
||||||
|
{ 0x0d46, 0x0d4a },
|
||||||
|
{ 0x0d46, 0x0d4c },
|
||||||
|
{ 0x0dd9, 0x0dda },
|
||||||
|
{ 0x0dd9, 0x0ddc },
|
||||||
|
{ 0x0dd9, 0x0dde }
|
||||||
|
};
|
||||||
|
static const guint16 compose_array[146][31] = {
|
||||||
|
{ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x0100, 0x0102, 0x0226, 0x00c4, 0x1ea2, 0x00c5, 0, 0x01cd, 0x0200, 0x0202, 0, 0, 0, 0x1ea0, 0, 0x1e00, 0, 0, 0x0104, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0x1e02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e04, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e06, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x0106, 0x0108, 0, 0, 0, 0x010a, 0, 0, 0, 0, 0x010c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00c7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0x1e0a, 0, 0, 0, 0, 0x010e, 0, 0, 0, 0, 0, 0x1e0c, 0, 0, 0, 0x1e10, 0, 0x1e12, 0, 0, 0x1e0e, 0, 0, 0, 0 },
|
||||||
|
{ 0x00c8, 0x00c9, 0x00ca, 0x1ebc, 0x0112, 0x0114, 0x0116, 0x00cb, 0x1eba, 0, 0, 0x011a, 0x0204, 0x0206, 0, 0, 0, 0x1eb8, 0, 0, 0, 0x0228, 0x0118, 0x1e18, 0, 0x1e1a, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x01f4, 0x011c, 0, 0x1e20, 0x011e, 0x0120, 0, 0, 0, 0, 0x01e6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0122, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0x0124, 0, 0, 0, 0x1e22, 0x1e26, 0, 0, 0, 0x021e, 0, 0, 0, 0, 0, 0x1e24, 0, 0, 0, 0x1e28, 0, 0, 0x1e2a, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x00cc, 0x00cd, 0x00ce, 0x0128, 0x012a, 0x012c, 0x0130, 0x00cf, 0x1ec8, 0, 0, 0x01cf, 0x0208, 0x020a, 0, 0, 0, 0x1eca, 0, 0, 0, 0, 0x012e, 0, 0, 0x1e2c, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x1e30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01e8, 0, 0, 0, 0, 0, 0x1e32, 0, 0, 0, 0x0136, 0, 0, 0, 0, 0x1e34, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x0139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x013d, 0, 0, 0, 0, 0, 0x1e36, 0, 0, 0, 0x013b, 0, 0x1e3c, 0, 0, 0x1e3a, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x1e3e, 0, 0, 0, 0, 0x1e40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x01f8, 0x0143, 0, 0x00d1, 0, 0, 0x1e44, 0, 0, 0, 0, 0x0147, 0, 0, 0, 0, 0, 0x1e46, 0, 0, 0, 0x0145, 0, 0x1e4a, 0, 0, 0x1e48, 0, 0, 0, 0 },
|
||||||
|
{ 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x014c, 0x014e, 0x022e, 0x00d6, 0x1ece, 0, 0x0150, 0x01d1, 0x020c, 0x020e, 0, 0, 0x01a0, 0x1ecc, 0, 0, 0, 0, 0x01ea, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x1e54, 0, 0, 0, 0, 0x1e56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x0154, 0, 0, 0, 0, 0x1e58, 0, 0, 0, 0, 0x0158, 0x0210, 0x0212, 0, 0, 0, 0x1e5a, 0, 0, 0, 0x0156, 0, 0, 0, 0, 0x1e5e, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x015a, 0x015c, 0, 0, 0, 0x1e60, 0, 0, 0, 0, 0x0160, 0, 0, 0, 0, 0, 0x1e62, 0, 0, 0x0218, 0x015e, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0x1e6a, 0, 0, 0, 0, 0x0164, 0, 0, 0, 0, 0, 0x1e6c, 0, 0, 0x021a, 0x0162, 0, 0x1e70, 0, 0, 0x1e6e, 0, 0, 0, 0 },
|
||||||
|
{ 0x00d9, 0x00da, 0x00db, 0x0168, 0x016a, 0x016c, 0, 0x00dc, 0x1ee6, 0x016e, 0x0170, 0x01d3, 0x0214, 0x0216, 0, 0, 0x01af, 0x1ee4, 0x1e72, 0, 0, 0, 0x0172, 0x1e76, 0, 0x1e74, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0x1e7c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e7e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1e80, 0x1e82, 0x0174, 0, 0, 0, 0x1e86, 0x1e84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0x1e8a, 0x1e8c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1ef2, 0x00dd, 0x0176, 0x1ef8, 0x0232, 0, 0x1e8e, 0x0178, 0x1ef6, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ef4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x0179, 0x1e90, 0, 0, 0, 0x017b, 0, 0, 0, 0, 0x017d, 0, 0, 0, 0, 0, 0x1e92, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e94, 0, 0, 0, 0 },
|
||||||
|
{ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x0101, 0x0103, 0x0227, 0x00e4, 0x1ea3, 0x00e5, 0, 0x01ce, 0x0201, 0x0203, 0, 0, 0, 0x1ea1, 0, 0x1e01, 0, 0, 0x0105, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0x1e03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e05, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e07, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x0107, 0x0109, 0, 0, 0, 0x010b, 0, 0, 0, 0, 0x010d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00e7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0x1e0b, 0, 0, 0, 0, 0x010f, 0, 0, 0, 0, 0, 0x1e0d, 0, 0, 0, 0x1e11, 0, 0x1e13, 0, 0, 0x1e0f, 0, 0, 0, 0 },
|
||||||
|
{ 0x00e8, 0x00e9, 0x00ea, 0x1ebd, 0x0113, 0x0115, 0x0117, 0x00eb, 0x1ebb, 0, 0, 0x011b, 0x0205, 0x0207, 0, 0, 0, 0x1eb9, 0, 0, 0, 0x0229, 0x0119, 0x1e19, 0, 0x1e1b, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x01f5, 0x011d, 0, 0x1e21, 0x011f, 0x0121, 0, 0, 0, 0, 0x01e7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0123, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0x0125, 0, 0, 0, 0x1e23, 0x1e27, 0, 0, 0, 0x021f, 0, 0, 0, 0, 0, 0x1e25, 0, 0, 0, 0x1e29, 0, 0, 0x1e2b, 0, 0x1e96, 0, 0, 0, 0 },
|
||||||
|
{ 0x00ec, 0x00ed, 0x00ee, 0x0129, 0x012b, 0x012d, 0, 0x00ef, 0x1ec9, 0, 0, 0x01d0, 0x0209, 0x020b, 0, 0, 0, 0x1ecb, 0, 0, 0, 0, 0x012f, 0, 0, 0x1e2d, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0x0135, 0, 0, 0, 0, 0, 0, 0, 0, 0x01f0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x1e31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01e9, 0, 0, 0, 0, 0, 0x1e33, 0, 0, 0, 0x0137, 0, 0, 0, 0, 0x1e35, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x013a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x013e, 0, 0, 0, 0, 0, 0x1e37, 0, 0, 0, 0x013c, 0, 0x1e3d, 0, 0, 0x1e3b, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x1e3f, 0, 0, 0, 0, 0x1e41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x01f9, 0x0144, 0, 0x00f1, 0, 0, 0x1e45, 0, 0, 0, 0, 0x0148, 0, 0, 0, 0, 0, 0x1e47, 0, 0, 0, 0x0146, 0, 0x1e4b, 0, 0, 0x1e49, 0, 0, 0, 0 },
|
||||||
|
{ 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x014d, 0x014f, 0x022f, 0x00f6, 0x1ecf, 0, 0x0151, 0x01d2, 0x020d, 0x020f, 0, 0, 0x01a1, 0x1ecd, 0, 0, 0, 0, 0x01eb, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x1e55, 0, 0, 0, 0, 0x1e57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x0155, 0, 0, 0, 0, 0x1e59, 0, 0, 0, 0, 0x0159, 0x0211, 0x0213, 0, 0, 0, 0x1e5b, 0, 0, 0, 0x0157, 0, 0, 0, 0, 0x1e5f, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x015b, 0x015d, 0, 0, 0, 0x1e61, 0, 0, 0, 0, 0x0161, 0, 0, 0, 0, 0, 0x1e63, 0, 0, 0x0219, 0x015f, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0x1e6b, 0x1e97, 0, 0, 0, 0x0165, 0, 0, 0, 0, 0, 0x1e6d, 0, 0, 0x021b, 0x0163, 0, 0x1e71, 0, 0, 0x1e6f, 0, 0, 0, 0 },
|
||||||
|
{ 0x00f9, 0x00fa, 0x00fb, 0x0169, 0x016b, 0x016d, 0, 0x00fc, 0x1ee7, 0x016f, 0x0171, 0x01d4, 0x0215, 0x0217, 0, 0, 0x01b0, 0x1ee5, 0x1e73, 0, 0, 0, 0x0173, 0x1e77, 0, 0x1e75, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0x1e7d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e7f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1e81, 0x1e83, 0x0175, 0, 0, 0, 0x1e87, 0x1e85, 0, 0x1e98, 0, 0, 0, 0, 0, 0, 0, 0x1e89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0x1e8b, 0x1e8d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1ef3, 0x00fd, 0x0177, 0x1ef9, 0x0233, 0, 0x1e8f, 0x00ff, 0x1ef7, 0x1e99, 0, 0, 0, 0, 0, 0, 0, 0x1ef5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x017a, 0x1e91, 0, 0, 0, 0x017c, 0, 0, 0, 0, 0x017e, 0, 0, 0, 0, 0, 0x1e93, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e95, 0, 0, 0, 0 },
|
||||||
|
{ 0x1fed, 0x0385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fc1, 0, 0, 0 },
|
||||||
|
{ 0x1ea6, 0x1ea4, 0, 0x1eaa, 0, 0, 0, 0, 0x1ea8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x01fc, 0, 0, 0x01e2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1ec0, 0x1ebe, 0, 0x1ec4, 0, 0, 0, 0, 0x1ec2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1ed2, 0x1ed0, 0, 0x1ed6, 0, 0, 0, 0, 0x1ed4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x1e4c, 0, 0, 0x022c, 0, 0, 0x1e4e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x01db, 0x01d7, 0, 0, 0x01d5, 0, 0, 0, 0, 0, 0, 0x01d9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1ea7, 0x1ea5, 0, 0x1eab, 0, 0, 0, 0, 0x1ea9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x01fd, 0, 0, 0x01e3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1ec1, 0x1ebf, 0, 0x1ec5, 0, 0, 0, 0, 0x1ec3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1ed3, 0x1ed1, 0, 0x1ed7, 0, 0, 0, 0, 0x1ed5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0x1e4d, 0, 0, 0x022d, 0, 0, 0x1e4f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x01dc, 0x01d8, 0, 0, 0x01d6, 0, 0, 0, 0, 0, 0, 0x01da, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1eb0, 0x1eae, 0, 0x1eb4, 0, 0, 0, 0, 0x1eb2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1eb1, 0x1eaf, 0, 0x1eb5, 0, 0, 0, 0, 0x1eb3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1e14, 0x1e16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1e15, 0x1e17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1e50, 0x1e52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1e51, 0x1e53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1edc, 0x1eda, 0, 0x1ee0, 0, 0, 0, 0, 0x1ede, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ee2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1edd, 0x1edb, 0, 0x1ee1, 0, 0, 0, 0, 0x1edf, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ee3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1eea, 0x1ee8, 0, 0x1eee, 0, 0, 0, 0, 0x1eec, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ef0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1eeb, 0x1ee9, 0, 0x1eef, 0, 0, 0, 0, 0x1eed, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ef1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1fba, 0x0386, 0, 0, 0x1fb9, 0x1fb8, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f08, 0x1f09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fbc, 0, 0 },
|
||||||
|
{ 0x1fc8, 0x0388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f18, 0x1f19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1fca, 0x0389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f28, 0x1f29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fcc, 0, 0 },
|
||||||
|
{ 0x1fda, 0x038a, 0, 0, 0x1fd9, 0x1fd8, 0, 0x03aa, 0, 0, 0, 0, 0, 0, 0x1f38, 0x1f39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1ff8, 0x038c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f48, 0x1f49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1fea, 0x038e, 0, 0, 0x1fe9, 0x1fe8, 0, 0x03ab, 0, 0, 0, 0, 0, 0, 0, 0x1f59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1ffa, 0x038f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f68, 0x1f69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ffc, 0, 0 },
|
||||||
|
{ 0x1f70, 0x03ac, 0, 0, 0x1fb1, 0x1fb0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f00, 0x1f01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fb6, 0x1fb3, 0, 0 },
|
||||||
|
{ 0x1f72, 0x03ad, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f10, 0x1f11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f74, 0x03ae, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f20, 0x1f21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fc6, 0x1fc3, 0, 0 },
|
||||||
|
{ 0x1f76, 0x03af, 0, 0, 0x1fd1, 0x1fd0, 0, 0x03ca, 0, 0, 0, 0, 0, 0, 0x1f30, 0x1f31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fd6, 0, 0, 0 },
|
||||||
|
{ 0x1f78, 0x03cc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f40, 0x1f41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fe4, 0x1fe5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f7a, 0x03cd, 0, 0, 0x1fe1, 0x1fe0, 0, 0x03cb, 0, 0, 0, 0, 0, 0, 0x1f50, 0x1f51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fe6, 0, 0, 0 },
|
||||||
|
{ 0x1f7c, 0x03ce, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f60, 0x1f61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ff6, 0x1ff3, 0, 0 },
|
||||||
|
{ 0x1fd2, 0x0390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fd7, 0, 0, 0 },
|
||||||
|
{ 0x1fe2, 0x03b0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fe7, 0, 0, 0 },
|
||||||
|
{ 0, 0x03d3, 0, 0, 0, 0, 0, 0x03d4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0x04d0, 0, 0x04d2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x0400, 0, 0, 0, 0, 0x04d6, 0, 0x0401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0x04c1, 0, 0x04dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x040d, 0, 0, 0, 0x04e2, 0x0419, 0, 0x04e4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0x04ee, 0x040e, 0, 0x04f0, 0, 0, 0x04f2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0x04d1, 0, 0x04d3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x0450, 0, 0, 0, 0, 0x04d7, 0, 0x0451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0x04c2, 0, 0x04dd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x045d, 0, 0, 0, 0x04e3, 0x0439, 0, 0x04e5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0x04ef, 0x045e, 0, 0x04f1, 0, 0, 0x04f3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0x1eac, 0, 0, 0x1eb6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0x1ead, 0, 0, 0x1eb7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f02, 0x1f04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f06, 0x1f80, 0, 0 },
|
||||||
|
{ 0x1f03, 0x1f05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f07, 0x1f81, 0, 0 },
|
||||||
|
{ 0x1f0a, 0x1f0c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f0e, 0x1f88, 0, 0 },
|
||||||
|
{ 0x1f0b, 0x1f0d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f0f, 0x1f89, 0, 0 },
|
||||||
|
{ 0x1f12, 0x1f14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f13, 0x1f15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f1a, 0x1f1c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f1b, 0x1f1d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f22, 0x1f24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f26, 0x1f90, 0, 0 },
|
||||||
|
{ 0x1f23, 0x1f25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f27, 0x1f91, 0, 0 },
|
||||||
|
{ 0x1f2a, 0x1f2c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f2e, 0x1f98, 0, 0 },
|
||||||
|
{ 0x1f2b, 0x1f2d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f2f, 0x1f99, 0, 0 },
|
||||||
|
{ 0x1f32, 0x1f34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f36, 0, 0, 0 },
|
||||||
|
{ 0x1f33, 0x1f35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f37, 0, 0, 0 },
|
||||||
|
{ 0x1f3a, 0x1f3c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f3e, 0, 0, 0 },
|
||||||
|
{ 0x1f3b, 0x1f3d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f3f, 0, 0, 0 },
|
||||||
|
{ 0x1f42, 0x1f44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f43, 0x1f45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f4a, 0x1f4c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f4b, 0x1f4d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0x1f52, 0x1f54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f56, 0, 0, 0 },
|
||||||
|
{ 0x1f53, 0x1f55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f57, 0, 0, 0 },
|
||||||
|
{ 0x1f5b, 0x1f5d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f5f, 0, 0, 0 },
|
||||||
|
{ 0x1f62, 0x1f64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f66, 0x1fa0, 0, 0 },
|
||||||
|
{ 0x1f63, 0x1f65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f67, 0x1fa1, 0, 0 },
|
||||||
|
{ 0x1f6a, 0x1f6c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f6e, 0x1fa8, 0, 0 },
|
||||||
|
{ 0x1f6b, 0x1f6d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f6f, 0x1fa9, 0, 0 },
|
||||||
|
{ 0x1fcd, 0x1fce, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fcf, 0, 0, 0 },
|
||||||
|
{ 0x1fdd, 0x1fde, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fdf, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3070, 0x3071 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3073, 0x3074 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3076, 0x3077 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3079, 0x307a },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x307c, 0x307d },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30d0, 0x30d1 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30d3, 0x30d4 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30d6, 0x30d7 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30d9, 0x30da },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30dc, 0x30dd }
|
||||||
|
};
|
10362
libidn/gunidecomp.h
Normal file
10362
libidn/gunidecomp.h
Normal file
File diff suppressed because it is too large
Load Diff
286
libidn/idn-int.h
Normal file
286
libidn/idn-int.h
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
#ifndef _LIBIDN_LIB_IDN_INT_H
|
||||||
|
#define _LIBIDN_LIB_IDN_INT_H 1
|
||||||
|
#ifndef _GENERATED_STDINT_H
|
||||||
|
#define _GENERATED_STDINT_H "libidn 0.3.5"
|
||||||
|
/* generated using gnu compiler gcc (GCC) 3.3.2 (Debian) */
|
||||||
|
#define _STDINT_HAVE_STDINT_H 1
|
||||||
|
|
||||||
|
/* ................... shortcircuit part ........................... */
|
||||||
|
|
||||||
|
#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
|
||||||
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* .................... configured part ............................ */
|
||||||
|
|
||||||
|
/* whether we have a C99 compatible stdint header file */
|
||||||
|
/* #undef _STDINT_HEADER_INTPTR */
|
||||||
|
/* whether we have a C96 compatible inttypes header file */
|
||||||
|
/* #undef _STDINT_HEADER_UINT32 */
|
||||||
|
/* whether we have a BSD compatible inet types header */
|
||||||
|
/* #undef _STDINT_HEADER_U_INT32 */
|
||||||
|
|
||||||
|
/* which 64bit typedef has been found */
|
||||||
|
/* #undef _STDINT_HAVE_UINT64_T */
|
||||||
|
/* #undef _STDINT_HAVE_U_INT64_T */
|
||||||
|
|
||||||
|
/* which type model has been detected */
|
||||||
|
/* #undef _STDINT_CHAR_MODEL // skipped */
|
||||||
|
/* #undef _STDINT_LONG_MODEL // skipped */
|
||||||
|
|
||||||
|
/* whether int_least types were detected */
|
||||||
|
/* #undef _STDINT_HAVE_INT_LEAST32_T */
|
||||||
|
/* whether int_fast types were detected */
|
||||||
|
/* #undef _STDINT_HAVE_INT_FAST32_T */
|
||||||
|
/* whether intmax_t type was detected */
|
||||||
|
/* #undef _STDINT_HAVE_INTMAX_T */
|
||||||
|
|
||||||
|
/* .................... detections part ............................ */
|
||||||
|
|
||||||
|
/* whether we need to define bitspecific types from compiler base types */
|
||||||
|
#ifndef _STDINT_HEADER_INTPTR
|
||||||
|
#ifndef _STDINT_HEADER_UINT32
|
||||||
|
#ifndef _STDINT_HEADER_U_INT32
|
||||||
|
#define _STDINT_NEED_INT_MODEL_T
|
||||||
|
#else
|
||||||
|
#define _STDINT_HAVE_U_INT_TYPES
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _STDINT_HAVE_U_INT_TYPES
|
||||||
|
#undef _STDINT_NEED_INT_MODEL_T
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _STDINT_CHAR_MODEL
|
||||||
|
#if _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
|
||||||
|
#ifndef _STDINT_BYTE_MODEL
|
||||||
|
#define _STDINT_BYTE_MODEL 12
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _STDINT_HAVE_INT_LEAST32_T
|
||||||
|
#define _STDINT_NEED_INT_LEAST_T
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _STDINT_HAVE_INT_FAST32_T
|
||||||
|
#define _STDINT_NEED_INT_FAST_T
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _STDINT_HEADER_INTPTR
|
||||||
|
#define _STDINT_NEED_INTPTR_T
|
||||||
|
#ifndef _STDINT_HAVE_INTMAX_T
|
||||||
|
#define _STDINT_NEED_INTMAX_T
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* .................... definition part ............................ */
|
||||||
|
|
||||||
|
/* some system headers have good uint64_t */
|
||||||
|
#ifndef _HAVE_UINT64_T
|
||||||
|
#if defined _STDINT_HAVE_UINT64_T || defined HAVE_UINT64_T
|
||||||
|
#define _HAVE_UINT64_T
|
||||||
|
#elif defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
|
||||||
|
#define _HAVE_UINT64_T
|
||||||
|
typedef u_int64_t uint64_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _HAVE_UINT64_T
|
||||||
|
/* .. here are some common heuristics using compiler runtime specifics */
|
||||||
|
#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
|
||||||
|
#define _HAVE_UINT64_T
|
||||||
|
typedef long long int64_t;
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
|
||||||
|
#elif !defined __STRICT_ANSI__
|
||||||
|
#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
|
||||||
|
#define _HAVE_UINT64_T
|
||||||
|
typedef __int64 int64_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
|
||||||
|
#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
|
||||||
|
/* note: all ELF-systems seem to have loff-support which needs 64-bit */
|
||||||
|
#if !defined _NO_LONGLONG
|
||||||
|
#define _HAVE_UINT64_T
|
||||||
|
typedef long long int64_t;
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined __alpha || (defined __mips && defined _ABIN32)
|
||||||
|
#if !defined _NO_LONGLONG
|
||||||
|
typedef long int64_t;
|
||||||
|
typedef unsigned long uint64_t;
|
||||||
|
#endif
|
||||||
|
/* compiler/cpu type to define int64_t */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined _STDINT_HAVE_U_INT_TYPES
|
||||||
|
/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
|
||||||
|
typedef u_int8_t uint8_t;
|
||||||
|
typedef u_int16_t uint16_t;
|
||||||
|
typedef u_int32_t uint32_t;
|
||||||
|
|
||||||
|
/* glibc compatibility */
|
||||||
|
#ifndef __int8_t_defined
|
||||||
|
#define __int8_t_defined
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _STDINT_NEED_INT_MODEL_T
|
||||||
|
/* we must guess all the basic types. Apart from byte-adressable system, */
|
||||||
|
/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */
|
||||||
|
/* (btw, those nibble-addressable systems are way off, or so we assume) */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined _STDINT_BYTE_MODEL
|
||||||
|
#if _STDINT_LONG_MODEL+0 == 242
|
||||||
|
/* 2:4:2 = IP16 = a normal 16-bit system */
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned long uint32_t;
|
||||||
|
#ifndef __int8_t_defined
|
||||||
|
#define __int8_t_defined
|
||||||
|
typedef char int8_t;
|
||||||
|
typedef short int16_t;
|
||||||
|
typedef long int32_t;
|
||||||
|
#endif
|
||||||
|
#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444
|
||||||
|
/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */
|
||||||
|
/* 4:4:4 = ILP32 = a normal 32-bit system */
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
#ifndef __int8_t_defined
|
||||||
|
#define __int8_t_defined
|
||||||
|
typedef char int8_t;
|
||||||
|
typedef short int16_t;
|
||||||
|
typedef int int32_t;
|
||||||
|
#endif
|
||||||
|
#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488
|
||||||
|
/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */
|
||||||
|
/* 4:8:8 = LP64 = a normal 64-bit system */
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
#ifndef __int8_t_defined
|
||||||
|
#define __int8_t_defined
|
||||||
|
typedef char int8_t;
|
||||||
|
typedef short int16_t;
|
||||||
|
typedef int int32_t;
|
||||||
|
#endif
|
||||||
|
/* this system has a "long" of 64bit */
|
||||||
|
#ifndef _HAVE_UINT64_T
|
||||||
|
#define _HAVE_UINT64_T
|
||||||
|
typedef unsigned long uint64_t;
|
||||||
|
typedef long int64_t;
|
||||||
|
#endif
|
||||||
|
#elif _STDINT_LONG_MODEL+0 == 448
|
||||||
|
/* LLP64 a 64-bit system derived from a 32-bit system */
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
#ifndef __int8_t_defined
|
||||||
|
#define __int8_t_defined
|
||||||
|
typedef char int8_t;
|
||||||
|
typedef short int16_t;
|
||||||
|
typedef int int32_t;
|
||||||
|
#endif
|
||||||
|
/* assuming the system has a "long long" */
|
||||||
|
#ifndef _HAVE_UINT64_T
|
||||||
|
#define _HAVE_UINT64_T
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
typedef long long int64_t;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define _STDINT_NO_INT32_T
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define _STDINT_NO_INT8_T
|
||||||
|
#define _STDINT_NO_INT32_T
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* quote from SunOS-5.8 sys/inttypes.h:
|
||||||
|
* Use at your own risk. As of February 1996, the committee is squarely
|
||||||
|
* behind the fixed sized types; the "least" and "fast" types are still being
|
||||||
|
* discussed. The probability that the "fast" types may be removed before
|
||||||
|
* the standard is finalized is high enough that they are not currently
|
||||||
|
* implemented.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined _STDINT_NEED_INT_LEAST_T
|
||||||
|
typedef int8_t int_least8_t;
|
||||||
|
typedef int16_t int_least16_t;
|
||||||
|
typedef int32_t int_least32_t;
|
||||||
|
#ifdef _HAVE_UINT64_T
|
||||||
|
typedef int64_t int_least64_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t uint_least8_t;
|
||||||
|
typedef uint16_t uint_least16_t;
|
||||||
|
typedef uint32_t uint_least32_t;
|
||||||
|
#ifdef _HAVE_UINT64_T
|
||||||
|
typedef uint64_t uint_least64_t;
|
||||||
|
#endif
|
||||||
|
/* least types */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined _STDINT_NEED_INT_FAST_T
|
||||||
|
typedef int8_t int_fast8_t;
|
||||||
|
typedef int int_fast16_t;
|
||||||
|
typedef int32_t int_fast32_t;
|
||||||
|
#ifdef _HAVE_UINT64_T
|
||||||
|
typedef int64_t int_fast64_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t uint_fast8_t;
|
||||||
|
typedef unsigned uint_fast16_t;
|
||||||
|
typedef uint32_t uint_fast32_t;
|
||||||
|
#ifdef _HAVE_UINT64_T
|
||||||
|
typedef uint64_t uint_fast64_t;
|
||||||
|
#endif
|
||||||
|
/* fast types */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _STDINT_NEED_INTMAX_T
|
||||||
|
#ifdef _HAVE_UINT64_T
|
||||||
|
typedef int64_t intmax_t;
|
||||||
|
typedef uint64_t uintmax_t;
|
||||||
|
#else
|
||||||
|
typedef long intmax_t;
|
||||||
|
typedef unsigned long uintmax_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _STDINT_NEED_INTPTR_T
|
||||||
|
#ifndef __intptr_t_defined
|
||||||
|
#define __intptr_t_defined
|
||||||
|
/* we encourage using "long" to store pointer values, never use "int" ! */
|
||||||
|
#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484
|
||||||
|
typedef unsinged int uintptr_t;
|
||||||
|
typedef int intptr_t;
|
||||||
|
#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444
|
||||||
|
typedef unsigned long uintptr_t;
|
||||||
|
typedef long intptr_t;
|
||||||
|
#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T
|
||||||
|
typedef uint64_t uintptr_t;
|
||||||
|
typedef int64_t intptr_t;
|
||||||
|
#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */
|
||||||
|
typedef unsigned long uintptr_t;
|
||||||
|
typedef long intptr_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* shortcircuit*/
|
||||||
|
#endif
|
||||||
|
/* once */
|
||||||
|
#endif
|
||||||
|
#endif
|
86
libidn/idn-stub.c
Normal file
86
libidn/idn-stub.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/* idn-stub.c --- Stub to dlopen libcidn.so and invoke idna_to_ascii_lz.
|
||||||
|
* Copyright (C) 2003, 2004 Simon Josefsson
|
||||||
|
*
|
||||||
|
* This file is part of GNU Libidn.
|
||||||
|
*
|
||||||
|
* GNU Libidn is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Libidn is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with GNU Libidn; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
/* Get specification for idna_to_ascii_lz. */
|
||||||
|
#include "idna.h"
|
||||||
|
|
||||||
|
/* Handle of the libidn DSO. */
|
||||||
|
static void *h;
|
||||||
|
|
||||||
|
|
||||||
|
/* Stub to dlopen libcidn.so and invoke the real idna_to_ascii_lz, or
|
||||||
|
return IDNA_DLOPEN_ERROR on failure. */
|
||||||
|
int
|
||||||
|
__idna_to_ascii_lz (const char *input, char **output, int flags)
|
||||||
|
{
|
||||||
|
/* If the input string contains no non-ASCII character the output
|
||||||
|
string will be the same. No valid locale encoding does not have
|
||||||
|
this property. */
|
||||||
|
const char *cp = input;
|
||||||
|
while (*cp != '\0' && isascii (*cp))
|
||||||
|
++cp;
|
||||||
|
|
||||||
|
if (*cp == '\0')
|
||||||
|
{
|
||||||
|
*output = strdup (input);
|
||||||
|
return *output == NULL ? IDNA_MALLOC_ERROR : IDNA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int (*to_ascii_lz) (const char *input, char **output, int flags);
|
||||||
|
|
||||||
|
if (h == NULL)
|
||||||
|
{
|
||||||
|
h = __libc_dlopen ("libcidn.so");
|
||||||
|
|
||||||
|
if (h == NULL)
|
||||||
|
h = (void *) 1l;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Get the function we are interested in. */
|
||||||
|
to_ascii_lz = __libc_dlsym (h, "idna_to_ascii_lz");
|
||||||
|
if (to_ascii_lz == NULL)
|
||||||
|
{
|
||||||
|
__libc_dlclose (h);
|
||||||
|
h = (void *) 1l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h == (void *) 1l)
|
||||||
|
return IDNA_DLOPEN_ERROR;
|
||||||
|
|
||||||
|
return to_ascii_lz (input, output, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
libc_freeres_fn (unload_libidn)
|
||||||
|
{
|
||||||
|
if (h != NULL && h != (void *) 1l)
|
||||||
|
{
|
||||||
|
__libc_dlclose (h);
|
||||||
|
h = (void *) 1l;
|
||||||
|
}
|
||||||
|
}
|
797
libidn/idna.c
Normal file
797
libidn/idna.c
Normal file
@ -0,0 +1,797 @@
|
|||||||
|
/* idna.c Convert to or from IDN strings.
|
||||||
|
* Copyright (C) 2002, 2003, 2004 Simon Josefsson
|
||||||
|
*
|
||||||
|
* This file is part of GNU Libidn.
|
||||||
|
*
|
||||||
|
* GNU Libidn is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Libidn is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with GNU Libidn; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stringprep.h>
|
||||||
|
#include <punycode.h>
|
||||||
|
|
||||||
|
#include "idna.h"
|
||||||
|
|
||||||
|
#define DOTP(c) ((c) == 0x002E || (c) == 0x3002 || \
|
||||||
|
(c) == 0xFF0E || (c) == 0xFF61)
|
||||||
|
|
||||||
|
/* Core functions */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_ascii_4i
|
||||||
|
* @in: input array with unicode code points.
|
||||||
|
* @inlen: length of input array with unicode code points.
|
||||||
|
* @out: output zero terminated string that must have room for at
|
||||||
|
* least 63 characters plus the terminating zero.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* The ToASCII operation takes a sequence of Unicode code points that make
|
||||||
|
* up one label and transforms it into a sequence of code points in the
|
||||||
|
* ASCII range (0..7F). If ToASCII succeeds, the original sequence and the
|
||||||
|
* resulting sequence are equivalent labels.
|
||||||
|
*
|
||||||
|
* It is important to note that the ToASCII operation can fail. ToASCII
|
||||||
|
* fails if any step of it fails. If any step of the ToASCII operation
|
||||||
|
* fails on any label in a domain name, that domain name MUST NOT be used
|
||||||
|
* as an internationalized domain name. The method for deadling with this
|
||||||
|
* failure is application-specific.
|
||||||
|
*
|
||||||
|
* The inputs to ToASCII are a sequence of code points, the AllowUnassigned
|
||||||
|
* flag, and the UseSTD3ASCIIRules flag. The output of ToASCII is either a
|
||||||
|
* sequence of ASCII code points or a failure condition.
|
||||||
|
*
|
||||||
|
* ToASCII never alters a sequence of code points that are all in the ASCII
|
||||||
|
* range to begin with (although it could fail). Applying the ToASCII
|
||||||
|
* operation multiple times has exactly the same effect as applying it just
|
||||||
|
* once.
|
||||||
|
*
|
||||||
|
* Return value: Returns 0 on success, or an error code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags)
|
||||||
|
{
|
||||||
|
size_t len, outlen;
|
||||||
|
uint32_t *src; /* XXX don't need to copy data? */
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ToASCII consists of the following steps:
|
||||||
|
*
|
||||||
|
* 1. If all code points in the sequence are in the ASCII range (0..7F)
|
||||||
|
* then skip to step 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
int inasciirange;
|
||||||
|
|
||||||
|
inasciirange = 1;
|
||||||
|
for (i = 0; i < inlen; i++)
|
||||||
|
if (in[i] > 0x7F)
|
||||||
|
inasciirange = 0;
|
||||||
|
if (inasciirange)
|
||||||
|
{
|
||||||
|
src = malloc (sizeof (in[0]) * (inlen + 1));
|
||||||
|
if (src == NULL)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
|
||||||
|
memcpy (src, in, sizeof (in[0]) * inlen);
|
||||||
|
src[inlen] = 0;
|
||||||
|
|
||||||
|
goto step3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2. Perform the steps specified in [NAMEPREP] and fail if there is
|
||||||
|
* an error. The AllowUnassigned flag is used in [NAMEPREP].
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = stringprep_ucs4_to_utf8 (in, inlen, NULL, NULL);
|
||||||
|
if (p == NULL)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
|
||||||
|
len = strlen (p);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
len = 2 * len + 10; /* XXX better guess? */
|
||||||
|
p = realloc (p, len);
|
||||||
|
if (p == NULL)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
|
||||||
|
if (flags & IDNA_ALLOW_UNASSIGNED)
|
||||||
|
rc = stringprep_nameprep (p, len);
|
||||||
|
else
|
||||||
|
rc = stringprep_nameprep_no_unassigned (p, len);
|
||||||
|
}
|
||||||
|
while (rc == STRINGPREP_TOO_SMALL_BUFFER);
|
||||||
|
|
||||||
|
if (rc != STRINGPREP_OK)
|
||||||
|
{
|
||||||
|
free (p);
|
||||||
|
return IDNA_STRINGPREP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = stringprep_utf8_to_ucs4 (p, -1, NULL);
|
||||||
|
|
||||||
|
free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
step3:
|
||||||
|
/*
|
||||||
|
* 3. If the UseSTD3ASCIIRules flag is set, then perform these checks:
|
||||||
|
*
|
||||||
|
* (a) Verify the absence of non-LDH ASCII code points; that is,
|
||||||
|
* the absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F.
|
||||||
|
*
|
||||||
|
* (b) Verify the absence of leading and trailing hyphen-minus;
|
||||||
|
* that is, the absence of U+002D at the beginning and end of
|
||||||
|
* the sequence.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (flags & IDNA_USE_STD3_ASCII_RULES)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; src[i]; i++)
|
||||||
|
if (src[i] <= 0x2C || src[i] == 0x2E || src[i] == 0x2F ||
|
||||||
|
(src[i] >= 0x3A && src[i] <= 0x40) ||
|
||||||
|
(src[i] >= 0x5B && src[i] <= 0x60) ||
|
||||||
|
(src[i] >= 0x7B && src[i] <= 0x7F))
|
||||||
|
{
|
||||||
|
free (src);
|
||||||
|
return IDNA_CONTAINS_NON_LDH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src[0] == 0x002D || (i > 0 && src[i - 1] == 0x002D))
|
||||||
|
{
|
||||||
|
free (src);
|
||||||
|
return IDNA_CONTAINS_MINUS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 4. If all code points in the sequence are in the ASCII range
|
||||||
|
* (0..7F), then skip to step 8.
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
int inasciirange;
|
||||||
|
|
||||||
|
inasciirange = 1;
|
||||||
|
for (i = 0; src[i]; i++)
|
||||||
|
{
|
||||||
|
if (src[i] > 0x7F)
|
||||||
|
inasciirange = 0;
|
||||||
|
/* copy string to output buffer if we are about to skip to step8 */
|
||||||
|
if (i < 64)
|
||||||
|
out[i] = src[i];
|
||||||
|
}
|
||||||
|
if (i < 64)
|
||||||
|
out[i] = '\0';
|
||||||
|
if (inasciirange)
|
||||||
|
goto step8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5. Verify that the sequence does NOT begin with the ACE prefix.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
int match;
|
||||||
|
|
||||||
|
match = 1;
|
||||||
|
for (i = 0; match && i < strlen (IDNA_ACE_PREFIX); i++)
|
||||||
|
if (((uint32_t) IDNA_ACE_PREFIX[i] & 0xFF) != src[i])
|
||||||
|
match = 0;
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
free (src);
|
||||||
|
return IDNA_CONTAINS_ACE_PREFIX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 6. Encode the sequence using the encoding algorithm in [PUNYCODE]
|
||||||
|
* and fail if there is an error.
|
||||||
|
*/
|
||||||
|
for (len = 0; src[len]; len++)
|
||||||
|
;
|
||||||
|
src[len] = '\0';
|
||||||
|
outlen = 63 - strlen (IDNA_ACE_PREFIX);
|
||||||
|
rc = punycode_encode (len, src, NULL,
|
||||||
|
&outlen, &out[strlen (IDNA_ACE_PREFIX)]);
|
||||||
|
if (rc != PUNYCODE_SUCCESS)
|
||||||
|
{
|
||||||
|
free (src);
|
||||||
|
return IDNA_PUNYCODE_ERROR;
|
||||||
|
}
|
||||||
|
out[strlen (IDNA_ACE_PREFIX) + outlen] = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 7. Prepend the ACE prefix.
|
||||||
|
*/
|
||||||
|
|
||||||
|
memcpy (out, IDNA_ACE_PREFIX, strlen (IDNA_ACE_PREFIX));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 8. Verify that the number of code points is in the range 1 to 63
|
||||||
|
* inclusive (0 is excluded).
|
||||||
|
*/
|
||||||
|
|
||||||
|
step8:
|
||||||
|
free (src);
|
||||||
|
if (strlen (out) < 1 || strlen (out) > 63)
|
||||||
|
return IDNA_INVALID_LENGTH;
|
||||||
|
|
||||||
|
return IDNA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ToUnicode(). May realloc() utf8in. */
|
||||||
|
static int
|
||||||
|
idna_to_unicode_internal (char *utf8in,
|
||||||
|
uint32_t * out, size_t * outlen, int flags)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char tmpout[64];
|
||||||
|
size_t utf8len = strlen (utf8in) + 1;
|
||||||
|
size_t addlen = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ToUnicode consists of the following steps:
|
||||||
|
*
|
||||||
|
* 1. If the sequence contains any code points outside the ASCII range
|
||||||
|
* (0..7F) then proceed to step 2, otherwise skip to step 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
int inasciirange;
|
||||||
|
|
||||||
|
inasciirange = 1;
|
||||||
|
for (i = 0; utf8in[i]; i++)
|
||||||
|
if (utf8in[i] & ~0x7F)
|
||||||
|
inasciirange = 0;
|
||||||
|
if (inasciirange)
|
||||||
|
goto step3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2. Perform the steps specified in [NAMEPREP] and fail if there is an
|
||||||
|
* error. (If step 3 of ToASCII is also performed here, it will not
|
||||||
|
* affect the overall behavior of ToUnicode, but it is not
|
||||||
|
* necessary.) The AllowUnassigned flag is used in [NAMEPREP].
|
||||||
|
*/
|
||||||
|
do
|
||||||
|
{
|
||||||
|
utf8in = realloc (utf8in, utf8len + addlen);
|
||||||
|
if (!utf8in)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
if (flags & IDNA_ALLOW_UNASSIGNED)
|
||||||
|
rc = stringprep_nameprep (utf8in, utf8len + addlen);
|
||||||
|
else
|
||||||
|
rc = stringprep_nameprep_no_unassigned (utf8in, utf8len + addlen);
|
||||||
|
addlen += 1;
|
||||||
|
}
|
||||||
|
while (rc == STRINGPREP_TOO_SMALL_BUFFER);
|
||||||
|
|
||||||
|
if (rc != STRINGPREP_OK)
|
||||||
|
return IDNA_STRINGPREP_ERROR;
|
||||||
|
|
||||||
|
/* 3. Verify that the sequence begins with the ACE prefix, and save a
|
||||||
|
* copy of the sequence.
|
||||||
|
*/
|
||||||
|
|
||||||
|
step3:
|
||||||
|
if (memcmp (IDNA_ACE_PREFIX, utf8in, strlen (IDNA_ACE_PREFIX)) != 0)
|
||||||
|
return IDNA_NO_ACE_PREFIX;
|
||||||
|
|
||||||
|
/* 4. Remove the ACE prefix.
|
||||||
|
*/
|
||||||
|
|
||||||
|
memmove (utf8in, &utf8in[strlen (IDNA_ACE_PREFIX)],
|
||||||
|
strlen (utf8in) - strlen (IDNA_ACE_PREFIX) + 1);
|
||||||
|
|
||||||
|
/* 5. Decode the sequence using the decoding algorithm in [PUNYCODE]
|
||||||
|
* and fail if there is an error. Save a copy of the result of
|
||||||
|
* this step.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(*outlen)--; /* reserve one for the zero */
|
||||||
|
|
||||||
|
rc = punycode_decode (strlen (utf8in), utf8in, outlen, out, NULL);
|
||||||
|
if (rc != PUNYCODE_SUCCESS)
|
||||||
|
return IDNA_PUNYCODE_ERROR;
|
||||||
|
|
||||||
|
out[*outlen] = 0; /* add zero */
|
||||||
|
|
||||||
|
/* 6. Apply ToASCII.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rc = idna_to_ascii_4i (out, *outlen, tmpout, flags);
|
||||||
|
if (rc != IDNA_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* 7. Verify that the result of step 6 matches the saved copy from
|
||||||
|
* step 3, using a case-insensitive ASCII comparison.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (strcasecmp (utf8in, tmpout + strlen (IDNA_ACE_PREFIX)) != 0)
|
||||||
|
return IDNA_ROUNDTRIP_VERIFY_ERROR;
|
||||||
|
|
||||||
|
/* 8. Return the saved copy from step 5.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return IDNA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_unicode_44i
|
||||||
|
* @in: input array with unicode code points.
|
||||||
|
* @inlen: length of input array with unicode code points.
|
||||||
|
* @out: output array with unicode code points.
|
||||||
|
* @outlen: on input, maximum size of output array with unicode code points,
|
||||||
|
* on exit, actual size of output array with unicode code points.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* The ToUnicode operation takes a sequence of Unicode code points
|
||||||
|
* that make up one label and returns a sequence of Unicode code
|
||||||
|
* points. If the input sequence is a label in ACE form, then the
|
||||||
|
* result is an equivalent internationalized label that is not in ACE
|
||||||
|
* form, otherwise the original sequence is returned unaltered.
|
||||||
|
*
|
||||||
|
* ToUnicode never fails. If any step fails, then the original input
|
||||||
|
* sequence is returned immediately in that step.
|
||||||
|
*
|
||||||
|
* The Punycode decoder can never output more code points than it
|
||||||
|
* inputs, but Nameprep can, and therefore ToUnicode can. Note that
|
||||||
|
* the number of octets needed to represent a sequence of code points
|
||||||
|
* depends on the particular character encoding used.
|
||||||
|
*
|
||||||
|
* The inputs to ToUnicode are a sequence of code points, the
|
||||||
|
* AllowUnassigned flag, and the UseSTD3ASCIIRules flag. The output of
|
||||||
|
* ToUnicode is always a sequence of Unicode code points.
|
||||||
|
*
|
||||||
|
* Return value: Returns error condition, but it must only be used for
|
||||||
|
* debugging purposes. The output buffer is always
|
||||||
|
* guaranteed to contain the correct data according to
|
||||||
|
* the specification (sans malloc induced errors). NB!
|
||||||
|
* This means that you normally ignore the return code
|
||||||
|
* from this function, as checking it means breaking the
|
||||||
|
* standard.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
idna_to_unicode_44i (const uint32_t * in, size_t inlen,
|
||||||
|
uint32_t * out, size_t * outlen, int flags)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
size_t outlensave = *outlen;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = stringprep_ucs4_to_utf8 (in, inlen, NULL, NULL);
|
||||||
|
if (p == NULL)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
|
||||||
|
rc = idna_to_unicode_internal (p, out, outlen, flags);
|
||||||
|
if (rc != IDNA_SUCCESS)
|
||||||
|
{
|
||||||
|
memcpy (out, in, sizeof (in[0]) * (inlen < outlensave ?
|
||||||
|
inlen : outlensave));
|
||||||
|
*outlen = inlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (p);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrappers that handle several labels */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_ascii_4z:
|
||||||
|
* @input: zero terminated input Unicode string.
|
||||||
|
* @output: pointer to newly allocated output string.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* Convert UCS-4 domain name to ASCII string. The domain name may
|
||||||
|
* contain several labels, separated by dots. The output buffer must
|
||||||
|
* be deallocated by the caller.
|
||||||
|
*
|
||||||
|
* Return value: Returns IDNA_SUCCESS on success, or error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
idna_to_ascii_4z (const uint32_t * input, char **output, int flags)
|
||||||
|
{
|
||||||
|
const uint32_t *start = input;
|
||||||
|
const uint32_t *end = input;
|
||||||
|
char buf[64];
|
||||||
|
char *out = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* 1) Whenever dots are used as label separators, the following
|
||||||
|
characters MUST be recognized as dots: U+002E (full stop),
|
||||||
|
U+3002 (ideographic full stop), U+FF0E (fullwidth full stop),
|
||||||
|
U+FF61 (halfwidth ideographic full stop). */
|
||||||
|
|
||||||
|
if (input[0] == 0)
|
||||||
|
{
|
||||||
|
/* Handle implicit zero-length root label. */
|
||||||
|
*output = malloc (1);
|
||||||
|
if (!*output)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
strcpy (*output, "");
|
||||||
|
return IDNA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DOTP (input[0]) && input[1] == 0)
|
||||||
|
{
|
||||||
|
/* Handle explicit zero-length root label. */
|
||||||
|
*output = malloc (2);
|
||||||
|
if (!*output)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
strcpy (*output, ".");
|
||||||
|
return IDNA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output = NULL;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
end = start;
|
||||||
|
|
||||||
|
for (; *end && !DOTP (*end); end++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (*end == '\0' && start == end)
|
||||||
|
{
|
||||||
|
/* Handle explicit zero-length root label. */
|
||||||
|
buf[0] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = idna_to_ascii_4i (start, end - start, buf, flags);
|
||||||
|
if (rc != IDNA_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out)
|
||||||
|
{
|
||||||
|
out = realloc (out, strlen (out) + 1 + strlen (buf) + 1);
|
||||||
|
if (!out)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
strcat (out, ".");
|
||||||
|
strcat (out, buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out = (char *) malloc (strlen (buf) + 1);
|
||||||
|
if (!out)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
strcpy (out, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
start = end + 1;
|
||||||
|
}
|
||||||
|
while (*end);
|
||||||
|
|
||||||
|
*output = out;
|
||||||
|
|
||||||
|
return IDNA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_ascii_8z:
|
||||||
|
* @input: zero terminated input UTF-8 string.
|
||||||
|
* @output: pointer to newly allocated output string.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* Convert UTF-8 domain name to ASCII string. The domain name may
|
||||||
|
* contain several labels, separated by dots. The output buffer must
|
||||||
|
* be deallocated by the caller.
|
||||||
|
*
|
||||||
|
* Return value: Returns IDNA_SUCCESS on success, or error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
idna_to_ascii_8z (const char *input, char **output, int flags)
|
||||||
|
{
|
||||||
|
uint32_t *ucs4;
|
||||||
|
size_t ucs4len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
ucs4 = stringprep_utf8_to_ucs4 (input, -1, &ucs4len);
|
||||||
|
if (!ucs4)
|
||||||
|
return IDNA_ICONV_ERROR;
|
||||||
|
|
||||||
|
rc = idna_to_ascii_4z (ucs4, output, flags);
|
||||||
|
|
||||||
|
free (ucs4);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_ascii_lz:
|
||||||
|
* @input: zero terminated input UTF-8 string.
|
||||||
|
* @output: pointer to newly allocated output string.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* Convert domain name in the locale's encoding to ASCII string. The
|
||||||
|
* domain name may contain several labels, separated by dots. The
|
||||||
|
* output buffer must be deallocated by the caller.
|
||||||
|
*
|
||||||
|
* Return value: Returns IDNA_SUCCESS on success, or error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
idna_to_ascii_lz (const char *input, char **output, int flags)
|
||||||
|
{
|
||||||
|
char *utf8;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
utf8 = stringprep_locale_to_utf8 (input);
|
||||||
|
if (!utf8)
|
||||||
|
return IDNA_ICONV_ERROR;
|
||||||
|
|
||||||
|
rc = idna_to_ascii_8z (utf8, output, flags);
|
||||||
|
|
||||||
|
free (utf8);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_unicode_4z4z:
|
||||||
|
* @input: zero-terminated Unicode string.
|
||||||
|
* @output: pointer to newly allocated output Unicode string.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* Convert possibly ACE encoded domain name in UCS-4 format into a
|
||||||
|
* UCS-4 string. The domain name may contain several labels,
|
||||||
|
* separated by dots. The output buffer must be deallocated by the
|
||||||
|
* caller.
|
||||||
|
*
|
||||||
|
* Return value: Returns IDNA_SUCCESS on success, or error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
idna_to_unicode_4z4z (const uint32_t * input, uint32_t ** output, int flags)
|
||||||
|
{
|
||||||
|
const uint32_t *start = input;
|
||||||
|
const uint32_t *end = input;
|
||||||
|
uint32_t *buf;
|
||||||
|
size_t buflen;
|
||||||
|
uint32_t *out = NULL;
|
||||||
|
size_t outlen = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
*output = NULL;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
end = start;
|
||||||
|
|
||||||
|
for (; *end && !DOTP (*end); end++)
|
||||||
|
;
|
||||||
|
|
||||||
|
buflen = end - start;
|
||||||
|
buf = malloc (sizeof (buf[0]) * (buflen + 1));
|
||||||
|
if (!buf)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
|
||||||
|
rc = idna_to_unicode_44i (start, end - start, buf, &buflen, flags);
|
||||||
|
/* don't check rc as per specification! */
|
||||||
|
|
||||||
|
if (out)
|
||||||
|
{
|
||||||
|
out = realloc (out, sizeof (out[0]) * (outlen + 1 + buflen + 1));
|
||||||
|
if (!out)
|
||||||
|
return IDNA_MALLOC_ERROR;
|
||||||
|
out[outlen++] = 0x002E; /* '.' (full stop) */
|
||||||
|
memcpy (out + outlen, buf, sizeof (buf[0]) * buflen);
|
||||||
|
outlen += buflen;
|
||||||
|
out[outlen] = 0x0;
|
||||||
|
free (buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out = buf;
|
||||||
|
outlen = buflen;
|
||||||
|
out[outlen] = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = end + 1;
|
||||||
|
}
|
||||||
|
while (*end);
|
||||||
|
|
||||||
|
*output = out;
|
||||||
|
|
||||||
|
return IDNA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_unicode_8z4z:
|
||||||
|
* @input: zero-terminated UTF-8 string.
|
||||||
|
* @output: pointer to newly allocated output Unicode string.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* Convert possibly ACE encoded domain name in UTF-8 format into a
|
||||||
|
* UCS-4 string. The domain name may contain several labels,
|
||||||
|
* separated by dots. The output buffer must be deallocated by the
|
||||||
|
* caller.
|
||||||
|
*
|
||||||
|
* Return value: Returns IDNA_SUCCESS on success, or error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
idna_to_unicode_8z4z (const char *input, uint32_t ** output, int flags)
|
||||||
|
{
|
||||||
|
uint32_t *ucs4;
|
||||||
|
size_t ucs4len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
ucs4 = stringprep_utf8_to_ucs4 (input, -1, &ucs4len);
|
||||||
|
if (!ucs4)
|
||||||
|
return IDNA_ICONV_ERROR;
|
||||||
|
|
||||||
|
rc = idna_to_unicode_4z4z (ucs4, output, flags);
|
||||||
|
free (ucs4);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_unicode_8z8z:
|
||||||
|
* @input: zero-terminated UTF-8 string.
|
||||||
|
* @output: pointer to newly allocated output UTF-8 string.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* Convert possibly ACE encoded domain name in UTF-8 format into a
|
||||||
|
* UTF-8 string. The domain name may contain several labels,
|
||||||
|
* separated by dots. The output buffer must be deallocated by the
|
||||||
|
* caller.
|
||||||
|
*
|
||||||
|
* Return value: Returns IDNA_SUCCESS on success, or error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
idna_to_unicode_8z8z (const char *input, char **output, int flags)
|
||||||
|
{
|
||||||
|
uint32_t *ucs4;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = idna_to_unicode_8z4z (input, &ucs4, flags);
|
||||||
|
*output = stringprep_ucs4_to_utf8 (ucs4, -1, NULL, NULL);
|
||||||
|
free (ucs4);
|
||||||
|
|
||||||
|
if (!*output)
|
||||||
|
return IDNA_ICONV_ERROR;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_unicode_8zlz:
|
||||||
|
* @input: zero-terminated UTF-8 string.
|
||||||
|
* @output: pointer to newly allocated output string encoded in the
|
||||||
|
* current locale's character set.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* Convert possibly ACE encoded domain name in UTF-8 format into a
|
||||||
|
* string encoded in the current locale's character set. The domain
|
||||||
|
* name may contain several labels, separated by dots. The output
|
||||||
|
* buffer must be deallocated by the caller.
|
||||||
|
*
|
||||||
|
* Return value: Returns IDNA_SUCCESS on success, or error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
idna_to_unicode_8zlz (const char *input, char **output, int flags)
|
||||||
|
{
|
||||||
|
char *utf8;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = idna_to_unicode_8z8z (input, &utf8, flags);
|
||||||
|
*output = stringprep_utf8_to_locale (utf8);
|
||||||
|
free (utf8);
|
||||||
|
|
||||||
|
if (!*output)
|
||||||
|
return IDNA_ICONV_ERROR;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* idna_to_unicode_lzlz:
|
||||||
|
* @input: zero-terminated string encoded in the current locale's
|
||||||
|
* character set.
|
||||||
|
* @output: pointer to newly allocated output string encoded in the
|
||||||
|
* current locale's character set.
|
||||||
|
* @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
|
||||||
|
*
|
||||||
|
* Convert possibly ACE encoded domain name in the locale's character
|
||||||
|
* set into a string encoded in the current locale's character set.
|
||||||
|
* The domain name may contain several labels, separated by dots. The
|
||||||
|
* output buffer must be deallocated by the caller.
|
||||||
|
*
|
||||||
|
* Return value: Returns IDNA_SUCCESS on success, or error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
idna_to_unicode_lzlz (const char *input, char **output, int flags)
|
||||||
|
{
|
||||||
|
char *utf8;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
utf8 = stringprep_locale_to_utf8 (input);
|
||||||
|
if (!utf8)
|
||||||
|
return IDNA_ICONV_ERROR;
|
||||||
|
|
||||||
|
rc = idna_to_unicode_8zlz (utf8, output, flags);
|
||||||
|
free (utf8);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IDNA_ACE_PREFIX
|
||||||
|
*
|
||||||
|
* The IANA allocated prefix to use for IDNA. "xn--"
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Idna_rc:
|
||||||
|
* @IDNA_SUCCESS: Successful operation. This value is guaranteed to
|
||||||
|
* always be zero, the remaining ones are only guaranteed to hold
|
||||||
|
* non-zero values, for logical comparison purposes.
|
||||||
|
* @IDNA_STRINGPREP_ERROR: Error during string preparation.
|
||||||
|
* @IDNA_PUNYCODE_ERROR: Error during punycode operation.
|
||||||
|
* @IDNA_CONTAINS_NON_LDH: For IDNA_USE_STD3_ASCII_RULES, indicate that
|
||||||
|
* the string contains non-LDH ASCII characters.
|
||||||
|
* @IDNA_CONTAINS_MINUS: For IDNA_USE_STD3_ASCII_RULES, indicate that
|
||||||
|
* the string contains a leading or trailing hyphen-minus (U+002D).
|
||||||
|
* @IDNA_INVALID_LENGTH: The final output string is not within the
|
||||||
|
* (inclusive) range 1 to 63 characters.
|
||||||
|
* @IDNA_NO_ACE_PREFIX: The string does not contain the ACE prefix
|
||||||
|
* (for ToUnicode).
|
||||||
|
* @IDNA_ROUNDTRIP_VERIFY_ERROR: The ToASCII operation on output
|
||||||
|
* string does not equal the input.
|
||||||
|
* @IDNA_CONTAINS_ACE_PREFIX: The input contains the ACE prefix (for
|
||||||
|
* ToASCII).
|
||||||
|
* @IDNA_ICONV_ERROR: Could not convert string in locale encoding.
|
||||||
|
* @IDNA_MALLOC_ERROR: Could not allocate buffer (this is typically a
|
||||||
|
* fatal error).
|
||||||
|
*
|
||||||
|
* Enumerated return codes of idna_to_ascii_4i(),
|
||||||
|
* idna_to_unicode_44i() functions (and functions derived from those
|
||||||
|
* functions). The value 0 is guaranteed to always correspond to
|
||||||
|
* success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Idna_flags:
|
||||||
|
* @IDNA_ALLOW_UNASSIGNED: Don't reject strings containing unassigned
|
||||||
|
* Unicode code points.
|
||||||
|
* @IDNA_USE_STD3_ASCII_RULES: Validate strings according to STD3
|
||||||
|
* rules (i.e., normal host name rules).
|
||||||
|
*
|
||||||
|
* Flags to pass to idna_to_ascii_4i(), idna_to_unicode_44i() etc.
|
||||||
|
*/
|
98
libidn/idna.h
Normal file
98
libidn/idna.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/* idna.h Declarations for IDNA.
|
||||||
|
* Copyright (C) 2002, 2003, 2004 Simon Josefsson
|
||||||
|
*
|
||||||
|
* This file is part of GNU Libidn.
|
||||||
|
*
|
||||||
|
* GNU Libidn is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Libidn is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with GNU Libidn; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IDNA_H
|
||||||
|
#define _IDNA_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
#include <stdint.h> /* uint32_t */
|
||||||
|
|
||||||
|
/* Error codes. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
IDNA_SUCCESS = 0,
|
||||||
|
IDNA_STRINGPREP_ERROR = 1,
|
||||||
|
IDNA_PUNYCODE_ERROR = 2,
|
||||||
|
IDNA_CONTAINS_NON_LDH = 3,
|
||||||
|
/* Workaround typo in earlier versions. */
|
||||||
|
IDNA_CONTAINS_LDH = IDNA_CONTAINS_NON_LDH,
|
||||||
|
IDNA_CONTAINS_MINUS = 4,
|
||||||
|
IDNA_INVALID_LENGTH = 5,
|
||||||
|
IDNA_NO_ACE_PREFIX = 6,
|
||||||
|
IDNA_ROUNDTRIP_VERIFY_ERROR = 7,
|
||||||
|
IDNA_CONTAINS_ACE_PREFIX = 8,
|
||||||
|
IDNA_ICONV_ERROR = 9,
|
||||||
|
/* Internal errors. */
|
||||||
|
IDNA_MALLOC_ERROR = 201,
|
||||||
|
IDNA_DLOPEN_ERROR = 202
|
||||||
|
} Idna_rc;
|
||||||
|
|
||||||
|
/* IDNA flags */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
IDNA_ALLOW_UNASSIGNED = 0x0001,
|
||||||
|
IDNA_USE_STD3_ASCII_RULES = 0x0002
|
||||||
|
} Idna_flags;
|
||||||
|
|
||||||
|
#ifndef IDNA_ACE_PREFIX
|
||||||
|
#define IDNA_ACE_PREFIX "xn--"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Core functions */
|
||||||
|
extern int idna_to_ascii_4i (const uint32_t * in, size_t inlen,
|
||||||
|
char *out, int flags);
|
||||||
|
extern int idna_to_unicode_44i (const uint32_t * in, size_t inlen,
|
||||||
|
uint32_t * out, size_t * outlen, int flags);
|
||||||
|
|
||||||
|
/* Wrappers that handle several labels */
|
||||||
|
|
||||||
|
extern int idna_to_ascii_4z (const uint32_t * input,
|
||||||
|
char **output, int flags);
|
||||||
|
|
||||||
|
extern int idna_to_ascii_8z (const char *input, char **output, int flags);
|
||||||
|
|
||||||
|
extern int idna_to_ascii_lz (const char *input, char **output, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
extern int idna_to_unicode_4z4z (const uint32_t * input,
|
||||||
|
uint32_t ** output, int flags);
|
||||||
|
|
||||||
|
extern int idna_to_unicode_8z4z (const char *input,
|
||||||
|
uint32_t ** output, int flags);
|
||||||
|
|
||||||
|
extern int idna_to_unicode_8z8z (const char *input,
|
||||||
|
char **output, int flags);
|
||||||
|
|
||||||
|
extern int idna_to_unicode_8zlz (const char *input,
|
||||||
|
char **output, int flags);
|
||||||
|
|
||||||
|
extern int idna_to_unicode_lzlz (const char *input,
|
||||||
|
char **output, int flags);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _PUNYCODE_H */
|
1058
libidn/nfkc.c
Normal file
1058
libidn/nfkc.c
Normal file
File diff suppressed because it is too large
Load Diff
310
libidn/profiles.c
Normal file
310
libidn/profiles.c
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
/* profiles.c Definitions of stringprep profiles.
|
||||||
|
* Copyright (C) 2002, 2003, 2004 Simon Josefsson
|
||||||
|
*
|
||||||
|
* This file is part of GNU Libidn.
|
||||||
|
*
|
||||||
|
* GNU Libidn is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Libidn is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with GNU Libidn; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stringprep.h"
|
||||||
|
|
||||||
|
const Stringprep_profiles stringprep_profiles[] = {
|
||||||
|
{"Nameprep", stringprep_nameprep},
|
||||||
|
{"KRBprep", stringprep_kerberos5}, /* Deprecate? */
|
||||||
|
{"Nodeprep", stringprep_xmpp_nodeprep},
|
||||||
|
{"Resourceprep", stringprep_xmpp_resourceprep},
|
||||||
|
{"plain", stringprep_plain}, /* sasl-anon-00. */
|
||||||
|
{"trace", stringprep_trace}, /* sasl-anon-01,02. */
|
||||||
|
{"SASLprep", stringprep_saslprep},
|
||||||
|
{"ISCSIprep", stringprep_iscsi}, /* Obsolete. */
|
||||||
|
{"iSCSI", stringprep_iscsi}, /* IANA. */
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_profile stringprep_nameprep[] = {
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_1},
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_2},
|
||||||
|
{STRINGPREP_NFKC, 0, 0},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_1_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_3},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_4},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_5},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_6},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_7},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_9},
|
||||||
|
{STRINGPREP_BIDI, 0, 0},
|
||||||
|
{STRINGPREP_BIDI_PROHIBIT_TABLE, ~STRINGPREP_NO_BIDI,
|
||||||
|
stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_BIDI_RAL_TABLE, 0, stringprep_rfc3454_D_1},
|
||||||
|
{STRINGPREP_BIDI_L_TABLE, 0, stringprep_rfc3454_D_2},
|
||||||
|
{STRINGPREP_UNASSIGNED_TABLE, ~STRINGPREP_NO_UNASSIGNED,
|
||||||
|
stringprep_rfc3454_A_1},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_profile stringprep_kerberos5[] = {
|
||||||
|
/* XXX this is likely to be wrong as the specification is
|
||||||
|
a rough draft. */
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_1},
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_3},
|
||||||
|
{STRINGPREP_NFKC, 0, 0},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_1_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_3},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_4},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_5},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_6},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_7},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_9},
|
||||||
|
{STRINGPREP_BIDI, 0, 0},
|
||||||
|
{STRINGPREP_BIDI_PROHIBIT_TABLE, ~STRINGPREP_NO_BIDI,
|
||||||
|
stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_BIDI_RAL_TABLE, 0, stringprep_rfc3454_D_1},
|
||||||
|
{STRINGPREP_BIDI_L_TABLE, 0, stringprep_rfc3454_D_2},
|
||||||
|
{STRINGPREP_UNASSIGNED_TABLE, ~STRINGPREP_NO_UNASSIGNED,
|
||||||
|
stringprep_rfc3454_A_1},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_table_element stringprep_xmpp_nodeprep_prohibit[] = {
|
||||||
|
{0x000022}, /* #x22 (") */
|
||||||
|
{0x000026}, /* #x26 (&) */
|
||||||
|
{0x000027}, /* #x27 (') */
|
||||||
|
{0x00002F}, /* #x2F (/) */
|
||||||
|
{0x00003A}, /* #x3A (:) */
|
||||||
|
{0x00003C}, /* #x3C (<) */
|
||||||
|
{0x00003E}, /* #x3E (>) */
|
||||||
|
{0x000040}, /* #x40 (@) */
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_profile stringprep_xmpp_nodeprep[] = {
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_1},
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_2},
|
||||||
|
{STRINGPREP_NFKC, 0, 0},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_1_1},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_1_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_1},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_3},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_4},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_5},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_6},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_7},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_9},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_xmpp_nodeprep_prohibit},
|
||||||
|
{STRINGPREP_BIDI, 0, 0},
|
||||||
|
{STRINGPREP_BIDI_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_BIDI_RAL_TABLE, 0, stringprep_rfc3454_D_1},
|
||||||
|
{STRINGPREP_BIDI_L_TABLE, 0, stringprep_rfc3454_D_2},
|
||||||
|
{STRINGPREP_UNASSIGNED_TABLE, ~STRINGPREP_NO_UNASSIGNED,
|
||||||
|
stringprep_rfc3454_A_1},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_profile stringprep_xmpp_resourceprep[] = {
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_1},
|
||||||
|
{STRINGPREP_NFKC, 0, 0},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_1_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_1},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_3},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_4},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_5},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_6},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_7},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_9},
|
||||||
|
{STRINGPREP_BIDI, 0, 0},
|
||||||
|
{STRINGPREP_BIDI_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_BIDI_RAL_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_1},
|
||||||
|
{STRINGPREP_BIDI_L_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_2},
|
||||||
|
{STRINGPREP_UNASSIGNED_TABLE, ~STRINGPREP_NO_UNASSIGNED,
|
||||||
|
stringprep_rfc3454_A_1},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_profile stringprep_plain[] = {
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_1},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_3},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_4},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_5},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_6},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_9},
|
||||||
|
{STRINGPREP_BIDI, 0, 0},
|
||||||
|
{STRINGPREP_BIDI_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_BIDI_RAL_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_1},
|
||||||
|
{STRINGPREP_BIDI_L_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_2},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_profile stringprep_trace[] = {
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_1},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_3},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_4},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_5},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_6},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_9},
|
||||||
|
{STRINGPREP_BIDI, 0, 0},
|
||||||
|
{STRINGPREP_BIDI_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_BIDI_RAL_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_1},
|
||||||
|
{STRINGPREP_BIDI_L_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_2},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_table_element stringprep_iscsi_prohibit[] = {
|
||||||
|
{0x0000}, /* [ASCII CONTROL CHARACTERS and SPACE through ,] */
|
||||||
|
{0x0001},
|
||||||
|
{0x0002},
|
||||||
|
{0x0003},
|
||||||
|
{0x0004},
|
||||||
|
{0x0005},
|
||||||
|
{0x0006},
|
||||||
|
{0x0007},
|
||||||
|
{0x0008},
|
||||||
|
{0x0009},
|
||||||
|
{0x000A},
|
||||||
|
{0x000B},
|
||||||
|
{0x000C},
|
||||||
|
{0x000D},
|
||||||
|
{0x000E},
|
||||||
|
{0x000F},
|
||||||
|
{0x0010},
|
||||||
|
{0x0011},
|
||||||
|
{0x0012},
|
||||||
|
{0x0013},
|
||||||
|
{0x0014},
|
||||||
|
{0x0015},
|
||||||
|
{0x0016},
|
||||||
|
{0x0017},
|
||||||
|
{0x0018},
|
||||||
|
{0x0019},
|
||||||
|
{0x001A},
|
||||||
|
{0x001B},
|
||||||
|
{0x001C},
|
||||||
|
{0x001D},
|
||||||
|
{0x001E},
|
||||||
|
{0x001F},
|
||||||
|
{0x0020},
|
||||||
|
{0x0021},
|
||||||
|
{0x0022},
|
||||||
|
{0x0023},
|
||||||
|
{0x0024},
|
||||||
|
{0x0025},
|
||||||
|
{0x0026},
|
||||||
|
{0x0027},
|
||||||
|
{0x0028},
|
||||||
|
{0x0029},
|
||||||
|
{0x002A},
|
||||||
|
{0x002B},
|
||||||
|
{0x002C},
|
||||||
|
{0x002F}, /* [ASCII /] */
|
||||||
|
{0x003B}, /* [ASCII ; through @] */
|
||||||
|
{0x003C},
|
||||||
|
{0x003D},
|
||||||
|
{0x003E},
|
||||||
|
{0x003F},
|
||||||
|
{0x0040},
|
||||||
|
{0x005B}, /* [ASCII [ through `] */
|
||||||
|
{0x005C},
|
||||||
|
{0x005D},
|
||||||
|
{0x005E},
|
||||||
|
{0x005F},
|
||||||
|
{0x0060},
|
||||||
|
{0x007B}, /* [ASCII { through DEL] */
|
||||||
|
{0x007C},
|
||||||
|
{0x007D},
|
||||||
|
{0x007E},
|
||||||
|
{0x007F},
|
||||||
|
{0x3002}, /* ideographic full stop */
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_profile stringprep_iscsi[] = {
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_1},
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_2},
|
||||||
|
{STRINGPREP_NFKC, 0, 0},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_1},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_1},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_3},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_4},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_5},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_6},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_9},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_iscsi_prohibit},
|
||||||
|
{STRINGPREP_BIDI, 0, 0},
|
||||||
|
{STRINGPREP_BIDI_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_BIDI_RAL_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_1},
|
||||||
|
{STRINGPREP_BIDI_L_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_2},
|
||||||
|
{STRINGPREP_UNASSIGNED_TABLE, ~STRINGPREP_NO_UNASSIGNED,
|
||||||
|
stringprep_rfc3454_A_1},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_table_element stringprep_saslprep_space_map[] = {
|
||||||
|
{0x0000A0, 0, {0x0020}}, /* 00A0; NO-BREAK SPACE */
|
||||||
|
{0x001680, 0, {0x0020}}, /* 1680; OGHAM SPACE MARK */
|
||||||
|
{0x002000, 0, {0x0020}}, /* 2000; EN QUAD */
|
||||||
|
{0x002001, 0, {0x0020}}, /* 2001; EM QUAD */
|
||||||
|
{0x002002, 0, {0x0020}}, /* 2002; EN SPACE */
|
||||||
|
{0x002003, 0, {0x0020}}, /* 2003; EM SPACE */
|
||||||
|
{0x002004, 0, {0x0020}}, /* 2004; THREE-PER-EM SPACE */
|
||||||
|
{0x002005, 0, {0x0020}}, /* 2005; FOUR-PER-EM SPACE */
|
||||||
|
{0x002006, 0, {0x0020}}, /* 2006; SIX-PER-EM SPACE */
|
||||||
|
{0x002007, 0, {0x0020}}, /* 2007; FIGURE SPACE */
|
||||||
|
{0x002008, 0, {0x0020}}, /* 2008; PUNCTUATION SPACE */
|
||||||
|
{0x002009, 0, {0x0020}}, /* 2009; THIN SPACE */
|
||||||
|
{0x00200A, 0, {0x0020}}, /* 200A; HAIR SPACE */
|
||||||
|
{0x00200B, 0, {0x0020}}, /* 200B; ZERO WIDTH SPACE */
|
||||||
|
{0x00202F, 0, {0x0020}}, /* 202F; NARROW NO-BREAK SPACE */
|
||||||
|
{0x00205F, 0, {0x0020}}, /* 205F; MEDIUM MATHEMATICAL SPACE */
|
||||||
|
{0x003000, 0, {0x0020}}, /* 3000; IDEOGRAPHIC SPACE */
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stringprep_profile stringprep_saslprep[] = {
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_saslprep_space_map},
|
||||||
|
{STRINGPREP_MAP_TABLE, 0, stringprep_rfc3454_B_1},
|
||||||
|
{STRINGPREP_NFKC, 0, 0},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_1_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_1},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_2_2},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_3},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_4},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_5},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_6},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_7},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_9},
|
||||||
|
{STRINGPREP_BIDI, 0, 0},
|
||||||
|
{STRINGPREP_BIDI_PROHIBIT_TABLE, 0, stringprep_rfc3454_C_8},
|
||||||
|
{STRINGPREP_BIDI_RAL_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_1},
|
||||||
|
{STRINGPREP_BIDI_L_TABLE, ~STRINGPREP_NO_BIDI, stringprep_rfc3454_D_2},
|
||||||
|
{STRINGPREP_UNASSIGNED_TABLE, ~STRINGPREP_NO_UNASSIGNED,
|
||||||
|
stringprep_rfc3454_A_1},
|
||||||
|
{0}
|
||||||
|
};
|
456
libidn/punycode.c
Normal file
456
libidn/punycode.c
Normal file
@ -0,0 +1,456 @@
|
|||||||
|
/* punycode.c Implementation of punycode used to ASCII encode IDN's.
|
||||||
|
* Copyright (C) 2002, 2003 Simon Josefsson
|
||||||
|
*
|
||||||
|
* This file is part of GNU Libidn.
|
||||||
|
*
|
||||||
|
* GNU Libidn is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Libidn is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with GNU Libidn; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is derived from RFC 3492bis written by Adam M. Costello.
|
||||||
|
*
|
||||||
|
* Disclaimer and license: Regarding this entire document or any
|
||||||
|
* portion of it (including the pseudocode and C code), the author
|
||||||
|
* makes no guarantees and is not responsible for any damage resulting
|
||||||
|
* from its use. The author grants irrevocable permission to anyone
|
||||||
|
* to use, modify, and distribute it in any way that does not diminish
|
||||||
|
* the rights of anyone else to use, modify, and distribute it,
|
||||||
|
* provided that redistributed derivative works do not contain
|
||||||
|
* misleading author or version information. Derivative works need
|
||||||
|
* not be licensed under similar terms.
|
||||||
|
*
|
||||||
|
* Copyright (C) The Internet Society (2003). All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This document and translations of it may be copied and furnished to
|
||||||
|
* others, and derivative works that comment on or otherwise explain it
|
||||||
|
* or assist in its implementation may be prepared, copied, published
|
||||||
|
* and distributed, in whole or in part, without restriction of any
|
||||||
|
* kind, provided that the above copyright notice and this paragraph are
|
||||||
|
* included on all such copies and derivative works. However, this
|
||||||
|
* document itself may not be modified in any way, such as by removing
|
||||||
|
* the copyright notice or references to the Internet Society or other
|
||||||
|
* Internet organizations, except as needed for the purpose of
|
||||||
|
* developing Internet standards in which case the procedures for
|
||||||
|
* copyrights defined in the Internet Standards process must be
|
||||||
|
* followed, or as required to translate it into languages other than
|
||||||
|
* English.
|
||||||
|
*
|
||||||
|
* The limited permissions granted above are perpetual and will not be
|
||||||
|
* revoked by the Internet Society or its successors or assigns.
|
||||||
|
*
|
||||||
|
* This document and the information contained herein is provided on an
|
||||||
|
* "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||||
|
* TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
* BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||||
|
* HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "punycode.h"
|
||||||
|
|
||||||
|
/*** Bootstring parameters for Punycode ***/
|
||||||
|
|
||||||
|
enum
|
||||||
|
{ base = 36, tmin = 1, tmax = 26, skew = 38, damp = 700,
|
||||||
|
initial_bias = 72, initial_n = 0x80, delimiter = 0x2D
|
||||||
|
};
|
||||||
|
|
||||||
|
/* basic(cp) tests whether cp is a basic code point: */
|
||||||
|
#define basic(cp) ((punycode_uint)(cp) < 0x80)
|
||||||
|
|
||||||
|
/* delim(cp) tests whether cp is a delimiter: */
|
||||||
|
#define delim(cp) ((cp) == delimiter)
|
||||||
|
|
||||||
|
/* decode_digit(cp) returns the numeric value of a basic code */
|
||||||
|
/* point (for use in representing integers) in the range 0 to */
|
||||||
|
/* base-1, or base if cp does not represent a value. */
|
||||||
|
|
||||||
|
static punycode_uint
|
||||||
|
decode_digit (punycode_uint cp)
|
||||||
|
{
|
||||||
|
return cp - 48 < 10 ? cp - 22 : cp - 65 < 26 ? cp - 65 :
|
||||||
|
cp - 97 < 26 ? cp - 97 : base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encode_digit(d,flag) returns the basic code point whose value */
|
||||||
|
/* (when used for representing integers) is d, which needs to be in */
|
||||||
|
/* the range 0 to base-1. The lowercase form is used unless flag is */
|
||||||
|
/* nonzero, in which case the uppercase form is used. The behavior */
|
||||||
|
/* is undefined if flag is nonzero and digit d has no uppercase form. */
|
||||||
|
|
||||||
|
static char
|
||||||
|
encode_digit (punycode_uint d, int flag)
|
||||||
|
{
|
||||||
|
return d + 22 + 75 * (d < 26) - ((flag != 0) << 5);
|
||||||
|
/* 0..25 map to ASCII a..z or A..Z */
|
||||||
|
/* 26..35 map to ASCII 0..9 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flagged(bcp) tests whether a basic code point is flagged */
|
||||||
|
/* (uppercase). The behavior is undefined if bcp is not a */
|
||||||
|
/* basic code point. */
|
||||||
|
|
||||||
|
#define flagged(bcp) ((punycode_uint)(bcp) - 65 < 26)
|
||||||
|
|
||||||
|
/* encode_basic(bcp,flag) forces a basic code point to lowercase */
|
||||||
|
/* if flag is zero, uppercase if flag is nonzero, and returns */
|
||||||
|
/* the resulting code point. The code point is unchanged if it */
|
||||||
|
/* is caseless. The behavior is undefined if bcp is not a basic */
|
||||||
|
/* code point. */
|
||||||
|
|
||||||
|
static char
|
||||||
|
encode_basic (punycode_uint bcp, int flag)
|
||||||
|
{
|
||||||
|
bcp -= (bcp - 97 < 26) << 5;
|
||||||
|
return bcp + ((!flag && (bcp - 65 < 26)) << 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Platform-specific constants ***/
|
||||||
|
|
||||||
|
/* maxint is the maximum value of a punycode_uint variable: */
|
||||||
|
static const punycode_uint maxint = -1;
|
||||||
|
/* Because maxint is unsigned, -1 becomes the maximum value. */
|
||||||
|
|
||||||
|
/*** Bias adaptation function ***/
|
||||||
|
|
||||||
|
static punycode_uint
|
||||||
|
adapt (punycode_uint delta, punycode_uint numpoints, int firsttime)
|
||||||
|
{
|
||||||
|
punycode_uint k;
|
||||||
|
|
||||||
|
delta = firsttime ? delta / damp : delta >> 1;
|
||||||
|
/* delta >> 1 is a faster way of doing delta / 2 */
|
||||||
|
delta += delta / numpoints;
|
||||||
|
|
||||||
|
for (k = 0; delta > ((base - tmin) * tmax) / 2; k += base)
|
||||||
|
{
|
||||||
|
delta /= base - tmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return k + (base - tmin + 1) * delta / (delta + skew);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Main encode function ***/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* punycode_encode:
|
||||||
|
* @input_length: The number of code points in the @input array and
|
||||||
|
* the number of flags in the @case_flags array.
|
||||||
|
* @input: An array of code points. They are presumed to be Unicode
|
||||||
|
* code points, but that is not strictly REQUIRED. The array
|
||||||
|
* contains code points, not code units. UTF-16 uses code units
|
||||||
|
* D800 through DFFF to refer to code points 10000..10FFFF. The
|
||||||
|
* code points D800..DFFF do not occur in any valid Unicode string.
|
||||||
|
* The code points that can occur in Unicode strings (0..D7FF and
|
||||||
|
* E000..10FFFF) are also called Unicode scalar values.
|
||||||
|
* @case_flags: A %NULL pointer or an array of boolean values parallel
|
||||||
|
* to the @input array. Nonzero (true, flagged) suggests that the
|
||||||
|
* corresponding Unicode character be forced to uppercase after
|
||||||
|
* being decoded (if possible), and zero (false, unflagged) suggests
|
||||||
|
* that it be forced to lowercase (if possible). ASCII code points
|
||||||
|
* (0..7F) are encoded literally, except that ASCII letters are
|
||||||
|
* forced to uppercase or lowercase according to the corresponding
|
||||||
|
* case flags. If @case_flags is a %NULL pointer then ASCII letters
|
||||||
|
* are left as they are, and other code points are treated as
|
||||||
|
* unflagged.
|
||||||
|
* @output_length: The caller passes in the maximum number of ASCII
|
||||||
|
* code points that it can receive. On successful return it will
|
||||||
|
* contain the number of ASCII code points actually output.
|
||||||
|
* @output: An array of ASCII code points. It is *not*
|
||||||
|
* null-terminated; it will contain zeros if and only if the @input
|
||||||
|
* contains zeros. (Of course the caller can leave room for a
|
||||||
|
* terminator and add one if needed.)
|
||||||
|
*
|
||||||
|
* Converts a sequence of code points (presumed to be Unicode code
|
||||||
|
* points) to Punycode.
|
||||||
|
*
|
||||||
|
* Return value: The return value can be any of the punycode_status
|
||||||
|
* values defined above except %punycode_bad_input. If not
|
||||||
|
* %punycode_success, then @output_size and @output might contain
|
||||||
|
* garbage.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
punycode_encode (size_t input_length,
|
||||||
|
const punycode_uint input[],
|
||||||
|
const unsigned char case_flags[],
|
||||||
|
size_t * output_length, char output[])
|
||||||
|
{
|
||||||
|
punycode_uint input_len, n, delta, h, b, bias, j, m, q, k, t;
|
||||||
|
size_t out, max_out;
|
||||||
|
|
||||||
|
/* The Punycode spec assumes that the input length is the same type */
|
||||||
|
/* of integer as a code point, so we need to convert the size_t to */
|
||||||
|
/* a punycode_uint, which could overflow. */
|
||||||
|
|
||||||
|
if (input_length > maxint)
|
||||||
|
return punycode_overflow;
|
||||||
|
input_len = (punycode_uint) input_length;
|
||||||
|
|
||||||
|
/* Initialize the state: */
|
||||||
|
|
||||||
|
n = initial_n;
|
||||||
|
delta = 0;
|
||||||
|
out = 0;
|
||||||
|
max_out = *output_length;
|
||||||
|
bias = initial_bias;
|
||||||
|
|
||||||
|
/* Handle the basic code points: */
|
||||||
|
|
||||||
|
for (j = 0; j < input_len; ++j)
|
||||||
|
{
|
||||||
|
if (basic (input[j]))
|
||||||
|
{
|
||||||
|
if (max_out - out < 2)
|
||||||
|
return punycode_big_output;
|
||||||
|
output[out++] = case_flags ?
|
||||||
|
encode_basic (input[j], case_flags[j]) : (char) input[j];
|
||||||
|
}
|
||||||
|
/* else if (input[j] < n) return punycode_bad_input; */
|
||||||
|
/* (not needed for Punycode with unsigned code points) */
|
||||||
|
}
|
||||||
|
|
||||||
|
h = b = (punycode_uint) out;
|
||||||
|
/* cannot overflow because out <= input_len <= maxint */
|
||||||
|
|
||||||
|
/* h is the number of code points that have been handled, b is the */
|
||||||
|
/* number of basic code points, and out is the number of ASCII code */
|
||||||
|
/* points that have been output. */
|
||||||
|
|
||||||
|
if (b > 0)
|
||||||
|
output[out++] = delimiter;
|
||||||
|
|
||||||
|
/* Main encoding loop: */
|
||||||
|
|
||||||
|
while (h < input_len)
|
||||||
|
{
|
||||||
|
/* All non-basic code points < n have been */
|
||||||
|
/* handled already. Find the next larger one: */
|
||||||
|
|
||||||
|
for (m = maxint, j = 0; j < input_len; ++j)
|
||||||
|
{
|
||||||
|
/* if (basic(input[j])) continue; */
|
||||||
|
/* (not needed for Punycode) */
|
||||||
|
if (input[j] >= n && input[j] < m)
|
||||||
|
m = input[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase delta enough to advance the decoder's */
|
||||||
|
/* <n,i> state to <m,0>, but guard against overflow: */
|
||||||
|
|
||||||
|
if (m - n > (maxint - delta) / (h + 1))
|
||||||
|
return punycode_overflow;
|
||||||
|
delta += (m - n) * (h + 1);
|
||||||
|
n = m;
|
||||||
|
|
||||||
|
for (j = 0; j < input_len; ++j)
|
||||||
|
{
|
||||||
|
/* Punycode does not need to check whether input[j] is basic: */
|
||||||
|
if (input[j] < n /* || basic(input[j]) */ )
|
||||||
|
{
|
||||||
|
if (++delta == 0)
|
||||||
|
return punycode_overflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input[j] == n)
|
||||||
|
{
|
||||||
|
/* Represent delta as a generalized variable-length integer: */
|
||||||
|
|
||||||
|
for (q = delta, k = base;; k += base)
|
||||||
|
{
|
||||||
|
if (out >= max_out)
|
||||||
|
return punycode_big_output;
|
||||||
|
t = k <= bias /* + tmin */ ? tmin : /* +tmin not needed */
|
||||||
|
k >= bias + tmax ? tmax : k - bias;
|
||||||
|
if (q < t)
|
||||||
|
break;
|
||||||
|
output[out++] = encode_digit (t + (q - t) % (base - t), 0);
|
||||||
|
q = (q - t) / (base - t);
|
||||||
|
}
|
||||||
|
|
||||||
|
output[out++] = encode_digit (q, case_flags && case_flags[j]);
|
||||||
|
bias = adapt (delta, h + 1, h == b);
|
||||||
|
delta = 0;
|
||||||
|
++h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++delta, ++n;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output_length = out;
|
||||||
|
return punycode_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Main decode function ***/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* punycode_decode:
|
||||||
|
* @input_length: The number of ASCII code points in the @input array.
|
||||||
|
* @input: An array of ASCII code points (0..7F).
|
||||||
|
* @output_length: The caller passes in the maximum number of code
|
||||||
|
* points that it can receive into the @output array (which is also
|
||||||
|
* the maximum number of flags that it can receive into the
|
||||||
|
* @case_flags array, if @case_flags is not a %NULL pointer). On
|
||||||
|
* successful return it will contain the number of code points
|
||||||
|
* actually output (which is also the number of flags actually
|
||||||
|
* output, if case_flags is not a null pointer). The decoder will
|
||||||
|
* never need to output more code points than the number of ASCII
|
||||||
|
* code points in the input, because of the way the encoding is
|
||||||
|
* defined. The number of code points output cannot exceed the
|
||||||
|
* maximum possible value of a punycode_uint, even if the supplied
|
||||||
|
* @output_length is greater than that.
|
||||||
|
* @output: An array of code points like the input argument of
|
||||||
|
* punycode_encode() (see above).
|
||||||
|
* @case_flags: A %NULL pointer (if the flags are not needed by the
|
||||||
|
* caller) or an array of boolean values parallel to the @output
|
||||||
|
* array. Nonzero (true, flagged) suggests that the corresponding
|
||||||
|
* Unicode character be forced to uppercase by the caller (if
|
||||||
|
* possible), and zero (false, unflagged) suggests that it be forced
|
||||||
|
* to lowercase (if possible). ASCII code points (0..7F) are output
|
||||||
|
* already in the proper case, but their flags will be set
|
||||||
|
* appropriately so that applying the flags would be harmless.
|
||||||
|
*
|
||||||
|
* Converts Punycode to a sequence of code points (presumed to be
|
||||||
|
* Unicode code points).
|
||||||
|
*
|
||||||
|
* Return value: The return value can be any of the punycode_status
|
||||||
|
* values defined above. If not %punycode_success, then
|
||||||
|
* @output_length, @output, and @case_flags might contain garbage.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
punycode_decode (size_t input_length,
|
||||||
|
const char input[],
|
||||||
|
size_t * output_length,
|
||||||
|
punycode_uint output[], unsigned char case_flags[])
|
||||||
|
{
|
||||||
|
punycode_uint n, out, i, max_out, bias, oldi, w, k, digit, t;
|
||||||
|
size_t b, j, in;
|
||||||
|
|
||||||
|
/* Initialize the state: */
|
||||||
|
|
||||||
|
n = initial_n;
|
||||||
|
out = i = 0;
|
||||||
|
max_out = *output_length > maxint ? maxint
|
||||||
|
: (punycode_uint) * output_length;
|
||||||
|
bias = initial_bias;
|
||||||
|
|
||||||
|
/* Handle the basic code points: Let b be the number of input code */
|
||||||
|
/* points before the last delimiter, or 0 if there is none, then */
|
||||||
|
/* copy the first b code points to the output. */
|
||||||
|
|
||||||
|
for (b = j = 0; j < input_length; ++j)
|
||||||
|
if (delim (input[j]))
|
||||||
|
b = j;
|
||||||
|
if (b > max_out)
|
||||||
|
return punycode_big_output;
|
||||||
|
|
||||||
|
for (j = 0; j < b; ++j)
|
||||||
|
{
|
||||||
|
if (case_flags)
|
||||||
|
case_flags[out] = flagged (input[j]);
|
||||||
|
if (!basic (input[j]))
|
||||||
|
return punycode_bad_input;
|
||||||
|
output[out++] = input[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main decoding loop: Start just after the last delimiter if any */
|
||||||
|
/* basic code points were copied; start at the beginning otherwise. */
|
||||||
|
|
||||||
|
for (in = b > 0 ? b + 1 : 0; in < input_length; ++out)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* in is the index of the next ASCII code point to be consumed, */
|
||||||
|
/* and out is the number of code points in the output array. */
|
||||||
|
|
||||||
|
/* Decode a generalized variable-length integer into delta, */
|
||||||
|
/* which gets added to i. The overflow checking is easier */
|
||||||
|
/* if we increase i as we go, then subtract off its starting */
|
||||||
|
/* value at the end to obtain delta. */
|
||||||
|
|
||||||
|
for (oldi = i, w = 1, k = base;; k += base)
|
||||||
|
{
|
||||||
|
if (in >= input_length)
|
||||||
|
return punycode_bad_input;
|
||||||
|
digit = decode_digit (input[in++]);
|
||||||
|
if (digit >= base)
|
||||||
|
return punycode_bad_input;
|
||||||
|
if (digit > (maxint - i) / w)
|
||||||
|
return punycode_overflow;
|
||||||
|
i += digit * w;
|
||||||
|
t = k <= bias /* + tmin */ ? tmin : /* +tmin not needed */
|
||||||
|
k >= bias + tmax ? tmax : k - bias;
|
||||||
|
if (digit < t)
|
||||||
|
break;
|
||||||
|
if (w > maxint / (base - t))
|
||||||
|
return punycode_overflow;
|
||||||
|
w *= (base - t);
|
||||||
|
}
|
||||||
|
|
||||||
|
bias = adapt (i - oldi, out + 1, oldi == 0);
|
||||||
|
|
||||||
|
/* i was supposed to wrap around from out+1 to 0, */
|
||||||
|
/* incrementing n each time, so we'll fix that now: */
|
||||||
|
|
||||||
|
if (i / (out + 1) > maxint - n)
|
||||||
|
return punycode_overflow;
|
||||||
|
n += i / (out + 1);
|
||||||
|
i %= (out + 1);
|
||||||
|
|
||||||
|
/* Insert n at position i of the output: */
|
||||||
|
|
||||||
|
/* not needed for Punycode: */
|
||||||
|
/* if (basic(n)) return punycode_invalid_input; */
|
||||||
|
if (out >= max_out)
|
||||||
|
return punycode_big_output;
|
||||||
|
|
||||||
|
if (case_flags)
|
||||||
|
{
|
||||||
|
memmove (case_flags + i + 1, case_flags + i, out - i);
|
||||||
|
/* Case of last ASCII code point determines case flag: */
|
||||||
|
case_flags[i] = flagged (input[in - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove (output + i + 1, output + i, (out - i) * sizeof *output);
|
||||||
|
output[i++] = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output_length = (size_t) out;
|
||||||
|
/* cannot overflow because out <= old value of *output_length */
|
||||||
|
return punycode_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* punycode_uint
|
||||||
|
*
|
||||||
|
* Unicode code point data type, this is always a 32 bit unsigned
|
||||||
|
* integer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Punycode_status
|
||||||
|
* @PUNYCODE_SUCCESS: Successful operation. This value is guaranteed
|
||||||
|
* to always be zero, the remaining ones are only guaranteed to hold
|
||||||
|
* non-zero values, for logical comparison purposes.
|
||||||
|
* @PUNYCODE_BAD_INPUT: Input is invalid.
|
||||||
|
* @PUNYCODE_BIG_OUTPUT: Output would exceed the space provided.
|
||||||
|
* @PUNYCODE_OVERFLOW: Input needs wider integers to process.
|
||||||
|
*
|
||||||
|
* Enumerated return codes of punycode_encode() and punycode_decode().
|
||||||
|
* The value 0 is guaranteed to always correspond to success.
|
||||||
|
*/
|
216
libidn/punycode.h
Normal file
216
libidn/punycode.h
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/* punycode.h Declarations for punycode functions.
|
||||||
|
* Copyright (C) 2002, 2003 Simon Josefsson
|
||||||
|
*
|
||||||
|
* This file is part of GNU Libidn.
|
||||||
|
*
|
||||||
|
* GNU Libidn is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Libidn is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with GNU Libidn; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is derived from RFC 3492bis written by Adam M. Costello.
|
||||||
|
*
|
||||||
|
* Disclaimer and license: Regarding this entire document or any
|
||||||
|
* portion of it (including the pseudocode and C code), the author
|
||||||
|
* makes no guarantees and is not responsible for any damage resulting
|
||||||
|
* from its use. The author grants irrevocable permission to anyone
|
||||||
|
* to use, modify, and distribute it in any way that does not diminish
|
||||||
|
* the rights of anyone else to use, modify, and distribute it,
|
||||||
|
* provided that redistributed derivative works do not contain
|
||||||
|
* misleading author or version information. Derivative works need
|
||||||
|
* not be licensed under similar terms.
|
||||||
|
*
|
||||||
|
* Copyright (C) The Internet Society (2003). All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This document and translations of it may be copied and furnished to
|
||||||
|
* others, and derivative works that comment on or otherwise explain it
|
||||||
|
* or assist in its implementation may be prepared, copied, published
|
||||||
|
* and distributed, in whole or in part, without restriction of any
|
||||||
|
* kind, provided that the above copyright notice and this paragraph are
|
||||||
|
* included on all such copies and derivative works. However, this
|
||||||
|
* document itself may not be modified in any way, such as by removing
|
||||||
|
* the copyright notice or references to the Internet Society or other
|
||||||
|
* Internet organizations, except as needed for the purpose of
|
||||||
|
* developing Internet standards in which case the procedures for
|
||||||
|
* copyrights defined in the Internet Standards process must be
|
||||||
|
* followed, or as required to translate it into languages other than
|
||||||
|
* English.
|
||||||
|
*
|
||||||
|
* The limited permissions granted above are perpetual and will not be
|
||||||
|
* revoked by the Internet Society or its successors or assigns.
|
||||||
|
*
|
||||||
|
* This document and the information contained herein is provided on an
|
||||||
|
* "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||||
|
* TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
* BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||||
|
* HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PUNYCODE_H
|
||||||
|
#define _PUNYCODE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
#include <stdint.h> /* uint32_t */
|
||||||
|
|
||||||
|
enum punycode_status
|
||||||
|
{
|
||||||
|
punycode_success = 0,
|
||||||
|
punycode_bad_input = 1, /* Input is invalid. */
|
||||||
|
punycode_big_output = 2, /* Output would exceed the space provided. */
|
||||||
|
punycode_overflow = 3 /* Wider integers needed to process input. */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PUNYCODE_SUCCESS = punycode_success,
|
||||||
|
PUNYCODE_BAD_INPUT = punycode_bad_input,
|
||||||
|
PUNYCODE_BIG_OUTPUT = punycode_big_output,
|
||||||
|
PUNYCODE_OVERFLOW = punycode_overflow
|
||||||
|
} Punycode_status;
|
||||||
|
|
||||||
|
/* punycode_uint needs to be unsigned and needs to be */
|
||||||
|
/* at least 26 bits wide. */
|
||||||
|
|
||||||
|
typedef uint32_t punycode_uint;
|
||||||
|
|
||||||
|
extern int punycode_encode (size_t input_length,
|
||||||
|
const punycode_uint input[],
|
||||||
|
const unsigned char case_flags[],
|
||||||
|
size_t * output_length, char output[]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
punycode_encode() converts a sequence of code points (presumed to be
|
||||||
|
Unicode code points) to Punycode.
|
||||||
|
|
||||||
|
Input arguments (to be supplied by the caller):
|
||||||
|
|
||||||
|
input_length
|
||||||
|
The number of code points in the input array and the number
|
||||||
|
of flags in the case_flags array.
|
||||||
|
|
||||||
|
input
|
||||||
|
An array of code points. They are presumed to be Unicode
|
||||||
|
code points, but that is not strictly REQUIRED. The
|
||||||
|
array contains code points, not code units. UTF-16 uses
|
||||||
|
code units D800 through DFFF to refer to code points
|
||||||
|
10000..10FFFF. The code points D800..DFFF do not occur in
|
||||||
|
any valid Unicode string. The code points that can occur in
|
||||||
|
Unicode strings (0..D7FF and E000..10FFFF) are also called
|
||||||
|
Unicode scalar values.
|
||||||
|
|
||||||
|
case_flags
|
||||||
|
A null pointer or an array of boolean values parallel to
|
||||||
|
the input array. Nonzero (true, flagged) suggests that the
|
||||||
|
corresponding Unicode character be forced to uppercase after
|
||||||
|
being decoded (if possible), and zero (false, unflagged)
|
||||||
|
suggests that it be forced to lowercase (if possible).
|
||||||
|
ASCII code points (0..7F) are encoded literally, except that
|
||||||
|
ASCII letters are forced to uppercase or lowercase according
|
||||||
|
to the corresponding case flags. If case_flags is a null
|
||||||
|
pointer then ASCII letters are left as they are, and other
|
||||||
|
code points are treated as unflagged.
|
||||||
|
|
||||||
|
Output arguments (to be filled in by the function):
|
||||||
|
|
||||||
|
output
|
||||||
|
An array of ASCII code points. It is *not* null-terminated;
|
||||||
|
it will contain zeros if and only if the input contains
|
||||||
|
zeros. (Of course the caller can leave room for a
|
||||||
|
terminator and add one if needed.)
|
||||||
|
|
||||||
|
Input/output arguments (to be supplied by the caller and overwritten
|
||||||
|
by the function):
|
||||||
|
|
||||||
|
output_length
|
||||||
|
The caller passes in the maximum number of ASCII code points
|
||||||
|
that it can receive. On successful return it will contain
|
||||||
|
the number of ASCII code points actually output.
|
||||||
|
|
||||||
|
Return value:
|
||||||
|
|
||||||
|
Can be any of the punycode_status values defined above except
|
||||||
|
punycode_bad_input. If not punycode_success, then output_size
|
||||||
|
and output might contain garbage.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int punycode_decode (size_t input_length,
|
||||||
|
const char input[],
|
||||||
|
size_t * output_length,
|
||||||
|
punycode_uint output[],
|
||||||
|
unsigned char case_flags[]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
punycode_decode() converts Punycode to a sequence of code points
|
||||||
|
(presumed to be Unicode code points).
|
||||||
|
|
||||||
|
Input arguments (to be supplied by the caller):
|
||||||
|
|
||||||
|
input_length
|
||||||
|
The number of ASCII code points in the input array.
|
||||||
|
|
||||||
|
input
|
||||||
|
An array of ASCII code points (0..7F).
|
||||||
|
|
||||||
|
Output arguments (to be filled in by the function):
|
||||||
|
|
||||||
|
output
|
||||||
|
An array of code points like the input argument of
|
||||||
|
punycode_encode() (see above).
|
||||||
|
|
||||||
|
case_flags
|
||||||
|
A null pointer (if the flags are not needed by the caller)
|
||||||
|
or an array of boolean values parallel to the output array.
|
||||||
|
Nonzero (true, flagged) suggests that the corresponding
|
||||||
|
Unicode character be forced to uppercase by the caller (if
|
||||||
|
possible), and zero (false, unflagged) suggests that it
|
||||||
|
be forced to lowercase (if possible). ASCII code points
|
||||||
|
(0..7F) are output already in the proper case, but their
|
||||||
|
flags will be set appropriately so that applying the flags
|
||||||
|
would be harmless.
|
||||||
|
|
||||||
|
Input/output arguments (to be supplied by the caller and overwritten
|
||||||
|
by the function):
|
||||||
|
|
||||||
|
output_length
|
||||||
|
The caller passes in the maximum number of code points
|
||||||
|
that it can receive into the output array (which is also
|
||||||
|
the maximum number of flags that it can receive into the
|
||||||
|
case_flags array, if case_flags is not a null pointer). On
|
||||||
|
successful return it will contain the number of code points
|
||||||
|
actually output (which is also the number of flags actually
|
||||||
|
output, if case_flags is not a null pointer). The decoder
|
||||||
|
will never need to output more code points than the number
|
||||||
|
of ASCII code points in the input, because of the way the
|
||||||
|
encoding is defined. The number of code points output
|
||||||
|
cannot exceed the maximum possible value of a punycode_uint,
|
||||||
|
even if the supplied output_length is greater than that.
|
||||||
|
|
||||||
|
Return value:
|
||||||
|
|
||||||
|
Can be any of the punycode_status values defined above. If not
|
||||||
|
punycode_success, then output_length, output, and case_flags
|
||||||
|
might contain garbage.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _PUNYCODE_H */
|
3544
libidn/rfc3454.c
Normal file
3544
libidn/rfc3454.c
Normal file
File diff suppressed because it is too large
Load Diff
667
libidn/stringprep.c
Normal file
667
libidn/stringprep.c
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
/* stringprep.c --- Core stringprep implementation.
|
||||||
|
* Copyright (C) 2002, 2003, 2004 Simon Josefsson
|
||||||
|
*
|
||||||
|
* This file is part of GNU Libidn.
|
||||||
|
*
|
||||||
|
* GNU Libidn is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Libidn is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with GNU Libidn; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "stringprep.h"
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
stringprep_find_character_in_table (uint32_t ucs4,
|
||||||
|
const Stringprep_table_element * table)
|
||||||
|
{
|
||||||
|
ssize_t i;
|
||||||
|
|
||||||
|
/* This is where typical uses of Libidn spends very close to all CPU
|
||||||
|
time and causes most cache misses. One could easily do a binary
|
||||||
|
search instead. Before rewriting this, I want hard evidence this
|
||||||
|
slowness is at all relevant in typical applications. (I don't
|
||||||
|
dispute optimization may improve matters significantly, I'm
|
||||||
|
mostly interested in having someone give real-world benchmark on
|
||||||
|
the impact of libidn.) */
|
||||||
|
|
||||||
|
for (i = 0; table[i].start; i++)
|
||||||
|
if (ucs4 >= table[i].start &&
|
||||||
|
ucs4 <= (table[i].end ? table[i].end : table[i].start))
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
stringprep_find_string_in_table (uint32_t * ucs4,
|
||||||
|
size_t ucs4len,
|
||||||
|
size_t * tablepos,
|
||||||
|
const Stringprep_table_element * table)
|
||||||
|
{
|
||||||
|
size_t j;
|
||||||
|
ssize_t pos;
|
||||||
|
|
||||||
|
for (j = 0; j < ucs4len; j++)
|
||||||
|
if ((pos = stringprep_find_character_in_table (ucs4[j], table)) != -1)
|
||||||
|
{
|
||||||
|
if (tablepos)
|
||||||
|
*tablepos = pos;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
stringprep_apply_table_to_string (uint32_t * ucs4,
|
||||||
|
size_t * ucs4len,
|
||||||
|
size_t maxucs4len,
|
||||||
|
const Stringprep_table_element * table)
|
||||||
|
{
|
||||||
|
ssize_t pos;
|
||||||
|
size_t i, maplen;
|
||||||
|
|
||||||
|
while ((pos = stringprep_find_string_in_table (ucs4, *ucs4len,
|
||||||
|
&i, table)) != -1)
|
||||||
|
{
|
||||||
|
for (maplen = STRINGPREP_MAX_MAP_CHARS;
|
||||||
|
maplen > 0 && table[i].map[maplen - 1] == 0; maplen--)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (*ucs4len - 1 + maplen >= maxucs4len)
|
||||||
|
return STRINGPREP_TOO_SMALL_BUFFER;
|
||||||
|
|
||||||
|
memmove (&ucs4[pos + maplen], &ucs4[pos + 1],
|
||||||
|
sizeof (uint32_t) * (*ucs4len - pos - 1));
|
||||||
|
memcpy (&ucs4[pos], table[i].map, sizeof (uint32_t) * maplen);
|
||||||
|
*ucs4len = *ucs4len - 1 + maplen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STRINGPREP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INVERTED(x) ((x) & ((~0UL) >> 1))
|
||||||
|
#define UNAPPLICAPLEFLAGS(flags, profileflags) \
|
||||||
|
((!INVERTED(profileflags) && !(profileflags & flags) && profileflags) || \
|
||||||
|
( INVERTED(profileflags) && (profileflags & flags)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_4i:
|
||||||
|
* @ucs4: input/output array with string to prepare.
|
||||||
|
* @len: on input, length of input array with Unicode code points,
|
||||||
|
* on exit, length of output array with Unicode code points.
|
||||||
|
* @maxucs4len: maximum length of input/output array.
|
||||||
|
* @flags: stringprep profile flags, or 0.
|
||||||
|
* @profile: pointer to stringprep profile to use.
|
||||||
|
*
|
||||||
|
* Prepare the input UCS-4 string according to the stringprep profile,
|
||||||
|
* and write back the result to the input string.
|
||||||
|
*
|
||||||
|
* The input is not required to be zero terminated (@ucs4[@len] = 0).
|
||||||
|
* The output will not be zero terminated unless @ucs4[@len] = 0.
|
||||||
|
* Instead, see stringprep_4zi() if your input is zero terminated or
|
||||||
|
* if you want the output to be.
|
||||||
|
*
|
||||||
|
* Since the stringprep operation can expand the string, @maxucs4len
|
||||||
|
* indicate how large the buffer holding the string is. This function
|
||||||
|
* will not read or write to code points outside that size.
|
||||||
|
*
|
||||||
|
* The @flags are one of Stringprep_profile_flags, or 0.
|
||||||
|
*
|
||||||
|
* The @profile contain the instructions to perform. Your application
|
||||||
|
* can define new profiles, possibly re-using the generic stringprep
|
||||||
|
* tables that always will be part of the library, or use one of the
|
||||||
|
* currently supported profiles.
|
||||||
|
*
|
||||||
|
* Return value: Returns %STRINGPREP_OK iff successful, or an error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
stringprep_4i (uint32_t * ucs4, size_t * len, size_t maxucs4len,
|
||||||
|
Stringprep_profile_flags flags,
|
||||||
|
const Stringprep_profile * profile)
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
ssize_t k;
|
||||||
|
size_t ucs4len = *len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
for (i = 0; profile[i].operation; i++)
|
||||||
|
{
|
||||||
|
switch (profile[i].operation)
|
||||||
|
{
|
||||||
|
case STRINGPREP_NFKC:
|
||||||
|
{
|
||||||
|
uint32_t *q = 0;
|
||||||
|
|
||||||
|
if (UNAPPLICAPLEFLAGS (flags, profile[i].flags))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (flags & STRINGPREP_NO_NFKC && !profile[i].flags)
|
||||||
|
/* Profile requires NFKC, but callee asked for no NFKC. */
|
||||||
|
return STRINGPREP_FLAG_ERROR;
|
||||||
|
|
||||||
|
q = stringprep_ucs4_nfkc_normalize (ucs4, ucs4len);
|
||||||
|
if (!q)
|
||||||
|
return STRINGPREP_NFKC_FAILED;
|
||||||
|
|
||||||
|
for (ucs4len = 0; q[ucs4len]; ucs4len++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (ucs4len >= maxucs4len)
|
||||||
|
{
|
||||||
|
free (q);
|
||||||
|
return STRINGPREP_TOO_SMALL_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (ucs4, q, ucs4len * sizeof (ucs4[0]));
|
||||||
|
|
||||||
|
free (q);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STRINGPREP_PROHIBIT_TABLE:
|
||||||
|
k = stringprep_find_string_in_table (ucs4, ucs4len,
|
||||||
|
NULL, profile[i].table);
|
||||||
|
if (k != -1)
|
||||||
|
return STRINGPREP_CONTAINS_PROHIBITED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STRINGPREP_UNASSIGNED_TABLE:
|
||||||
|
if (UNAPPLICAPLEFLAGS (flags, profile[i].flags))
|
||||||
|
break;
|
||||||
|
if (flags & STRINGPREP_NO_UNASSIGNED)
|
||||||
|
{
|
||||||
|
k = stringprep_find_string_in_table
|
||||||
|
(ucs4, ucs4len, NULL, profile[i].table);
|
||||||
|
if (k != -1)
|
||||||
|
return STRINGPREP_CONTAINS_UNASSIGNED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STRINGPREP_MAP_TABLE:
|
||||||
|
if (UNAPPLICAPLEFLAGS (flags, profile[i].flags))
|
||||||
|
break;
|
||||||
|
rc = stringprep_apply_table_to_string
|
||||||
|
(ucs4, &ucs4len, maxucs4len, profile[i].table);
|
||||||
|
if (rc != STRINGPREP_OK)
|
||||||
|
return rc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STRINGPREP_BIDI_PROHIBIT_TABLE:
|
||||||
|
case STRINGPREP_BIDI_RAL_TABLE:
|
||||||
|
case STRINGPREP_BIDI_L_TABLE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STRINGPREP_BIDI:
|
||||||
|
{
|
||||||
|
int done_prohibited = 0;
|
||||||
|
int done_ral = 0;
|
||||||
|
int done_l = 0;
|
||||||
|
int contains_ral = -1;
|
||||||
|
int contains_l = -1;
|
||||||
|
|
||||||
|
for (j = 0; profile[j].operation; j++)
|
||||||
|
if (profile[j].operation == STRINGPREP_BIDI_PROHIBIT_TABLE)
|
||||||
|
{
|
||||||
|
done_prohibited = 1;
|
||||||
|
k = stringprep_find_string_in_table (ucs4, ucs4len,
|
||||||
|
NULL,
|
||||||
|
profile[j].table);
|
||||||
|
if (k != -1)
|
||||||
|
return STRINGPREP_BIDI_CONTAINS_PROHIBITED;
|
||||||
|
}
|
||||||
|
else if (profile[j].operation == STRINGPREP_BIDI_RAL_TABLE)
|
||||||
|
{
|
||||||
|
done_ral = 1;
|
||||||
|
if (stringprep_find_string_in_table
|
||||||
|
(ucs4, ucs4len, NULL, profile[j].table) != -1)
|
||||||
|
contains_ral = j;
|
||||||
|
}
|
||||||
|
else if (profile[j].operation == STRINGPREP_BIDI_L_TABLE)
|
||||||
|
{
|
||||||
|
done_l = 1;
|
||||||
|
if (stringprep_find_string_in_table
|
||||||
|
(ucs4, ucs4len, NULL, profile[j].table) != -1)
|
||||||
|
contains_l = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done_prohibited || !done_ral || !done_l)
|
||||||
|
return STRINGPREP_PROFILE_ERROR;
|
||||||
|
|
||||||
|
if (contains_ral != -1 && contains_l != -1)
|
||||||
|
return STRINGPREP_BIDI_BOTH_L_AND_RAL;
|
||||||
|
|
||||||
|
if (contains_ral != -1)
|
||||||
|
{
|
||||||
|
if (!(stringprep_find_character_in_table
|
||||||
|
(ucs4[0], profile[contains_ral].table) != -1 &&
|
||||||
|
stringprep_find_character_in_table
|
||||||
|
(ucs4[ucs4len - 1], profile[contains_ral].table) != -1))
|
||||||
|
return STRINGPREP_BIDI_LEADTRAIL_NOT_RAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return STRINGPREP_PROFILE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = ucs4len;
|
||||||
|
|
||||||
|
return STRINGPREP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
stringprep_4zi_1 (uint32_t * ucs4, size_t ucs4len, size_t maxucs4len,
|
||||||
|
Stringprep_profile_flags flags,
|
||||||
|
const Stringprep_profile * profile)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = stringprep_4i (ucs4, &ucs4len, maxucs4len, flags, profile);
|
||||||
|
if (rc != STRINGPREP_OK)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (ucs4len >= maxucs4len)
|
||||||
|
return STRINGPREP_TOO_SMALL_BUFFER;
|
||||||
|
|
||||||
|
ucs4[ucs4len] = 0;
|
||||||
|
|
||||||
|
return STRINGPREP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_4zi:
|
||||||
|
* @ucs4: input/output array with zero terminated string to prepare.
|
||||||
|
* @maxucs4len: maximum length of input/output array.
|
||||||
|
* @flags: stringprep profile flags, or 0.
|
||||||
|
* @profile: pointer to stringprep profile to use.
|
||||||
|
*
|
||||||
|
* Prepare the input zero terminated UCS-4 string according to the
|
||||||
|
* stringprep profile, and write back the result to the input string.
|
||||||
|
*
|
||||||
|
* Since the stringprep operation can expand the string, @maxucs4len
|
||||||
|
* indicate how large the buffer holding the string is. This function
|
||||||
|
* will not read or write to code points outside that size.
|
||||||
|
*
|
||||||
|
* The @flags are one of Stringprep_profile_flags, or 0.
|
||||||
|
*
|
||||||
|
* The @profile contain the instructions to perform. Your application
|
||||||
|
* can define new profiles, possibly re-using the generic stringprep
|
||||||
|
* tables that always will be part of the library, or use one of the
|
||||||
|
* currently supported profiles.
|
||||||
|
*
|
||||||
|
* Return value: Returns %STRINGPREP_OK iff successful, or an error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
stringprep_4zi (uint32_t * ucs4, size_t maxucs4len,
|
||||||
|
Stringprep_profile_flags flags,
|
||||||
|
const Stringprep_profile * profile)
|
||||||
|
{
|
||||||
|
size_t ucs4len;
|
||||||
|
|
||||||
|
for (ucs4len = 0; ucs4len < maxucs4len && ucs4[ucs4len] != 0; ucs4len++)
|
||||||
|
;
|
||||||
|
|
||||||
|
return stringprep_4zi_1 (ucs4, ucs4len, maxucs4len, flags, profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep:
|
||||||
|
* @in: input/ouput array with string to prepare.
|
||||||
|
* @maxlen: maximum length of input/output array.
|
||||||
|
* @flags: stringprep profile flags, or 0.
|
||||||
|
* @profile: pointer to stringprep profile to use.
|
||||||
|
*
|
||||||
|
* Prepare the input zero terminated UTF-8 string according to the
|
||||||
|
* stringprep profile, and write back the result to the input string.
|
||||||
|
*
|
||||||
|
* Note that you must convert strings entered in the systems locale
|
||||||
|
* into UTF-8 before using this function, see
|
||||||
|
* stringprep_locale_to_utf8().
|
||||||
|
*
|
||||||
|
* Since the stringprep operation can expand the string, @maxlen
|
||||||
|
* indicate how large the buffer holding the string is. This function
|
||||||
|
* will not read or write to characters outside that size.
|
||||||
|
*
|
||||||
|
* The @flags are one of Stringprep_profile_flags, or 0.
|
||||||
|
*
|
||||||
|
* The @profile contain the instructions to perform. Your application
|
||||||
|
* can define new profiles, possibly re-using the generic stringprep
|
||||||
|
* tables that always will be part of the library, or use one of the
|
||||||
|
* currently supported profiles.
|
||||||
|
*
|
||||||
|
* Return value: Returns %STRINGPREP_OK iff successful, or an error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
stringprep (char *in,
|
||||||
|
size_t maxlen,
|
||||||
|
Stringprep_profile_flags flags,
|
||||||
|
const Stringprep_profile * profile)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char *utf8 = NULL;
|
||||||
|
uint32_t *ucs4 = NULL;
|
||||||
|
size_t ucs4len, maxucs4len, adducs4len = 50;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (ucs4)
|
||||||
|
free (ucs4);
|
||||||
|
ucs4 = stringprep_utf8_to_ucs4 (in, -1, &ucs4len);
|
||||||
|
maxucs4len = ucs4len + adducs4len;
|
||||||
|
ucs4 = realloc (ucs4, maxucs4len * sizeof (uint32_t));
|
||||||
|
if (!ucs4)
|
||||||
|
return STRINGPREP_MALLOC_ERROR;
|
||||||
|
|
||||||
|
rc = stringprep_4i (ucs4, &ucs4len, maxucs4len, flags, profile);
|
||||||
|
adducs4len += 50;
|
||||||
|
}
|
||||||
|
while (rc == STRINGPREP_TOO_SMALL_BUFFER);
|
||||||
|
if (rc != STRINGPREP_OK)
|
||||||
|
{
|
||||||
|
free (ucs4);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
utf8 = stringprep_ucs4_to_utf8 (ucs4, ucs4len, 0, 0);
|
||||||
|
free (ucs4);
|
||||||
|
if (!utf8)
|
||||||
|
return STRINGPREP_MALLOC_ERROR;
|
||||||
|
|
||||||
|
if (strlen (utf8) >= maxlen)
|
||||||
|
{
|
||||||
|
free (utf8);
|
||||||
|
return STRINGPREP_TOO_SMALL_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (in, utf8); /* flawfinder: ignore */
|
||||||
|
|
||||||
|
free (utf8);
|
||||||
|
|
||||||
|
return STRINGPREP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_profile:
|
||||||
|
* @in: input array with UTF-8 string to prepare.
|
||||||
|
* @out: output variable with pointer to newly allocate string.
|
||||||
|
* @profile: name of stringprep profile to use.
|
||||||
|
* @flags: stringprep profile flags, or 0.
|
||||||
|
*
|
||||||
|
* Prepare the input zero terminated UTF-8 string according to the
|
||||||
|
* stringprep profile, and return the result in a newly allocated
|
||||||
|
* variable.
|
||||||
|
*
|
||||||
|
* Note that you must convert strings entered in the systems locale
|
||||||
|
* into UTF-8 before using this function, see
|
||||||
|
* stringprep_locale_to_utf8().
|
||||||
|
*
|
||||||
|
* The output @out variable must be deallocated by the caller.
|
||||||
|
*
|
||||||
|
* The @flags are one of Stringprep_profile_flags, or 0.
|
||||||
|
*
|
||||||
|
* The @profile specifies the name of the stringprep profile to use.
|
||||||
|
* It must be one of the internally supported stringprep profiles.
|
||||||
|
*
|
||||||
|
* Return value: Returns %STRINGPREP_OK iff successful, or an error code.
|
||||||
|
**/
|
||||||
|
int
|
||||||
|
stringprep_profile (const char *in,
|
||||||
|
char **out,
|
||||||
|
const char *profile, Stringprep_profile_flags flags)
|
||||||
|
{
|
||||||
|
const Stringprep_profiles *p;
|
||||||
|
char *str = NULL;
|
||||||
|
size_t len = strlen (in) + 1;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
for (p = &stringprep_profiles[0]; p->name; p++)
|
||||||
|
if (strcmp (p->name, profile) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!p || !p->name || !p->tables)
|
||||||
|
return STRINGPREP_UNKNOWN_PROFILE;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (str)
|
||||||
|
free (str);
|
||||||
|
str = (char *) malloc (len);
|
||||||
|
if (str == NULL)
|
||||||
|
return STRINGPREP_MALLOC_ERROR;
|
||||||
|
|
||||||
|
strcpy (str, in);
|
||||||
|
|
||||||
|
rc = stringprep (str, len, flags, p->tables);
|
||||||
|
len += 50;
|
||||||
|
}
|
||||||
|
while (rc == STRINGPREP_TOO_SMALL_BUFFER);
|
||||||
|
|
||||||
|
if (rc == STRINGPREP_OK)
|
||||||
|
*out = str;
|
||||||
|
else
|
||||||
|
free (str);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \mainpage GNU Internationalized Domain Name Library
|
||||||
|
*
|
||||||
|
* \section intro Introduction
|
||||||
|
*
|
||||||
|
* GNU Libidn is an implementation of the Stringprep, Punycode and IDNA
|
||||||
|
* specifications defined by the IETF Internationalized Domain Names
|
||||||
|
* (IDN) working group, used for internationalized domain names. The
|
||||||
|
* package is available under the GNU Lesser General Public License.
|
||||||
|
*
|
||||||
|
* The library contains a generic Stringprep implementation that does
|
||||||
|
* Unicode 3.2 NFKC normalization, mapping and prohibitation of
|
||||||
|
* characters, and bidirectional character handling. Profiles for
|
||||||
|
* Nameprep, iSCSI, SASL and XMPP are included. Punycode and ASCII
|
||||||
|
* Compatible Encoding (ACE) via IDNA are supported. A mechanism to
|
||||||
|
* define Top-Level Domain (TLD) specific validation tables, and to
|
||||||
|
* compare strings against those tables, is included. Default tables
|
||||||
|
* for some TLDs are also included.
|
||||||
|
*
|
||||||
|
* The Stringprep API consists of two main functions, one for
|
||||||
|
* converting data from the system's native representation into UTF-8,
|
||||||
|
* and one function to perform the Stringprep processing. Adding a
|
||||||
|
* new Stringprep profile for your application within the API is
|
||||||
|
* straightforward. The Punycode API consists of one encoding
|
||||||
|
* function and one decoding function. The IDNA API consists of the
|
||||||
|
* ToASCII and ToUnicode functions, as well as an high-level interface
|
||||||
|
* for converting entire domain names to and from the ACE encoded
|
||||||
|
* form. The TLD API consists of one set of functions to extract the
|
||||||
|
* TLD name from a domain string, one set of functions to locate the
|
||||||
|
* proper TLD table to use based on the TLD name, and core functions
|
||||||
|
* to validate a string against a TLD table, and some utility wrappers
|
||||||
|
* to perform all the steps in one call.
|
||||||
|
*
|
||||||
|
* The library is used by, e.g., GNU SASL and Shishi to process user
|
||||||
|
* names and passwords. Libidn can be built into GNU Libc to enable a
|
||||||
|
* new system-wide getaddrinfo() flag for IDN processing.
|
||||||
|
*
|
||||||
|
* Libidn is developed for the GNU/Linux system, but runs on over 20 Unix
|
||||||
|
* platforms (including Solaris, IRIX, AIX, and Tru64) and Windows.
|
||||||
|
* Libidn is written in C and (parts of) the API is accessible from C,
|
||||||
|
* C++, Emacs Lisp, Python and Java.
|
||||||
|
*
|
||||||
|
* The project web page:\n
|
||||||
|
* http://www.gnu.org/software/libidn/
|
||||||
|
*
|
||||||
|
* The software archive:\n
|
||||||
|
* ftp://alpha.gnu.org/pub/gnu/libidn/
|
||||||
|
*
|
||||||
|
* For more information see:\n
|
||||||
|
* http://www.ietf.org/html.charters/idn-charter.html\n
|
||||||
|
* http://www.ietf.org/rfc/rfc3454.txt (stringprep specification)\n
|
||||||
|
* http://www.ietf.org/rfc/rfc3490.txt (idna specification)\n
|
||||||
|
* http://www.ietf.org/rfc/rfc3491.txt (nameprep specification)\n
|
||||||
|
* http://www.ietf.org/rfc/rfc3492.txt (punycode specification)\n
|
||||||
|
* http://www.ietf.org/internet-drafts/draft-ietf-ips-iscsi-string-prep-04.txt\n
|
||||||
|
* http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-utf8-profile-01.txt\n
|
||||||
|
* http://www.ietf.org/internet-drafts/draft-ietf-sasl-anon-00.txt\n
|
||||||
|
* http://www.ietf.org/internet-drafts/draft-ietf-sasl-saslprep-00.txt\n
|
||||||
|
* http://www.ietf.org/internet-drafts/draft-ietf-xmpp-nodeprep-01.txt\n
|
||||||
|
* http://www.ietf.org/internet-drafts/draft-ietf-xmpp-resourceprep-01.txt\n
|
||||||
|
*
|
||||||
|
* Further information and paid contract development:\n
|
||||||
|
* Simon Josefsson <simon@josefsson.org>
|
||||||
|
*
|
||||||
|
* \section examples Examples
|
||||||
|
*
|
||||||
|
* \include example.c
|
||||||
|
* \include example3.c
|
||||||
|
* \include example4.c
|
||||||
|
* \include example5.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STRINGPREP_VERSION
|
||||||
|
*
|
||||||
|
* String defined via CPP denoting the header file version number.
|
||||||
|
* Used together with stringprep_check_version() to verify header file
|
||||||
|
* and run-time library consistency.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STRINGPREP_MAX_MAP_CHARS
|
||||||
|
*
|
||||||
|
* Maximum number of code points that can replace a single code point,
|
||||||
|
* during stringprep mapping.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stringprep_rc:
|
||||||
|
* @STRINGPREP_OK: Successful operation. This value is guaranteed to
|
||||||
|
* always be zero, the remaining ones are only guaranteed to hold
|
||||||
|
* non-zero values, for logical comparison purposes.
|
||||||
|
* @STRINGPREP_CONTAINS_UNASSIGNED: String contain unassigned Unicode
|
||||||
|
* code points, which is forbidden by the profile.
|
||||||
|
* @STRINGPREP_CONTAINS_PROHIBITED: String contain code points
|
||||||
|
* prohibited by the profile.
|
||||||
|
* @STRINGPREP_BIDI_BOTH_L_AND_RAL: String contain code points with
|
||||||
|
* conflicting bidirection category.
|
||||||
|
* @STRINGPREP_BIDI_LEADTRAIL_NOT_RAL: Leading and trailing character
|
||||||
|
* in string not of proper bidirectional category.
|
||||||
|
* @STRINGPREP_BIDI_CONTAINS_PROHIBITED: Contains prohibited code
|
||||||
|
* points detected by bidirectional code.
|
||||||
|
* @STRINGPREP_TOO_SMALL_BUFFER: Buffer handed to function was too
|
||||||
|
* small. This usually indicate a problem in the calling
|
||||||
|
* application.
|
||||||
|
* @STRINGPREP_PROFILE_ERROR: The stringprep profile was inconsistent.
|
||||||
|
* This usually indicate an internal error in the library.
|
||||||
|
* @STRINGPREP_FLAG_ERROR: The supplied flag conflicted with profile.
|
||||||
|
* This usually indicate a problem in the calling application.
|
||||||
|
* @STRINGPREP_UNKNOWN_PROFILE: The supplied profile name was not
|
||||||
|
* known to the library.
|
||||||
|
* @STRINGPREP_NFKC_FAILED: The Unicode NFKC operation failed. This
|
||||||
|
* usually indicate an internal error in the library.
|
||||||
|
* @STRINGPREP_MALLOC_ERROR: The malloc() was out of memory. This is
|
||||||
|
* usually a fatal error.
|
||||||
|
*
|
||||||
|
* Enumerated return codes of stringprep(), stringprep_profile()
|
||||||
|
* functions (and macros using those functions). The value 0 is
|
||||||
|
* guaranteed to always correspond to success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stringprep_profile_flags:
|
||||||
|
* @STRINGPREP_NO_NFKC: Disable the NFKC normalization, as well as
|
||||||
|
* selecting the non-NFKC case folding tables. Usually the profile
|
||||||
|
* specifies BIDI and NFKC settings, and applications should not
|
||||||
|
* override it unless in special situations.
|
||||||
|
* @STRINGPREP_NO_BIDI: Disable the BIDI step. Usually the profile
|
||||||
|
* specifies BIDI and NFKC settings, and applications should not
|
||||||
|
* override it unless in special situations.
|
||||||
|
* @STRINGPREP_NO_UNASSIGNED: Make the library return with an error if
|
||||||
|
* string contains unassigned characters according to profile.
|
||||||
|
*
|
||||||
|
* Stringprep profile flags.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stringprep_profile_steps:
|
||||||
|
*
|
||||||
|
* Various steps in the stringprep algorithm. You really want to
|
||||||
|
* study the source code to understand this one. Only useful if you
|
||||||
|
* want to add another profile.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_nameprep:
|
||||||
|
* @in: input/ouput array with string to prepare.
|
||||||
|
* @maxlen: maximum length of input/output array.
|
||||||
|
*
|
||||||
|
* Prepare the input UTF-8 string according to the nameprep profile.
|
||||||
|
* The AllowUnassigned flag is true, use
|
||||||
|
* stringprep_nameprep_no_unassigned() if you want a false
|
||||||
|
* AllowUnassigned. Returns 0 iff successful, or an error code.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_nameprep_no_unassigned:
|
||||||
|
* @in: input/ouput array with string to prepare.
|
||||||
|
* @maxlen: maximum length of input/output array.
|
||||||
|
*
|
||||||
|
* Prepare the input UTF-8 string according to the nameprep profile.
|
||||||
|
* The AllowUnassigned flag is false, use stringprep_nameprep() for
|
||||||
|
* true AllowUnassigned. Returns 0 iff successful, or an error code.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_iscsi:
|
||||||
|
* @in: input/ouput array with string to prepare.
|
||||||
|
* @maxlen: maximum length of input/output array.
|
||||||
|
*
|
||||||
|
* Prepare the input UTF-8 string according to the draft iSCSI
|
||||||
|
* stringprep profile. Returns 0 iff successful, or an error code.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_plain:
|
||||||
|
* @in: input/ouput array with string to prepare.
|
||||||
|
* @maxlen: maximum length of input/output array.
|
||||||
|
*
|
||||||
|
* Prepare the input UTF-8 string according to the draft SASL
|
||||||
|
* ANONYMOUS profile. Returns 0 iff successful, or an error code.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_xmpp_nodeprep:
|
||||||
|
* @in: input/ouput array with string to prepare.
|
||||||
|
* @maxlen: maximum length of input/output array.
|
||||||
|
*
|
||||||
|
* Prepare the input UTF-8 string according to the draft XMPP node
|
||||||
|
* identifier profile. Returns 0 iff successful, or an error code.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_xmpp_resourceprep:
|
||||||
|
* @in: input/ouput array with string to prepare.
|
||||||
|
* @maxlen: maximum length of input/output array.
|
||||||
|
*
|
||||||
|
* Prepare the input UTF-8 string according to the draft XMPP resource
|
||||||
|
* identifier profile. Returns 0 iff successful, or an error code.
|
||||||
|
**/
|
211
libidn/stringprep.h
Normal file
211
libidn/stringprep.h
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/* stringprep.h Header file for stringprep functions. -*- c -*-
|
||||||
|
* Copyright (C) 2002, 2003 Simon Josefsson
|
||||||
|
*
|
||||||
|
* This file is part of GNU Libidn.
|
||||||
|
*
|
||||||
|
* GNU Libidn is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Libidn is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with GNU Libidn; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STRINGPREP_H
|
||||||
|
#define _STRINGPREP_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
#include <unistd.h> /* ssize_t */
|
||||||
|
#include <idn-int.h> /* uint32_t */
|
||||||
|
|
||||||
|
#define STRINGPREP_VERSION "0.4.1"
|
||||||
|
|
||||||
|
/* Error codes. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
STRINGPREP_OK = 0,
|
||||||
|
/* Stringprep errors. */
|
||||||
|
STRINGPREP_CONTAINS_UNASSIGNED = 1,
|
||||||
|
STRINGPREP_CONTAINS_PROHIBITED = 2,
|
||||||
|
STRINGPREP_BIDI_BOTH_L_AND_RAL = 3,
|
||||||
|
STRINGPREP_BIDI_LEADTRAIL_NOT_RAL = 4,
|
||||||
|
STRINGPREP_BIDI_CONTAINS_PROHIBITED = 5,
|
||||||
|
/* Error in calling application. */
|
||||||
|
STRINGPREP_TOO_SMALL_BUFFER = 100,
|
||||||
|
STRINGPREP_PROFILE_ERROR = 101,
|
||||||
|
STRINGPREP_FLAG_ERROR = 102,
|
||||||
|
STRINGPREP_UNKNOWN_PROFILE = 103,
|
||||||
|
/* Internal errors. */
|
||||||
|
STRINGPREP_NFKC_FAILED = 200,
|
||||||
|
STRINGPREP_MALLOC_ERROR = 201
|
||||||
|
} Stringprep_rc;
|
||||||
|
|
||||||
|
/* Flags used when calling stringprep(). */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
STRINGPREP_NO_NFKC = 1,
|
||||||
|
STRINGPREP_NO_BIDI = 2,
|
||||||
|
STRINGPREP_NO_UNASSIGNED = 4
|
||||||
|
} Stringprep_profile_flags;
|
||||||
|
|
||||||
|
/* Steps in a stringprep profile. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
STRINGPREP_NFKC = 1,
|
||||||
|
STRINGPREP_BIDI = 2,
|
||||||
|
STRINGPREP_MAP_TABLE = 3,
|
||||||
|
STRINGPREP_UNASSIGNED_TABLE = 4,
|
||||||
|
STRINGPREP_PROHIBIT_TABLE = 5,
|
||||||
|
STRINGPREP_BIDI_PROHIBIT_TABLE = 6,
|
||||||
|
STRINGPREP_BIDI_RAL_TABLE = 7,
|
||||||
|
STRINGPREP_BIDI_L_TABLE = 8
|
||||||
|
} Stringprep_profile_steps;
|
||||||
|
|
||||||
|
#define STRINGPREP_MAX_MAP_CHARS 4
|
||||||
|
|
||||||
|
struct Stringprep_table_element
|
||||||
|
{
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t end; /* 0 if only one character */
|
||||||
|
uint32_t map[STRINGPREP_MAX_MAP_CHARS]; /* NULL if end is not 0 */
|
||||||
|
};
|
||||||
|
typedef struct Stringprep_table_element Stringprep_table_element;
|
||||||
|
|
||||||
|
struct Stringprep_table
|
||||||
|
{
|
||||||
|
Stringprep_profile_steps operation;
|
||||||
|
Stringprep_profile_flags flags;
|
||||||
|
const Stringprep_table_element *table;
|
||||||
|
};
|
||||||
|
typedef struct Stringprep_table Stringprep_profile;
|
||||||
|
|
||||||
|
struct Stringprep_profiles
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const Stringprep_profile *tables;
|
||||||
|
};
|
||||||
|
typedef struct Stringprep_profiles Stringprep_profiles;
|
||||||
|
|
||||||
|
extern const Stringprep_profiles stringprep_profiles[];
|
||||||
|
|
||||||
|
/* Profiles */
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_A_1[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_B_1[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_B_2[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_B_3[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_1_1[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_1_2[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_2_1[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_2_2[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_3[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_4[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_5[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_6[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_7[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_8[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_C_9[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_D_1[];
|
||||||
|
extern const Stringprep_table_element stringprep_rfc3454_D_2[];
|
||||||
|
|
||||||
|
/* Nameprep */
|
||||||
|
|
||||||
|
extern const Stringprep_profile stringprep_nameprep[];
|
||||||
|
|
||||||
|
#define stringprep_nameprep(in, maxlen) \
|
||||||
|
stringprep(in, maxlen, 0, stringprep_nameprep)
|
||||||
|
|
||||||
|
#define stringprep_nameprep_no_unassigned(in, maxlen) \
|
||||||
|
stringprep(in, maxlen, STRINGPREP_NO_UNASSIGNED, stringprep_nameprep)
|
||||||
|
|
||||||
|
/* SASL */
|
||||||
|
|
||||||
|
extern const Stringprep_profile stringprep_saslprep[];
|
||||||
|
extern const Stringprep_profile stringprep_plain[];
|
||||||
|
extern const Stringprep_profile stringprep_trace[];
|
||||||
|
|
||||||
|
#define stringprep_plain(in, maxlen) \
|
||||||
|
stringprep(in, maxlen, 0, stringprep_plain)
|
||||||
|
|
||||||
|
/* Kerberos */
|
||||||
|
|
||||||
|
extern const Stringprep_profile stringprep_kerberos5[];
|
||||||
|
|
||||||
|
#define stringprep_kerberos5(in, maxlen) \
|
||||||
|
stringprep(in, maxlen, 0, stringprep_kerberos5)
|
||||||
|
|
||||||
|
/* XMPP */
|
||||||
|
|
||||||
|
extern const Stringprep_profile stringprep_xmpp_nodeprep[];
|
||||||
|
extern const Stringprep_profile stringprep_xmpp_resourceprep[];
|
||||||
|
extern const Stringprep_table_element stringprep_xmpp_nodeprep_prohibit[];
|
||||||
|
|
||||||
|
#define stringprep_xmpp_nodeprep(in, maxlen) \
|
||||||
|
stringprep(in, maxlen, 0, stringprep_xmpp_nodeprep)
|
||||||
|
#define stringprep_xmpp_resourceprep(in, maxlen) \
|
||||||
|
stringprep(in, maxlen, 0, stringprep_xmpp_resourceprep)
|
||||||
|
|
||||||
|
/* iSCSI */
|
||||||
|
|
||||||
|
extern const Stringprep_profile stringprep_iscsi[];
|
||||||
|
|
||||||
|
#define stringprep_iscsi(in, maxlen) \
|
||||||
|
stringprep(in, maxlen, 0, stringprep_iscsi)
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
|
||||||
|
extern int stringprep_4i (uint32_t * ucs4, size_t * len, size_t maxucs4len,
|
||||||
|
Stringprep_profile_flags flags,
|
||||||
|
const Stringprep_profile * profile);
|
||||||
|
extern int stringprep_4zi (uint32_t * ucs4, size_t maxucs4len,
|
||||||
|
Stringprep_profile_flags flags,
|
||||||
|
const Stringprep_profile * profile);
|
||||||
|
extern int stringprep (char *in, size_t maxlen,
|
||||||
|
Stringprep_profile_flags flags,
|
||||||
|
const Stringprep_profile * profile);
|
||||||
|
|
||||||
|
extern int stringprep_profile (const char *in,
|
||||||
|
char **out,
|
||||||
|
const char *profile,
|
||||||
|
Stringprep_profile_flags flags);
|
||||||
|
|
||||||
|
extern const char *stringprep_check_version (const char *req_version);
|
||||||
|
|
||||||
|
/* Utility */
|
||||||
|
|
||||||
|
extern int stringprep_unichar_to_utf8 (uint32_t c, char *outbuf);
|
||||||
|
extern uint32_t stringprep_utf8_to_unichar (const char *p);
|
||||||
|
|
||||||
|
extern uint32_t *stringprep_utf8_to_ucs4 (const char *str, ssize_t len,
|
||||||
|
size_t * items_written);
|
||||||
|
extern char *stringprep_ucs4_to_utf8 (const uint32_t * str, ssize_t len,
|
||||||
|
size_t * items_read,
|
||||||
|
size_t * items_written);
|
||||||
|
|
||||||
|
extern char *stringprep_utf8_nfkc_normalize (const char *str, ssize_t len);
|
||||||
|
extern uint32_t *stringprep_ucs4_nfkc_normalize (uint32_t * str,
|
||||||
|
ssize_t len);
|
||||||
|
|
||||||
|
extern const char *stringprep_locale_charset (void);
|
||||||
|
extern char *stringprep_convert (const char *str,
|
||||||
|
const char *to_codeset,
|
||||||
|
const char *from_codeset);
|
||||||
|
extern char *stringprep_locale_to_utf8 (const char *str);
|
||||||
|
extern char *stringprep_utf8_to_locale (const char *str);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _STRINGPREP_H */
|
2
libidn/sysdeps/unix/configure
vendored
Executable file
2
libidn/sysdeps/unix/configure
vendored
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
# Signal that libidn is available.
|
||||||
|
libc_cv_idn=yes
|
283
libidn/toutf8.c
Normal file
283
libidn/toutf8.c
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
/* toutf8.c Convert strings from system locale into UTF-8.
|
||||||
|
* Copyright (C) 2002, 2003, 2004 Simon Josefsson
|
||||||
|
*
|
||||||
|
* This file is part of GNU Libidn.
|
||||||
|
*
|
||||||
|
* GNU Libidn is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Libidn is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with GNU Libidn; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "stringprep.h"
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define HAVE_ICONV 1
|
||||||
|
# define LOCALE_WORKS 1
|
||||||
|
# define ICONV_CONST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ICONV
|
||||||
|
# include <iconv.h>
|
||||||
|
|
||||||
|
# if LOCALE_WORKS
|
||||||
|
# include <langinfo.h>
|
||||||
|
# include <locale.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef _LIBC
|
||||||
|
static const char *
|
||||||
|
stringprep_locale_charset_slow (void)
|
||||||
|
{
|
||||||
|
return nl_langinfo (CODESET);
|
||||||
|
const char *charset = getenv ("CHARSET"); /* flawfinder: ignore */
|
||||||
|
|
||||||
|
if (charset && *charset)
|
||||||
|
return charset;
|
||||||
|
|
||||||
|
# ifdef LOCALE_WORKS
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = setlocale (LC_CTYPE, NULL);
|
||||||
|
setlocale (LC_CTYPE, "");
|
||||||
|
|
||||||
|
charset = nl_langinfo (CODESET);
|
||||||
|
|
||||||
|
setlocale (LC_CTYPE, p);
|
||||||
|
|
||||||
|
if (charset && *charset)
|
||||||
|
return charset;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
return "ASCII";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *stringprep_locale_charset_cache;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_locale_charset:
|
||||||
|
*
|
||||||
|
* Find out system locale charset.
|
||||||
|
*
|
||||||
|
* Note that this function return what it believe the SYSTEM is using
|
||||||
|
* as a locale, not what locale the program is currently in (modified,
|
||||||
|
* e.g., by a setlocale(LC_CTYPE, "ISO-8859-1")). The reason is that
|
||||||
|
* data read from argv[], stdin etc comes from the system, and is more
|
||||||
|
* likely to be encoded using the system locale than the program
|
||||||
|
* locale.
|
||||||
|
*
|
||||||
|
* You can set the environment variable CHARSET to override the value
|
||||||
|
* returned. Note that this function caches the result, so you will
|
||||||
|
* have to modify CHARSET before calling (even indirectly) any
|
||||||
|
* stringprep functions, e.g., by setting it when invoking the
|
||||||
|
* application.
|
||||||
|
*
|
||||||
|
* Return value: Return the character set used by the system locale.
|
||||||
|
* It will never return NULL, but use "ASCII" as a fallback.
|
||||||
|
**/
|
||||||
|
# ifdef _LIBC
|
||||||
|
# define stringprep_locale_charset() nl_langinfo (CODESET)
|
||||||
|
# else
|
||||||
|
const char *
|
||||||
|
stringprep_locale_charset (void)
|
||||||
|
{
|
||||||
|
if (!stringprep_locale_charset_cache)
|
||||||
|
stringprep_locale_charset_cache = stringprep_locale_charset_slow ();
|
||||||
|
|
||||||
|
return stringprep_locale_charset_cache;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_convert:
|
||||||
|
* @str: input zero-terminated string.
|
||||||
|
* @to_codeset: name of destination character set.
|
||||||
|
* @from_codeset: name of origin character set, as used by @str.
|
||||||
|
*
|
||||||
|
* Convert the string from one character set to another using the
|
||||||
|
* system's iconv() function.
|
||||||
|
*
|
||||||
|
* Return value: Returns newly allocated zero-terminated string which
|
||||||
|
* is @str transcoded into to_codeset.
|
||||||
|
**/
|
||||||
|
char *
|
||||||
|
stringprep_convert (const char *str,
|
||||||
|
const char *to_codeset, const char *from_codeset)
|
||||||
|
{
|
||||||
|
iconv_t cd;
|
||||||
|
char *dest;
|
||||||
|
char *outp;
|
||||||
|
ICONV_CONST char *p;
|
||||||
|
size_t inbytes_remaining;
|
||||||
|
size_t outbytes_remaining;
|
||||||
|
size_t err;
|
||||||
|
size_t outbuf_size;
|
||||||
|
int have_error = 0;
|
||||||
|
|
||||||
|
if (strcmp (to_codeset, from_codeset) == 0)
|
||||||
|
{
|
||||||
|
#if defined HAVE_STRDUP || defined _LIBC
|
||||||
|
return strdup (str);
|
||||||
|
#else
|
||||||
|
char *p;
|
||||||
|
p = malloc (strlen (str) + 1);
|
||||||
|
if (!p)
|
||||||
|
return NULL;
|
||||||
|
return strcpy (p, str);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
cd = iconv_open (to_codeset, from_codeset);
|
||||||
|
|
||||||
|
if (cd == (iconv_t) - 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p = (ICONV_CONST char *) str;
|
||||||
|
|
||||||
|
inbytes_remaining = strlen (p);
|
||||||
|
/* Guess the maximum length the output string can have. */
|
||||||
|
outbuf_size = (inbytes_remaining + 1) * MAX (7, MB_CUR_MAX);
|
||||||
|
|
||||||
|
outp = dest = malloc (outbuf_size);
|
||||||
|
if (dest == NULL)
|
||||||
|
goto out;
|
||||||
|
outbytes_remaining = outbuf_size - 1; /* -1 for NUL */
|
||||||
|
|
||||||
|
again:
|
||||||
|
|
||||||
|
err = iconv (cd, (ICONV_CONST char **) &p, &inbytes_remaining,
|
||||||
|
&outp, &outbytes_remaining);
|
||||||
|
|
||||||
|
if (err == (size_t) - 1)
|
||||||
|
{
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
|
case EINVAL:
|
||||||
|
/* Incomplete text, do not report an error */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case E2BIG:
|
||||||
|
{
|
||||||
|
size_t used = outp - dest;
|
||||||
|
char *newdest;
|
||||||
|
|
||||||
|
outbuf_size *= 2;
|
||||||
|
newdest = realloc (dest, outbuf_size);
|
||||||
|
if (newdest == NULL)
|
||||||
|
{
|
||||||
|
have_error = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
dest = newdest;
|
||||||
|
|
||||||
|
outp = dest + used;
|
||||||
|
outbytes_remaining = outbuf_size - used - 1; /* -1 for NUL */
|
||||||
|
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EILSEQ:
|
||||||
|
have_error = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
have_error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*outp = '\0';
|
||||||
|
|
||||||
|
if (*p != '\0')
|
||||||
|
have_error = 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
iconv_close (cd);
|
||||||
|
|
||||||
|
if (have_error)
|
||||||
|
{
|
||||||
|
free (dest);
|
||||||
|
dest = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* HAVE_ICONV */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
stringprep_locale_charset ()
|
||||||
|
{
|
||||||
|
return "ASCII";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
stringprep_convert (const char *str,
|
||||||
|
const char *to_codeset, const char *from_codeset)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
fprintf (stderr, "libidn: warning: libiconv not installed, cannot "
|
||||||
|
"convert data to UTF-8\n");
|
||||||
|
p = malloc (strlen (str) + 1);
|
||||||
|
if (!p)
|
||||||
|
return NULL;
|
||||||
|
strcpy (p, str);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_ICONV */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_locale_to_utf8:
|
||||||
|
* @str: input zero terminated string.
|
||||||
|
*
|
||||||
|
* Convert string encoded in the locale's character set into UTF-8 by
|
||||||
|
* using stringprep_convert().
|
||||||
|
*
|
||||||
|
* Return value: Returns newly allocated zero-terminated string which
|
||||||
|
* is @str transcoded into UTF-8.
|
||||||
|
**/
|
||||||
|
char *
|
||||||
|
stringprep_locale_to_utf8 (const char *str)
|
||||||
|
{
|
||||||
|
return stringprep_convert (str, "UTF-8", stringprep_locale_charset ());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stringprep_utf8_to_locale:
|
||||||
|
* @str: input zero terminated string.
|
||||||
|
*
|
||||||
|
* Convert string encoded in UTF-8 into the locale's character set by
|
||||||
|
* using stringprep_convert().
|
||||||
|
*
|
||||||
|
* Return value: Returns newly allocated zero-terminated string which
|
||||||
|
* is @str transcoded into the locale's character set.
|
||||||
|
**/
|
||||||
|
char *
|
||||||
|
stringprep_utf8_to_locale (const char *str)
|
||||||
|
{
|
||||||
|
return stringprep_convert (str, stringprep_locale_charset (), "UTF-8");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user