diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-10-16 12:11:24 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-10-16 12:11:24 +0000 |
commit | 40811e93f3fdf9342a9295369994012420fac548 (patch) | |
tree | a8d85e094a9c21e10aa250f537c101fc2016a049 /contrib/libs/curl/lib/idn.c | |
parent | 30ebe5357bb143648c6be4d151ecd4944af81ada (diff) | |
parent | 28a0c4a9f297064538a018c512cd9bbd00a1a35d (diff) | |
download | ydb-40811e93f3fdf9342a9295369994012420fac548.tar.gz |
Merge branch 'rightlib' into mergelibs-241016-1210
Diffstat (limited to 'contrib/libs/curl/lib/idn.c')
-rw-r--r-- | contrib/libs/curl/lib/idn.c | 133 |
1 files changed, 21 insertions, 112 deletions
diff --git a/contrib/libs/curl/lib/idn.c b/contrib/libs/curl/lib/idn.c index 102da52cff..76b44564b3 100644 --- a/contrib/libs/curl/lib/idn.c +++ b/contrib/libs/curl/lib/idn.c @@ -50,108 +50,10 @@ #include "curl_memory.h" #include "memdebug.h" -/* for macOS and iOS targets */ -#if defined(USE_APPLE_IDN) -#error #include <unicode/uidna.h> -#include <iconv.h> -#include <langinfo.h> - -#define MAX_HOST_LENGTH 512 - -static CURLcode iconv_to_utf8(const char *in, size_t inlen, - char **out, size_t *outlen) -{ - iconv_t cd = iconv_open("UTF-8", nl_langinfo(CODESET)); - if(cd != (iconv_t)-1) { - size_t iconv_outlen = *outlen; - char *iconv_in = (char *)in; - size_t iconv_inlen = inlen; - size_t iconv_result = iconv(cd, &iconv_in, &iconv_inlen, - out, &iconv_outlen); - *outlen -= iconv_outlen; - iconv_close(cd); - if(iconv_result == (size_t)-1) { - if(errno == ENOMEM) - return CURLE_OUT_OF_MEMORY; - else - return CURLE_URL_MALFORMAT; - } - - return CURLE_OK; - } - else { - if(errno == ENOMEM) - return CURLE_OUT_OF_MEMORY; - else - return CURLE_FAILED_INIT; - } -} - -static CURLcode mac_idn_to_ascii(const char *in, char **out) -{ - size_t inlen = strlen(in); - if(inlen < MAX_HOST_LENGTH) { - char iconv_buffer[MAX_HOST_LENGTH] = {0}; - char *iconv_outptr = iconv_buffer; - size_t iconv_outlen = sizeof(iconv_buffer); - CURLcode iconv_result = iconv_to_utf8(in, inlen, - &iconv_outptr, &iconv_outlen); - if(!iconv_result) { - UErrorCode err = U_ZERO_ERROR; - UIDNA* idna = uidna_openUTS46( - UIDNA_CHECK_BIDI|UIDNA_NONTRANSITIONAL_TO_ASCII, &err); - if(!U_FAILURE(err)) { - UIDNAInfo info = UIDNA_INFO_INITIALIZER; - char buffer[MAX_HOST_LENGTH] = {0}; - (void)uidna_nameToASCII_UTF8(idna, iconv_buffer, (int)iconv_outlen, - buffer, sizeof(buffer) - 1, &info, &err); - uidna_close(idna); - if(!U_FAILURE(err) && !info.errors) { - *out = strdup(buffer); - if(*out) - return CURLE_OK; - else - return CURLE_OUT_OF_MEMORY; - } - } - } - else - return iconv_result; - } - return CURLE_URL_MALFORMAT; -} - -static CURLcode mac_ascii_to_idn(const char *in, char **out) -{ - size_t inlen = strlen(in); - if(inlen < MAX_HOST_LENGTH) { - UErrorCode err = U_ZERO_ERROR; - UIDNA* idna = uidna_openUTS46( - UIDNA_CHECK_BIDI|UIDNA_NONTRANSITIONAL_TO_UNICODE, &err); - if(!U_FAILURE(err)) { - UIDNAInfo info = UIDNA_INFO_INITIALIZER; - char buffer[MAX_HOST_LENGTH] = {0}; - (void)uidna_nameToUnicodeUTF8(idna, in, -1, buffer, - sizeof(buffer) - 1, &info, &err); - uidna_close(idna); - if(!U_FAILURE(err)) { - *out = strdup(buffer); - if(*out) - return CURLE_OK; - else - return CURLE_OUT_OF_MEMORY; - } - } - } - return CURLE_URL_MALFORMAT; -} -#endif - #ifdef USE_WIN32_IDN /* using Windows kernel32 and normaliz libraries. */ -#if (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x600) && \ - (!defined(WINVER) || WINVER < 0x600) +#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x600 WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags, const WCHAR *lpUnicodeCharStr, int cchUnicodeChar, @@ -248,7 +150,7 @@ bool Curl_is_ASCII_name(const char *hostname) * Curl_idn_decode() returns an allocated IDN decoded string if it was * possible. NULL on error. * - * CURLE_URL_MALFORMAT - the hostname could not be converted + * CURLE_URL_MALFORMAT - the host name could not be converted * CURLE_OUT_OF_MEMORY - memory problem * */ @@ -279,8 +181,6 @@ static CURLcode idn_decode(const char *input, char **output) result = CURLE_NOT_BUILT_IN; #elif defined(USE_WIN32_IDN) result = win32_idn_to_ascii(input, &decoded); -#elif defined(USE_APPLE_IDN) - result = mac_idn_to_ascii(input, &decoded); #endif if(!result) *output = decoded; @@ -298,10 +198,6 @@ static CURLcode idn_encode(const char *puny, char **output) CURLcode result = win32_ascii_to_idn(puny, &enc); if(result) return result; -#elif defined(USE_APPLE_IDN) - CURLcode result = mac_ascii_to_idn(puny, &enc); - if(result) - return result; #endif *output = enc; return CURLE_OK; @@ -350,7 +246,11 @@ CURLcode Curl_idn_encode(const char *puny, char **output) */ void Curl_free_idnconverted_hostname(struct hostname *host) { - Curl_safefree(host->encalloc); + if(host->encalloc) { + /* must be freed with idn2_free() if allocated by libidn */ + Curl_idn_free(host->encalloc); + host->encalloc = NULL; + } } #endif /* USE_IDN */ @@ -360,18 +260,27 @@ void Curl_free_idnconverted_hostname(struct hostname *host) */ CURLcode Curl_idnconvert_hostname(struct hostname *host) { - /* set the name we use to display the hostname */ + /* set the name we use to display the host name */ host->dispname = host->name; #ifdef USE_IDN /* Check name for non-ASCII and convert hostname if we can */ if(!Curl_is_ASCII_name(host->name)) { char *decoded; - CURLcode result = Curl_idn_decode(host->name, &decoded); - if(result) + CURLcode result = idn_decode(host->name, &decoded); + if(!result) { + if(!*decoded) { + /* zero length is a bad host name */ + Curl_idn_free(decoded); + return CURLE_URL_MALFORMAT; + } + /* successful */ + host->encalloc = decoded; + /* change the name pointer to point to the encoded hostname */ + host->name = host->encalloc; + } + else return result; - /* successful */ - host->name = host->encalloc = decoded; } #endif return CURLE_OK; |