diff --git a/CMakeLists.txt b/CMakeLists.txt index 4187d37d0..ed3f38a75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -449,7 +449,7 @@ if(NOT CURL_DISABLE_LDAPS) endif() # Check for idn -check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN) +check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2) # Check for symbol dlopen (same as HAVE_LIBDL) check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN) @@ -618,7 +618,7 @@ check_include_file_concat("des.h" HAVE_DES_H) check_include_file_concat("err.h" HAVE_ERR_H) check_include_file_concat("errno.h" HAVE_ERRNO_H) check_include_file_concat("fcntl.h" HAVE_FCNTL_H) -check_include_file_concat("idn-free.h" HAVE_IDN_FREE_H) +check_include_file_concat("idn2.h" HAVE_IDN2_H) check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H) check_include_file_concat("io.h" HAVE_IO_H) check_include_file_concat("krb.h" HAVE_KRB_H) @@ -648,7 +648,6 @@ check_include_file_concat("stropts.h" HAVE_STROPTS_H) check_include_file_concat("termio.h" HAVE_TERMIO_H) check_include_file_concat("termios.h" HAVE_TERMIOS_H) check_include_file_concat("time.h" HAVE_TIME_H) -check_include_file_concat("tld.h" HAVE_TLD_H) check_include_file_concat("unistd.h" HAVE_UNISTD_H) check_include_file_concat("utime.h" HAVE_UTIME_H) check_include_file_concat("x509.h" HAVE_X509_H) @@ -662,9 +661,6 @@ check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H) check_include_file_concat("stdint.h" HAVE_STDINT_H) check_include_file_concat("sockio.h" HAVE_SOCKIO_H) check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H) -check_include_file_concat("idna.h" HAVE_IDNA_H) - - check_type_size(size_t SIZEOF_SIZE_T) check_type_size(ssize_t SIZEOF_SSIZE_T) @@ -811,9 +807,6 @@ check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE) check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE) check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME) check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT) -check_symbol_exists(idn_free "${CURL_INCLUDES}" HAVE_IDN_FREE) -check_symbol_exists(idna_strerror "${CURL_INCLUDES}" HAVE_IDNA_STRERROR) -check_symbol_exists(tld_strerror "${CURL_INCLUDES}" HAVE_TLD_STRERROR) check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE) check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT) check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL) @@ -1078,7 +1071,7 @@ _add_if("IPv6" ENABLE_IPV6) _add_if("unix-sockets" USE_UNIX_SOCKETS) _add_if("libz" HAVE_LIBZ) _add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32) -_add_if("IDN" HAVE_LIBIDN) +_add_if("IDN" HAVE_LIBIDN2) _add_if("Largefile" (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES)) # TODO SSP1 (WinSSL) check is missing diff --git a/configure.ac b/configure.ac index 83cfbff9a..74f231608 100644 --- a/configure.ac +++ b/configure.ac @@ -157,7 +157,7 @@ curl_tls_srp_msg="no (--enable-tls-srp)" curl_res_msg="default (--enable-ares / --enable-threaded-resolver)" curl_ipv6_msg="no (--enable-ipv6)" curl_unix_sockets_msg="no (--enable-unix-sockets)" - curl_idn_msg="no (--with-{libidn,winidn})" + curl_idn_msg="no (--with-{libidn2,winidn})" curl_manual_msg="no (--enable-manual)" curl_libcurl_msg="enabled (--disable-libcurl-option)" curl_verbose_msg="enabled (--disable-verbose)" @@ -2830,15 +2830,15 @@ dnl ********************************************************************** dnl Check for the presence of IDN libraries and headers dnl ********************************************************************** -AC_MSG_CHECKING([whether to build with libidn]) +AC_MSG_CHECKING([whether to build with libidn2]) OPT_IDN="default" AC_ARG_WITH(libidn, -AC_HELP_STRING([--with-libidn=PATH],[Enable libidn usage]) -AC_HELP_STRING([--without-libidn],[Disable libidn usage]), +AC_HELP_STRING([--with-libidn2=PATH],[Enable libidn2 usage]) +AC_HELP_STRING([--without-libidn2],[Disable libidn2 usage]), [OPT_IDN=$withval]) case "$OPT_IDN" in no) - dnl --without-libidn option used + dnl --without-libidn2 option used want_idn="no" AC_MSG_RESULT([no]) ;; @@ -2849,13 +2849,13 @@ case "$OPT_IDN" in AC_MSG_RESULT([(assumed) yes]) ;; yes) - dnl --with-libidn option used without path + dnl --with-libidn2 option used without path want_idn="yes" want_idn_path="default" AC_MSG_RESULT([yes]) ;; *) - dnl --with-libidn option used with path + dnl --with-libidn2 option used with path want_idn="yes" want_idn_path="$withval" AC_MSG_RESULT([yes ($withval)]) @@ -2872,33 +2872,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(libidn, [$IDN_PCDIR]) + CURL_CHECK_PKGCONFIG(libidn2, [$IDN_PCDIR]) if test "$PKGCONFIG" != "no"; then IDN_LIBS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl - $PKGCONFIG --libs-only-l libidn 2>/dev/null` + $PKGCONFIG --libs-only-l libidn2 2>/dev/null` IDN_LDFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl - $PKGCONFIG --libs-only-L libidn 2>/dev/null` + $PKGCONFIG --libs-only-L libidn2 2>/dev/null` IDN_CPPFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl - $PKGCONFIG --cflags-only-I libidn 2>/dev/null` + $PKGCONFIG --cflags-only-I libidn2 2>/dev/null` IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'` else dnl pkg-config not available or provides no info - IDN_LIBS="-lidn" + IDN_LIBS="-lidn2" 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(libidn) + CURL_CHECK_PKGCONFIG(libidn2) if test "$PKGCONFIG" != "no"; then - IDN_LIBS=`$PKGCONFIG --libs-only-l libidn 2>/dev/null` - IDN_LDFLAGS=`$PKGCONFIG --libs-only-L libidn 2>/dev/null` - IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I libidn 2>/dev/null` + IDN_LIBS=`$PKGCONFIG --libs-only-l libidn2 2>/dev/null` + IDN_LDFLAGS=`$PKGCONFIG --libs-only-L libidn2 2>/dev/null` + IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I libidn2 2>/dev/null` IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'` else dnl pkg-config not available or provides no info - IDN_LIBS="-lidn" + IDN_LIBS="-lidn2" fi fi # @@ -2918,9 +2918,9 @@ if test "$want_idn" = "yes"; then LDFLAGS="$IDN_LDFLAGS $LDFLAGS" LIBS="$IDN_LIBS $LIBS" # - AC_MSG_CHECKING([if idna_to_ascii_4i can be linked]) + AC_MSG_CHECKING([if idn2_lookup_ul can be linked]) AC_LINK_IFELSE([ - AC_LANG_FUNC_LINK_TRY([idna_to_ascii_4i]) + AC_LANG_FUNC_LINK_TRY([idn2_lookup_ul]) ],[ AC_MSG_RESULT([yes]) tst_links_libidn="yes" @@ -2928,37 +2928,19 @@ if test "$want_idn" = "yes"; then AC_MSG_RESULT([no]) tst_links_libidn="no" ]) - if test "$tst_links_libidn" = "no"; then - AC_MSG_CHECKING([if idna_to_ascii_lz can be linked]) - AC_LINK_IFELSE([ - AC_LANG_FUNC_LINK_TRY([idna_to_ascii_lz]) - ],[ - AC_MSG_RESULT([yes]) - tst_links_libidn="yes" - ],[ - AC_MSG_RESULT([no]) - tst_links_libidn="no" - ]) - fi # + AC_CHECK_HEADERS( idn2.h ) + if test "$tst_links_libidn" = "yes"; then - AC_DEFINE(HAVE_LIBIDN, 1, [Define to 1 if you have the `idn' library (-lidn).]) + AC_DEFINE(HAVE_LIBIDN2, 1, [Define to 1 if you have the `idn2' library (-lidn2).]) dnl different versions of libidn have different setups of these: - AC_CHECK_FUNCS( idn_free idna_strerror tld_strerror ) - AC_CHECK_HEADERS( idn-free.h tld.h ) - if test "x$ac_cv_header_tld_h" = "xyes"; then - AC_SUBST([IDN_ENABLED], [1]) - curl_idn_msg="enabled" - if test -n "$IDN_DIR" -a "x$cross_compiling" != "xyes"; then - LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$IDN_DIR" - export LD_LIBRARY_PATH - AC_MSG_NOTICE([Added $IDN_DIR to LD_LIBRARY_PATH]) - fi - else - AC_MSG_WARN([Libraries for IDN support too old: IDN disabled]) - CPPFLAGS="$clean_CPPFLAGS" - LDFLAGS="$clean_LDFLAGS" - LIBS="$clean_LIBS" + + AC_SUBST([IDN_ENABLED], [1]) + curl_idn_msg="enabled (libidn2)" + if test -n "$IDN_DIR" -a "x$cross_compiling" != "xyes"; then + LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$IDN_DIR" + export LD_LIBRARY_PATH + AC_MSG_NOTICE([Added $IDN_DIR to LD_LIBRARY_PATH]) fi else AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled]) diff --git a/lib/curl_setup.h b/lib/curl_setup.h index 5d82e339b..9619a1e66 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -599,10 +599,9 @@ int netware_init(void); #endif #endif -#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H) -/* The lib was present and the tld.h header (which is missing in libidn 0.3.X - but we only work with libidn 0.4.1 or later) */ -#define USE_LIBIDN +#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) +/* The lib and header are present */ +#define USE_LIBIDN2 #endif #ifndef SIZEOF_TIME_T diff --git a/lib/easy.c b/lib/easy.c index 517c39ffc..cb0ac6740 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -144,28 +144,6 @@ static CURLcode win32_init(void) return CURLE_OK; } -#ifdef USE_LIBIDN -/* - * Initialise use of IDNA library. - * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for - * idna_to_ascii_lz(). - */ -static void idna_init (void) -{ -#ifdef WIN32 - char buf[60]; - UINT cp = GetACP(); - - if(!getenv("CHARSET") && cp > 0) { - snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp); - putenv(buf); - } -#else - /* to do? */ -#endif -} -#endif /* USE_LIBIDN */ - /* true globals -- for curl_global_init() and curl_global_cleanup() */ static unsigned int initialized; static long init_flags; @@ -262,10 +240,6 @@ static CURLcode global_init(long flags, bool memoryfuncs) } #endif -#ifdef USE_LIBIDN - idna_init(); -#endif - if(Curl_resolver_global_init()) { DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n")); return CURLE_FAILED_INIT; diff --git a/lib/strerror.c b/lib/strerror.c index edb96d201..db50c7d1a 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -35,8 +35,8 @@ #include -#ifdef USE_LIBIDN -#include +#ifdef USE_LIBIDN2 +#include #endif #ifdef USE_WINDOWS_SSPI @@ -726,83 +726,6 @@ const char *Curl_strerror(struct connectdata *conn, int err) return buf; } -#ifdef USE_LIBIDN -/* - * Return error-string for libidn status as returned from idna_to_ascii_lz(). - */ -const char *Curl_idn_strerror (struct connectdata *conn, int err) -{ -#ifdef HAVE_IDNA_STRERROR - (void)conn; - return idna_strerror((Idna_rc) err); -#else - const char *str; - char *buf; - size_t max; - - DEBUGASSERT(conn); - - buf = conn->syserr_buf; - max = sizeof(conn->syserr_buf)-1; - *buf = '\0'; - -#ifndef CURL_DISABLE_VERBOSE_STRINGS - switch ((Idna_rc)err) { - case IDNA_SUCCESS: - str = "No error"; - break; - case IDNA_STRINGPREP_ERROR: - str = "Error in string preparation"; - break; - case IDNA_PUNYCODE_ERROR: - str = "Error in Punycode operation"; - break; - case IDNA_CONTAINS_NON_LDH: - str = "Illegal ASCII characters"; - break; - case IDNA_CONTAINS_MINUS: - str = "Contains minus"; - break; - case IDNA_INVALID_LENGTH: - str = "Invalid output length"; - break; - case IDNA_NO_ACE_PREFIX: - str = "No ACE prefix (\"xn--\")"; - break; - case IDNA_ROUNDTRIP_VERIFY_ERROR: - str = "Round trip verify error"; - break; - case IDNA_CONTAINS_ACE_PREFIX: - str = "Already have ACE prefix (\"xn--\")"; - break; - case IDNA_ICONV_ERROR: - str = "Locale conversion failed"; - break; - case IDNA_MALLOC_ERROR: - str = "Allocation failed"; - break; - case IDNA_DLOPEN_ERROR: - str = "dlopen() error"; - break; - default: - snprintf(buf, max, "error %d", err); - str = NULL; - break; - } -#else - if((Idna_rc)err == IDNA_SUCCESS) - str = "No error"; - else - str = "Error"; -#endif - if(str) - strncpy(buf, str, max); - buf[max] = '\0'; - return (buf); -#endif -} -#endif /* USE_LIBIDN */ - #ifdef USE_WINDOWS_SSPI const char *Curl_sspi_strerror (struct connectdata *conn, int err) { diff --git a/lib/strerror.h b/lib/strerror.h index ae8c96bd4..627273eb2 100644 --- a/lib/strerror.h +++ b/lib/strerror.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,7 +26,7 @@ const char *Curl_strerror (struct connectdata *conn, int err); -#ifdef USE_LIBIDN +#ifdef USE_LIBIDN2 const char *Curl_idn_strerror (struct connectdata *conn, int err); #endif diff --git a/lib/url.c b/lib/url.c index 98236e219..b42673163 100644 --- a/lib/url.c +++ b/lib/url.c @@ -59,24 +59,15 @@ #include #endif -#ifdef USE_LIBIDN -#include -#include -#include -#ifdef HAVE_IDN_FREE_H -#include -#else -/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */ -void idn_free (void *ptr); -#endif -#ifndef HAVE_IDN_FREE -/* if idn_free() was not found in this version of libidn use free() instead */ -#define idn_free(x) (free)(x) -#endif +#ifdef USE_LIBIDN2 +#include + #elif defined(USE_WIN32_IDN) /* prototype for curl_win32_idn_to_ascii() */ bool curl_win32_idn_to_ascii(const char *in, char **out); -#endif /* USE_LIBIDN */ +#endif /* USE_LIBIDN2 */ + +#include #include "urldata.h" #include "netrc.h" @@ -3771,58 +3762,15 @@ static bool is_ASCII_name(const char *hostname) return TRUE; } -#ifdef USE_LIBIDN -/* - * Check if characters in hostname is allowed in Top Level Domain. - */ -static bool tld_check_name(struct Curl_easy *data, - const char *ace_hostname) -{ - size_t err_pos; - char *uc_name = NULL; - int rc; -#ifndef CURL_DISABLE_VERBOSE_STRINGS - const char *tld_errmsg = ""; -#else - (void)data; -#endif - - /* Convert (and downcase) ACE-name back into locale's character set */ - rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0); - if(rc != IDNA_SUCCESS) - return FALSE; - - /* Warning: err_pos receives "the decoded character offset rather than the - byte position in the string." And as of libidn 1.32 that character offset - is for UTF-8, even if the passed in string is another locale. */ - rc = tld_check_lz(uc_name, &err_pos, NULL); -#ifndef CURL_DISABLE_VERBOSE_STRINGS -#ifdef HAVE_TLD_STRERROR - if(rc != TLD_SUCCESS) - tld_errmsg = tld_strerror((Tld_rc)rc); -#endif - if(rc != TLD_SUCCESS) - infof(data, "WARNING: TLD check for %s failed; %s\n", - uc_name, tld_errmsg); -#endif /* CURL_DISABLE_VERBOSE_STRINGS */ - if(uc_name) - idn_free(uc_name); - if(rc != TLD_SUCCESS) - return FALSE; - - return TRUE; -} -#endif - /* * Perform any necessary IDN conversion of hostname */ -static void fix_hostname(struct Curl_easy *data, - struct connectdata *conn, struct hostname *host) +static void fix_hostname(struct connectdata *conn, struct hostname *host) { size_t len; + struct Curl_easy *data = conn->data; -#ifndef USE_LIBIDN +#ifndef USE_LIBIDN2 (void)data; (void)conn; #elif defined(CURL_DISABLE_VERBOSE_STRINGS) @@ -3840,25 +3788,18 @@ static void fix_hostname(struct Curl_easy *data, /* Check name for non-ASCII and convert hostname to ACE form if we can */ if(!is_ASCII_name(host->name)) { -#ifdef USE_LIBIDN - if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { +#ifdef USE_LIBIDN2 + if(idn2_check_version(IDN2_VERSION)) { char *ace_hostname = NULL; - - int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); - infof(data, "Input domain encoded as `%s'\n", - stringprep_locale_charset()); - if(rc == IDNA_SUCCESS) { - /* tld_check_name() displays a warning if the host name contains - "illegal" characters for this TLD */ - (void)tld_check_name(data, ace_hostname); - - host->encalloc = ace_hostname; + int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, 0); + if(rc == IDN2_OK) { + host->encalloc = (char *)ace_hostname; /* change the name pointer to point to the encoded hostname */ host->name = host->encalloc; } else infof(data, "Failed to convert %s to ACE; %s\n", host->name, - Curl_idn_strerror(conn, rc)); + idn2_strerror(rc)); } #elif defined(USE_WIN32_IDN) char *ace_hostname = NULL; @@ -3881,9 +3822,9 @@ static void fix_hostname(struct Curl_easy *data, */ static void free_fixed_hostname(struct hostname *host) { -#if defined(USE_LIBIDN) +#if defined(USE_LIBIDN2) if(host->encalloc) { - idn_free(host->encalloc); /* must be freed with idn_free() since this was + idn2_free(host->encalloc); /* must be freed with idn2_free() since this was allocated by libidn */ host->encalloc = NULL; } @@ -6046,11 +5987,11 @@ static CURLcode create_conn(struct Curl_easy *data, /************************************************************* * IDN-fix the hostnames *************************************************************/ - fix_hostname(data, conn, &conn->host); + fix_hostname(conn, &conn->host); if(conn->bits.conn_to_host) - fix_hostname(data, conn, &conn->conn_to_host); + fix_hostname(conn, &conn->conn_to_host); if(conn->proxy.name && *conn->proxy.name) - fix_hostname(data, conn, &conn->proxy); + fix_hostname(conn, &conn->proxy); /************************************************************* * Check whether the host and the "connect to host" are equal. diff --git a/lib/version.c b/lib/version.c index 12924453c..a434a6287 100644 --- a/lib/version.c +++ b/lib/version.c @@ -36,8 +36,8 @@ # include #endif -#ifdef USE_LIBIDN -#include +#ifdef USE_LIBIDN2 +#include #endif #ifdef USE_LIBPSL @@ -111,9 +111,9 @@ char *curl_version(void) left -= len; ptr += len; #endif -#ifdef USE_LIBIDN - if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { - len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL)); +#ifdef USE_LIBIDN2 + if(idn2_check_version(IDN2_VERSION)) { + len = snprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL)); left -= len; ptr += len; } @@ -365,10 +365,10 @@ curl_version_info_data *curl_version_info(CURLversion stamp) version_info.ares_num = aresnum; } #endif -#ifdef USE_LIBIDN +#ifdef USE_LIBIDN2 /* This returns a version string if we use the given version or later, otherwise it returns NULL */ - version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION); + version_info.libidn = idn2_check_version(IDN2_VERSION); if(version_info.libidn) version_info.features |= CURL_VERSION_IDN; #elif defined(USE_WIN32_IDN)