Skip to content

Halide Util.cpp uses Win32 functions that are not encoding-safe #5223

@shoaibkamil

Description

@shoaibkamil

Instead of using CreateDirectoryA() and other <foo>A() functions on Windows, we need to use the corresponding CreateDirectoryW() and other W() suffixed functions in order to handle directories that may have characters outside the system encoding. The original reporter at Adobe suggests:

It is OK to use std::string as their cross platform API. They must decide to use UTF8 and then convert UTF8 to wstring (UTF16) before calling Windows APIs

Currently, trying to use Halide in a user account that has characters outside the system encoding results in an unhandled exception at line 399 of Util.cpp, here:

Halide/src/Util.cpp

Lines 364 to 400 in d046701

std::string dir_make_temp() {
#ifdef _WIN32
std::string tmp_dir = get_windows_tmp_dir();
// There's no direct API to do this in Windows;
// our clunky-but-adequate approach here is to use
// CoCreateGuid() to create a probably-unique name.
// Add a limit on the number of tries just in case.
for (int tries = 0; tries < 100; ++tries) {
GUID guid;
HRESULT hr = CoCreateGuid(&guid);
internal_assert(hr == S_OK);
std::ostringstream name;
name << std::hex
<< std::setfill('0')
<< std::setw(8)
<< guid.Data1
<< std::setw(4)
<< guid.Data2
<< guid.Data3
<< std::setw(2);
for (int i = 0; i < 8; i++) {
name << (int)guid.Data4[i];
}
std::string dir = tmp_dir + name.str();
BOOL result = CreateDirectoryA(dir.c_str(), nullptr);
if (result) {
debug(1) << "temp dir is: " << dir << "\n";
return dir;
}
// If name already existed, just loop and try again.
// Any other error, break from loop and fail.
if (GetLastError() != ERROR_ALREADY_EXISTS) {
break;
}
}
internal_error << "Unable to create temp directory in " << tmp_dir << "\n";
return "";

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions