]> granicus.if.org Git - neomutt/commitdiff
Do not rely on idn2 to provide an idn1 compat layer
authorPietro Cerutti <gahr@gahr.ch>
Mon, 29 Apr 2019 11:26:36 +0000 (11:26 +0000)
committerRichard Russon <rich@flatcap.org>
Mon, 29 Apr 2019 13:30:09 +0000 (14:30 +0100)
Do not rely on idn2 to provide a compat layer to idn1, as Ubuntu doesn't
provide it. Instead, really code address/idna.c to use the different
APIs provided by the two versions of libidn. Systems with an old version
of idn2 which does not provide the needed functionality will fail at
configure time now, and users of such systems will see an error message
with instructions how to build with libidn1. While at it, polish a bit
the auto.def sections for idn and idn2.

address/idna.c
auto.def

index ef7861e8d137caec0057d4bde431877ffb6df896..b6b06d7f402c2a7d5a700b0145dc6a504d923b6b 100644 (file)
@@ -37,8 +37,8 @@
 #elif defined(HAVE_IDN_STRINGPREP_H)
 #include <idn/stringprep.h>
 #endif
+#define IDN2_SKIP_LIBIDN_COMPAT
 #ifdef HAVE_IDN2_H
-#include <idna.h>
 #include <idn2.h>
 #elif defined(HAVE_IDN_IDN2_H)
 #include <idn/idn2.h>
 #include <idn/idna.h>
 #endif
 
+#if defined(HAVE_IDN2_H) || defined(HAVE_IDN_IDN2_H)
+#define IDN_VERSION 2
+#elif defined(HAVE_IDNA_H) || defined(HAVE_IDN_IDNA_H)
+#define IDN_VERSION 1
+#endif
+
 /* These Config Variables are only used in mutt/idna.c */
 #ifdef HAVE_LIBIDN
 bool C_IdnDecode; ///< Config: (idn) Decode international domain names
@@ -110,7 +116,11 @@ int mutt_idna_to_ascii_lz(const char *input, char **output, int flags)
   if (!input || !output)
     return 1;
 
+#if IDN_VERSION == 2
+  return idn2_to_ascii_8z(input, output, flags | IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL);
+#else
   return idna_to_ascii_lz(input, output, flags);
+#endif
 }
 #endif /* HAVE_LIBIDN */
 
@@ -145,8 +155,14 @@ char *mutt_idna_intl_to_local(const char *user, const char *domain, int flags)
   bool is_idn_encoded = check_idn(local_domain);
   if (is_idn_encoded && C_IdnDecode)
   {
+#if IDN_VERSION == 2
+    if (idn2_to_unicode_8z8z(local_domain, &tmp, IDN2_ALLOW_UNASSIGNED) != IDN2_OK)
+#else
     if (idna_to_unicode_8z8z(local_domain, &tmp, IDNA_ALLOW_UNASSIGNED) != IDNA_SUCCESS)
+#endif
+    {
       goto cleanup;
+    }
     mutt_str_replace(&local_domain, tmp);
     FREE(&tmp);
   }
