summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/LibIDN/src/idna.c')
-rw-r--r--3rdParty/LibIDN/src/idna.c121
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,48 +1,59 @@
-/* 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.
*
* The ToASCII operation takes a sequence of Unicode code points that
* make up one domain label and transforms it into a sequence of code
@@ -103,19 +114,19 @@ idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags)
/*
* 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);
+ p = stringprep_ucs4_to_utf8 (in, (ssize_t) inlen, NULL, NULL);
if (p == NULL)
return IDNA_MALLOC_ERROR;
len = strlen (p);
do
{
char *newp;
len = 2 * len + 10; /* XXX better guess? */
@@ -137,18 +148,21 @@ idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags)
if (rc != STRINGPREP_OK)
{
free (p);
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:
*
* (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.
*
@@ -312,22 +326,24 @@ idna_to_unicode_internal (char *utf8in,
if (rc != STRINGPREP_OK)
{
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.
*/
memmove (utf8in, &utf8in[strlen (IDNA_ACE_PREFIX)],
@@ -357,33 +373,33 @@ step3:
{
free (utf8in);
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)
+ 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.
*/
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
* %IDNA_USE_STD3_ASCII_RULES.
*
* The ToUnicode operation takes a sequence of Unicode code points
@@ -413,19 +429,19 @@ step3:
*/
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);
+ 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)
{
memcpy (out, in, sizeof (in[0]) * (inlen < outlensave ?
inlen : outlensave));
*outlen = inlen;
@@ -433,35 +449,35 @@ idna_to_unicode_44i (const uint32_t * in, size_t inlen,
/* p is freed in idna_to_unicode_internal. */
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
* 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;
+ 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),
U+3002 (ideographic full stop), U+FF0E (fullwidth full stop),
U+FF61 (halfwidth ideographic full stop). */
@@ -494,54 +510,57 @@ idna_to_ascii_4z (const uint32_t * input, char **output, int flags)
;
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);
+ 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
* contain several labels, separated by dots. The output buffer must
* be deallocated by the caller.
*
@@ -561,19 +580,19 @@ idna_to_ascii_8z (const char *input, char **output, int flags)
rc = idna_to_ascii_4z (ucs4, output, flags);
free (ucs4);
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.
*
* 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.
@@ -592,58 +611,58 @@ idna_to_ascii_lz (const char *input, char **output, int flags)
rc = idna_to_ascii_8z (utf8, output, 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
* 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;
+ 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));
if (!newp)
{
free (buf);
@@ -668,19 +687,19 @@ idna_to_unicode_4z4z (const uint32_t * input, uint32_t ** output, int flags)
}
while (*end);
*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
* UCS-4 string. The domain name may contain several labels,
* separated by dots. The output buffer must be deallocated by the
* caller.
@@ -699,19 +718,19 @@ idna_to_unicode_8z4z (const char *input, uint32_t ** output, int flags)
return IDNA_ICONV_ERROR;
rc = idna_to_unicode_4z4z (ucs4, output, 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
* UTF-8 string. The domain name may contain several labels,
* separated by dots. The output buffer must be deallocated by the
* caller.
@@ -719,29 +738,32 @@ idna_to_unicode_8z4z (const char *input, uint32_t ** output, int flags)
* 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);
+ 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.
*
* 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
@@ -750,29 +772,32 @@ idna_to_unicode_8z8z (const char *input, char **output, int flags)
* 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);
+ 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.
*
* Convert possibly ACE encoded domain name in the locale's character
* set into a string encoded in the current locale's character set.
@@ -806,18 +831,20 @@ idna_to_unicode_lzlz (const char *input, char **output, int flags)
/**
* 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_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).
* @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