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 using Windows kernel32 and normaliz libraries.
27 */
28
29#include "curl_setup.h"
30
31#ifdef USE_WIN32_IDN
32
33#include "curl_multibyte.h"
34#include "curl_memory.h"
35#include "warnless.h"
36
37 /* The last #include file should be: */
38#include "memdebug.h"
39
40#ifdef WANT_IDN_PROTOTYPES
41# if defined(_SAL_VERSION)
42WINNORMALIZEAPI int WINAPI
43IdnToAscii(_In_ DWORD dwFlags,
44 _In_reads_(cchUnicodeChar) LPCWSTR lpUnicodeCharStr,
45 _In_ int cchUnicodeChar,
46 _Out_writes_opt_(cchASCIIChar) LPWSTR lpASCIICharStr,
47 _In_ int cchASCIIChar);
48WINNORMALIZEAPI int WINAPI
49IdnToUnicode(_In_ DWORD dwFlags,
50 _In_reads_(cchASCIIChar) LPCWSTR lpASCIICharStr,
51 _In_ int cchASCIIChar,
52 _Out_writes_opt_(cchUnicodeChar) LPWSTR lpUnicodeCharStr,
53 _In_ int cchUnicodeChar);
54# else
55WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
56 const WCHAR *lpUnicodeCharStr,
57 int cchUnicodeChar,
58 WCHAR *lpASCIICharStr,
59 int cchASCIIChar);
60WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
61 const WCHAR *lpASCIICharStr,
62 int cchASCIIChar,
63 WCHAR *lpUnicodeCharStr,
64 int cchUnicodeChar);
65# endif
66#endif
67
68#define IDN_MAX_LENGTH 255
69
70bool curl_win32_idn_to_ascii(const char *in, char **out);
71bool curl_win32_ascii_to_idn(const char *in, char **out);
72
73bool curl_win32_idn_to_ascii(const char *in, char **out)
74{
75 bool success = FALSE;
76
77 wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
78 if(in_w) {
79 wchar_t punycode[IDN_MAX_LENGTH];
80 int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH);
81 curlx_unicodefree(in_w);
82 if(chars) {
83 char *mstr = curlx_convert_wchar_to_UTF8(punycode);
84 if(mstr) {
85 *out = strdup(mstr);
86 curlx_unicodefree(mstr);
87 if(*out)
88 success = TRUE;
89 }
90 }
91 }
92
93 return success;
94}
95
96bool curl_win32_ascii_to_idn(const char *in, char **out)
97{
98 bool success = FALSE;
99
100 wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
101 if(in_w) {
102 size_t in_len = wcslen(in_w) + 1;
103 wchar_t unicode[IDN_MAX_LENGTH];
104 int chars = IdnToUnicode(0, in_w, curlx_uztosi(in_len),
105 unicode, IDN_MAX_LENGTH);
106 curlx_unicodefree(in_w);
107 if(chars) {
108 char *mstr = curlx_convert_wchar_to_UTF8(unicode);
109 if(mstr) {
110 *out = strdup(mstr);
111 curlx_unicodefree(mstr);
112 if(*out)
113 success = TRUE;
114 }
115 }
116 }
117
118 return success;
119}
120
121#endif /* USE_WIN32_IDN */
122