diff --git a/base/file.cpp b/base/file.cpp index b1ddc5d4d..6321fc624 100644 --- a/base/file.cpp +++ b/base/file.cpp @@ -53,34 +53,47 @@ namespace { #ifdef _WIN32 static int mkstemp(char* name_template, size_t size_in_chars) { - auto path = name_template; - if (_mktemp_s(path, size_in_chars) != 0) { + std::wstring path; + CHECK(android::base::UTF8ToWide(name_template, &path)) + << "path can't be converted to wchar: " << name_template; + if (_wmktemp_s(path.data(), path.size() + 1) != 0) { return -1; } - std::wstring path_wide; - CHECK(android::base::UTF8ToWide(path, &path_wide)) - << "path can't be converted to wchar: " << path; - // Use open() to match the close() that TemporaryFile's destructor does. // Use O_BINARY to match base file APIs. - return _wopen(path_wide.c_str(), O_CREAT | O_EXCL | O_RDWR | O_BINARY, S_IRUSR | S_IWUSR); + int fd = _wopen(path.c_str(), O_CREAT | O_EXCL | O_RDWR | O_BINARY, S_IRUSR | S_IWUSR); + if (fd < 0) { + return -1; + } + + std::string path_utf8; + CHECK(android::base::WideToUTF8(path, &path_utf8)) << "path can't be converted to utf8"; + CHECK(strcpy_s(name_template, size_in_chars, path_utf8.c_str()) == 0) + << "utf8 path can't be assigned back to name_template"; + + return fd; } static char* mkdtemp(char* name_template, size_t size_in_chars) { - auto path = name_template; - if (_mktemp_s(path, size_in_chars) != 0) { + std::wstring path; + CHECK(android::base::UTF8ToWide(name_template, &path)) + << "path can't be converted to wchar: " << name_template; + + if (_wmktemp_s(path.data(), path.size() + 1) != 0) { return nullptr; } - std::wstring path_wide; - CHECK(android::base::UTF8ToWide(path, &path_wide)) - << "path can't be converted to wchar: " << path; - - if (_wmkdir(path_wide.c_str()) != 0) { + if (_wmkdir(path.c_str()) != 0) { return nullptr; } - return path; + + std::string path_utf8; + CHECK(android::base::WideToUTF8(path, &path_utf8)) << "path can't be converted to utf8"; + CHECK(strcpy_s(name_template, size_in_chars, path_utf8.c_str()) == 0) + << "utf8 path can't be assigned back to name_template"; + + return name_template; } #endif diff --git a/base/file_test.cpp b/base/file_test.cpp index 65ee2351c..120228d94 100644 --- a/base/file_test.cpp +++ b/base/file_test.cpp @@ -30,7 +30,7 @@ #if !defined(_WIN32) #include #else -#include +#include #endif #include "android-base/logging.h" // and must be after windows.h for ERROR @@ -99,6 +99,11 @@ TEST(file, NonUnicodeCharsWindows) { std::wstring old_tmp; old_tmp.resize(kMaxEnvVariableValueSize); old_tmp.resize(GetEnvironmentVariableW(L"TMP", old_tmp.data(), old_tmp.size())); + if (old_tmp.empty()) { + // Can't continue with empty TMP folder. + return; + } + std::wstring new_tmp = old_tmp; if (new_tmp.back() != L'\\') { new_tmp.push_back(L'\\'); @@ -156,14 +161,18 @@ TEST(file, NonUnicodeCharsWindows) { TEST(file, RootDirectoryWindows) { constexpr auto kMaxEnvVariableValueSize = 32767; std::wstring old_tmp; + bool tmp_is_empty = false; old_tmp.resize(kMaxEnvVariableValueSize); old_tmp.resize(GetEnvironmentVariableW(L"TMP", old_tmp.data(), old_tmp.size())); + if (old_tmp.empty()) { + tmp_is_empty = (GetLastError() == ERROR_ENVVAR_NOT_FOUND); + } SetEnvironmentVariableW(L"TMP", L"C:"); TemporaryFile tf; ASSERT_NE(tf.fd, -1) << tf.path; - SetEnvironmentVariableW(L"TMP", old_tmp.c_str()); + SetEnvironmentVariableW(L"TMP", tmp_is_empty ? nullptr : old_tmp.c_str()); } #endif