Fix: BLI_getenv returns ascii not UTF8 on windows
BLI_getenv has always incorrectly returned ascii rather than UTF-8. This change corrects this behaviour. This resolves issues when the `BLENDER_USER_CONFIG` environment variable contains a path with Unicode characters on windows as reported in T74510 (but unlikely the root cause for the issue at hand there) Differential Revision: https://developer.blender.org/D9831 Reviewed by: brecht
This commit is contained in:
parent
92ab76c38f
commit
87b19b3aba
Notes:
blender-bot
2023-02-13 23:16:01 +01:00
Referenced by commit 0dbbcaf1e6
, Fix: Fix potential memory leak in BLI_getenv
Referenced by issue #74510, Various Addons using filesystem properties (PROP_FILEPATH etc): UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe0 in position 24: invalid continuation byte
|
@ -32,6 +32,7 @@
|
|||
#include "BLI_fnmatch.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -1307,18 +1308,30 @@ void BLI_setenv_if_new(const char *env, const char *val)
|
|||
* On windows getenv gets its variables from a static copy of the environment variables taken at
|
||||
* process start-up, causing it to not pick up on environment variables created during runtime.
|
||||
* This function uses an alternative method to get environment variables that does pick up on
|
||||
* runtime environment variables.
|
||||
* runtime environment variables. The result will be UTF-8 encoded.
|
||||
*/
|
||||
|
||||
const char *BLI_getenv(const char *env)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static char buffer[32767]; /* 32767 is the total size of the environment block on windows*/
|
||||
if (GetEnvironmentVariableA(env, buffer, sizeof(buffer))) {
|
||||
return buffer;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
const char *result = NULL;
|
||||
static wchar_t buffer[32768]; /* 32767 is the maximum size of the environment variable on
|
||||
windows, reserve one more character for the zero terminator. */
|
||||
wchar_t *env_16 = alloc_utf16_from_8(env, 0);
|
||||
if (env_16) {
|
||||
if (GetEnvironmentVariableW(env_16, buffer, ARRAY_SIZE(buffer))) {
|
||||
char *res_utf8 = alloc_utf_8_from_16(buffer, 0);
|
||||
// make sure the result is valid, and will fit into our temporary storage buffer
|
||||
if (res_utf8 && (strlen(res_utf8) + 1) < sizeof(buffer)) {
|
||||
// We are re-using the utf16 buffer here, since allocating a second static buffer to
|
||||
// contain the UTF-8 version to return would be wasteful.
|
||||
memcpy(buffer, res_utf8, strlen(res_utf8) + 1);
|
||||
free(res_utf8);
|
||||
result = (const char *)buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return getenv(env);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue