Branch data Line data Source code
1 : : /* idna.c --- Prototypes for Internationalized Domain Name library.
2 : : Copyright (C) 2002-2012 Simon Josefsson
3 : :
4 : : This file is part of GNU Libidn.
5 : :
6 : : GNU Libidn is free software: you can redistribute it and/or
7 : : modify it under the terms of either:
8 : :
9 : : * the GNU Lesser General Public License as published by the Free
10 : : Software Foundation; either version 3 of the License, or (at
11 : : your option) any later version.
12 : :
13 : : or
14 : :
15 : : * the GNU General Public License as published by the Free
16 : : Software Foundation; either version 2 of the License, or (at
17 : : your option) any later version.
18 : :
19 : : or both in parallel, as here.
20 : :
21 : : GNU Libidn is distributed in the hope that it will be useful,
22 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : : General Public License for more details.
25 : :
26 : : You should have received copies of the GNU General Public License and
27 : : the GNU Lesser General Public License along with this program. If
28 : : not, see <http://www.gnu.org/licenses/>. */
29 : :
30 : : #ifdef HAVE_CONFIG_H
31 : : # include "config.h"
32 : : #endif
33 : :
34 : : #include <stdlib.h>
35 : : #include <string.h>
36 : : #include <stringprep.h>
37 : : #include <punycode.h>
38 : :
39 : : #include "idna.h"
40 : :
41 : : /* Get c_strcasecmp. */
42 : : #include <c-strcase.h>
43 : :
44 : : #define DOTP(c) ((c) == 0x002E || (c) == 0x3002 || \
45 : : (c) == 0xFF0E || (c) == 0xFF61)
46 : :
47 : : /* Core functions */
48 : :
49 : : /**
50 : : * idna_to_ascii_4i:
51 : : * @in: input array with unicode code points.
52 : : * @inlen: length of input array with unicode code points.
53 : : * @out: output zero terminated string that must have room for at
54 : : * least 63 characters plus the terminating zero.
55 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
56 : : * %IDNA_USE_STD3_ASCII_RULES.
57 : : *
58 : : * The ToASCII operation takes a sequence of Unicode code points that
59 : : * make up one domain label and transforms it into a sequence of code
60 : : * points in the ASCII range (0..7F). If ToASCII succeeds, the
61 : : * original sequence and the resulting sequence are equivalent labels.
62 : : *
63 : : * It is important to note that the ToASCII operation can fail. ToASCII
64 : : * fails if any step of it fails. If any step of the ToASCII operation
65 : : * fails on any label in a domain name, that domain name MUST NOT be used
66 : : * as an internationalized domain name. The method for deadling with this
67 : : * failure is application-specific.
68 : : *
69 : : * The inputs to ToASCII are a sequence of code points, the AllowUnassigned
70 : : * flag, and the UseSTD3ASCIIRules flag. The output of ToASCII is either a
71 : : * sequence of ASCII code points or a failure condition.
72 : : *
73 : : * ToASCII never alters a sequence of code points that are all in the ASCII
74 : : * range to begin with (although it could fail). Applying the ToASCII
75 : : * operation multiple times has exactly the same effect as applying it just
76 : : * once.
77 : : *
78 : : * Return value: Returns 0 on success, or an #Idna_rc error code.
79 : : */
80 : : int
81 : 221 : idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags)
82 : : {
83 : : size_t len, outlen;
84 : : uint32_t *src; /* XXX don't need to copy data? */
85 : : int rc;
86 : :
87 : : /*
88 : : * ToASCII consists of the following steps:
89 : : *
90 : : * 1. If all code points in the sequence are in the ASCII range (0..7F)
91 : : * then skip to step 3.
92 : : */
93 : :
94 : : {
95 : : size_t i;
96 : : int inasciirange;
97 : :
98 : 221 : inasciirange = 1;
99 [ + + ]: 2089 : for (i = 0; i < inlen; i++)
100 [ + + ]: 1868 : if (in[i] > 0x7F)
101 : 786 : inasciirange = 0;
102 [ + + ]: 221 : if (inasciirange)
103 : : {
104 : 74 : src = malloc (sizeof (in[0]) * (inlen + 1));
105 [ - + ]: 74 : if (src == NULL)
106 : 0 : return IDNA_MALLOC_ERROR;
107 : :
108 : 74 : memcpy (src, in, sizeof (in[0]) * inlen);
109 : 74 : src[inlen] = 0;
110 : :
111 : 74 : goto step3;
112 : : }
113 : : }
114 : :
115 : : /*
116 : : * 2. Perform the steps specified in [NAMEPREP] and fail if there is
117 : : * an error. The AllowUnassigned flag is used in [NAMEPREP].
118 : : */
119 : :
120 : : {
121 : : char *p;
122 : :
123 : 147 : p = stringprep_ucs4_to_utf8 (in, (ssize_t) inlen, NULL, NULL);
124 [ - + ]: 147 : if (p == NULL)
125 : 0 : return IDNA_MALLOC_ERROR;
126 : :
127 : 147 : len = strlen (p);
128 : : do
129 : : {
130 : : char *newp;
131 : :
132 : 147 : len = 2 * len + 10; /* XXX better guess? */
133 : 147 : newp = realloc (p, len);
134 [ - + ]: 147 : if (newp == NULL)
135 : : {
136 : 0 : free (p);
137 : 0 : return IDNA_MALLOC_ERROR;
138 : : }
139 : 147 : p = newp;
140 : :
141 [ + + ]: 147 : if (flags & IDNA_ALLOW_UNASSIGNED)
142 : 98 : rc = stringprep_nameprep (p, len);
143 : : else
144 : 49 : rc = stringprep_nameprep_no_unassigned (p, len);
145 : : }
146 [ - + ]: 147 : while (rc == STRINGPREP_TOO_SMALL_BUFFER);
147 : :
148 [ + + ]: 147 : if (rc != STRINGPREP_OK)
149 : : {
150 : 17 : free (p);
151 : 17 : return IDNA_STRINGPREP_ERROR;
152 : : }
153 : :
154 : 130 : src = stringprep_utf8_to_ucs4 (p, -1, NULL);
155 : :
156 : 130 : free (p);
157 : :
158 [ - + ]: 130 : if (!src)
159 : 0 : return IDNA_MALLOC_ERROR;
160 : : }
161 : :
162 : : step3:
163 : : /*
164 : : * 3. If the UseSTD3ASCIIRules flag is set, then perform these checks:
165 : : *
166 : : * (a) Verify the absence of non-LDH ASCII code points; that is,
167 : : * the absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F.
168 : : *
169 : : * (b) Verify the absence of leading and trailing hyphen-minus;
170 : : * that is, the absence of U+002D at the beginning and end of
171 : : * the sequence.
172 : : */
173 : :
174 [ + + ]: 204 : if (flags & IDNA_USE_STD3_ASCII_RULES)
175 : : {
176 : : size_t i;
177 : :
178 [ + + ]: 1057 : for (i = 0; src[i]; i++)
179 [ + + ][ + - ]: 915 : if (src[i] <= 0x2C || src[i] == 0x2E || src[i] == 0x2F ||
[ + - ][ + + ]
180 [ + + ][ + + ]: 910 : (src[i] >= 0x3A && src[i] <= 0x40) ||
181 [ + - ][ + + ]: 909 : (src[i] >= 0x5B && src[i] <= 0x60) ||
182 [ - + ]: 170 : (src[i] >= 0x7B && src[i] <= 0x7F))
183 : : {
184 : 6 : free (src);
185 : 6 : return IDNA_CONTAINS_NON_LDH;
186 : : }
187 : :
188 [ + + ][ + - ]: 142 : if (src[0] == 0x002D || (i > 0 && src[i - 1] == 0x002D))
[ + + ]
189 : : {
190 : 4 : free (src);
191 : 4 : return IDNA_CONTAINS_MINUS;
192 : : }
193 : : }
194 : :
195 : : /*
196 : : * 4. If all code points in the sequence are in the ASCII range
197 : : * (0..7F), then skip to step 8.
198 : : */
199 : :
200 : : {
201 : : size_t i;
202 : : int inasciirange;
203 : :
204 : 194 : inasciirange = 1;
205 [ + + ]: 1944 : for (i = 0; src[i]; i++)
206 : : {
207 [ + + ]: 1750 : if (src[i] > 0x7F)
208 : 724 : inasciirange = 0;
209 : : /* copy string to output buffer if we are about to skip to step8 */
210 [ + - ]: 1750 : if (i < 64)
211 : 1750 : out[i] = src[i];
212 : : }
213 [ + - ]: 194 : if (i < 64)
214 : 194 : out[i] = '\0';
215 [ + + ]: 194 : if (inasciirange)
216 : 77 : goto step8;
217 : : }
218 : :
219 : : /*
220 : : * 5. Verify that the sequence does NOT begin with the ACE prefix.
221 : : *
222 : : */
223 : :
224 : : {
225 : : size_t i;
226 : : int match;
227 : :
228 : 117 : match = 1;
229 [ + + ][ + + ]: 243 : for (i = 0; match && i < strlen (IDNA_ACE_PREFIX); i++)
230 [ + + ]: 126 : if (((uint32_t) IDNA_ACE_PREFIX[i] & 0xFF) != src[i])
231 : 114 : match = 0;
232 [ + + ]: 117 : if (match)
233 : : {
234 : 3 : free (src);
235 : 3 : return IDNA_CONTAINS_ACE_PREFIX;
236 : : }
237 : : }
238 : :
239 : : /*
240 : : * 6. Encode the sequence using the encoding algorithm in [PUNYCODE]
241 : : * and fail if there is an error.
242 : : */
243 [ + + ]: 1336 : for (len = 0; src[len]; len++)
244 : : ;
245 : 114 : src[len] = '\0';
246 : 114 : outlen = 63 - strlen (IDNA_ACE_PREFIX);
247 : 114 : rc = punycode_encode (len, src, NULL,
248 : : &outlen, &out[strlen (IDNA_ACE_PREFIX)]);
249 [ + + ]: 114 : if (rc != PUNYCODE_SUCCESS)
250 : : {
251 : 2 : free (src);
252 : 2 : return IDNA_PUNYCODE_ERROR;
253 : : }
254 : 112 : out[strlen (IDNA_ACE_PREFIX) + outlen] = '\0';
255 : :
256 : : /*
257 : : * 7. Prepend the ACE prefix.
258 : : */
259 : :
260 : 112 : memcpy (out, IDNA_ACE_PREFIX, strlen (IDNA_ACE_PREFIX));
261 : :
262 : : /*
263 : : * 8. Verify that the number of code points is in the range 1 to 63
264 : : * inclusive (0 is excluded).
265 : : */
266 : :
267 : : step8:
268 : 189 : free (src);
269 [ + + ][ - + ]: 189 : if (strlen (out) < 1 || strlen (out) > 63)
270 : 3 : return IDNA_INVALID_LENGTH;
271 : :
272 : 221 : return IDNA_SUCCESS;
273 : : }
274 : :
275 : : /* ToUnicode(). May realloc() utf8in. Will free utf8in unconditionally. */
276 : : static int
277 : 28 : idna_to_unicode_internal (char *utf8in,
278 : : uint32_t * out, size_t * outlen, int flags)
279 : : {
280 : : int rc;
281 : : char tmpout[64];
282 : 28 : size_t utf8len = strlen (utf8in) + 1;
283 : 28 : size_t addlen = 0;
284 : :
285 : : /*
286 : : * ToUnicode consists of the following steps:
287 : : *
288 : : * 1. If the sequence contains any code points outside the ASCII range
289 : : * (0..7F) then proceed to step 2, otherwise skip to step 3.
290 : : */
291 : :
292 : : {
293 : : size_t i;
294 : : int inasciirange;
295 : :
296 : 28 : inasciirange = 1;
297 [ + + ]: 951 : for (i = 0; utf8in[i]; i++)
298 [ - + ]: 923 : if (utf8in[i] & ~0x7F)
299 : 0 : inasciirange = 0;
300 [ + - ]: 28 : if (inasciirange)
301 : 28 : goto step3;
302 : : }
303 : :
304 : : /*
305 : : * 2. Perform the steps specified in [NAMEPREP] and fail if there is an
306 : : * error. (If step 3 of ToASCII is also performed here, it will not
307 : : * affect the overall behavior of ToUnicode, but it is not
308 : : * necessary.) The AllowUnassigned flag is used in [NAMEPREP].
309 : : */
310 : : do
311 : : {
312 : 0 : char *newp = realloc (utf8in, utf8len + addlen);
313 [ # # ]: 0 : if (newp == NULL)
314 : : {
315 : 0 : free (utf8in);
316 : 0 : return IDNA_MALLOC_ERROR;
317 : : }
318 : 0 : utf8in = newp;
319 [ # # ]: 0 : if (flags & IDNA_ALLOW_UNASSIGNED)
320 : 0 : rc = stringprep_nameprep (utf8in, utf8len + addlen);
321 : : else
322 : 0 : rc = stringprep_nameprep_no_unassigned (utf8in, utf8len + addlen);
323 : 0 : addlen += 1;
324 : : }
325 [ # # ]: 0 : while (rc == STRINGPREP_TOO_SMALL_BUFFER);
326 : :
327 [ # # ]: 0 : if (rc != STRINGPREP_OK)
328 : : {
329 : 0 : free (utf8in);
330 : 0 : return IDNA_STRINGPREP_ERROR;
331 : : }
332 : :
333 : : /* 3. Verify that the sequence begins with the ACE prefix, and save a
334 : : * copy of the sequence.
335 : : * ... The ToASCII and ToUnicode operations MUST recognize the ACE
336 : : prefix in a case-insensitive manner.
337 : : */
338 : :
339 : : step3:
340 [ - + ]: 28 : if (c_strncasecmp (utf8in, IDNA_ACE_PREFIX, strlen (IDNA_ACE_PREFIX)) != 0)
341 : : {
342 : 0 : free (utf8in);
343 : 0 : return IDNA_NO_ACE_PREFIX;
344 : : }
345 : :
346 : : /* 4. Remove the ACE prefix.
347 : : */
348 : :
349 : 28 : memmove (utf8in, &utf8in[strlen (IDNA_ACE_PREFIX)],
350 : 28 : strlen (utf8in) - strlen (IDNA_ACE_PREFIX) + 1);
351 : :
352 : : /* 5. Decode the sequence using the decoding algorithm in [PUNYCODE]
353 : : * and fail if there is an error. Save a copy of the result of
354 : : * this step.
355 : : */
356 : :
357 : 28 : (*outlen)--; /* reserve one for the zero */
358 : :
359 : 28 : rc = punycode_decode (strlen (utf8in), utf8in, outlen, out, NULL);
360 [ + + ]: 28 : if (rc != PUNYCODE_SUCCESS)
361 : : {
362 : 1 : free (utf8in);
363 : 1 : return IDNA_PUNYCODE_ERROR;
364 : : }
365 : :
366 : 27 : out[*outlen] = 0; /* add zero */
367 : :
368 : : /* 6. Apply ToASCII.
369 : : */
370 : :
371 : 27 : rc = idna_to_ascii_4i (out, *outlen, tmpout, flags);
372 [ + + ]: 27 : if (rc != IDNA_SUCCESS)
373 : : {
374 : 1 : free (utf8in);
375 : 1 : return rc;
376 : : }
377 : :
378 : : /* 7. Verify that the result of step 6 matches the saved copy from
379 : : * step 3, using a case-insensitive ASCII comparison.
380 : : */
381 : :
382 [ - + ]: 26 : if (c_strcasecmp (utf8in, tmpout + strlen (IDNA_ACE_PREFIX)) != 0)
383 : : {
384 : 0 : free (utf8in);
385 : 0 : return IDNA_ROUNDTRIP_VERIFY_ERROR;
386 : : }
387 : :
388 : : /* 8. Return the saved copy from step 5.
389 : : */
390 : :
391 : 26 : free (utf8in);
392 : 28 : return IDNA_SUCCESS;
393 : : }
394 : :
395 : : /**
396 : : * idna_to_unicode_44i:
397 : : * @in: input array with unicode code points.
398 : : * @inlen: length of input array with unicode code points.
399 : : * @out: output array with unicode code points.
400 : : * @outlen: on input, maximum size of output array with unicode code points,
401 : : * on exit, actual size of output array with unicode code points.
402 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
403 : : * %IDNA_USE_STD3_ASCII_RULES.
404 : : *
405 : : * The ToUnicode operation takes a sequence of Unicode code points
406 : : * that make up one domain label and returns a sequence of Unicode
407 : : * code points. If the input sequence is a label in ACE form, then the
408 : : * result is an equivalent internationalized label that is not in ACE
409 : : * form, otherwise the original sequence is returned unaltered.
410 : : *
411 : : * ToUnicode never fails. If any step fails, then the original input
412 : : * sequence is returned immediately in that step.
413 : : *
414 : : * The Punycode decoder can never output more code points than it
415 : : * inputs, but Nameprep can, and therefore ToUnicode can. Note that
416 : : * the number of octets needed to represent a sequence of code points
417 : : * depends on the particular character encoding used.
418 : : *
419 : : * The inputs to ToUnicode are a sequence of code points, the
420 : : * AllowUnassigned flag, and the UseSTD3ASCIIRules flag. The output of
421 : : * ToUnicode is always a sequence of Unicode code points.
422 : : *
423 : : * Return value: Returns #Idna_rc error condition, but it must only be
424 : : * used for debugging purposes. The output buffer is always
425 : : * guaranteed to contain the correct data according to the
426 : : * specification (sans malloc induced errors). NB! This means that
427 : : * you normally ignore the return code from this function, as
428 : : * checking it means breaking the standard.
429 : : */
430 : : int
431 : 28 : idna_to_unicode_44i (const uint32_t * in, size_t inlen,
432 : : uint32_t * out, size_t * outlen, int flags)
433 : : {
434 : : int rc;
435 : 28 : size_t outlensave = *outlen;
436 : : char *p;
437 : :
438 : 28 : p = stringprep_ucs4_to_utf8 (in, (ssize_t) inlen, NULL, NULL);
439 [ - + ]: 28 : if (p == NULL)
440 : 0 : return IDNA_MALLOC_ERROR;
441 : :
442 : 28 : rc = idna_to_unicode_internal (p, out, outlen, flags);
443 [ + + ]: 28 : if (rc != IDNA_SUCCESS)
444 : : {
445 : 2 : memcpy (out, in, sizeof (in[0]) * (inlen < outlensave ?
446 : 2 : inlen : outlensave));
447 : 2 : *outlen = inlen;
448 : : }
449 : :
450 : : /* p is freed in idna_to_unicode_internal. */
451 : :
452 : 28 : return rc;
453 : : }
454 : :
455 : : /* Wrappers that handle several labels */
456 : :
457 : : /**
458 : : * idna_to_ascii_4z:
459 : : * @input: zero terminated input Unicode string.
460 : : * @output: pointer to newly allocated output string.
461 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
462 : : * %IDNA_USE_STD3_ASCII_RULES.
463 : : *
464 : : * Convert UCS-4 domain name to ASCII string. The domain name may
465 : : * contain several labels, separated by dots. The output buffer must
466 : : * be deallocated by the caller.
467 : : *
468 : : * Return value: Returns %IDNA_SUCCESS on success, or error code.
469 : : **/
470 : : int
471 : 101 : idna_to_ascii_4z (const uint32_t * input, char **output, int flags)
472 : : {
473 : 101 : const uint32_t *start = input;
474 : : const uint32_t *end;
475 : : char buf[64];
476 : 101 : char *out = NULL;
477 : : int rc;
478 : :
479 : : /* 1) Whenever dots are used as label separators, the following
480 : : characters MUST be recognized as dots: U+002E (full stop),
481 : : U+3002 (ideographic full stop), U+FF0E (fullwidth full stop),
482 : : U+FF61 (halfwidth ideographic full stop). */
483 : :
484 [ + + ]: 101 : if (input[0] == 0)
485 : : {
486 : : /* Handle implicit zero-length root label. */
487 : 1 : *output = malloc (1);
488 [ - + ]: 1 : if (!*output)
489 : 0 : return IDNA_MALLOC_ERROR;
490 : 1 : strcpy (*output, "");
491 : 1 : return IDNA_SUCCESS;
492 : : }
493 : :
494 [ + - ][ + - ]: 100 : if (DOTP (input[0]) && input[1] == 0)
[ + - ][ - + ]
[ # # ]
495 : : {
496 : : /* Handle explicit zero-length root label. */
497 : 0 : *output = malloc (2);
498 [ # # ]: 0 : if (!*output)
499 : 0 : return IDNA_MALLOC_ERROR;
500 : 0 : strcpy (*output, ".");
501 : 0 : return IDNA_SUCCESS;
502 : : }
503 : :
504 : 100 : *output = NULL;
505 : : do
506 : : {
507 : 172 : end = start;
508 : :
509 [ + + ][ + + ]: 1196 : for (; *end && !DOTP (*end); end++)
[ + + ][ + + ]
[ + + ]
510 : : ;
511 : :
512 [ + + ][ - + ]: 172 : if (*end == '\0' && start == end)
513 : : {
514 : : /* Handle explicit zero-length root label. */
515 : 0 : buf[0] = '\0';
516 : : }
517 : : else
518 : : {
519 : 172 : rc = idna_to_ascii_4i (start, (size_t) (end - start), buf, flags);
520 [ + + ]: 172 : if (rc != IDNA_SUCCESS)
521 : : {
522 : 32 : free (out);
523 : 32 : return rc;
524 : : }
525 : : }
526 : :
527 [ + + ]: 140 : if (out)
528 : : {
529 : 69 : size_t l = strlen (out) + 1 + strlen (buf) + 1;
530 : 69 : char *newp = realloc (out, l);
531 [ - + ]: 69 : if (!newp)
532 : : {
533 : 0 : free (out);
534 : 0 : return IDNA_MALLOC_ERROR;
535 : : }
536 : 69 : out = newp;
537 : 69 : strcat (out, ".");
538 : 69 : strcat (out, buf);
539 : : }
540 : : else
541 : : {
542 : 71 : size_t l = strlen (buf) + 1;
543 : 71 : out = (char *) malloc (l);
544 [ - + ]: 71 : if (!out)
545 : 0 : return IDNA_MALLOC_ERROR;
546 : 71 : strcpy (out, buf);
547 : : }
548 : :
549 : 140 : start = end + 1;
550 : : }
551 [ + + ]: 140 : while (*end);
552 : :
553 : 68 : *output = out;
554 : :
555 : 101 : return IDNA_SUCCESS;
556 : : }
557 : :
558 : : /**
559 : : * idna_to_ascii_8z:
560 : : * @input: zero terminated input UTF-8 string.
561 : : * @output: pointer to newly allocated output string.
562 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
563 : : * %IDNA_USE_STD3_ASCII_RULES.
564 : : *
565 : : * Convert UTF-8 domain name to ASCII string. The domain name may
566 : : * contain several labels, separated by dots. The output buffer must
567 : : * be deallocated by the caller.
568 : : *
569 : : * Return value: Returns %IDNA_SUCCESS on success, or error code.
570 : : **/
571 : : int
572 : 101 : idna_to_ascii_8z (const char *input, char **output, int flags)
573 : : {
574 : : uint32_t *ucs4;
575 : : size_t ucs4len;
576 : : int rc;
577 : :
578 : 101 : ucs4 = stringprep_utf8_to_ucs4 (input, -1, &ucs4len);
579 [ - + ]: 101 : if (!ucs4)
580 : 0 : return IDNA_ICONV_ERROR;
581 : :
582 : 101 : rc = idna_to_ascii_4z (ucs4, output, flags);
583 : :
584 : 101 : free (ucs4);
585 : :
586 : 101 : return rc;
587 : :
588 : : }
589 : :
590 : : /**
591 : : * idna_to_ascii_lz:
592 : : * @input: zero terminated input string encoded in the current locale's
593 : : * character set.
594 : : * @output: pointer to newly allocated output string.
595 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
596 : : * %IDNA_USE_STD3_ASCII_RULES.
597 : : *
598 : : * Convert domain name in the locale's encoding to ASCII string. The
599 : : * domain name may contain several labels, separated by dots. The
600 : : * output buffer must be deallocated by the caller.
601 : : *
602 : : * Return value: Returns %IDNA_SUCCESS on success, or error code.
603 : : **/
604 : : int
605 : 0 : idna_to_ascii_lz (const char *input, char **output, int flags)
606 : : {
607 : : char *utf8;
608 : : int rc;
609 : :
610 : 0 : utf8 = stringprep_locale_to_utf8 (input);
611 [ # # ]: 0 : if (!utf8)
612 : 0 : return IDNA_ICONV_ERROR;
613 : :
614 : 0 : rc = idna_to_ascii_8z (utf8, output, flags);
615 : :
616 : 0 : free (utf8);
617 : :
618 : 0 : return rc;
619 : : }
620 : :
621 : : /**
622 : : * idna_to_unicode_4z4z:
623 : : * @input: zero-terminated Unicode string.
624 : : * @output: pointer to newly allocated output Unicode string.
625 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
626 : : * %IDNA_USE_STD3_ASCII_RULES.
627 : : *
628 : : * Convert possibly ACE encoded domain name in UCS-4 format into a
629 : : * UCS-4 string. The domain name may contain several labels,
630 : : * separated by dots. The output buffer must be deallocated by the
631 : : * caller.
632 : : *
633 : : * Return value: Returns %IDNA_SUCCESS on success, or error code.
634 : : **/
635 : : int
636 : 3 : idna_to_unicode_4z4z (const uint32_t * input, uint32_t ** output, int flags)
637 : : {
638 : 3 : const uint32_t *start = input;
639 : : const uint32_t *end;
640 : : uint32_t *buf;
641 : : size_t buflen;
642 : 3 : uint32_t *out = NULL;
643 : 3 : size_t outlen = 0;
644 : :
645 : 3 : *output = NULL;
646 : :
647 : : do
648 : : {
649 : 6 : end = start;
650 : :
651 [ + + ][ + + ]: 111 : for (; *end && !DOTP (*end); end++)
[ + - ][ + - ]
[ + - ]
652 : : ;
653 : :
654 : 6 : buflen = (size_t) (end - start);
655 : 6 : buf = malloc (sizeof (buf[0]) * (buflen + 1));
656 [ - + ]: 6 : if (!buf)
657 : 0 : return IDNA_MALLOC_ERROR;
658 : :
659 : : /* don't check return code as per specification! */
660 : 6 : idna_to_unicode_44i (start, (size_t) (end - start),
661 : : buf, &buflen, flags);
662 : :
663 [ + + ]: 6 : if (out)
664 : : {
665 : 3 : uint32_t *newp = realloc (out,
666 : : sizeof (out[0])
667 : 3 : * (outlen + 1 + buflen + 1));
668 [ - + ]: 3 : if (!newp)
669 : : {
670 : 0 : free (buf);
671 : 0 : free (out);
672 : 0 : return IDNA_MALLOC_ERROR;
673 : : }
674 : 3 : out = newp;
675 : 3 : out[outlen++] = 0x002E; /* '.' (full stop) */
676 : 3 : memcpy (out + outlen, buf, sizeof (buf[0]) * buflen);
677 : 3 : outlen += buflen;
678 : 3 : out[outlen] = 0x0;
679 : 3 : free (buf);
680 : : }
681 : : else
682 : : {
683 : 3 : out = buf;
684 : 3 : outlen = buflen;
685 : 3 : out[outlen] = 0x0;
686 : : }
687 : :
688 : 6 : start = end + 1;
689 : : }
690 [ + + ]: 6 : while (*end);
691 : :
692 : 3 : *output = out;
693 : :
694 : 3 : return IDNA_SUCCESS;
695 : : }
696 : :
697 : : /**
698 : : * idna_to_unicode_8z4z:
699 : : * @input: zero-terminated UTF-8 string.
700 : : * @output: pointer to newly allocated output Unicode string.
701 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
702 : : * %IDNA_USE_STD3_ASCII_RULES.
703 : : *
704 : : * Convert possibly ACE encoded domain name in UTF-8 format into a
705 : : * UCS-4 string. The domain name may contain several labels,
706 : : * separated by dots. The output buffer must be deallocated by the
707 : : * caller.
708 : : *
709 : : * Return value: Returns %IDNA_SUCCESS on success, or error code.
710 : : **/
711 : : int
712 : 3 : idna_to_unicode_8z4z (const char *input, uint32_t ** output, int flags)
713 : : {
714 : : uint32_t *ucs4;
715 : : size_t ucs4len;
716 : : int rc;
717 : :
718 : 3 : ucs4 = stringprep_utf8_to_ucs4 (input, -1, &ucs4len);
719 [ - + ]: 3 : if (!ucs4)
720 : 0 : return IDNA_ICONV_ERROR;
721 : :
722 : 3 : rc = idna_to_unicode_4z4z (ucs4, output, flags);
723 : 3 : free (ucs4);
724 : :
725 : 3 : return rc;
726 : : }
727 : :
728 : : /**
729 : : * idna_to_unicode_8z8z:
730 : : * @input: zero-terminated UTF-8 string.
731 : : * @output: pointer to newly allocated output UTF-8 string.
732 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
733 : : * %IDNA_USE_STD3_ASCII_RULES.
734 : : *
735 : : * Convert possibly ACE encoded domain name in UTF-8 format into a
736 : : * UTF-8 string. The domain name may contain several labels,
737 : : * separated by dots. The output buffer must be deallocated by the
738 : : * caller.
739 : : *
740 : : * Return value: Returns %IDNA_SUCCESS on success, or error code.
741 : : **/
742 : : int
743 : 3 : idna_to_unicode_8z8z (const char *input, char **output, int flags)
744 : : {
745 : : uint32_t *ucs4;
746 : : int rc;
747 : :
748 : 3 : rc = idna_to_unicode_8z4z (input, &ucs4, flags);
749 : 3 : *output = stringprep_ucs4_to_utf8 (ucs4, -1, NULL, NULL);
750 : 3 : free (ucs4);
751 : :
752 [ - + ]: 3 : if (!*output)
753 : 0 : return IDNA_ICONV_ERROR;
754 : :
755 : 3 : return rc;
756 : : }
757 : :
758 : : /**
759 : : * idna_to_unicode_8zlz:
760 : : * @input: zero-terminated UTF-8 string.
761 : : * @output: pointer to newly allocated output string encoded in the
762 : : * current locale's character set.
763 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
764 : : * %IDNA_USE_STD3_ASCII_RULES.
765 : : *
766 : : * Convert possibly ACE encoded domain name in UTF-8 format into a
767 : : * string encoded in the current locale's character set. The domain
768 : : * name may contain several labels, separated by dots. The output
769 : : * buffer must be deallocated by the caller.
770 : : *
771 : : * Return value: Returns %IDNA_SUCCESS on success, or error code.
772 : : **/
773 : : int
774 : 0 : idna_to_unicode_8zlz (const char *input, char **output, int flags)
775 : : {
776 : : char *utf8;
777 : : int rc;
778 : :
779 : 0 : rc = idna_to_unicode_8z8z (input, &utf8, flags);
780 : 0 : *output = stringprep_utf8_to_locale (utf8);
781 : 0 : free (utf8);
782 : :
783 [ # # ]: 0 : if (!*output)
784 : 0 : return IDNA_ICONV_ERROR;
785 : :
786 : 0 : return rc;
787 : : }
788 : :
789 : : /**
790 : : * idna_to_unicode_lzlz:
791 : : * @input: zero-terminated string encoded in the current locale's
792 : : * character set.
793 : : * @output: pointer to newly allocated output string encoded in the
794 : : * current locale's character set.
795 : : * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or
796 : : * %IDNA_USE_STD3_ASCII_RULES.
797 : : *
798 : : * Convert possibly ACE encoded domain name in the locale's character
799 : : * set into a string encoded in the current locale's character set.
800 : : * The domain name may contain several labels, separated by dots. The
801 : : * output buffer must be deallocated by the caller.
802 : : *
803 : : * Return value: Returns %IDNA_SUCCESS on success, or error code.
804 : : **/
805 : : int
806 : 0 : idna_to_unicode_lzlz (const char *input, char **output, int flags)
807 : : {
808 : : char *utf8;
809 : : int rc;
810 : :
811 : 0 : utf8 = stringprep_locale_to_utf8 (input);
812 [ # # ]: 0 : if (!utf8)
813 : 0 : return IDNA_ICONV_ERROR;
814 : :
815 : 0 : rc = idna_to_unicode_8zlz (utf8, output, flags);
816 : 0 : free (utf8);
817 : :
818 : 0 : return rc;
819 : : }
820 : :
821 : : /**
822 : : * IDNA_ACE_PREFIX
823 : : *
824 : : * The IANA allocated prefix to use for IDNA. "xn--"
825 : : */
826 : :
827 : : /**
828 : : * Idna_rc:
829 : : * @IDNA_SUCCESS: Successful operation. This value is guaranteed to
830 : : * always be zero, the remaining ones are only guaranteed to hold
831 : : * non-zero values, for logical comparison purposes.
832 : : * @IDNA_STRINGPREP_ERROR: Error during string preparation.
833 : : * @IDNA_PUNYCODE_ERROR: Error during punycode operation.
834 : : * @IDNA_CONTAINS_NON_LDH: For IDNA_USE_STD3_ASCII_RULES, indicate that
835 : : * the string contains non-LDH ASCII characters.
836 : : * @IDNA_CONTAINS_LDH: Same as @IDNA_CONTAINS_NON_LDH, for compatibility
837 : : * with typo in earlier versions.
838 : : * @IDNA_CONTAINS_MINUS: For IDNA_USE_STD3_ASCII_RULES, indicate that
839 : : * the string contains a leading or trailing hyphen-minus (U+002D).
840 : : * @IDNA_INVALID_LENGTH: The final output string is not within the
841 : : * (inclusive) range 1 to 63 characters.
842 : : * @IDNA_NO_ACE_PREFIX: The string does not contain the ACE prefix
843 : : * (for ToUnicode).
844 : : * @IDNA_ROUNDTRIP_VERIFY_ERROR: The ToASCII operation on output
845 : : * string does not equal the input.
846 : : * @IDNA_CONTAINS_ACE_PREFIX: The input contains the ACE prefix (for
847 : : * ToASCII).
848 : : * @IDNA_ICONV_ERROR: Could not convert string in locale encoding.
849 : : * @IDNA_MALLOC_ERROR: Could not allocate buffer (this is typically a
850 : : * fatal error).
851 : : * @IDNA_DLOPEN_ERROR: Could not dlopen the libcidn DSO (only used
852 : : * internally in libc).
853 : : *
854 : : * Enumerated return codes of idna_to_ascii_4i(),
855 : : * idna_to_unicode_44i() functions (and functions derived from those
856 : : * functions). The value 0 is guaranteed to always correspond to
857 : : * success.
858 : : */
859 : :
860 : :
861 : : /**
862 : : * Idna_flags:
863 : : * @IDNA_ALLOW_UNASSIGNED: Don't reject strings containing unassigned
864 : : * Unicode code points.
865 : : * @IDNA_USE_STD3_ASCII_RULES: Validate strings according to STD3
866 : : * rules (i.e., normal host name rules).
867 : : *
868 : : * Flags to pass to idna_to_ascii_4i(), idna_to_unicode_44i() etc.
869 : : */
|