diff options
Diffstat (limited to '3rdParty/LibIDN/src/idna.c')
-rw-r--r-- | 3rdParty/LibIDN/src/idna.c | 121 |
1 files changed, 74 insertions, 47 deletions
diff --git a/3rdParty/LibIDN/src/idna.c b/3rdParty/LibIDN/src/idna.c index 8061086..5107d73 100644 --- a/3rdParty/LibIDN/src/idna.c +++ b/3rdParty/LibIDN/src/idna.c @@ -1,45 +1,56 @@ -/* idna.c --- Convert to or from IDN strings. - * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - * - */ +/* idna.c --- Prototypes for Internationalized Domain Name library. + Copyright (C) 2002-2015 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 either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version. + + or both in parallel, as here. + + 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 + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdlib.h> #include <string.h> #include <stringprep.h> #include <punycode.h> #include "idna.h" +/* Get c_strcasecmp. */ +#include <c-strcase.h> + #define DOTP(c) ((c) == 0x002E || (c) == 0x3002 || \ (c) == 0xFF0E || (c) == 0xFF61) /* Core functions */ /** - * idna_to_ascii_4i - convert Unicode domain name label to text + * 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: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or * %IDNA_USE_STD3_ASCII_RULES. @@ -106,13 +117,13 @@ idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags) * an error. The AllowUnassigned flag is used in [NAMEPREP]. */ { char *p; - p = stringprep_ucs4_to_utf8 (in, inlen, NULL, NULL); + p = stringprep_ucs4_to_utf8 (in, (ssize_t) inlen, NULL, NULL); if (p == NULL) return IDNA_MALLOC_ERROR; len = strlen (p); do { @@ -140,12 +151,15 @@ idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags) return IDNA_STRINGPREP_ERROR; } src = stringprep_utf8_to_ucs4 (p, -1, NULL); free (p); + + if (!src) + return IDNA_MALLOC_ERROR; } step3: /* * 3. If the UseSTD3ASCIIRules flag is set, then perform these checks: * @@ -315,16 +329,18 @@ idna_to_unicode_internal (char *utf8in, free (utf8in); return IDNA_STRINGPREP_ERROR; } /* 3. Verify that the sequence begins with the ACE prefix, and save a * copy of the sequence. + * ... The ToASCII and ToUnicode operations MUST recognize the ACE + prefix in a case-insensitive manner. */ step3: - if (memcmp (IDNA_ACE_PREFIX, utf8in, strlen (IDNA_ACE_PREFIX)) != 0) + if (c_strncasecmp (utf8in, IDNA_ACE_PREFIX, strlen (IDNA_ACE_PREFIX)) != 0) { free (utf8in); return IDNA_NO_ACE_PREFIX; } /* 4. Remove the ACE prefix. @@ -360,13 +376,13 @@ step3: } /* 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) + if (c_strcasecmp (utf8in, tmpout + strlen (IDNA_ACE_PREFIX)) != 0) { free (utf8in); return IDNA_ROUNDTRIP_VERIFY_ERROR; } /* 8. Return the saved copy from step 5. @@ -374,13 +390,13 @@ step3: free (utf8in); return IDNA_SUCCESS; } /** - * idna_to_unicode_44i - convert domain name label to Unicode + * 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: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or @@ -416,13 +432,13 @@ 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); + p = stringprep_ucs4_to_utf8 (in, (ssize_t) inlen, NULL, NULL); if (p == NULL) return IDNA_MALLOC_ERROR; rc = idna_to_unicode_internal (p, out, outlen, flags); if (rc != IDNA_SUCCESS) { @@ -436,13 +452,13 @@ idna_to_unicode_44i (const uint32_t * in, size_t inlen, return rc; } /* Wrappers that handle several labels */ /** - * idna_to_ascii_4z - convert Unicode domain name to text + * idna_to_ascii_4z: * @input: zero terminated input Unicode string. * @output: pointer to newly allocated output string. * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or * %IDNA_USE_STD3_ASCII_RULES. * * Convert UCS-4 domain name to ASCII string. The domain name may @@ -452,13 +468,13 @@ idna_to_unicode_44i (const uint32_t * in, size_t inlen, * 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; + const uint32_t *end; 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), @@ -497,48 +513,51 @@ idna_to_ascii_4z (const uint32_t * input, char **output, int flags) { /* Handle explicit zero-length root label. */ buf[0] = '\0'; } else { - rc = idna_to_ascii_4i (start, end - start, buf, flags); + rc = idna_to_ascii_4i (start, (size_t) (end - start), buf, flags); if (rc != IDNA_SUCCESS) - return rc; + { + free (out); + return rc; + } } if (out) { - char *newp = realloc (out, strlen (out) + 1 + strlen (buf) + 1); + size_t l = strlen (out) + 1 + strlen (buf) + 1; + char *newp = realloc (out, l); if (!newp) { free (out); return IDNA_MALLOC_ERROR; } out = newp; strcat (out, "."); strcat (out, buf); } else { - out = (char *) malloc (strlen (buf) + 1); + out = strdup (buf); if (!out) return IDNA_MALLOC_ERROR; - strcpy (out, buf); } start = end + 1; } while (*end); *output = out; return IDNA_SUCCESS; } /** - * idna_to_ascii_8z - convert Unicode domain name to text + * idna_to_ascii_8z: * @input: zero terminated input UTF-8 string. * @output: pointer to newly allocated output string. * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or * %IDNA_USE_STD3_ASCII_RULES. * * Convert UTF-8 domain name to ASCII string. The domain name may @@ -564,13 +583,13 @@ idna_to_ascii_8z (const char *input, char **output, int flags) return rc; } /** - * idna_to_ascii_lz - convert Unicode domain name to text + * idna_to_ascii_lz: * @input: zero terminated input string encoded in the current locale's * character set. * @output: pointer to newly allocated output string. * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or * %IDNA_USE_STD3_ASCII_RULES. * @@ -595,13 +614,13 @@ idna_to_ascii_lz (const char *input, char **output, int flags) free (utf8); return rc; } /** - * idna_to_unicode_4z4z - convert domain name to Unicode + * idna_to_unicode_4z4z: * @input: zero-terminated Unicode string. * @output: pointer to newly allocated output Unicode string. * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or * %IDNA_USE_STD3_ASCII_RULES. * * Convert possibly ACE encoded domain name in UCS-4 format into a @@ -612,35 +631,35 @@ idna_to_ascii_lz (const char *input, char **output, int flags) * 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; + const uint32_t *end; 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; + buflen = (size_t) (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! */ + /* don't check return code as per specification! */ + idna_to_unicode_44i (start, (size_t) (end - start), + buf, &buflen, flags); if (out) { uint32_t *newp = realloc (out, sizeof (out[0]) * (outlen + 1 + buflen + 1)); @@ -671,13 +690,13 @@ idna_to_unicode_4z4z (const uint32_t * input, uint32_t ** output, int flags) *output = out; return IDNA_SUCCESS; } /** - * idna_to_unicode_8z4z - convert domain name to Unicode + * idna_to_unicode_8z4z: * @input: zero-terminated UTF-8 string. * @output: pointer to newly allocated output Unicode string. * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or * %IDNA_USE_STD3_ASCII_RULES. * * Convert possibly ACE encoded domain name in UTF-8 format into a @@ -702,13 +721,13 @@ idna_to_unicode_8z4z (const char *input, uint32_t ** output, int flags) free (ucs4); return rc; } /** - * idna_to_unicode_8z8z - convert domain name to Unicode + * idna_to_unicode_8z8z: * @input: zero-terminated UTF-8 string. * @output: pointer to newly allocated output UTF-8 string. * @flags: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or * %IDNA_USE_STD3_ASCII_RULES. * * Convert possibly ACE encoded domain name in UTF-8 format into a @@ -722,23 +741,26 @@ 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); + if (rc != IDNA_SUCCESS) + return rc; + *output = stringprep_ucs4_to_utf8 (ucs4, -1, NULL, NULL); free (ucs4); if (!*output) return IDNA_ICONV_ERROR; - return rc; + return IDNA_SUCCESS; } /** - * idna_to_unicode_8zlz - convert domain name to Unicode + * 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: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or * %IDNA_USE_STD3_ASCII_RULES. * @@ -753,23 +775,26 @@ int idna_to_unicode_8zlz (const char *input, char **output, int flags) { char *utf8; int rc; rc = idna_to_unicode_8z8z (input, &utf8, flags); + if (rc != IDNA_SUCCESS) + return rc; + *output = stringprep_utf8_to_locale (utf8); free (utf8); if (!*output) return IDNA_ICONV_ERROR; - return rc; + return IDNA_SUCCESS; } /** - * idna_to_unicode_lzlz - convert domain name to Unicode + * 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: an #Idna_flags value, e.g., %IDNA_ALLOW_UNASSIGNED or * %IDNA_USE_STD3_ASCII_RULES. @@ -809,12 +834,14 @@ idna_to_unicode_lzlz (const char *input, char **output, int flags) * 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_LDH: Same as @IDNA_CONTAINS_NON_LDH, for compatibility + * with typo in earlier versions. * @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). |