mirror of
https://github.com/curl/curl.git
synced 2025-02-23 15:10:03 +08:00
idn: support non-UTF-8 input under AppleIDN
This aligns the behaviour with libidn2 and the curl documentation. Closes #14431
This commit is contained in:
parent
07843d8167
commit
a35687831f
@ -980,7 +980,7 @@ if(APPLE)
|
||||
check_symbol_exists("uidna_openUTS46" "unicode/uidna.h" HAVE_APPLE_IDN)
|
||||
cmake_pop_check_state()
|
||||
if(HAVE_APPLE_IDN)
|
||||
list(APPEND CURL_LIBS "icucore")
|
||||
list(APPEND CURL_LIBS "icucore" "iconv")
|
||||
else()
|
||||
set(USE_APPLE_IDN OFF)
|
||||
endif()
|
||||
|
@ -2780,7 +2780,7 @@ case $host_os in
|
||||
AC_DEFINE(USE_APPLE_IDN, 1, [if AppleIDN])
|
||||
AC_SUBST(USE_APPLE_IDN, [1])
|
||||
AC_SUBST([IDN_ENABLED], [1])
|
||||
LIBS="-licucore $LIBS"
|
||||
LIBS="-licucore -liconv $LIBS"
|
||||
)
|
||||
])
|
||||
;;
|
||||
|
@ -530,7 +530,7 @@ problems may have been fixed or changed somewhat since this was written.
|
||||
|
||||
11.7 AppleIDN test failures
|
||||
|
||||
Test 1034 and 1035 fail on macOS when built to use AppleIDN.
|
||||
Test 1035 fail on macOS when built to use AppleIDN.
|
||||
|
||||
See https://github.com/curl/curl/issues/14176
|
||||
|
||||
|
68
lib/idn.c
68
lib/idn.c
@ -53,30 +53,70 @@
|
||||
/* for macOS and iOS targets */
|
||||
#if defined(USE_APPLE_IDN)
|
||||
#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) {
|
||||
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, in, -1, buffer,
|
||||
sizeof(buffer) - 1, &info, &err);
|
||||
uidna_close(idna);
|
||||
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)) {
|
||||
*out = strdup(buffer);
|
||||
if(*out)
|
||||
return CURLE_OK;
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
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)) {
|
||||
*out = strdup(buffer);
|
||||
if(*out)
|
||||
return CURLE_OK;
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return iconv_result;
|
||||
}
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
@ -94,7 +94,6 @@
|
||||
313
|
||||
%endif
|
||||
%if AppleIDN
|
||||
1034
|
||||
1035
|
||||
%endif
|
||||
%if WinIDN
|
||||
|
Loading…
Reference in New Issue
Block a user