From 08f66d8509d0e46f9e6d61a58ee959e8104fef12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Mon, 19 Mar 2018 16:09:04 +0000 Subject: [PATCH] Don't use the IDN traslated name if no conversion took a place --- bin/dig/dighost.c | 49 +++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 57712ec347..7654451c50 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -2096,8 +2096,7 @@ setup_lookup(dig_lookup_t *lookup) { textname = lookup->textname; #ifdef WITH_IDN_SUPPORT if (lookup->idnin) { - result = idn_locale_to_ace(lookup->textname, idn_textname, - sizeof(idn_textname)); + result = idn_locale_to_ace(textname, idn_textname, sizeof(idn_textname)); check_result(result, "convert textname to IDN encoding"); debug("idn_textname: %s", idn_textname); textname = idn_textname; @@ -2133,8 +2132,7 @@ setup_lookup(dig_lookup_t *lookup) { origin = lookup->origin->origin; #ifdef WITH_IDN_SUPPORT if (lookup->idnin) { - result = idn_locale_to_ace(lookup->origin->origin, - idn_origin, sizeof(idn_origin)); + result = idn_locale_to_ace(origin, idn_origin, sizeof(idn_origin)); check_result(result, "convert origin to IDN encoding"); debug("trying idn origin %s", idn_origin); origin = idn_origin; @@ -4273,21 +4271,19 @@ output_filter(isc_buffer_t *buffer, unsigned int used_org, if (result != ISC_R_SUCCESS) { return (ISC_R_SUCCESS); } - strlcpy(tmp1, tmp2, MAXDLEN); - /* * Copy the converted contents in 'tmp1' back to 'buffer'. * If we have appended trailing dot, remove it. */ - tolen = strlen(tmp1); - if (absolute && !end_with_dot && tmp1[tolen - 1] == '.') + tolen = strlen(tmp2); + if (absolute && !end_with_dot && tmp2[tolen - 1] == '.') tolen--; if (isc_buffer_length(buffer) < used_org + tolen) return (ISC_R_NOSPACE); isc_buffer_subtract(buffer, isc_buffer_usedlength(buffer) - used_org); - memmove(isc_buffer_used(buffer), tmp1, tolen); + memmove(isc_buffer_used(buffer), tmp2, tolen); isc_buffer_add(buffer, (unsigned int)tolen); return (ISC_R_SUCCESS); @@ -4305,11 +4301,28 @@ idn_locale_to_ace(const char *from, char *to, size_t tolen) { int res; char *tmp_str = NULL; - res = idn2_lookup_ul(from, &tmp_str, IDN2_NONTRANSITIONAL); - if (res == IDN2_DISALLOWED) - res = idn2_lookup_ul(from, &tmp_str, IDN2_TRANSITIONAL); + res = idn2_to_ascii_lz(from, &tmp_str, IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT); + if (res == IDN2_DISALLOWED) { + res = idn2_to_ascii_lz(from, &tmp_str, IDN2_TRANSITIONAL|IDN2_NFC_INPUT); + } if (res == IDN2_OK) { + /* + * idn2_to_ascii_lz() normalizes all strings to lowerl case, + * but we generally don't want to lowercase all input strings; + * make sure to return the original case if the two strings + * differ only in case + */ + if (!strcasecmp(from, tmp_str)) { + if (strlen(from) >= tolen) { + debug("from string is too long"); + idn2_free(tmp_str); + return ISC_R_NOSPACE; + } + idn2_free(tmp_str); + (void) strlcpy(to, from, tolen); + return ISC_R_SUCCESS; + } /* check the length */ if (strlen(tmp_str) >= tolen) { debug("ACE string is too long"); @@ -4322,7 +4335,7 @@ idn_locale_to_ace(const char *from, char *to, size_t tolen) { return ISC_R_SUCCESS; } - fatal("idn2_lookup_ul failed: %s", idn2_strerror(res)); + fatal("'%s' is not a legal IDN name (%s), use +noidnin", from, idn2_strerror(res)); return ISC_R_FAILURE; } @@ -4333,7 +4346,7 @@ idn_ace_to_locale(const char *from, char *to, size_t tolen) { char *tmp_str = NULL; res = idn2_to_unicode_8zlz(from, &tmp_str, - IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT); + IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT); if (res == IDN2_OK) { /* check the length */ @@ -4343,14 +4356,12 @@ idn_ace_to_locale(const char *from, char *to, size_t tolen) { return ISC_R_FAILURE; } - (void) strncpy(to, tmp_str, tolen); - free(tmp_str); + (void) strlcpy(to, tmp_str, tolen); + idn2_free(tmp_str); return ISC_R_SUCCESS; - } else { - debug("idn2_to_unicode_8zlz failed: %s", - idn2_strerror(res)); } + fatal("'%s' is not a legal IDN name (%s), use +noidnout", from, idn2_strerror(res)); return ISC_R_FAILURE; } #endif /* WITH_IDN_OUT_SUPPORT */