[vlc-commits] vlc_UrlParse: support for Internationalized Domain Names (fixes #7343)
Rémi Denis-Courmont
git at videolan.org
Mon Aug 20 22:24:59 CEST 2012
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | 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
+}
More information about the vlc-commits
mailing list