crypto/LPdir_win.c: harmonize with o_fopen.c.
authorAndy Polyakov <appro@openssl.org>
Fri, 15 Jul 2016 13:21:00 +0000 (15:21 +0200)
committerAndy Polyakov <appro@openssl.org>
Sat, 16 Jul 2016 18:30:35 +0000 (20:30 +0200)
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
crypto/LPdir_win.c

index 37cca97..35d2c98 100644 (file)
 # define NAME_MAX 255
 #endif
 
 # define NAME_MAX 255
 #endif
 
+#ifdef CP_UTF8
+# define CP_DEFAULT CP_UTF8
+#else
+# define CP_DEFAULT CP_ACP
+#endif
+
 struct LP_dir_context_st {
     WIN32_FIND_DATA ctx;
     HANDLE handle;
 struct LP_dir_context_st {
     WIN32_FIND_DATA ctx;
     HANDLE handle;
@@ -104,27 +110,41 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
             TCHAR *wdir = NULL;
             /* len_0 denotes string length *with* trailing 0 */
             size_t index = 0, len_0 = strlen(extdir) + 1;
             TCHAR *wdir = NULL;
             /* len_0 denotes string length *with* trailing 0 */
             size_t index = 0, len_0 = strlen(extdir) + 1;
-
-            wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR));
-            if (wdir == NULL) {
-                if (extdirbuf != NULL) {
-                    free(extdirbuf);
-                }
-                free(*ctx);
-                *ctx = NULL;
-                errno = ENOMEM;
-                return 0;
-            }
 #ifdef LP_MULTIBYTE_AVAILABLE
 #ifdef LP_MULTIBYTE_AVAILABLE
-            if (!MultiByteToWideChar
-                (CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0))
+            int sz = 0;
+            UINT cp;
+
+            do {
+# ifdef CP_UTF8
+                if ((sz = MultiByteToWideChar((cp = CP_UTF8), 0, extdir, len_0,
+                                              NULL, 0)) > 0 ||
+                    GetLastError() != ERROR_NO_UNICODE_TRANSLATION)
+                    break;
+# endif
+                sz = MultiByteToWideChar((cp = CP_ACP), 0, extdir, len_0,
+                                         NULL, 0);
+            } while (0);
+
+            if (sz > 0) {
+                wdir = _alloca(sz * sizeof(TCHAR));
+                if (!MultiByteToWideChar(cp, 0, extdir, len_0, wdir, sz)) {
+                    if (extdirbuf != NULL) {
+                        free(extdirbuf);
+                    }
+                    free(*ctx);
+                    *ctx = NULL;
+                    errno = EINVAL;
+                    return 0;
+                }
+            } else
 #endif
 #endif
+            {
+                wdir = _alloca(len_0 * sizeof(TCHAR));
                 for (index = 0; index < len_0; index++)
                     wdir[index] = (TCHAR)extdir[index];
                 for (index = 0; index < len_0; index++)
                     wdir[index] = (TCHAR)extdir[index];
+            }
 
             (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
 
             (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
-
-            free(wdir);
         } else {
             (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx);
         }
         } else {
             (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx);
         }
@@ -152,9 +172,9 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
         len_0++;
 
 #ifdef LP_MULTIBYTE_AVAILABLE
         len_0++;
 
 #ifdef LP_MULTIBYTE_AVAILABLE
-        if (!WideCharToMultiByte
-            (CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name,
-             sizeof((*ctx)->entry_name), NULL, 0))
+        if (!WideCharToMultiByte(CP_DEFAULT, 0, (WCHAR *)wdir, len_0,
+                                 (*ctx)->entry_name,
+                                 sizeof((*ctx)->entry_name), NULL, 0))
 #endif
             for (index = 0; index < len_0; index++)
                 (*ctx)->entry_name[index] = (char)wdir[index];
 #endif
             for (index = 0; index < len_0; index++)
                 (*ctx)->entry_name[index] = (char)wdir[index];