Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / contrib / idn / idnkit-1.0-src / lib / nameprep.c
blob85f8b6ad406ea83339b895ea5c71d6758c1c9039
1 /* $NetBSD: nameprep.c,v 1.4 2014/12/10 04:37:55 christos Exp $ */
3 #ifndef lint
4 static char *rcsid = "Id: nameprep.c,v 1.1 2003/06/04 00:25:56 marka Exp ";
5 #endif
7 /*
8 * Copyright (c) 2001,2002 Japan Network Information Center.
9 * All rights reserved.
11 * By using this file, you agree to the terms and conditions set forth bellow.
13 * LICENSE TERMS AND CONDITIONS
15 * The following License Terms and Conditions apply, unless a different
16 * license is obtained from Japan Network Information Center ("JPNIC"),
17 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
18 * Chiyoda-ku, Tokyo 101-0047, Japan.
20 * 1. Use, Modification and Redistribution (including distribution of any
21 * modified or derived work) in source and/or binary forms is permitted
22 * under this License Terms and Conditions.
24 * 2. Redistribution of source code must retain the copyright notices as they
25 * appear in each source code file, this License Terms and Conditions.
27 * 3. Redistribution in binary form must reproduce the Copyright Notice,
28 * this License Terms and Conditions, in the documentation and/or other
29 * materials provided with the distribution. For the purposes of binary
30 * distribution the "Copyright Notice" refers to the following language:
31 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
33 * 4. The name of JPNIC may not be used to endorse or promote products
34 * derived from this Software without specific prior written approval of
35 * JPNIC.
37 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
38 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
40 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
45 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
46 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
50 #include <config.h>
52 #include <stdlib.h>
53 #include <string.h>
55 #include <idn/result.h>
56 #include <idn/assert.h>
57 #include <idn/log.h>
58 #include <idn/logmacro.h>
59 #include <idn/debug.h>
60 #include <idn/nameprep.h>
62 #define UCS_MAX 0x7fffffff
63 #define UNICODE_MAX 0x10ffff
67 * Load NAMEPREP compiled tables.
69 #include "nameprepdata.c"
72 * Define mapping/checking functions for each version of the draft.
75 #define VERSION rfc3491
76 #include "nameprep_template.c"
77 #undef VERSION
79 typedef const char *(*nameprep_mapproc)(unsigned long v);
80 typedef int (*nameprep_checkproc)(unsigned long v);
81 typedef idn_biditype_t (*nameprep_biditypeproc)(unsigned long v);
83 static struct idn_nameprep {
84 char *version;
85 nameprep_mapproc map_proc;
86 nameprep_checkproc prohibited_proc;
87 nameprep_checkproc unassigned_proc;
88 nameprep_biditypeproc biditype_proc;
89 } nameprep_versions[] = {
90 #define MAKE_NAMEPREP_HANDLE(version, id) \
91 { version, \
92 compose_sym2(nameprep_map_, id), \
93 compose_sym2(nameprep_prohibited_, id), \
94 compose_sym2(nameprep_unassigned_, id), \
95 compose_sym2(nameprep_biditype_, id), }
96 MAKE_NAMEPREP_HANDLE("RFC3491", rfc3491),
97 { NULL, NULL, NULL },
100 static idn_result_t idn_nameprep_check(nameprep_checkproc proc,
101 const unsigned long *str,
102 const unsigned long **found);
104 idn_result_t
105 idn_nameprep_create(const char *version, idn_nameprep_t *handlep) {
106 idn_nameprep_t handle;
108 assert(handlep != NULL);
110 TRACE(("idn_nameprep_create(version=%-.50s)\n",
111 version == NULL ? "<NULL>" : version));
113 if (version == NULL)
114 version = IDN_NAMEPREP_CURRENT;
117 * Lookup table for the specified version. Since the number of
118 * versions won't be large (I don't want see draft-23 or such :-),
119 * simple linear search is OK.
121 for (handle = nameprep_versions; handle->version != NULL; handle++) {
122 if (strcmp(handle->version, version) == 0) {
123 *handlep = handle;
124 return (idn_success);
127 return (idn_notfound);
130 void
131 idn_nameprep_destroy(idn_nameprep_t handle) {
132 assert(handle != NULL);
134 TRACE(("idn_nameprep_destroy()\n"));
136 /* Nothing to do. */
139 idn_result_t
140 idn_nameprep_map(idn_nameprep_t handle, const unsigned long *from,
141 unsigned long *to, size_t tolen) {
142 assert(handle != NULL && from != NULL && to != NULL);
144 TRACE(("idn_nameprep_map(ctx=%s, from=\"%s\")\n",
145 handle->version, idn__debug_ucs4xstring(from, 50)));
147 while (*from != '\0') {
148 unsigned long v = *from;
149 const char *mapped;
151 if (v > UCS_MAX) {
152 /* This cannot happen, but just in case.. */
153 return (idn_invalid_codepoint);
154 } else if (v > UNICODE_MAX) {
155 /* No mapping is possible. */
156 mapped = NULL;
157 } else {
158 /* Try mapping. */
159 mapped = (*handle->map_proc)(v);
162 if (mapped == NULL) {
163 /* No mapping. Just copy verbatim. */
164 if (tolen < 1)
165 return (idn_buffer_overflow);
166 *to++ = v;
167 tolen--;
168 } else {
169 const unsigned char *mappeddata;
170 size_t mappedlen;
172 mappeddata = (const unsigned char *)mapped + 1;
173 mappedlen = *mapped;
175 if (tolen < (mappedlen + 3) / 4)
176 return (idn_buffer_overflow);
177 tolen -= (mappedlen + 3) / 4;
178 while (mappedlen >= 4) {
179 *to = *mappeddata++;
180 *to |= *mappeddata++ << 8;
181 *to |= *mappeddata++ << 16;
182 *to |= *mappeddata++ << 24;
183 mappedlen -= 4;
184 to++;
186 if (mappedlen > 0) {
187 *to = *mappeddata++;
188 *to |= (mappedlen >= 2) ?
189 *mappeddata++ << 8: 0;
190 *to |= (mappedlen >= 3) ?
191 *mappeddata++ << 16: 0;
192 to++;
195 from++;
197 if (tolen == 0)
198 return (idn_buffer_overflow);
199 *to = '\0';
200 return (idn_success);
203 idn_result_t
204 idn_nameprep_isprohibited(idn_nameprep_t handle, const unsigned long *str,
205 const unsigned long **found) {
206 assert(handle != NULL && str != NULL && found != NULL);
208 TRACE(("idn_nameprep_isprohibited(ctx=%s, str=\"%s\")\n",
209 handle->version, idn__debug_ucs4xstring(str, 50)));
211 return (idn_nameprep_check(handle->prohibited_proc, str, found));
214 idn_result_t
215 idn_nameprep_isunassigned(idn_nameprep_t handle, const unsigned long *str,
216 const unsigned long **found) {
217 assert(handle != NULL && str != NULL && found != NULL);
219 TRACE(("idn_nameprep_isunassigned(handle->version, str=\"%s\")\n",
220 handle->version, idn__debug_ucs4xstring(str, 50)));
222 return (idn_nameprep_check(handle->unassigned_proc, str, found));
225 static idn_result_t
226 idn_nameprep_check(nameprep_checkproc proc, const unsigned long *str,
227 const unsigned long **found) {
228 unsigned long v;
230 while (*str != '\0') {
231 v = *str;
233 if (v > UCS_MAX) {
234 /* This cannot happen, but just in case.. */
235 return (idn_invalid_codepoint);
236 } else if (v > UNICODE_MAX) {
237 /* It is invalid.. */
238 *found = str;
239 return (idn_success);
240 } else if ((*proc)(v)) {
241 *found = str;
242 return (idn_success);
244 str++;
246 *found = NULL;
247 return (idn_success);
250 idn_result_t
251 idn_nameprep_isvalidbidi(idn_nameprep_t handle, const unsigned long *str,
252 const unsigned long **found) {
253 unsigned long v;
254 idn_biditype_t first_char;
255 idn_biditype_t last_char;
256 int found_r_al;
258 assert(handle != NULL && str != NULL && found != NULL);
260 TRACE(("idn_nameprep_isvalidbidi(ctx=%s, str=\"%s\")\n",
261 handle->version, idn__debug_ucs4xstring(str, 50)));
263 if (*str == '\0') {
264 *found = NULL;
265 return (idn_success);
269 * check first character's type and initialize variables.
271 found_r_al = 0;
272 if (*str > UCS_MAX) {
273 /* This cannot happen, but just in case.. */
274 return (idn_invalid_codepoint);
275 } else if (*str > UNICODE_MAX) {
276 /* It is invalid.. */
277 *found = str;
278 return (idn_success);
280 first_char = last_char = (*(handle->biditype_proc))(*str);
281 if (first_char == idn_biditype_r_al) {
282 found_r_al = 1;
284 str++;
287 * see whether string is valid or not.
289 while (*str != '\0') {
290 v = *str;
292 if (v > UCS_MAX) {
293 /* This cannot happen, but just in case.. */
294 return (idn_invalid_codepoint);
295 } else if (v > UNICODE_MAX) {
296 /* It is invalid.. */
297 *found = str;
298 return (idn_success);
299 } else {
300 last_char = (*(handle->biditype_proc))(v);
301 if (found_r_al && last_char == idn_biditype_l) {
302 *found = str;
303 return (idn_success);
305 if (first_char != idn_biditype_r_al && last_char == idn_biditype_r_al) {
306 *found = str;
307 return (idn_success);
309 if (last_char == idn_biditype_r_al) {
310 found_r_al = 1;
313 str++;
316 if (found_r_al) {
317 if (last_char != idn_biditype_r_al) {
318 *found = str - 1;
319 return (idn_success);
323 *found = NULL;
324 return (idn_success);
327 idn_result_t
328 idn_nameprep_createproc(const char *parameter, void **handlep) {
329 return idn_nameprep_create(parameter, (idn_nameprep_t *)handlep);
332 void
333 idn_nameprep_destroyproc(void *handle) {
334 idn_nameprep_destroy((idn_nameprep_t)handle);
337 idn_result_t
338 idn_nameprep_mapproc(void *handle, const unsigned long *from,
339 unsigned long *to, size_t tolen) {
340 return idn_nameprep_map((idn_nameprep_t)handle, from, to, tolen);
343 idn_result_t
344 idn_nameprep_prohibitproc(void *handle, const unsigned long *str,
345 const unsigned long **found) {
346 return idn_nameprep_isprohibited((idn_nameprep_t)handle, str, found);
349 idn_result_t
350 idn_nameprep_unassignedproc(void *handle, const unsigned long *str,
351 const unsigned long **found) {
352 return idn_nameprep_isunassigned((idn_nameprep_t)handle, str, found);
355 idn_result_t
356 idn_nameprep_bidiproc(void *handle, const unsigned long *str,
357 const unsigned long **found) {
358 return idn_nameprep_isvalidbidi((idn_nameprep_t)handle, str, found);