Home | History | Annotate | Download | only in lib
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel (at) 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 http://curl.haxx.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 
     33 #include "curl_memory.h"
     34 /* The last #include file should be: */
     35 #include "memdebug.h"
     36 
     37 #ifdef WANT_IDN_PROTOTYPES
     38 #  if defined(_SAL_VERSION)
     39 WINNORMALIZEAPI int WINAPI
     40 IdnToAscii(_In_                           DWORD    dwFlags,
     41            _In_reads_(cchUnicodeChar)     LPCWSTR  lpUnicodeCharStr,
     42            _In_                           int      cchUnicodeChar,
     43            _Out_writes_opt_(cchASCIIChar) LPWSTR   lpASCIICharStr,
     44            _In_                           int      cchASCIIChar);
     45 WINNORMALIZEAPI int WINAPI
     46 IdnToUnicode(_In_                             DWORD   dwFlags,
     47              _In_reads_(cchASCIIChar)         LPCWSTR lpASCIICharStr,
     48              _In_                             int     cchASCIIChar,
     49              _Out_writes_opt_(cchUnicodeChar) LPWSTR  lpUnicodeCharStr,
     50              _In_                             int     cchUnicodeChar);
     51 #  else
     52 WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
     53                                  const WCHAR *lpUnicodeCharStr,
     54                                  int cchUnicodeChar,
     55                                  WCHAR *lpASCIICharStr,
     56                                  int cchASCIIChar);
     57 WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
     58                                    const WCHAR *lpASCIICharStr,
     59                                    int cchASCIIChar,
     60                                    WCHAR *lpUnicodeCharStr,
     61                                    int cchUnicodeChar);
     62 #  endif
     63 #endif
     64 
     65 #define IDN_MAX_LENGTH 255
     66 
     67 int curl_win32_idn_to_ascii(const char *in, char **out);
     68 int curl_win32_ascii_to_idn(const char *in, size_t in_len, char **out_utf8);
     69 
     70 int curl_win32_idn_to_ascii(const char *in, char **out)
     71 {
     72   wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
     73   if(in_w) {
     74     wchar_t punycode[IDN_MAX_LENGTH];
     75     if(IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH) == 0) {
     76       wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
     77       free(in_w);
     78       return 0;
     79     }
     80     free(in_w);
     81 
     82     *out = Curl_convert_wchar_to_UTF8(punycode);
     83     if(!*out)
     84       return 0;
     85   }
     86   return 1;
     87 }
     88 
     89 int curl_win32_ascii_to_idn(const char *in, size_t in_len, char **out_utf8)
     90 {
     91   (void)in_len; /* unused */
     92   if(in) {
     93     WCHAR unicode[IDN_MAX_LENGTH];
     94 
     95     if(IdnToUnicode(0, (wchar_t *)in, -1, unicode, IDN_MAX_LENGTH) == 0) {
     96       wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
     97       return 0;
     98     }
     99     else {
    100       *out_utf8 = Curl_convert_wchar_to_UTF8(unicode);
    101       if(!*out_utf8)
    102         return 0;
    103     }
    104   }
    105   return 1;
    106 }
    107 
    108 #endif /* USE_WIN32_IDN */
    109