diff --git a/CHANGES b/CHANGES index c0348360fec8500cf225849177bc0dc3d65db481..90a04e576cde20d2394fd88d99019998613b1da5 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,12 @@ Changelog +Daniel (2 October 2004) +- Gisle Vanem provided code that displays an error message when the (libidn + based) IDN conversion fails. This is really due to a missing suitable + function in the libidn API that I hope we can remove once libidn gets a + function like this. + Daniel (1 October 2004) - Aleksandar Milivojevic reported a problem in the Redhat bugzilla (see https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=134133) and not to diff --git a/lib/strerror.c b/lib/strerror.c index 5263f442c85696cb315249d03a44c6fb81f6db1e..b64af1cb842f4808cc8d2fbd81087fb3e3fd80f4 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -27,6 +27,10 @@ #include <string.h> #include <errno.h> +#ifdef USE_LIBIDN +#include <idna.h> +#endif + #include "strerror.h" #define _MPRINTF_REPLACE /* use our functions only */ @@ -556,3 +560,68 @@ const char *Curl_strerror(struct connectdata *conn, int err) *p = '\0'; return buf; } + +#ifdef USE_LIBIDN +/* + * Return error-string for libidn status as returned + * from idna_to_ascii_lz(). + */ +const char *Curl_idn_strerror (struct connectdata *conn, int err) +{ + const char *str; + char *buf; + size_t max; + + curlassert(conn); + + buf = conn->syserr_buf; + max = sizeof(conn->syserr_buf)-1; + + switch ((Idna_rc)err) { + case IDNA_SUCCESS: + str = "No error"; + break; + case IDNA_STRINGPREP_ERROR: + str = "Error in string preparation"; + break; + case IDNA_PUNYCODE_ERROR: + str = "Error in Punycode operation"; + break; + case IDNA_CONTAINS_NON_LDH: + str = "Illegal ASCII characters"; + break; + case IDNA_CONTAINS_MINUS: + str = "Contains minus"; + break; + case IDNA_INVALID_LENGTH: + str = "Invalid output length"; + break; + case IDNA_NO_ACE_PREFIX: + str = "No ACE prefix (\"xn--\")"; + break; + case IDNA_ROUNDTRIP_VERIFY_ERROR: + str = "Roundtrip verify error"; + break; + case IDNA_CONTAINS_ACE_PREFIX: + str = "Already have ACE prefix (\"xn--\")"; + break; + case IDNA_ICONV_ERROR: + str = "Locale conversion failed"; + break; + case IDNA_MALLOC_ERROR: + str = "Allocation failed"; + break; + case IDNA_DLOPEN_ERROR: + str = "dlopen() error"; + break; + default: + snprintf(buf, max, "error %d", (int)err); + str = NULL; + break; + } + if (str) + strncpy(buf, str, max); + buf[max] = '\0'; + return (buf); +} +#endif /* USE_LIBIDN */ diff --git a/lib/strerror.h b/lib/strerror.h index 7d687230edc582628a8e0c558fc403814ef9656f..d003cb182eb138902ac5a87a48f5b8fbe0605e31 100644 --- a/lib/strerror.h +++ b/lib/strerror.h @@ -27,4 +27,8 @@ const char *Curl_strerror (struct connectdata *conn, int err); +#ifdef USE_LIBIDN +const char *Curl_idn_strerror (struct connectdata *conn, int err); +#endif + #endif diff --git a/lib/url.c b/lib/url.c index 3f40b6b610aaf4cb61f75fc979e91d07135ad7c2..c0921ced4322b3c5d31b2e9ff1271553717a0c34 100644 --- a/lib/url.c +++ b/lib/url.c @@ -116,6 +116,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by #include "progress.h" #include "cookie.h" #include "strequal.h" +#include "strerror.h" #include "escape.h" #include "strtok.h" #include "share.h" @@ -2078,8 +2079,8 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host) infof (data, "Input domain encoded as `%s'\n", stringprep_locale_charset ()); if (rc != IDNA_SUCCESS) - infof(data, "Failed to convert %s to ACE; IDNA error %d\n", - host->name, rc); + infof(data, "Failed to convert %s to ACE; %s\n", + host->name, Curl_idn_strerror(conn,rc)); else { host->encalloc = ace_hostname; /* change the name pointer to point to the encoded hostname */