diff --git a/configure.ac b/configure.ac index ffd406a..52da77c 100644 --- a/configure.ac +++ b/configure.ac @@ -74,19 +74,13 @@ AC_ARG_ENABLE(builtin, ], [ enable_builtin=yes AC_DEFINE([WITH_BUILTIN], [1], [compile PSL data into library]) + + PKG_CHECK_MODULES(LIBICU, [icu-uc], + [AC_DEFINE([WITH_LIBICU], [1], [generate PSL data with IDNA2008 UTS#46 punycode])], + [AC_CHECK_PROG(HAVE_IDN2, idn2, yes, AC_MSG_ERROR(Cannot find required tool 'idn2'.))]) ]) AM_CONDITIONAL([WITH_BUILTIN], [test $enable_builtin = yes]) -AC_ARG_WITH(icu, AS_HELP_STRING([--without-icu], [disable ICU punycode conversion]), with_icu=$withval, with_icu=yes) -if test $with_icu != "no" -then - AC_CHECK_LIB(icuuc, uidna_openUTS46, [with_icu=yes; AC_SUBST(ICU_LIBS, "-licu") AC_DEFINE([WITH_LIBICU], [1], [Use libicu])], [with_icu=no; AC_MSG_WARN(*** LIBICU was not found. Falling back to idn2.)]) -fi -AM_CONDITIONAL([WITH_LIBICU], [test $with_icu = "yes"]) - -# Check for idn2 -AC_CHECK_PROG(HAVE_IDN2, idn2, yes, AC_MSG_ERROR(Cannot find required tool 'idn2'.)) - # Check for valgrind ac_enable_valgrind=no AC_ARG_ENABLE(valgrind-tests, diff --git a/src/Makefile.am b/src/Makefile.am index 93010e4..0fe1ec7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,8 +13,8 @@ libpsl_la_LDFLAGS = -version-info $(LIBPSL_SO_VERSION) noinst_PROGRAMS = psl2c psl2c_SOURCES = psl2c.c -psl2c_CPPFLAGS = -I$(top_srcdir)/include -D _GNU_SOURCE -#psl2c_LDADD = -lidn2 +psl2c_CPPFLAGS = -I$(top_srcdir)/include -D _GNU_SOURCE $(LIBICU_CFLAGS) +psl2c_LDADD = $(LIBICU_LIBS) # Build rule for suffix.c # PSL_FILE can be set by ./configure --with-psl-file=[PATH] diff --git a/src/psl2c.c b/src/psl2c.c index 8bcad50..d0d9f0d 100644 --- a/src/psl2c.c +++ b/src/psl2c.c @@ -47,6 +47,7 @@ #ifdef WITH_LIBICU # include +# include # include #endif @@ -349,21 +350,36 @@ static void _add_punycode_if_needed(_psl_vector_t *v) */ /* IDNA2008 UTS#46 punycode conversion */ - if ((idna = uidna_openUTS46(UIDNA_USE_STD3_RULES, &status))) { - uidna_nameToASCII(idna, (UChar *) e->label_buf, (int32_t) strlen(e->label_buf), - (UChar *) lookupname, (int32_t) sizeof(lookupname), NULL, &status); - uidna_close(idna); - } +// if ((idna = uidna_openUTS46(UIDNA_USE_STD3_RULES, &status))) { + if ((idna = uidna_openUTS46(UIDNA_DEFAULT, &status))) { + UChar utf16_dst[64], utf16_src[64]; + int32_t utf16_src_length; + UIDNAInfo info = UIDNA_INFO_INITIALIZER; + + u_strFromUTF8(utf16_src, sizeof(utf16_src)/sizeof(utf16_src[0]), &utf16_src_length, e->label_buf, (int32_t) strlen(e->label_buf), &status); + if (U_SUCCESS(status)) { + int32_t dst_length = uidna_nameToASCII(idna, utf16_src, utf16_src_length, utf16_dst, sizeof(utf16_dst)/sizeof(utf16_dst[0]), &info, &status); + if (U_SUCCESS(status)) { + u_strToUTF8(lookupname, (int32_t) sizeof(lookupname), NULL, utf16_dst, dst_length, &status); + if (U_SUCCESS(status)) { + if (strcmp(e->label_buf, lookupname)) { + /* fprintf(stderr, "libicu '%s' -> '%s'\n", e->label_buf, lookupname); */ + _suffix_init(&suffix, lookupname, strlen(lookupname)); + suffix.wildcard = e->wildcard; + suffixp = _vector_get(v, _vector_add(v, &suffix)); + suffixp->label = suffixp->label_buf; /* set label to changed address */ + } // else ignore + } else + fprintf(stderr, "Failed to convert UTF-16 to UTF-8 (status %d)\n", status); + } else + fprintf(stderr, "Failed to convert to ASCII (status %d)\n", status); + } else + fprintf(stderr, "Failed to convert UTF-8 to UTF-16 (status %d)\n", status); + + uidna_close(idna); + } else + fprintf(stderr, "Failed to get UTS46 IDNA handle\n"); - if (U_FAILURE(status)) { - fprintf(stderr, "Failed to convert '%s' to ASCII\n", e->label_buf); - } else if (strcmp(e->label_buf, lookupname)) { - /* fprintf(stderr, "libicu '%s' -> '%s'\n", e->label_buf, lookupname); */ - _suffix_init(&suffix, lookupname, strlen(lookupname)); - suffix.wildcard = e->wildcard; - suffixp = _vector_get(v, _vector_add(v, &suffix)); - suffixp->label = suffixp->label_buf; /* set label to changed address */ - } /* else ignore */ #else /* this is much slower than the libidn2 API but should have no license issues */ FILE *pp;