Use icu library for IDN feature 72/168072/1
authorSeonah Moon <seonah1.moon@samsung.com>
Wed, 16 Aug 2017 09:21:40 +0000 (18:21 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Wed, 24 Jan 2018 04:48:17 +0000 (13:48 +0900)
Change-Id: Ie0cae521c7eacfcd788a32b90adc20ba19ec66da

configure.ac
lib/curl_config.h.in
lib/url.c
packaging/curl.spec

index ab6a629..c0ec6df 100644 (file)
@@ -2954,18 +2954,18 @@ dnl http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/ \
 dnl genprogc/thread_quick_ref.htm
 
 dnl **********************************************************************
-dnl Check for GLIB-2.0 (IDN support)
+dnl Check for ICU-UC (IDN support)
 dnl **********************************************************************
 
-AC_MSG_CHECKING([whether to build with glib-2.0])
+AC_MSG_CHECKING([whether to build with icu-uc])
 OPT_IDN="default"
-AC_ARG_WITH(glib-2.0,
-AC_HELP_STRING([--with-glib2=PATH],[Enable glib-2.0 usage])
-AC_HELP_STRING([--without-glib2],[Disable glib-2.0 usage]),
+AC_ARG_WITH(icu-uc,
+AC_HELP_STRING([--with-icu-uc=PATH],[Enable icu-uc usage])
+AC_HELP_STRING([--without-icu-uc],[Disable icu-uc usage]),
   [OPT_IDN=$withval])
 case "$OPT_IDN" in
   no)
-    dnl --without-glib2 option used
+    dnl --without-icu-uc option used
     want_idn="no"
     AC_MSG_RESULT([no])
     ;;
@@ -2976,13 +2976,13 @@ case "$OPT_IDN" in
     AC_MSG_RESULT([(assumed) yes])
     ;;
   yes)
-    dnl --with-glib2 option used without path
+    dnl --with-icu-uc option used without path
     want_idn="yes"
     want_idn_path="default"
     AC_MSG_RESULT([yes])
     ;;
   *)
-    dnl --with-glib2 option used with path
+    dnl --with-icu-uc option used with path
     want_idn="yes"
     want_idn_path="$withval"
     AC_MSG_RESULT([yes ($withval)])
@@ -2999,33 +2999,33 @@ if test "$want_idn" = "yes"; then
   if test "$want_idn_path" != "default"; then
     dnl path has been specified
     IDN_PCDIR="$want_idn_path/lib$libsuff/pkgconfig"
-    CURL_CHECK_PKGCONFIG(glib-2.0, [$IDN_PCDIR])
+    CURL_CHECK_PKGCONFIG(icu-uc, [$IDN_PCDIR])
     if test "$PKGCONFIG" != "no"; then
       IDN_LIBS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
-        $PKGCONFIG --libs-only-l glib-2.0 2>/dev/null`
+        $PKGCONFIG --libs-only-l icu-uc 2>/dev/null`
       IDN_LDFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
-        $PKGCONFIG --libs-only-L glib-2.0 2>/dev/null`
+        $PKGCONFIG --libs-only-L icu-uc 2>/dev/null`
       IDN_CPPFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
-        $PKGCONFIG --cflags-only-I glib-2.0 2>/dev/null`
+        $PKGCONFIG --cflags-only-I icu-uc 2>/dev/null`
       IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
     else
       dnl pkg-config not available or provides no info
-      IDN_LIBS="-lglib-2.0"
+      IDN_LIBS="-licu-uc"
       IDN_LDFLAGS="-L$want_idn_path/lib$libsuff"
       IDN_CPPFLAGS="-I$want_idn_path/include"
       IDN_DIR="$want_idn_path/lib$libsuff"
     fi
   else
     dnl path not specified
-    CURL_CHECK_PKGCONFIG(glib-2.0)
+    CURL_CHECK_PKGCONFIG(icu-uc)
     if test "$PKGCONFIG" != "no"; then
-      IDN_LIBS=`$PKGCONFIG --libs-only-l glib-2.0 2>/dev/null`
-      IDN_LDFLAGS=`$PKGCONFIG --libs-only-L glib-2.0 2>/dev/null`
-      IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I glib-2.0 2>/dev/null`
+      IDN_LIBS=`$PKGCONFIG --libs-only-l icu-uc 2>/dev/null`
+      IDN_LDFLAGS=`$PKGCONFIG --libs-only-L icu-uc 2>/dev/null`
+      IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I icu-uc 2>/dev/null`
       IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
     else
       dnl pkg-config not available or provides no info
-      IDN_LIBS="-lglib-2.0"
+      IDN_LIBS="-licu-uc"
     fi
   fi
   #
@@ -3045,23 +3045,23 @@ if test "$want_idn" = "yes"; then
   LDFLAGS="$IDN_LDFLAGS $LDFLAGS"
   LIBS="$IDN_LIBS $LIBS"
   #
-  AC_MSG_CHECKING([if g_hostname_to_ascii can be linked])
+  AC_MSG_CHECKING([if uidna_nameToASCII_UTF8 can be linked])
   AC_LINK_IFELSE([
-    AC_LANG_FUNC_LINK_TRY([g_hostname_to_ascii])
+    AC_LANG_FUNC_LINK_TRY([uidna_nameToASCII_UTF8])
   ],[
     AC_MSG_RESULT([yes])
-    tst_links_glib2="yes"
+    tst_links_icu="yes"
   ],[
     AC_MSG_RESULT([no])
-    tst_links_glib2="no"
+    tst_links_icu="no"
   ])
   #
