vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Mon Aug 20 23:24:08 2012 +0300| [6ae9dc2d0d59ac332e170f228ecd908e5b5e106b] | committer: Rémi Denis-Courmont
vlc_UrlParse: support for Internationalized Domain Names (fixes #7343) > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6ae9dc2d0d59ac332e170f228ecd908e5b5e106b --- src/Makefile.am | 4 ++-- src/text/url.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 4b12e6e..da40d00 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -164,7 +164,7 @@ EXTRA_DIST += libvlc_win32_rc.rc.in lib_LTLIBRARIES = libvlccore.la -AM_CPPFLAGS = $(INCICONV) \ +AM_CPPFLAGS = $(INCICONV) $(IDN_CFLAGS) \ -DMODULE_STRING=\"main\" \ -DLOCALEDIR=\"$(localedir)\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ @@ -182,7 +182,7 @@ libvlccore_la_LDFLAGS = \ libvlccore_la_LIBADD = $(LIBS_libvlccore) \ ../compat/libcompat.la \ $(LTLIBINTL) $(LTLIBICONV) \ - $(SOCKET_LIBS) $(LIBDL) $(LIBM) + $(IDN_LIBS) $(SOCKET_LIBS) $(LIBDL) $(LIBM) libvlccore_la_DEPENDENCIES = libvlccore.sym if HAVE_WIN32 libvlccore_la_DEPENDENCIES += libvlc_win32_rc.$(OBJEXT) diff --git a/src/text/url.c b/src/text/url.c index fa9d86b..021613f 100644 --- a/src/text/url.c +++ b/src/text/url.c @@ -370,6 +370,8 @@ out: return ret; /* unknown scheme */ } +static char *vlc_idna_to_ascii (const char *); + /** * Splits an URL into parts. * \param url structure of URL parts [OUT] @@ -459,7 +461,7 @@ void vlc_UrlParse (vlc_url_t *restrict url, const char *str, unsigned char opt) } else { - url->psz_host = strdup (cur); + url->psz_host = vlc_idna_to_ascii (cur); next = strchr (cur, ':'); } @@ -482,3 +484,62 @@ void vlc_UrlClean (vlc_url_t *restrict url) free (url->psz_host); free (url->psz_buffer); } + +#if defined (HAVE_IDN) +# include <idna.h> +#elif defined (WIN32) +# include <windows.h> +# include <vlc_charset.h> +#endif + +/** + * Converts a UTF-8 nul-terminated IDN to nul-terminated ASCII domain name. + * \param idn UTF-8 Internationalized Domain Name to convert + * \return a heap-allocated string or NULL on error. + */ +static char *vlc_idna_to_ascii (const char *idn) +{ +#if defined (HAVE_IDN) + char *adn; + + if (idna_to_ascii_8z (idn, &adn, IDNA_ALLOW_UNASSIGNED) != IDNA_SUCCESS) + return NULL; + return adn; + +#elif defined (WIN32) && (_WIN32_WINNT >= 0x0601) + char *ret = NULL; + + wchar_t *wide = ToWide (idn); + if (wide == NULL) + return NULL; + + int len = IdnToAscii (IDN_ALLOW_UNASSIGNED, wide, -1, NULL, 0); + if (len == 0) + goto error; + + wchar_t *buf = malloc (sizeof (*buf) * len); + if (unlikely(buf == NULL)) + goto error; + if (!IdnToAscii (IDN_ALLOW_UNASSIGNED, wide, -1, buf, len)) + { + free (buf); + goto error; + } + free (wide); + + ret = FromWide (buf); + free (buf); +error: + free (wide); + return ret; + +#else + /* No IDN support, filter out non-ASCII domain names */ + for (const char *p = idn; *p; p++) + if (((unsigned char)*p) >= 0x80) + return NULL; + + return strdup (idn); + +#endif +} _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
