mirror of
https://github.com/curl/curl.git
synced 2026-08-24 19:03:40 +03:00
idn: add native AppleIDN (icucore) support for macOS/iOS
I implemented the IDN functions for macOS and iOS using Unicode libraries coming with macOS and iOS. Builds and runs here on macOS 14.2.1. Also verified to load and run on older macOS version 10.13. Build requires macOS SDK 13 or equivalent. Set `-DUSE_APPLE_IDN=ON` CMake option to enable it. With autotools and other build tools, set these manual options: ``` CPPFLAGS=-DUSE_APPLE_IDN LIBS=-licucore ``` Completes TODO 1.6. TODO: add autotools option and feature-detection. Refs: #5330 #5371 Co-authored-by: Viktor Szakats Closes #13246
This commit is contained in:
parent
08d10d2a00
commit
add22feeef
9 changed files with 92 additions and 19 deletions
|
|
@ -794,6 +794,9 @@ ${SIZEOF_TIME_T_CODE}
|
|||
/* to enable Windows IDN */
|
||||
#cmakedefine USE_WIN32_IDN 1
|
||||
|
||||
/* to enable Apple IDN */
|
||||
#cmakedefine USE_APPLE_IDN 1
|
||||
|
||||
/* Define to 1 to enable websocket support. */
|
||||
#cmakedefine USE_WEBSOCKETS 1
|
||||
|
||||
|
|
|
|||
|
|
@ -649,13 +649,14 @@
|
|||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && !defined(USE_WIN32_IDN)
|
||||
#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && \
|
||||
!defined(USE_WIN32_IDN) && !defined(USE_APPLE_IDN)
|
||||
/* The lib and header are present */
|
||||
#define USE_LIBIDN2
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBIDN2) && defined(USE_WIN32_IDN)
|
||||
#error "Both libidn2 and WinIDN are enabled, choose one."
|
||||
#if defined(USE_LIBIDN2) && (defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN))
|
||||
#error "libidn2 cannot be enabled with WinIDN or AppleIDN, choose one."
|
||||
#endif
|
||||
|
||||
#define LIBIDN_REQUIRED_VERSION "0.4.1"
|
||||
|
|
|
|||
63
lib/idn.c
63
lib/idn.c
|
|
@ -50,6 +50,63 @@
|
|||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* for macOS and iOS targets */
|
||||
#if defined(USE_APPLE_IDN)
|
||||
#include <unicode/uidna.h>
|
||||
|
||||
static CURLcode mac_idn_to_ascii(const char *in, char **out)
|
||||
{
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
UIDNA* idna = uidna_openUTS46(UIDNA_CHECK_BIDI, &err);
|
||||
if(U_FAILURE(err)) {
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
UIDNAInfo info = UIDNA_INFO_INITIALIZER;
|
||||
char buffer[256] = {0};
|
||||
(void)uidna_nameToASCII_UTF8(idna, in, -1, buffer,
|
||||
sizeof(buffer), &info, &err);
|
||||
uidna_close(idna);
|
||||
if(U_FAILURE(err)) {
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
else {
|
||||
*out = strdup(buffer);
|
||||
if(*out)
|
||||
return CURLE_OK;
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode mac_ascii_to_idn(const char *in, char **out)
|
||||
{
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
UIDNA* idna = uidna_openUTS46(UIDNA_CHECK_BIDI, &err);
|
||||
if(U_FAILURE(err)) {
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
UIDNAInfo info = UIDNA_INFO_INITIALIZER;
|
||||
char buffer[256] = {0};
|
||||
(void)uidna_nameToUnicodeUTF8(idna, in, -1, buffer,
|
||||
sizeof(buffer), &info, &err);
|
||||
uidna_close(idna);
|
||||
if(U_FAILURE(err)) {
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
else {
|
||||
*out = strdup(buffer);
|
||||
if(*out)
|
||||
return CURLE_OK;
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_WIN32_IDN
|
||||
/* using Windows kernel32 and normaliz libraries. */
|
||||
|
||||
|
|
@ -181,6 +238,8 @@ 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;
|
||||
|
|
@ -198,6 +257,10 @@ 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;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
bool Curl_is_ASCII_name(const char *hostname);
|
||||
CURLcode Curl_idnconvert_hostname(struct hostname *host);
|
||||
#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN)
|
||||
#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN)
|
||||
#define USE_IDN
|
||||
void Curl_free_idnconverted_hostname(struct hostname *host);
|
||||
CURLcode Curl_idn_decode(const char *input, char **output);
|
||||
|
|
|
|||
|
|
@ -209,6 +209,8 @@ char *curl_version(void)
|
|||
src[i++] = idn_version;
|
||||
#elif defined(USE_WIN32_IDN)
|
||||
src[i++] = (char *)"WinIDN";
|
||||
#elif defined(USE_APPLE_IDN)
|
||||
src[i++] = (char *)"AppleIDN";
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBPSL
|
||||
|
|
@ -475,7 +477,7 @@ static const struct feat features_table[] = {
|
|||
!defined(CURL_DISABLE_HTTP)
|
||||
FEATURE("HTTPS-proxy", https_proxy_present, CURL_VERSION_HTTPS_PROXY),
|
||||
#endif
|
||||
#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN)
|
||||
#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN)
|
||||
FEATURE("IDN", idn_present, CURL_VERSION_IDN),
|
||||
#endif
|
||||
#ifdef USE_IPV6
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue