]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Don't use the IDN traslated name if no conversion took a place
authorOndřej Surý <ondrej@sury.org>
Mon, 19 Mar 2018 16:09:04 +0000 (16:09 +0000)
committerOndřej Surý <ondrej@sury.org>
Wed, 21 Mar 2018 14:05:00 +0000 (14:05 +0000)
bin/dig/dighost.c

index 57712ec347faec70748335ba4d19a80ab04bde2e..7654451c509324aeab239eac2296d0a4ead18b12 100644 (file)
@@ -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 */