From 7f9f1ecb710eac4d65bb02785ddf288cac098323 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 23 May 2018 15:26:19 +0200 Subject: Switch IDNA implementation to libidn2 [BZ #19728] [BZ #19729] [BZ #22247] This provides an implementation of the IDNA2008 standard and fixes CVE-2016-6261, CVE-2016-6263, CVE-2017-14062. --- libidn/idna.c | 834 ---------------------------------------------------------- 1 file changed, 834 deletions(-) delete mode 100644 libidn/idna.c (limited to 'libidn/idna.c') diff --git a/libidn/idna.c b/libidn/idna.c deleted file mode 100644 index 7a15a25b21..0000000000 --- a/libidn/idna.c +++ /dev/null @@ -1,834 +0,0 @@ -/* idna.c Convert to or from IDN strings. - * Copyright (C) 2002, 2003, 2004, 2011 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, see . - */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include - -#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 - { - char *newp; - - len = 2 * len + 10; /* XXX better guess? */ - newp = realloc (p, len); - if (newp == NULL) - { - free (p); - return IDNA_MALLOC_ERROR; - } - p = newp; - - 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 - { - char *newp = realloc (utf8in, utf8len + addlen); - if (newp == NULL) - { - free (utf8in); - return IDNA_MALLOC_ERROR; - } - utf8in = newp; - 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) - { - free (utf8in); - 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) - { - free (utf8in); - 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) - { - free (utf8in); - 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) - { - 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) - { - free (utf8in); - return IDNA_ROUNDTRIP_VERIFY_ERROR; - } - - /* 8. Return the saved copy from step 5. - */ - - free (utf8in); - 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; - } - - /* p is freed in idna_to_unicode_internal. */ - - 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) - { - char *newp = realloc (out, strlen (out) + 1 + strlen (buf) + 1); - if (!newp) - { - free (out); - return IDNA_MALLOC_ERROR; - } - out = newp; - 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; - - *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; - - idna_to_unicode_44i (start, end - start, buf, &buflen, flags); - /* don't check return value as per specification! */ - - if (out) - { - uint32_t *newp = realloc (out, - sizeof (out[0]) - * (outlen + 1 + buflen + 1)); - if (!newp) - { - free (buf); - free (out); - return IDNA_MALLOC_ERROR; - } - out = newp; - 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). - * @IDNA_DLOPEN_ERROR: Could not dlopen the libcidn DSO (only used - * internally in libc). - * - * 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. - */ -- cgit v1.2.3