diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c index 12c4d65dd3..139d286af8 100644 --- a/src/shared/dns-domain.c +++ b/src/shared/dns-domain.c @@ -1274,15 +1274,38 @@ int dns_name_apply_idna(const char *name, char **ret) { #if defined(HAVE_LIBIDN2) int r; + _cleanup_free_ char *t = NULL; assert(name); assert(ret); - r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) ret, + r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) &t, IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL); - if (r == IDN2_OK) + log_debug("idn2_lookup_u8: %s → %s", name, t); + if (r == IDN2_OK) { + if (!startswith(name, "xn--")) { + _cleanup_free_ char *s = NULL; + + r = idn2_to_unicode_8z8z(t, &s, 0); + if (r != IDN2_OK) { + log_debug("idn2_to_unicode_8z8z(\"%s\") failed: %d/%s", + t, r, idn2_strerror(r)); + return 0; + } + + if (!streq_ptr(name, s)) { + log_debug("idn2 roundtrip failed: \"%s\" → \"%s\" → \"%s\", ignoring.", + name, t, s); + return 0; + } + } + + *ret = t; + t = NULL; return 1; /* *ret has been written */ - log_debug("idn2_lookup_u8(\"%s\") failed: %s", name, idn2_strerror(r)); + } + + log_debug("idn2_lookup_u8(\"%s\") failed: %d/%s", name, r, idn2_strerror(r)); if (r == IDN2_2HYPHEN) /* The name has two hypens — forbidden by IDNA2008 in some cases */ return 0; diff --git a/src/test/test-dns-domain.c b/src/test/test-dns-domain.c index 11cf0b1f0b..cbd2d1e656 100644 --- a/src/test/test-dns-domain.c +++ b/src/test/test-dns-domain.c @@ -652,6 +652,12 @@ static void test_dns_name_apply_idna(void) { test_dns_name_apply_idna_one("föö.bär.", ret, "xn--f-1gaa.xn--br-via"); test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret, "xn--f-1gaa.xn--br-via"); + test_dns_name_apply_idna_one("_443._tcp.fedoraproject.org", ret2, + "_443._tcp.fedoraproject.org"); + test_dns_name_apply_idna_one("_443", ret2, "_443"); + test_dns_name_apply_idna_one("gateway", ret, "gateway"); + test_dns_name_apply_idna_one("_gateway", ret2, "_gateway"); + test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", ret2, ret2 ? "r3---sn-ab5l6ne7.googlevideo.com" : ""); }