mirror of
https://github.com/mirror/wget.git
synced 2025-01-27 21:00:31 +08:00
Move Wget from IDN2003 (libidn) to IDN2008 (libidn2)
* .travis.yml: Install libidn2-dev instead libidn11-dev. * bootstrap.conf: Add modules libunistring-optional, unistr/base, unicase/tolower. * configure.ac: Check for libidn2. * src/Makefile.am: Add $(LTLIBUNISTRING) to LDADD. * tests/Makefile.am: Set LDADD similar to LDADD in src/Makefile.am * src/connect.c: Use libidn2 code instead of libidn. * src/host.c: Likewise. * src/iri.c: Likewise. * src/iri.h: Likewise. * src/options.h: Likewise. * src/url.c: Likewise. * src/url.h: Likewise. * src/log.c: Fix C99 comment. IDN2003 should not be used any more due to security concerns. We use libunistring (resp. the unicode code from gnulib) for lowercasing UTF-8 before we give data to libidn2. TR#46 is missing, no support in libidn2 nor in libunistring.
This commit is contained in:
parent
2242d5aee4
commit
00ae9b4ee2
@ -36,7 +36,7 @@ addons:
|
|||||||
- make
|
- make
|
||||||
- libhttp-daemon-perl
|
- libhttp-daemon-perl
|
||||||
- libio-socket-ssl-perl
|
- libio-socket-ssl-perl
|
||||||
- libidn11-dev
|
- libidn2-dev
|
||||||
- gettext
|
- gettext
|
||||||
- texlive
|
- texlive
|
||||||
- python3
|
- python3
|
||||||
|
@ -101,6 +101,9 @@ tmpdir
|
|||||||
unlink
|
unlink
|
||||||
unlocked-io
|
unlocked-io
|
||||||
update-copyright
|
update-copyright
|
||||||
|
libunistring-optional
|
||||||
|
unistr/base
|
||||||
|
unicase/tolower
|
||||||
vasprintf
|
vasprintf
|
||||||
vsnprintf
|
vsnprintf
|
||||||
write
|
write
|
||||||
|
49
configure.ac
49
configure.ac
@ -640,9 +640,6 @@ AC_ARG_ENABLE(iri,
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_ARG_WITH(libidn, AC_HELP_STRING([--with-libidn=[DIR]],
|
|
||||||
[Support IDN/IRIs (needs GNU Libidn)]),
|
|
||||||
libidn=$withval, libidn="")
|
|
||||||
AS_IF([test "X$iri" != "Xno"],[
|
AS_IF([test "X$iri" != "Xno"],[
|
||||||
AM_ICONV
|
AM_ICONV
|
||||||
|
|
||||||
@ -660,33 +657,26 @@ AS_IF([test "X$iri" != "Xno"],[
|
|||||||
LIBICONV=
|
LIBICONV=
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AC_ARG_WITH(libidn, AC_HELP_STRING([--with-libidn=[DIR]],
|
||||||
|
[Support IDN2008/IRIs (needs GNU libidn2 + libunicode)]),
|
||||||
|
libidn=$withval, libidn="")
|
||||||
if test "X$iri" != "Xno"; then
|
if test "X$iri" != "Xno"; then
|
||||||
if test "$libidn" != ""; then
|
AS_IF([test "x$with_libidn2" != xno], [
|
||||||
LDFLAGS="${LDFLAGS} -L$libidn/lib"
|
AC_SEARCH_LIBS(idn2_lookup_u8, idn2,
|
||||||
CPPFLAGS="${CPPFLAGS} -I$libidn/include"
|
[with_libidn2=yes; AC_DEFINE([ENABLE_IRI], 1, [Define if IRI support is enabled.])],
|
||||||
fi
|
[with_libidn2=no; iri=no; AC_MSG_WARN(*** LIBIDN2 was not found. You will not be able to use IDN2008 support)])
|
||||||
|
|
||||||
# If idna.h can't be found, check to see if it was installed under
|
# AS_IF([test "x$with_libidn2" = xyes], [
|
||||||
# /usr/include/idn (OpenSolaris, at least, places it there).
|
# AC_SEARCH_LIBS(u8_tolower, unistring,
|
||||||
# Check for idn-int.h in that case, because idna.h won't find
|
# [AC_DEFINE([ENABLE_IRI], 1, [Define if IRI support is enabled.])],
|
||||||
# idn-int.h until we've decided to add -I/usr/include/idn.
|
# [iri=no; AC_MSG_WARN(*** LIBUNISTRING was not found. You will not be able to use IDN2008 support)])
|
||||||
AC_CHECK_HEADER(idna.h, ,
|
# ])
|
||||||
[AC_CHECK_HEADER(idn/idn-int.h,
|
])
|
||||||
[CPPFLAGS="${CPPFLAGS} -I/usr/include/idn"],
|
fi
|
||||||
[iri=no])]
|
if test "X$iri" = "Xno"; then
|
||||||
)
|
# we don't need libunistring - clear settings from gnulib module
|
||||||
|
LIBUNISTRING=""
|
||||||
if test "X$iri" != "Xno"; then
|
LTLIBUNISTRING=""
|
||||||
AC_CHECK_LIB(idn, stringprep_check_version,
|
|
||||||
[iri=yes LIBS="${LIBS} -lidn"], iri=no)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "X$iri" != "Xno" ; then
|
|
||||||
AC_DEFINE([ENABLE_IRI], 1, [Define if IRI support is enabled.])
|
|
||||||
AC_MSG_NOTICE([Enabling support for IRI.])
|
|
||||||
else
|
|
||||||
AC_MSG_WARN([Libidn not found])
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
@ -755,7 +745,7 @@ dnl
|
|||||||
dnl Check for libcares (resolver library)
|
dnl Check for libcares (resolver library)
|
||||||
dnl
|
dnl
|
||||||
|
|
||||||
AS_IF([test "X$with_cares" == "Xyes"],[
|
AS_IF([test "X$with_cares" = "Xyes"],[
|
||||||
PKG_CHECK_MODULES([CARES], libcares, [
|
PKG_CHECK_MODULES([CARES], libcares, [
|
||||||
CFLAGS="$CARES_CFLAGS $CFLAGS"
|
CFLAGS="$CARES_CFLAGS $CFLAGS"
|
||||||
AC_CHECK_HEADER(ares.h, [
|
AC_CHECK_HEADER(ares.h, [
|
||||||
@ -839,4 +829,5 @@ AC_MSG_NOTICE([Summary of build options:
|
|||||||
Metalink: $with_metalink
|
Metalink: $with_metalink
|
||||||
Resolver: $RESOLVER_INFO
|
Resolver: $RESOLVER_INFO
|
||||||
GPGME: $have_gpg
|
GPGME: $have_gpg
|
||||||
|
IRI: $iri
|
||||||
])
|
])
|
||||||
|
@ -65,7 +65,7 @@ nodist_wget_SOURCES = version.c
|
|||||||
EXTRA_wget_SOURCES = iri.c
|
EXTRA_wget_SOURCES = iri.c
|
||||||
LDADD = $(LIBOBJS) ../lib/libgnu.a $(GETADDRINFO_LIB) $(HOSTENT_LIB) $(INET_NTOP_LIB) $(LIBSOCKET)\
|
LDADD = $(LIBOBJS) ../lib/libgnu.a $(GETADDRINFO_LIB) $(HOSTENT_LIB) $(INET_NTOP_LIB) $(LIBSOCKET)\
|
||||||
$(LIB_CLOCK_GETTIME) $(LIB_CRYPTO) $(LIB_SELECT) $(LTLIBICONV) $(LTLIBINTL) $(LTLIBTHREAD)\
|
$(LIB_CLOCK_GETTIME) $(LIB_CRYPTO) $(LIB_SELECT) $(LTLIBICONV) $(LTLIBINTL) $(LTLIBTHREAD)\
|
||||||
$(SERVENT_LIB)
|
$(LTLIBUNISTRING) $(SERVENT_LIB)
|
||||||
AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib
|
AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ as that of the covered work. */
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#ifdef ENABLE_IRI
|
#ifdef ENABLE_IRI
|
||||||
#include <idn-free.h>
|
#include <idn2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -283,7 +283,7 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
|
|||||||
str = xmalloc (len);
|
str = xmalloc (len);
|
||||||
snprintf (str, len, "%s (%s)", name, print);
|
snprintf (str, len, "%s (%s)", name, print);
|
||||||
str[len-1] = '\0';
|
str[len-1] = '\0';
|
||||||
idn_free (name);
|
idn2_free (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
|
logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
|
||||||
|
@ -58,7 +58,7 @@ as that of the covered work. */
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef ENABLE_IRI
|
#ifdef ENABLE_IRI
|
||||||
#include <idn-free.h>
|
#include <idn2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -852,7 +852,7 @@ lookup_host (const char *host, int flags)
|
|||||||
str = xmalloc (len);
|
str = xmalloc (len);
|
||||||
snprintf (str, len, "%s (%s)", name, host);
|
snprintf (str, len, "%s (%s)", name, host);
|
||||||
str[len-1] = '\0';
|
str[len-1] = '\0';
|
||||||
idn_free (name);
|
idn2_free (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
logprintf (LOG_VERBOSE, _("Resolving %s... "),
|
logprintf (LOG_VERBOSE, _("Resolving %s... "),
|
||||||
|
64
src/iri.c
64
src/iri.c
@ -33,13 +33,14 @@ as that of the covered work. */
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <langinfo.h>
|
||||||
|
#include <errno.h>
|
||||||
#ifdef HAVE_ICONV
|
#ifdef HAVE_ICONV
|
||||||
# include <iconv.h>
|
# include <iconv.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stringprep.h>
|
#include <idn2.h>
|
||||||
#include <idna.h>
|
#include <unicase.h>
|
||||||
#include <idn-free.h>
|
#include <unistr.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
@ -90,10 +91,15 @@ parse_charset (const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find the locale used, or fall back on a default value */
|
/* Find the locale used, or fall back on a default value */
|
||||||
char *
|
const char *
|
||||||
find_locale (void)
|
find_locale (void)
|
||||||
{
|
{
|
||||||
return (char *) stringprep_locale_charset ();
|
const char *encoding = nl_langinfo(CODESET);
|
||||||
|
|
||||||
|
if (!encoding || !*encoding)
|
||||||
|
return "ASCII";
|
||||||
|
|
||||||
|
return encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Basic check of an encoding name. */
|
/* Basic check of an encoding name. */
|
||||||
@ -284,33 +290,47 @@ idn_encode (const struct iri *i, const char *host)
|
|||||||
int ret;
|
int ret;
|
||||||
char *ascii_encoded;
|
char *ascii_encoded;
|
||||||
char *utf8_encoded = NULL;
|
char *utf8_encoded = NULL;
|
||||||
|
const char *src;
|
||||||
|
uint8_t *lower;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
/* Encode to UTF-8 if not done */
|
/* Encode to UTF-8 if not done */
|
||||||
if (!i->utf8_encode)
|
if (!i->utf8_encode)
|
||||||
{
|
{
|
||||||
if (!remote_to_utf8 (i, host, &utf8_encoded))
|
if (!remote_to_utf8 (i, host, &utf8_encoded))
|
||||||
return NULL; /* Nothing to encode or an error occured */
|
return NULL; /* Nothing to encode or an error occured */
|
||||||
|
src = utf8_encoded;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
src = host;
|
||||||
|
|
||||||
if (!_utf8_is_valid(utf8_encoded ? utf8_encoded : host))
|
if (!_utf8_is_valid (src))
|
||||||
{
|
{
|
||||||
logprintf (LOG_VERBOSE, _("Invalid UTF-8 sequence: %s\n"),
|
logprintf (LOG_VERBOSE, _("Invalid UTF-8 sequence: %s\n"),
|
||||||
quote(utf8_encoded ? utf8_encoded : host));
|
quote (src));
|
||||||
xfree (utf8_encoded);
|
xfree (utf8_encoded);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store in ascii_encoded the ASCII UTF-8 NULL terminated string */
|
/* we need a conversion to lowercase */
|
||||||
ret = idna_to_ascii_8z (utf8_encoded ? utf8_encoded : host, &ascii_encoded, IDNA_FLAGS);
|
lower = u8_tolower ((uint8_t *) src, u8_strlen ((uint8_t *) src) + 1, 0, UNINORM_NFKC, NULL, &len);
|
||||||
xfree (utf8_encoded);
|
if (!lower)
|
||||||
|
|
||||||
if (ret != IDNA_SUCCESS)
|
|
||||||
{
|
{
|
||||||
logprintf (LOG_VERBOSE, _("idn_encode failed (%d): %s\n"), ret,
|
logprintf (LOG_VERBOSE, _("Failed to convert to lower: %d: %s\n"),
|
||||||
quote (idna_strerror (ret)));
|
errno, quote (src));
|
||||||
|
xfree (utf8_encoded);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ret = idn2_lookup_u8 (lower, (uint8_t **) &ascii_encoded, IDN2_NFC_INPUT)) != IDN2_OK)
|
||||||
|
{
|
||||||
|
logprintf (LOG_VERBOSE, _("idn_encode failed (%d): %s\n"), ret,
|
||||||
|
quote (idn2_strerror (ret)));
|
||||||
|
ascii_encoded = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree (lower);
|
||||||
|
|
||||||
return ascii_encoded;
|
return ascii_encoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,18 +339,24 @@ idn_encode (const struct iri *i, const char *host)
|
|||||||
char *
|
char *
|
||||||
idn_decode (const char *host)
|
idn_decode (const char *host)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
char *new;
|
char *new;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = idna_to_unicode_8zlz (host, &new, IDNA_FLAGS);
|
ret = idn2_register_u8 (NULL, host, (uint8_t **) &new, 0);
|
||||||
if (ret != IDNA_SUCCESS)
|
if (ret != IDN2_OK)
|
||||||
{
|
{
|
||||||
logprintf (LOG_VERBOSE, _("idn_decode failed (%d): %s\n"), ret,
|
logprintf (LOG_VERBOSE, _("idn2_register_u8 failed (%d): %s: %s\n"), ret,
|
||||||
quote (idna_strerror (ret)));
|
quote (idn2_strerror (ret)), host);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
|
*/
|
||||||
|
/* idn2_register_u8() just works label by label.
|
||||||
|
* That is pretty much overhead for just displaying the original ulabels.
|
||||||
|
* To keep at least the debug output format, return a cloned host. */
|
||||||
|
return xstrdup(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to transcode string str from remote encoding to UTF-8. On success, *new
|
/* Try to transcode string str from remote encoding to UTF-8. On success, *new
|
||||||
|
@ -40,11 +40,10 @@ struct iri {
|
|||||||
|
|
||||||
#ifdef ENABLE_IRI
|
#ifdef ENABLE_IRI
|
||||||
|
|
||||||
# include <idna.h>
|
# include <idn2.h>
|
||||||
# include <idn-free.h>
|
|
||||||
|
|
||||||
char *parse_charset (const char *str);
|
char *parse_charset (const char *str);
|
||||||
char *find_locale (void);
|
const char *find_locale (void);
|
||||||
bool check_encoding_name (const char *encoding);
|
bool check_encoding_name (const char *encoding);
|
||||||
const char *locale_to_utf8 (const char *str);
|
const char *locale_to_utf8 (const char *str);
|
||||||
char *idn_encode (const struct iri *i, const char *host);
|
char *idn_encode (const struct iri *i, const char *host);
|
||||||
@ -66,7 +65,7 @@ extern struct iri dummy_iri;
|
|||||||
#define locale_to_utf8(str) (str)
|
#define locale_to_utf8(str) (str)
|
||||||
#define idn_encode(a,b) NULL
|
#define idn_encode(a,b) NULL
|
||||||
#define idn_decode(str) NULL
|
#define idn_decode(str) NULL
|
||||||
#define idn_free(str) ((void)0)
|
#define idn2_free(str) ((void)0)
|
||||||
#define remote_to_utf8(a,b,c) false
|
#define remote_to_utf8(a,b,c) false
|
||||||
#define iri_new() (&dummy_iri)
|
#define iri_new() (&dummy_iri)
|
||||||
#define iri_dup(a) (&dummy_iri)
|
#define iri_dup(a) (&dummy_iri)
|
||||||
|
@ -964,12 +964,12 @@ check_redirect_output (void)
|
|||||||
{
|
{
|
||||||
if (tcgetpgrp (STDIN_FILENO) != getpgrp ())
|
if (tcgetpgrp (STDIN_FILENO) != getpgrp ())
|
||||||
{
|
{
|
||||||
// Process backgrounded
|
/* Process backgrounded */
|
||||||
redirect_output (true,NULL);
|
redirect_output (true,NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Process foregrounded
|
/* Process foregrounded */
|
||||||
redirect_output (false,NULL);
|
redirect_output (false,NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,7 @@ struct options
|
|||||||
|
|
||||||
bool enable_iri;
|
bool enable_iri;
|
||||||
char *encoding_remote;
|
char *encoding_remote;
|
||||||
char *locale;
|
const char *locale;
|
||||||
|
|
||||||
bool trustservernames;
|
bool trustservernames;
|
||||||
#ifdef __VMS
|
#ifdef __VMS
|
||||||
|
@ -1213,7 +1213,7 @@ url_free (struct url *url)
|
|||||||
if (url)
|
if (url)
|
||||||
{
|
{
|
||||||
if (url->idn_allocated) {
|
if (url->idn_allocated) {
|
||||||
idn_free (url->host); /* A dummy if !defined(ENABLE_IRI) */
|
idn2_free (url->host); /* A dummy if !defined(ENABLE_IRI) */
|
||||||
url->host = NULL;
|
url->host = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -100,8 +100,8 @@ struct url
|
|||||||
char *user;
|
char *user;
|
||||||
char *passwd;
|
char *passwd;
|
||||||
|
|
||||||
/* 'host' is allocated by idna_to_ascii_8z() via idn_encode().
|
/* 'host' is allocated by idn2_lookup_u8() via idn_encode().
|
||||||
* Call 'idn_free()' to free this memory. */
|
* Call 'idn2_free()' to free this memory. */
|
||||||
bool idn_allocated;
|
bool idn_allocated;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -136,7 +136,10 @@ EXTRA_DIST = FTPServer.pm FTPTest.pm HTTPServer.pm HTTPTest.pm \
|
|||||||
|
|
||||||
check_PROGRAMS = unit-tests
|
check_PROGRAMS = unit-tests
|
||||||
unit_tests_SOURCES =
|
unit_tests_SOURCES =
|
||||||
LDADD = ../src/libunittest.a ../lib/libgnu.a @LIBICONV@ @LIBINTL@ $(LIBS) $(LIB_CLOCK_GETTIME)
|
LDADD = ../src/libunittest.a ../lib/libgnu.a $(GETADDRINFO_LIB) $(HOSTENT_LIB) $(INET_NTOP_LIB) $(LIBSOCKET)\
|
||||||
|
$(LIB_CLOCK_GETTIME) $(LIB_CRYPTO) $(LIB_SELECT) $(LTLIBICONV) $(LTLIBINTL) $(LTLIBTHREAD)\
|
||||||
|
$(LTLIBUNISTRING) $(SERVENT_LIB)
|
||||||
|
|
||||||
|
|
||||||
CLEANFILES = *~ *.bak core core.[0-9]*
|
CLEANFILES = *~ *.bak core core.[0-9]*
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user