idn: fix libidn2 with windows unicode builds

Unicode Windows builds use UTF-8 strings internally in libcurl,
so make sure to call the UTF-8 flavour of the libidn2 API. Also
document that Windows builds with libidn2 and UNICODE do expect
CURLOPT_URL as an UTF-8 string.

Reported-by: dEajL3kA on github
Assisted-by: Jay Satiro
Reviewed-by: Marcel Raad
Closes #7246
Fixes #7228
This commit is contained in:
Viktor Szakats 2021-06-15 12:10:48 +00:00
parent b67d3ba73e
commit 2026124691
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
2 changed files with 12 additions and 4 deletions

View File

@ -72,7 +72,7 @@ expected to be a sequence of characters using an ASCII compatible encoding.
If libcurl is built with IDN support, the server name part of the URL can use
an "international name" by using the current encoding (according to locale) or
UTF-8 (when winidn is used).
UTF-8 (when winidn is used; or a Windows Unicode build using libidn2).
If libcurl is built without IDN support, the server name is used exactly as
specified when passed to the name resolver functions.

View File

@ -62,6 +62,14 @@
#ifdef USE_LIBIDN2
#include <idn2.h>
#if defined(WIN32) && defined(UNICODE)
#define IDN2_LOOKUP(name, host, flags) \
idn2_lookup_u8((const uint8_t *)name, (uint8_t **)host, flags)
#else
#define IDN2_LOOKUP(name, host, flags) \
idn2_lookup_ul((const char *)name, (char **)host, flags)
#endif
#elif defined(USE_WIN32_IDN)
/* prototype for curl_win32_idn_to_ascii() */
bool curl_win32_idn_to_ascii(const char *in, char **out);
@ -1585,12 +1593,12 @@ CURLcode Curl_idnconvert_hostname(struct Curl_easy *data,
#else
int flags = IDN2_NFC_INPUT;
#endif
int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, flags);
int rc = IDN2_LOOKUP(host->name, &ace_hostname, flags);
if(rc != IDN2_OK)
/* fallback to TR46 Transitional mode for better IDNA2003
compatibility */
rc = idn2_lookup_ul((const char *)host->name, &ace_hostname,
IDN2_TRANSITIONAL);
rc = IDN2_LOOKUP(host->name, &ace_hostname,
IDN2_TRANSITIONAL);
if(rc == IDN2_OK) {
host->encalloc = (char *)ace_hostname;
/* change the name pointer to point to the encoded hostname */