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:
Ulrich Drepper 2004-03-08 03:55:39 +00:00
parent 001836c8c1
commit 01859b1c24
20 changed files with 19096 additions and 0 deletions

1
libidn/Banner Normal file
View file

@ -0,0 +1 @@
GNU Libidn by Simon Josefsson

20
libidn/ChangeLog Normal file
View 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
View 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
View file

@ -0,0 +1,5 @@
libcidn {
GLIBC_PRIVATE {
idna_to_ascii_lz;
}
}

2
libidn/configure vendored Normal file
View 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
View 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

File diff suppressed because it is too large Load diff

286
libidn/idn-int.h Normal file
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

310
libidn/profiles.c Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

667
libidn/stringprep.c Normal file
View 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
View 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
View file

@ -0,0 +1,2 @@
# Signal that libidn is available.
libc_cv_idn=yes

283
libidn/toutf8.c Normal file
View 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");
}