#define IDN_MAX_LENGTH 255
-bool Curl_win32_idn_to_ascii(const char *in, char **out)
+static CURLcode win32_idn_to_ascii(const char *in, char **out)
{
- bool success = FALSE;
-
wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
+ *out = NULL;
if(in_w) {
wchar_t punycode[IDN_MAX_LENGTH];
int chars = IdnToAscii(0, in_w, (int)(wcslen(in_w) + 1), punycode,
if(mstr) {
*out = strdup(mstr);
curlx_unicodefree(mstr);
- if(*out)
- success = TRUE;
+ if(!*out)
+ return CURLE_OUT_OF_MEMORY;
}
+ else
+ return CURLE_OUT_OF_MEMORY;
}
+ else
+ return CURLE_URL_MALFORMAT;
}
- return success;
+ return CURLE_OK;
}
-char *Curl_win32_ascii_to_idn(const char *in)
+static CURLcode win32_ascii_to_idn(const char *in, char **output)
{
char *out = NULL;
if(mstr) {
out = strdup(mstr);
curlx_unicodefree(mstr);
+ if(!out)
+ return CURLE_OUT_OF_MEMORY;
}
}
+ else
+ return CURLE_URL_MALFORMAT;
}
- return out;
+ else
+ return CURLE_URL_MALFORMAT;
+ *output = out;
+ return CURLE_OK;
}
#endif /* USE_WIN32_IDN */
/*
* Curl_idn_decode() returns an allocated IDN decoded string if it was
* possible. NULL on error.
+ *
+ * CURLE_URL_MALFORMAT - the host name could not be converted
+ * CURLE_OUT_OF_MEMORY - memory problem
+ *
*/
-static char *idn_decode(const char *input)
+static CURLcode idn_decode(const char *input, char **output)
{
char *decoded = NULL;
+ CURLcode result = CURLE_OK;
#ifdef USE_LIBIDN2
if(idn2_check_version(IDN2_VERSION)) {
int flags = IDN2_NFC_INPUT
compatibility */
rc = IDN2_LOOKUP(input, &decoded, IDN2_TRANSITIONAL);
if(rc != IDN2_OK)
- decoded = NULL;
+ result = CURLE_URL_MALFORMAT;
}
#elif defined(USE_WIN32_IDN)
- if(!Curl_win32_idn_to_ascii(input, &decoded))
- decoded = NULL;
+ result = win32_idn_to_ascii(input, &decoded);
#endif
- return decoded;
+ if(!result)
+ *output = decoded;
+ return result;
}
-static char *idn_encode(const char *puny)
+static CURLcode idn_encode(const char *puny, char **output)
{
char *enc = NULL;
#ifdef USE_LIBIDN2
int rc = idn2_to_unicode_8z8z(puny, &enc, 0);
if(rc != IDNA_SUCCESS)
- return NULL;
+ return rc == IDNA_MALLOC_ERROR ? CURLE_OUT_OF_MEMORY : CURLE_URL_MALFORMAT;
#elif defined(USE_WIN32_IDN)
- enc = Curl_win32_ascii_to_idn(puny);
+ CURLcode result = win32_ascii_to_idn(puny, &enc);
+ if(result)
+ return result;
#endif
- return enc;
+ *output = enc;
+ return CURLE_OK;
}
-char *Curl_idn_decode(const char *input)
+CURLcode Curl_idn_decode(const char *input, char **output)
{
- char *d = idn_decode(input);
+ char *d = NULL;
+ CURLcode result = idn_decode(input, &d);
#ifdef USE_LIBIDN2
- if(d) {
+ if(!result) {
char *c = strdup(d);
idn2_free(d);
- d = c;
+ if(c)
+ d = c;
+ else
+ result = CURLE_OUT_OF_MEMORY;
}
#endif
- return d;
+ if(!result)
+ *output = d;
+ return result;
}
-char *Curl_idn_encode(const char *puny)
+CURLcode Curl_idn_encode(const char *puny, char **output)
{
- char *d = idn_encode(puny);
+ char *d = NULL;
+ CURLcode result = idn_encode(puny, &d);
#ifdef USE_LIBIDN2
- if(d) {
+ if(!result) {
char *c = strdup(d);
idn2_free(d);
- d = c;
+ if(c)
+ d = c;
+ else
+ result = CURLE_OUT_OF_MEMORY;
}
#endif
- return d;
+ if(!result)
+ *output = d;
+ return result;
}
/*
#ifdef USE_IDN
/* Check name for non-ASCII and convert hostname if we can */
if(!Curl_is_ASCII_name(host->name)) {
- char *decoded = idn_decode(host->name);
- if(decoded) {
+ char *decoded;
+ CURLcode result = idn_decode(host->name, &decoded);
+ if(!result) {
if(!*decoded) {
/* zero length is a bad host name */
Curl_idn_free(decoded);
host->name = host->encalloc;
}
else
- return CURLE_URL_MALFORMAT;
+ return result;
}
#endif
return CURLE_OK;
*
***************************************************************************/
-#ifdef USE_WIN32_IDN
-bool Curl_win32_idn_to_ascii(const char *in, char **out);
-char *Curl_win32_ascii_to_idn(const char *in);
-#endif /* USE_WIN32_IDN */
bool Curl_is_ASCII_name(const char *hostname);
CURLcode Curl_idnconvert_hostname(struct hostname *host);
#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN)
#define USE_IDN
void Curl_free_idnconverted_hostname(struct hostname *host);
-char *Curl_idn_decode(const char *input);
-char *Curl_idn_encode(const char *input);
+CURLcode Curl_idn_decode(const char *input, char **output);
+CURLcode Curl_idn_encode(const char *input, char **output);
#ifdef USE_LIBIDN2
#define Curl_idn_free(x) idn2_free(x)
#else
#ifndef USE_IDN
return CURLUE_LACKS_IDN;
#else
- allochost = Curl_idn_decode(u->host);
- if(!allochost)
- return CURLUE_OUT_OF_MEMORY;
+ CURLcode result = Curl_idn_decode(u->host, &allochost);
+ if(result)
+ return (result == CURLE_OUT_OF_MEMORY) ?
+ CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME;
#endif
}
}
#ifndef USE_IDN
return CURLUE_LACKS_IDN;
#else
- allochost = Curl_idn_encode(u->host);
- if(!allochost)
- return CURLUE_OUT_OF_MEMORY;
+ CURLcode result = Curl_idn_encode(u->host, &allochost);
+ if(result)
+ /* this is the most likely error */
+ return (result == CURLE_OUT_OF_MEMORY) ?
+ CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME;
#endif
}
}
#ifndef USE_IDN
return CURLUE_LACKS_IDN;
#else
- char *allochost = Curl_idn_decode(*part);
- if(!allochost)
- return CURLUE_OUT_OF_MEMORY;
+ char *allochost;
+ CURLcode result = Curl_idn_decode(*part, &allochost);
+ if(result)
+ return (result == CURLE_OUT_OF_MEMORY) ?
+ CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME;
free(*part);
*part = allochost;
#endif
#ifndef USE_IDN
return CURLUE_LACKS_IDN;
#else
- char *allochost = Curl_idn_encode(*part);
- if(!allochost)
- return CURLUE_OUT_OF_MEMORY;
+ char *allochost;
+ CURLcode result = Curl_idn_encode(*part, &allochost);
+ if(result)
+ return (result == CURLE_OUT_OF_MEMORY) ?
+ CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME;
free(*part);
*part = allochost;
#endif