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) |
42 | WINNORMALIZEAPI int WINAPI |
43 | IdnToAscii(_In_ DWORD dwFlags, |
44 | _In_reads_(cchUnicodeChar) LPCWSTR lpUnicodeCharStr, |
45 | _In_ int cchUnicodeChar, |
46 | _Out_writes_opt_(cchASCIIChar) LPWSTR lpASCIICharStr, |
47 | _In_ int cchASCIIChar); |
48 | WINNORMALIZEAPI int WINAPI |
49 | IdnToUnicode(_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 |
55 | WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags, |
56 | const WCHAR *lpUnicodeCharStr, |
57 | int cchUnicodeChar, |
58 | WCHAR *lpASCIICharStr, |
59 | int cchASCIIChar); |
60 | WINBASEAPI 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 | |
70 | bool curl_win32_idn_to_ascii(const char *in, char **out); |
71 | bool curl_win32_ascii_to_idn(const char *in, char **out); |
72 | |
73 | bool 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 | |
96 | bool 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 | |