Skip to content

Commit 72038b1

Browse files
committed
[compiler-rt][profile] Accept Unicode profile names on Windows
This addresses a small FIXME: when opening a profile file on Windows, we now use `CreateFileW` instead of `CreateFileA`. This fixes a relatively niche scenario in which the profile file contains Unicode codepoints that `CreateFileA` can't handle. I've also added a small test for `lprofOpenFileEx` that exercises the change. Signed-off-by: William Woodruff <william@yossarian.net>
1 parent 431a821 commit 72038b1

2 files changed

Lines changed: 40 additions & 2 deletions

File tree

compiler-rt/lib/profile/InstrProfilingUtil.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,26 @@ COMPILER_RT_VISIBILITY FILE *lprofOpenFileEx(const char *ProfileName) {
237237

238238
f = fdopen(fd, "r+b");
239239
#elif defined(_WIN32)
240-
// FIXME: Use the wide variants to handle Unicode filenames.
241-
HANDLE h = CreateFileA(ProfileName, GENERIC_READ | GENERIC_WRITE,
240+
int WideLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
241+
ProfileName, -1, NULL, 0);
242+
if (WideLength == 0)
243+
return NULL;
244+
245+
WCHAR *WideProfileName =
246+
(WCHAR *)malloc((size_t)WideLength * sizeof(*WideProfileName));
247+
if (!WideProfileName)
248+
return NULL;
249+
250+
if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, ProfileName, -1,
251+
WideProfileName, WideLength) == 0) {
252+
free(WideProfileName);
253+
return NULL;
254+
}
255+
256+
HANDLE h = CreateFileW(WideProfileName, GENERIC_READ | GENERIC_WRITE,
242257
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS,
243258
FILE_ATTRIBUTE_NORMAL, 0);
259+
free(WideProfileName);
244260
if (h == INVALID_HANDLE_VALUE)
245261
return NULL;
246262

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_profgen -o %t.exe %s
2+
// RUN: rm -rf %t.dir
3+
// RUN: mkdir %t.dir
4+
// RUN: cd %t.dir
5+
// RUN: %run %t.exe
6+
7+
#include <stdio.h>
8+
#include <windows.h>
9+
10+
extern FILE *lprofOpenFileEx(const char *);
11+
12+
int main(void) {
13+
const char *Filename = "profile-\xe6\x97\xa5.dump";
14+
FILE *File = lprofOpenFileEx(Filename);
15+
if (!File)
16+
return 1;
17+
18+
fputs("profile data", File);
19+
fclose(File);
20+
21+
return GetFileAttributesW(L"profile-\u65e5.dump") == INVALID_FILE_ATTRIBUTES;
22+
}

0 commit comments

Comments
 (0)