introduced flag to disable TR46 processing

These introduce flag IDN2_NO_TR46 which can be used by applications to explicitly disable TR46 processing which is now the default option. Signed-off-by: Nikos Mavrogiannopoulos's avatarNikos Mavrogiannopoulos <nmav@gnutls.org>
parent 2d577b4d
......@@ -151,6 +151,7 @@ extern "C"
* idn2_flags:
* @IDN2_NFC_INPUT: Normalize input string using normalization form C.
* @IDN2_ALABEL_ROUNDTRIP: Perform optional IDNA2008 lookup roundtrip check (not implemented yet).
* @IDN2_NO_TR46: Disable Unicode TR46 processing (default).
* @IDN2_TRANSITIONAL: Perform Unicode TR46 transitional processing.
* @IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional processing.
* @IDN2_ALLOW_UNASSIGNED: Libidn compatibility flag, unused.
......@@ -169,6 +170,7 @@ extern "C"
IDN2_NONTRANSITIONAL = 8,
IDN2_ALLOW_UNASSIGNED = 16,
IDN2_USE_STD3_ASCII_RULES = 32,
IDN2_NO_TR46 = 64
} idn2_flags;
/* IDNA2008 with UTF-8 encoded inputs. */
......
......@@ -43,6 +43,20 @@
#include "idna.h" /* _idn2_label_test */
#include "tr46map.h" /* defintion for tr46map.c */
static int set_default_flags(int *flags)
{
if (((*flags) & IDN2_TRANSITIONAL) && ((*flags) & IDN2_NONTRANSITIONAL))
return IDN2_INVALID_FLAGS;
if (((*flags) & (IDN2_TRANSITIONAL|IDN2_NONTRANSITIONAL)) && ((*flags) & IDN2_NO_TR46))
return IDN2_INVALID_FLAGS;
if (!((*flags) & (IDN2_TRANSITIONAL|IDN2_NONTRANSITIONAL)))
*flags |= IDN2_NO_TR46;
return IDN2_OK;
}
static int
label (const uint8_t * src, size_t srclen, uint8_t * dst, size_t * dstlen,
int flags)
......@@ -388,7 +402,7 @@ idn2_lookup_u8 (const uint8_t * src, uint8_t ** lookupname, int flags)
size_t lookupnamelen = 0;
uint8_t _lookupname[IDN2_DOMAIN_MAX_LENGTH + 1];
uint8_t _mapped[IDN2_DOMAIN_MAX_LENGTH + 1];
int rc, tr46_mode = 0;
int rc;
if (src == NULL)
{
......@@ -397,16 +411,11 @@ idn2_lookup_u8 (const uint8_t * src, uint8_t ** lookupname, int flags)
return IDN2_OK;
}
if ((flags & (IDN2_TRANSITIONAL | IDN2_NONTRANSITIONAL)) ==
(IDN2_TRANSITIONAL | IDN2_NONTRANSITIONAL))
return IDN2_INVALID_FLAGS;
if (flags & IDN2_TRANSITIONAL)
tr46_mode = IDN2_TRANSITIONAL;
else if (flags & IDN2_NONTRANSITIONAL)
tr46_mode = IDN2_NONTRANSITIONAL;
rc = set_default_flags(&flags);
if (rc != IDN2_OK)
return rc;
if (tr46_mode)
if (!(flags & IDN2_NO_TR46))
{
uint8_t *out;
size_t outlen;
......
......@@ -828,6 +828,11 @@ static const struct idna idna[] = {
{"_\xc3\xbc", "xn--tda", IDN2_OK, IDN2_USE_STD3_ASCII_RULES|IDN2_NONTRANSITIONAL},
{"_\xc3\xbc", "xn--tda", IDN2_OK, IDN2_USE_STD3_ASCII_RULES|IDN2_TRANSITIONAL},
{"_\xc3\xbc", "xn--_-eha", IDN2_DISALLOWED, IDN2_USE_STD3_ASCII_RULES}, /* flag is ignored when not using TR46 */
/* test invalid flags */
{"_443._tcp.example.com", "_443._tcp.example.com", IDN2_INVALID_FLAGS, IDN2_NONTRANSITIONAL|IDN2_TRANSITIONAL},
{"_443._tcp.example.com", "_443._tcp.example.com", IDN2_INVALID_FLAGS, IDN2_NONTRANSITIONAL|IDN2_NO_TR46},
{"_443._tcp.example.com", "_443._tcp.example.com", IDN2_INVALID_FLAGS, IDN2_TRANSITIONAL|IDN2_NO_TR46},
{"_443._tcp.example.com", "_443._tcp.example.com", IDN2_INVALID_FLAGS, IDN2_TRANSITIONAL|IDN2_NONTRANSITIONAL|IDN2_NO_TR46},
};
static int ok = 0, failed = 0;
......@@ -917,6 +922,27 @@ test_homebrewed(void)
if (rc == IDN2_OK)
idn2_free (out);
/* Try the IDN2_NO_TR46 flag behavior */
if (!(idna[i].flags & (IDN2_NONTRANSITIONAL|IDN2_TRANSITIONAL))) {
rc = idn2_lookup_u8 ((uint8_t *) idna[i].in, &out, idna[i].flags|IDN2_NO_TR46);
printf ("%3d %-25s %-40s %s\n", (int) i, idn2_strerror_name (rc),
rc == IDN2_OK ? idna[i].out : "", idna[i].in);
if (rc != idna[i].rc && rc == IDN2_ENCODING_ERROR) {
printf("utc bug\n");
} else if (rc != idna[i].rc && idna[i].rc != -1) {
failed++;
printf("expected rc %d got rc %d\n", idna[i].rc, rc);
} else if (rc == IDN2_OK && strcmp ((char *) out, idna[i].out) != 0) {
failed++;
printf("expected: %s\ngot: %s\n", idna[i].out, out);
} else
ok++;
if (rc == IDN2_OK)
idn2_free (out);
}
if (failed && break_on_error)
exit (EXIT_FAILURE);
}
......@@ -1177,6 +1203,10 @@ test_unicode_range (void)
if (rc == IDN2_OK)
idn2_free (out);
rc = idn2_lookup_u8 (utf8, &out, IDN2_NO_TR46);
if (rc == IDN2_OK)
idn2_free (out);
free (utf8);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment