VirtualBox

source: vbox/trunk/src/libs/curl-8.0.1/lib/idn.c@ 99371

Last change on this file since 99371 was 99344, checked in by vboxsync, 2 years ago

curl-8.0.1: Applied and adjusted our curl changes to 7.87.0 bugref:10417

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 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 *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
147char *Curl_idn_decode(const char *input)
148{
149 char *d = idn_decode(input);
150#ifdef USE_LIBIDN2
151 if(d) {
152 char *c = strdup(d);
153 idn2_free(d);
154 d = c;
155 }
156#endif
157 return d;
158}
159
160/*
161 * Frees data allocated by idnconvert_hostname()
162 */
163void Curl_free_idnconverted_hostname(struct hostname *host)
164{
165 if(host->encalloc) {
166 /* must be freed with idn2_free() if allocated by libidn */
167 Curl_idn_free(host->encalloc);
168 host->encalloc = NULL;
169 }
170}
171
172#endif /* USE_IDN */
173
174/*
175 * Perform any necessary IDN conversion of hostname
176 */
177CURLcode Curl_idnconvert_hostname(struct hostname *host)
178{
179 /* set the name we use to display the host name */
180 host->dispname = host->name;
181
182#ifdef USE_IDN
183 /* Check name for non-ASCII and convert hostname if we can */
184 if(!Curl_is_ASCII_name(host->name)) {
185 char *decoded = idn_decode(host->name);
186 if(decoded) {
187 if(!*decoded) {
188 /* zero length is a bad host name */
189 Curl_idn_free(decoded);
190 return CURLE_URL_MALFORMAT;
191 }
192 /* successful */
193 host->encalloc = decoded;
194 /* change the name pointer to point to the encoded hostname */
195 host->name = host->encalloc;
196 }
197 else
198 return CURLE_URL_MALFORMAT;
199 }
200#endif
201 return CURLE_OK;
202}
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