Skip to content

Commit 74881aa

Browse files
committed
Fix Windows GetEnv mangling non-ASCII environment values
On Windows, GetEnv read variables through the narrow _dupenv_s, which returns the value in the active ANSI code page (e.g. CP-1252). Non-ASCII values -- such as a home path with an accented username -- were then reinterpreted as UTF-8 and came out mangled, so ~/.aws/credentials and ~/.aws/config failed to load and the profile provider fell back to an anonymous request (GitHub issue #3865). Read env vars through the wide _wdupenv_s and convert explicitly to UTF-8, since Windows stores them natively as UTF-16. Mirrors the same fix in the CRT (awslabs/aws-c-common#1260). Non-MSVC compilers keep the existing std::getenv path. Adds a Windows-only regression test that injects a non-ASCII value via the wide CRT API and asserts GetEnv returns the correct UTF-8 bytes.
1 parent 69ee6af commit 74881aa

2 files changed

Lines changed: 25 additions & 12 deletions

File tree

src/aws-cpp-sdk-core/source/platform/windows/Environment.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
#include <aws/core/platform/Environment.h>
7+
#include <aws/core/utils/StringUtils.h>
78

89
#include <stdio.h>
910
#include <utility>
@@ -13,25 +14,19 @@ namespace Aws
1314
namespace Environment
1415
{
1516

16-
/*
17-
using std::getenv generates a warning on windows so we use _dupenv_s instead. The character array returned by this function is our responsibility to clean up, so rather than returning raw strings
18-
that would need to be manually freed in all the client functions, just copy it into a Aws::String instead, freeing it here.
19-
20-
since _dupenv_s is a non-standard function, on non-Microsoft compilers we will fall back to using std::getenv instead.
21-
*/
2217
Aws::String GetEnv(const char *variableName)
2318
{
24-
#ifdef _MSC_VER
25-
char* variableValue = nullptr;
19+
#ifdef _MSC_VER
20+
wchar_t* variableValue = nullptr;
2621
std::size_t valueSize = 0;
27-
auto queryResult = _dupenv_s(&variableValue, &valueSize, variableName);
22+
const auto queryResult = _wdupenv_s(&variableValue, &valueSize, Aws::Utils::StringUtils::ToWString(variableName).c_str());
2823

2924
Aws::String result;
30-
if(queryResult == 0 && variableValue != nullptr && valueSize > 0)
25+
if(queryResult == 0 && variableValue != nullptr)
3126
{
32-
result.assign(variableValue, valueSize - 1); // don't copy the c-string terminator byte
33-
free(variableValue);
27+
result = Aws::Utils::StringUtils::FromWString(variableValue);
3428
}
29+
free(variableValue);
3530

3631
return result;
3732
#else

tests/aws-cpp-sdk-core-tests/utils/FileSystemUtilsTest.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
* SPDX-License-Identifier: Apache-2.0.
44
*/
55

6+
#include <aws/core/platform/Environment.h>
67
#include <aws/core/platform/FileSystem.h>
78
#include <aws/core/utils/FileSystemUtils.h>
89
#include <aws/core/utils/memory/stl/AWSSet.h>
910
#include <aws/testing/AwsCppSdkGTestSuite.h>
1011
#include <fstream>
12+
#ifdef _MSC_VER
13+
#include <stdlib.h> // _wputenv_s
14+
#endif
1115
#if defined(HAS_PATHCONF)
1216
#include <unistd.h>
1317
#include <climits>
@@ -32,6 +36,20 @@ TEST_F(FileTest, HomeDirectory)
3236
ASSERT_EQ(Aws::FileSystem::PATH_DELIM, homeDirectory.back());
3337
}
3438

39+
#ifdef _MSC_VER
40+
TEST_F(FileTest, GetEnvReturnsNonAsciiValueAsUtf8)
41+
{
42+
const char* varName = "AWS_SDK_TEST_NONASCII";
43+
// Set via the wide CRT API so the true Unicode value is stored, not a pre-mangled narrow one.
44+
ASSERT_EQ(0, _wputenv_s(L"AWS_SDK_TEST_NONASCII", L"José"));
45+
46+
const auto value = Aws::Environment::GetEnv(varName);
47+
_wputenv_s(L"AWS_SDK_TEST_NONASCII", L"");
48+
49+
ASSERT_EQ(Aws::String("Jos\xC3\xA9"), value); // "José" in UTF-8
50+
}
51+
#endif
52+
3553
TEST_F(FileTest, TestInvalidDirectoryPath)
3654
{
3755
auto badDir = Aws::FileSystem::OpenDirectory("boogieMan");

0 commit comments

Comments
 (0)