1 | /*************************************************************************** |
2 | * _ _ ____ _ |
3 | * Project ___| | | | _ \| | |
4 | * / __| | | | |_) | | |
5 | * | (__| |_| | _ <| |___ |
6 | * \___|\___/|_| \_\_____| |
7 | * |
8 | * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, 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 | ***************************************************************************/ |
22 | |
23 | /* |
24 | * IDN conversions using Windows kernel32 and normaliz libraries. |
25 | */ |
26 | |
27 | #include "curl_setup.h" |
28 | |
29 | #ifdef USE_WIN32_IDN |
30 | |
31 | #include "curl_multibyte.h" |
32 | #include "curl_memory.h" |
33 | #include "warnless.h" |
34 | |
35 | /* The last #include file should be: */ |
36 | #include "memdebug.h" |
37 | |
38 | #ifdef WANT_IDN_PROTOTYPES |
39 | # if defined(_SAL_VERSION) |
40 | WINNORMALIZEAPI int WINAPI |
41 | IdnToAscii(_In_ DWORD dwFlags, |
42 | _In_reads_(cchUnicodeChar) LPCWSTR lpUnicodeCharStr, |
43 | _In_ int cchUnicodeChar, |
44 | _Out_writes_opt_(cchASCIIChar) LPWSTR lpASCIICharStr, |
45 | _In_ int cchASCIIChar); |
46 | WINNORMALIZEAPI int WINAPI |
47 | IdnToUnicode(_In_ DWORD dwFlags, |
48 | _In_reads_(cchASCIIChar) LPCWSTR lpASCIICharStr, |
49 | _In_ int cchASCIIChar, |
50 | _Out_writes_opt_(cchUnicodeChar) LPWSTR lpUnicodeCharStr, |
51 | _In_ int cchUnicodeChar); |
52 | # else |
53 | WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags, |
54 | const WCHAR *lpUnicodeCharStr, |
55 | int cchUnicodeChar, |
56 | WCHAR *lpASCIICharStr, |
57 | int cchASCIIChar); |
58 | WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags, |
59 | const WCHAR *lpASCIICharStr, |
60 | int cchASCIIChar, |
61 | WCHAR *lpUnicodeCharStr, |
62 | int cchUnicodeChar); |
63 | # endif |
64 | #endif |
65 | |
66 | #define IDN_MAX_LENGTH 255 |
67 | |
68 | bool curl_win32_idn_to_ascii(const char *in, char **out); |
69 | bool curl_win32_ascii_to_idn(const char *in, char **out); |
70 | |
71 | bool 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 | free(in_w); |
80 | if(chars) { |
81 | *out = curlx_convert_wchar_to_UTF8(punycode); |
82 | if(*out) |
83 | success = TRUE; |
84 | } |
85 | } |
86 | |
87 | return success; |
88 | } |
89 | |
90 | bool curl_win32_ascii_to_idn(const char *in, char **out) |
91 | { |
92 | bool success = FALSE; |
93 | |
94 | wchar_t *in_w = curlx_convert_UTF8_to_wchar(in); |
95 | if(in_w) { |
96 | size_t in_len = wcslen(in_w) + 1; |
97 | wchar_t unicode[IDN_MAX_LENGTH]; |
98 | int chars = IdnToUnicode(0, in_w, curlx_uztosi(in_len), |
99 | unicode, IDN_MAX_LENGTH); |
100 | free(in_w); |
101 | if(chars) { |
102 | *out = curlx_convert_wchar_to_UTF8(unicode); |
103 | if(*out) |
104 | success = TRUE; |
105 | } |
106 | } |
107 | |
108 | return success; |
109 | } |
110 | |
111 | #endif /* USE_WIN32_IDN */ |
112 | |