-  if test "$tst_links_glib2" = "yes"; then
-    AC_DEFINE(USE_GLIB2_HOSTNAME, 1, [Define to 1 if you have the `glib-2.0' library (-lglib-2.0).])
+  if test "$tst_links_icu" = "yes"; then
+    AC_DEFINE(USE_ICU_IDNA, 1, [Define to 1 if you have the `icu-uc' library (-licu-uc).])
     dnl different versions of libidn have different setups of these:
 
     AC_SUBST([IDN_ENABLED], [1])
-    curl_idn_msg="enabled (glib-2.0)"
+    curl_idn_msg="enabled (icu-uc)"
     if test -n "$IDN_DIR" -a "x$cross_compiling" != "xyes"; then
       LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$IDN_DIR"
       export LD_LIBRARY_PATH
index 21bf76d..f1a2d1b 100644 (file)
 /* to enable Apple OS native SSL/TLS support */
 #undef USE_DARWINSSL
 
-/* Define to 1 if you have the `glib-2.0' library (-lglib-2.0). */
-#undef USE_GLIB2_HOSTNAME
+/* Define to 1 if you have the `icu-uc' library (-licu-uc). */
+#undef USE_ICU_IDNA
 
 /* if GnuTLS is enabled */
 #undef USE_GNUTLS
index 8692e68..97f5d86 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -65,8 +65,8 @@
 #elif defined(USE_WIN32_IDN)
 /* prototype for curl_win32_idn_to_ascii() */
 bool curl_win32_idn_to_ascii(const char *in, char **out);
-#elif defined(USE_GLIB2_HOSTNAME)
-#include <glib.h>
+#elif defined(USE_ICU_IDNA)
+#include <unicode/uidna.h>
 #endif  /* USE_LIBIDN2 */
 
 #include "urldata.h"
@@ -126,6 +126,10 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
 #include "curl_memory.h"
 #include "memdebug.h"
 
+#if defined(USE_ICU_IDNA)
+#define MAX_DOMAIN_NAME_LEN 256
+#endif  /* USE_ICU_IDNA */
+
 /* Local static prototypes */
 static struct connectdata *
 find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
@@ -4074,15 +4078,24 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host)
     }
     else
       infof(data, "Failed to convert %s to ACE;\n", host->name);
-#elif defined(USE_GLIB2_HOSTNAME)
-    gchar *ace_hostname = NULL;
-    ace_hostname = g_hostname_to_ascii(host->name);
-    if(ace_hostname) {
-      host->encalloc = (char *)ace_hostname;
+#elif defined(USE_ICU_IDNA)
+    char *ace_hostname = malloc(MAX_DOMAIN_NAME_LEN * sizeof(char));
+    UErrorCode errorCode = U_ZERO_ERROR;
+    UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+    UIDNA *uts46 =
+      uidna_openUTS46(UIDNA_USE_STD3_RULES|UIDNA_NONTRANSITIONAL_TO_UNICODE,
+      &errorCode);
+    int32_t length = uidna_nameToASCII_UTF8(uts46,
+      host->name, strlen(host->name),
+      ace_hostname, MAX_DOMAIN_NAME_LEN, &info, &errorCode);
+    uidna_close(uts46);
+
+    if(errorCode != U_ZERO_ERROR || info.errors || length < 1)
+      infof(data, "Failed to convert %s to ACE;\n", host->name);
+    else {
+      host->encalloc = ace_hostname;
       host->name = host->encalloc;
     }
-    else
-      infof(data, "Failed to convert %s to ACE;\n", host->name);
 #else
     infof(data, "IDN support not present, can't parse Unicode domains\n");
 #endif
@@ -4104,6 +4117,9 @@ static void free_fixed_hostname(struct hostname *host)
   free(host->encalloc); /* must be freed withidn_free() since this was
                            allocated by curl_win32_idn_to_ascii */
   host->encalloc = NULL;
+#elif defined(USE_ICU_IDNA)
+  free(host->encalloc);
+  host->encalloc = NULL;
 #else
   (void)host;
 #endif
index bb36ac8..b2171cf 100644 (file)
@@ -9,7 +9,7 @@ URL:        http://curl.haxx.se/
 Source0:    %{name}-%{version}.tar.gz
 Source1001:     %{name}.manifest
 
-BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(icu-uc)
 BuildRequires:  pkgconfig(openssl)
 BuildRequires:  pkgconfig(zlib)
 BuildRequires:  pkgconfig(libcares)
@@ -43,7 +43,6 @@ Summary:    Files needed for building applications with libcurl
 Group:      Development/Libraries
 License:    MIT
 Requires:   libcurl = %{version}-%{release}
-Requires:   glib2-devel
 Provides:   curl-devel = %{version}-%{release}
 Obsoletes:   curl-devel < %{version}-%{release}
 
@@ -79,7 +78,7 @@ CFLAGS+=" -DTIZEN_TV_EXT"
 %endif
 --with-ca-path==/etc/ssl/certs \
 --with-ca-bundle=/etc/ssl/ca-bundle.pem \
---with-glib2 \
+--with-icu-uc \
 --with-lber-lib=lber \
 --enable-manual --enable-versioned-symbols --enable-ares --enable-debug --enable-curldebug \
 --disable-static \