VirtualBox

source: vbox/trunk/src/libs/curl-7.87.0/lib/idn.c@ 99005

Last change on this file since 99005 was 98339, checked in by vboxsync, 2 years ago

curl-7.87.0: EOL style fixing, bit more irrelevant export fixing

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2022, Daniel Stenberg, <[email protected]>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24
25 /*
26 * IDN conversions
27 */
28
29#include "curl_setup.h"
30#include "urldata.h"
31#include "idn.h"
32#include "sendf.h"
33#include "curl_multibyte.h"
34#include "warnless.h"
35
36#ifdef USE_LIBIDN2
37#include <idn2.h>
38
39#if defined(WIN32) && defined(UNICODE)
40#define IDN2_LOOKUP(name, host, flags) \
41 idn2_lookup_u8((const uint8_t *)name, (uint8_t **)host, flags)
42#else
43#define IDN2_LOOKUP(name, host, flags) \
44 idn2_lookup_ul((const char *)name, (char **)host, flags)
45#endif
46#endif /* USE_LIBIDN2 */
47
48/* The last 3 #include files should be in this order */
49#include "curl_printf.h"
50#include "curl_memory.h"
51#include "memdebug.h"
52
53#ifdef USE_WIN32_IDN
54/* using Windows kernel32 and normaliz libraries. */
55
56#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x600
57WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
58 const WCHAR *lpUnicodeCharStr,
59 int cchUnicodeChar,
60 WCHAR *lpASCIICharStr,
61 int cchASCIIChar);
62WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
63 const WCHAR *lpASCIICharStr,
64 int cchASCIIChar,
65 WCHAR *lpUnicodeCharStr,
66 int cchUnicodeChar);
67#endif
68
69#define IDN_MAX_LENGTH 255
70
71bool Curl_win32_idn_to_ascii(const char *in, char **out)
72{
73 bool success = FALSE;
74
75 wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
76 if(in_w) {
77 wchar_t punycode[IDN_MAX_LENGTH];
78 int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH);
79 curlx_unicodefree(in_w);
80 if(chars) {
81 char *mstr = curlx_convert_wchar_to_UTF8(punycode);
82 if(mstr) {
83 *out = strdup(mstr);
84 curlx_unicodefree(mstr);
85 if(*out)
86 success = TRUE;
87 }
88 }
89 }
90
91 return success;
92}
93
94#endif /* USE_WIN32_IDN */
95
96/*
97 * Helpers for IDNA conversions.
98 */
99bool Curl_is_ASCII_name(const char *hostname)
100{
101 /* get an UNSIGNED local version of the pointer */
102 const unsigned char *ch = (const unsigned char *)hostname;
103
104 if(!hostname) /* bad input, consider it ASCII! */
105 return TRUE;
106
107 while(*ch) {
108 if(*ch++ & 0x80)
109 return FALSE;
110 }
111 return TRUE;
112}
113
114#ifdef USE_IDN
115/*
116 * Curl_idn_decode() returns an allocated IDN decoded string if it was
117 * possible. NULL on error.
118 */
119static char *Curl_idn_decode(const char *input)
120{
121 char *decoded = NULL;
122#ifdef USE_LIBIDN2
123 if(idn2_check_version(IDN2_VERSION)) {
124 int flags = IDN2_NFC_INPUT
125#if IDN2_VERSION_NUMBER >= 0x00140000
126 /* IDN2_NFC_INPUT: Normalize input string using normalization form C.
127 IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional
128 processing. */
129 | IDN2_NONTRANSITIONAL
130#endif
131 ;
132 int rc = IDN2_LOOKUP(input, &decoded, flags);
133 if(rc != IDN2_OK)
134 /* fallback to TR46 Transitional mode for better IDNA2003
135 compatibility */
136 rc = IDN2_LOOKUP(input, &decoded, IDN2_TRANSITIONAL);
137 if(rc != IDN2_OK)
138 decoded = NULL;
139 }
140#elif defined(USE_WIN32_IDN)
141 if(!Curl_win32_idn_to_ascii(input, &decoded))
142 decoded = NULL;
143#endif
144 return decoded;
145}
146
147/*
148 * Frees data allocated by idnconvert_hostname()
149 */
150void Curl_free_idnconverted_hostname(struct hostname *host)
151{
152#if defined(USE_LIBIDN2)
153 if(host->encalloc) {
154 idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
155 allocated by libidn */
156 host->encalloc = NULL;
157 }
158#elif defined(USE_WIN32_IDN)
159 free(host->encalloc); /* must be freed with free() since this was
160 allocated by Curl_win32_idn_to_ascii */
161 host->encalloc = NULL;
162#else
163 (void)host;
164#endif
165}
166
167#endif /* USE_IDN */
168
169/*
170 * Perform any necessary IDN conversion of hostname
171 */
172CURLcode Curl_idnconvert_hostname(struct hostname *host)
173{
174 /* set the name we use to display the host name */
175 host->dispname = host->name;
176
177#ifdef USE_IDN
178 /* Check name for non-ASCII and convert hostname if we can */
179 if(!Curl_is_ASCII_name(host->name)) {
180 char *decoded = Curl_idn_decode(host->name);
181 if(decoded) {
182 /* successful */
183 host->encalloc = decoded;
184 /* change the name pointer to point to the encoded hostname */
185 host->name = host->encalloc;
186 }
187 else
188 return CURLE_URL_MALFORMAT;
189 }
190#endif
191 return CURLE_OK;
192}
193
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette