From c7b33a418d9426ee311db45473cb20bad94df26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Mon, 10 Feb 2020 15:10:54 +0100 Subject: [PATCH] Implement full roundtrip for lookup functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With TR64 enabled (default), '☺i' was converted to 'xn-- o-oia59s'. The output contains an illegal space and thus could not be decoded any more. References: https://gitlab.com/libidn/libidn2/issues/78 https://gitlab.isc.org/isc-projects/bind9/issues/1610 Reported-by: Chris Malton --- lib/lookup.c | 33 +++++++++++++++++++++++---------- tests/test-lookup.c | 5 +++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/lookup.c b/lib/lookup.c index a55f82b..5e5ff12 100644 --- a/lib/lookup.c +++ b/lib/lookup.c @@ -1,5 +1,6 @@ /* lookup.c - implementation of IDNA2008 lookup functions Copyright (C) 2011-2017 Simon Josefsson + Copyright (C) 2017-2020 Tim Ruehsen Libidn2 is free software: you can redistribute it and/or modify it under the terms of either: @@ -123,7 +124,7 @@ label (const uint8_t * src, size_t srclen, uint8_t * dst, size_t * dstlen, int flags) { size_t plen; - uint32_t *p; + uint32_t *p = NULL; const uint8_t *src_org = NULL; uint8_t *src_allocated = NULL; int rc, check_roundtrip = 0; @@ -187,10 +188,7 @@ label (const uint8_t * src, size_t srclen, uint8_t * dst, size_t * dstlen, p, plen); if (rc != IDN2_OK) - { - free (p); - goto out; - } + goto out; } dst[0] = 'x'; @@ -200,7 +198,6 @@ label (const uint8_t * src, size_t srclen, uint8_t * dst, size_t * dstlen, tmpl = *dstlen - 4; rc = _idn2_punycode_encode_internal (plen, p, &tmpl, (char *) dst + 4); - free (p); if (rc != IDN2_OK) goto out; @@ -210,15 +207,31 @@ label (const uint8_t * src, size_t srclen, uint8_t * dst, size_t * dstlen, if (check_roundtrip) { if (srclen_org != *dstlen || c_strncasecmp ((char *) src_org, (char *) dst, srclen_org)) - { - rc = IDN2_ALABEL_ROUNDTRIP_FAILED; - goto out; - } + { + rc = IDN2_ALABEL_ROUNDTRIP_FAILED; + goto out; + } + } + else if (!(flags & IDN2_NO_ALABEL_ROUNDTRIP)) + { + rc = _idn2_punycode_decode_internal (*dstlen - 4, (char *) dst + 4, &label32_len, label_u32); + if (rc) + { + rc = IDN2_ALABEL_ROUNDTRIP_FAILED; + goto out; + } + + if (plen != label32_len || u32_cmp (p, label_u32, label32_len)) + { + rc = IDN2_ALABEL_ROUNDTRIP_FAILED; + goto out; + } } rc = IDN2_OK; out: + free (p); free (src_allocated); return rc; } diff --git a/tests/test-lookup.c b/tests/test-lookup.c index aa75e18..2b49cb1 100644 --- a/tests/test-lookup.c +++ b/tests/test-lookup.c @@ -1,5 +1,6 @@ /* test-lookup.c --- Self tests for IDNA processing Copyright (C) 2011-2017 Simon Josefsson + Copyright (C) 2017-2020 Tim Ruehsen This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -838,6 +839,10 @@ static const struct idna idna[] = { {"\xc3\xa4_x", "xn--_x-uia", IDN2_OK, IDN2_TRANSITIONAL}, /* failing lookup round-trip */ {"xn--te_", "", IDN2_ALABEL_ROUNDTRIP_FAILED}, + /* failing lookup round-trip: ☺ -> xn-- o-oia59s (illegal space in output, see https://gitlab.com/libidn/libidn2/issues/78) */ + {"\xc3\xa2\xcb\x9c\xc2\xba", "", IDN2_DISALLOWED, IDN2_NO_TR46}, + {"\xc3\xa2\xcb\x9c\xc2\xba", "", IDN2_ALABEL_ROUNDTRIP_FAILED, IDN2_TRANSITIONAL}, + {"\xc3\xa2\xcb\x9c\xc2\xba", "", IDN2_ALABEL_ROUNDTRIP_FAILED, IDN2_NONTRANSITIONAL}, }; static int ok = 0, failed = 0; -- 1.8.3.1