]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Windows get ENV value as UTF-8 encoded string instead of a raw string
authorRobert Jędrzejczyk <robert@prog.olsztyn.pl>
Sat, 22 Aug 2020 05:05:56 +0000 (15:05 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Sat, 22 Aug 2020 05:05:56 +0000 (15:05 +1000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12657)

crypto/getenv.c

index a49a06f8ed2cf7a161a2c922caab4e6219c1de0c..431a7644b9e5d9f25434096ed3e779c25adb03e5 100644 (file)
 
 #include <stdlib.h>
 #include "internal/cryptlib.h"
+#include "e_os.h"
 
 char *ossl_safe_getenv(const char *name)
 {
+#if defined(_WIN32) && defined(CP_UTF8) && !defined(_WIN32_WCE)
+    if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) != 0) {
+        char *val = NULL;
+        int vallen = 0;
+        WCHAR *namew = NULL;
+        WCHAR *valw = NULL;
+        DWORD envlen = 0;
+        DWORD dwFlags = MB_ERR_INVALID_CHARS;
+        int rsize, fsize;
+        UINT curacp;
+
+        curacp = GetACP();
+
+        /*
+         * For the code pages listed below, dwFlags must be set to 0.
+         * Otherwise, the function fails with ERROR_INVALID_FLAGS.
+         */
+        if (curacp == 50220 || curacp == 50221 || curacp == 50222 ||
+            curacp == 50225 || curacp == 50227 || curacp == 50229 ||
+            (57002 <= curacp && curacp <=57011) || curacp == 65000 ||
+            curacp == 42)
+            dwFlags = 0;
+
+        /* query for buffer len */
+        rsize = MultiByteToWideChar(curacp, dwFlags, name, -1, NULL, 0);
+        /* if name is valid string and can be converted to wide string */
+        if (rsize > 0)
+            namew = _malloca(rsize * sizeof(WCHAR));
+
+        if (NULL != namew) {
+            /* convert name to wide string */
+            fsize = MultiByteToWideChar(curacp, dwFlags, name, -1, namew, rsize);
+            /* if conversion is ok, then determine value string size in wchars */
+            if (fsize > 0)
+                envlen = GetEnvironmentVariableW(namew, NULL, 0);
+        }
+
+        if (envlen > 0)
+            valw = _malloca(envlen * sizeof(WCHAR));
+
+        if (NULL != valw) {
+            /* if can get env value as wide string */
+            if (GetEnvironmentVariableW(namew, valw, envlen) < envlen) {
+                /* determine value string size in utf-8 */
+                vallen = WideCharToMultiByte(CP_UTF8, 0, valw, -1, NULL, 0,
+                                             NULL, NULL);
+            }
+        }
+
+        if (vallen > 0)
+            val = OPENSSL_malloc(vallen);
+
+        if (NULL != val) {
+            /* convert value string from wide to utf-8 */
+            if (WideCharToMultiByte(CP_UTF8, 0, valw, -1, val, vallen,
+                                    NULL, NULL) == 0) {
+                OPENSSL_free(val);
+                val = NULL;
+            }
+        }
+
+        if (NULL != namew)
+            _freea(namew);
+
+        if (NULL != valw)
+            _freea(valw);
+
+        return val;
+    }
+#endif
+
 #if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
 # if __GLIBC_PREREQ(2, 17)
 #  define SECURE_GETENV