summaryrefslogtreecommitdiffstats
path: root/crypto/getenv.c
diff options
context:
space:
mode:
authorRobert Jędrzejczyk <robert@prog.olsztyn.pl>2020-08-22 15:05:56 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-08-22 15:05:56 +1000
commiteed12622faf01369141caa558439ac5f6fd5dcd1 (patch)
tree99ed611767bd1ae45add32cfbcef91464b141c31 /crypto/getenv.c
parentc0f39ded68ba0929698a8773e63e9806ec9e5c74 (diff)
Windows get ENV value as UTF-8 encoded string instead of a raw string
Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/12657)
Diffstat (limited to 'crypto/getenv.c')
-rw-r--r--crypto/getenv.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/crypto/getenv.c b/crypto/getenv.c
index a49a06f8ed..431a7644b9 100644
--- a/crypto/getenv.c
+++ b/crypto/getenv.c
@@ -13,9 +13,81 @@
#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