@@ -194,7 +210,12 @@ char *mutt_idna_intl_to_local(const char *user, const char *domain, int flags)
      * idna_to_ascii_8z() if the original domain was IDNA encoded.  */
     if (is_idn_encoded && C_IdnDecode)
     {
+#if IDN_VERSION == 2
+      if (idn2_to_ascii_8z(reversed_domain, &tmp,
+                           IDN2_ALLOW_UNASSIGNED | IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL) != IDN2_OK)
+#else
       if (idna_to_ascii_8z(reversed_domain, &tmp, IDNA_ALLOW_UNASSIGNED) != IDNA_SUCCESS)
+#endif
       {
         mutt_debug(LL_DEBUG1, "Not reversible. idna_to_ascii_8z failed for domain = '%s'\n",
                    reversed_domain);
@@ -257,8 +278,15 @@ char *mutt_idna_local_to_intl(const char *user, const char *domain)
 #ifdef HAVE_LIBIDN
   if (C_IdnEncode)
   {
+#if IDN_VERSION == 2
+    if (idn2_to_ascii_8z(intl_domain, &tmp,
+                         IDN2_ALLOW_UNASSIGNED | IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL) != IDN2_OK)
+#else
     if (idna_to_ascii_8z(intl_domain, &tmp, IDNA_ALLOW_UNASSIGNED) != IDNA_SUCCESS)
+#endif
+    {
       goto cleanup;
+    }
     mutt_str_replace(&intl_domain, tmp);
   }
 #endif /* HAVE_LIBIDN */
@@ -284,13 +312,15 @@ const char *mutt_idna_print_version(void)
 {
   static char vstring[256];
 
-#ifdef HAVE_IDN2_H
+#ifdef HAVE_LIBIDN
+#if IDN_VERSION == 2
   snprintf(vstring, sizeof(vstring), "libidn2: %s (compiled with %s)",
            idn2_check_version(NULL), IDN2_VERSION);
-#elif defined(HAVE_LIBIDN)
+#elif IDN_VERSION == 1
   snprintf(vstring, sizeof(vstring), "libidn: %s (compiled with %s)",
            stringprep_check_version(NULL), STRINGPREP_VERSION);
 #endif
+#endif /* HAVE_LIBIDN */
 
   return vstring;
 }
index 54f432cb62906e49e05c6b8daa51d347bf65e40f..f54b05f2cf46b5ce923b145c9b44d9a3593af364 100644 (file)
--- a/auto.def
+++ b/auto.def
@@ -697,12 +697,9 @@ if {[get-define want-idn]} {
   set sprep 0
   set idna 0
   cc-with [list -cflags -I$idn_prefix/include -libs -L$idn_prefix/lib] {
-    incr sprep [cc-check-includes stringprep.h]
-    incr sprep [cc-check-includes idn/stringprep.h]
-    incr idna  [cc-check-includes idna.h]
-    incr idna  [cc-check-includes idn/idna.h]
-    set  sprcv [cc-check-function-in-lib stringprep_check_version idn]
-    if {$sprep == 0 || $idna == 0 || $sprcv == 0} {
+    if {!([cc-check-includes stringprep.h] || [cc-check-includes idn/stringprep.h]) ||
+        !([cc-check-includes idna.h] || [cc-check-includes idn/idna.h]) ||
+        ![cc-check-function-in-lib stringprep_check_version idn]} {
       user-error "Unable to find GNU libidn"
     }
     define-feature libidn
@@ -715,21 +712,19 @@ if {[get-define want-idn]} {
 } elseif {[get-define want-idn2]} {
   set idn_prefix [opt-val with-idn2 $prefix]
   cc-with [list -cflags -I$idn_prefix/include -libs -L$idn_prefix/lib] {
-    set idn2 [cc-check-includes idn2.h]
-    incr idn2 [cc-check-includes idn/idn2.h]
-    set  sprcv [cc-check-function-in-lib stringprep_check_version idn]
-    set lu8  [cc-check-function-in-lib idn2_lookup_u8 idn2]
-    if {$idn2 == 0 || $lu8 == 0} {
+    if {!([cc-check-includes idn2.h] || [cc-check-includes idn/idn2.h])} {
       user-error "Unable to find GNU libidn2"
     }
+    if {![cc-check-function-in-lib idn2_to_ascii_8z     idn2] ||
+        ![cc-check-function-in-lib idn2_to_unicode_8z8z idn2] ||
+        ![cc-check-function-in-lib idn2_check_version   idn2]} {
+      user-error "Unable to find required functions in GNU libidn2.\
+                  Please consider using idn1 with './configure --idn'."
+    }
+
     define-feature libidn
     define-append CFLAGS -I$idn_prefix/include
     define-append LDFLAGS -L$idn_prefix/lib
-    cc-with {-includes "idn2.h idn/idn2.h"} {
-      cc-check-defines idna_to_unicode_utf8_from_utf8 idna_to_unicode_8z8z
-      cc-check-defines idna_to_ascii_from_utf8 idna_to_ascii_8z
-      cc-check-defines idna_to_ascii_lz idna_to_ascii_from_locale
-    }
   }
 }