summaryrefslogtreecommitdiff
path: root/src/iri.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/iri.c')
-rw-r--r--src/iri.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/src/iri.c b/src/iri.c
index 8be109e..af0dfb6 100644
--- a/src/iri.c
+++ b/src/iri.c
@@ -39,8 +39,10 @@ as that of the covered work. */
# include <iconv.h>
#endif
#include <idn2.h>
-#include <unicase.h>
-#include <unistr.h>
+#if IDN2_VERSION_NUMBER < 0x00140000
+# include <unicase.h>
+# include <unistr.h>
+#endif
#include "utils.h"
#include "url.h"
@@ -119,6 +121,7 @@ check_encoding_name (const char *encoding)
return true;
}
+#ifdef HAVE_ICONV
/* Do the conversion according to the passed conversion descriptor cd. *out
will contain the transcoded string on success. *out content is
unspecified otherwise. */
@@ -210,6 +213,15 @@ do_conversion (const char *tocode, const char *fromcode, char const *in_org, siz
}
return false;
}
+#else
+static bool
+do_conversion (const char *tocode _GL_UNUSED, const char *fromcode _GL_UNUSED,
+ char const *in_org _GL_UNUSED, size_t inlen _GL_UNUSED, char **out)
+{
+ *out = NULL;
+ return false;
+}
+#endif
/* Try converting string str from locale to UTF-8. Return a new string
on success, or str on error or if conversion isn't needed. */
@@ -253,7 +265,7 @@ idn_encode (const struct iri *i, const char *host)
if (!i->utf8_encode)
{
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 occurred */
src = utf8_encoded;
}
else
@@ -261,11 +273,14 @@ idn_encode (const struct iri *i, const char *host)
#if IDN2_VERSION_NUMBER >= 0x00140000
/* IDN2_TRANSITIONAL implies input NFC encoding */
- if ((ret = idn2_lookup_u8 ((uint8_t *) src, (uint8_t **) &ascii_encoded, IDN2_NONTRANSITIONAL)) != IDN2_OK)
- {
- logprintf (LOG_VERBOSE, _("idn_encode failed (%d): %s\n"), ret,
- quote (idn2_strerror (ret)));
- }
+ ret = idn2_lookup_u8 ((uint8_t *) src, (uint8_t **) &ascii_encoded, IDN2_NONTRANSITIONAL);
+ if (ret != IDN2_OK)
+ /* fall back to TR46 Transitional mode, max IDNA2003 compatibility */
+ ret = idn2_lookup_u8 ((uint8_t *) src, (uint8_t **) &ascii_encoded, IDN2_TRANSITIONAL);
+
+ if (ret != IDN2_OK)
+ logprintf (LOG_VERBOSE, _("idn_encode failed (%d): %s\n"), ret,
+ quote (idn2_strerror (ret)));
#else
/* we need a conversion to lowercase */
lower = u8_tolower ((uint8_t *) src, u8_strlen ((uint8_t *) src) + 1, 0, UNINORM_NFKC, NULL, &len);
@@ -288,6 +303,13 @@ idn_encode (const struct iri *i, const char *host)
xfree (utf8_encoded);
+ if (ret == IDN2_OK && ascii_encoded)
+ {
+ char *tmp = xstrdup (ascii_encoded);
+ idn2_free (ascii_encoded);
+ ascii_encoded = tmp;
+ }
+
return ret == IDN2_OK ? ascii_encoded : NULL;
}