@@ -38,9 +38,10 @@ using namespace llbuild::basic;
38
38
39
39
bool sys::chdir (const char *fileName) {
40
40
#if defined(_WIN32)
41
- llvm::SmallVector<llvm::UTF16, 20 > wFileName;
42
- llvm::convertUTF8ToUTF16String (fileName, wFileName);
43
- return SetCurrentDirectoryW ((LPCWSTR)wFileName.data ());
41
+ llvm::SmallVector<wchar_t , MAX_PATH> wFileName;
42
+ if (llvm::sys::path::widenPath (fileName, wFileName))
43
+ return false ;
44
+ return ::_wchdir (wFileName.data ());
44
45
#else
45
46
return ::chdir (fileName) == 0 ;
46
47
#endif
@@ -63,10 +64,13 @@ time_t filetimeToTime_t(FILETIME ft) {
63
64
64
65
int sys::lstat (const char *fileName, sys::StatStruct *buf) {
65
66
#if defined(_WIN32)
66
- llvm::SmallVector<llvm::UTF16, 20 > wfilename;
67
- llvm::convertUTF8ToUTF16String (fileName, wfilename);
67
+ llvm::SmallVector<wchar_t , MAX_PATH> wfilename;
68
+ if (llvm::sys::path::widenPath (fileName, wfilename)) {
69
+ errno = EINVAL;
70
+ return -1 ;
71
+ }
68
72
HANDLE h = CreateFileW (
69
- /* lpFileName=*/ (LPCWSTR) wfilename.data (),
73
+ /* lpFileName=*/ wfilename.data (),
70
74
/* dwDesiredAccess=*/ 0 ,
71
75
/* dwShareMode=*/ FILE_SHARE_READ,
72
76
/* lpSecurityAttributes=*/ NULL ,
@@ -123,7 +127,10 @@ int sys::lstat(const char *fileName, sys::StatStruct *buf) {
123
127
124
128
bool sys::mkdir (const char * fileName) {
125
129
#if defined(_WIN32)
126
- return _mkdir (fileName) == 0 ;
130
+ llvm::SmallVector<wchar_t , MAX_PATH> wfilename;
131
+ if (llvm::sys::path::widenPath (fileName, wfilename))
132
+ return false ;
133
+ return ::_wmkdir (wfilename.data ()) != 0 ;
127
134
#else
128
135
return ::mkdir (fileName, S_IRWXU | S_IRWXG | S_IRWXO) == 0 ;
129
136
#endif
@@ -164,15 +171,25 @@ int sys::read(int fileHandle, void *destinationBuffer,
164
171
165
172
int sys::rmdir (const char *path) {
166
173
#if defined(_WIN32)
167
- return ::_rmdir (path);
174
+ llvm::SmallVector<wchar_t , MAX_PATH> wpath;
175
+ if (llvm::sys::path::widenPath (path, wpath)) {
176
+ errno = EINVAL;
177
+ return -1 ;
178
+ }
179
+ return ::_wrmdir (wpath.data ());
168
180
#else
169
181
return ::rmdir (path);
170
182
#endif
171
183
}
172
184
173
185
int sys::stat (const char *fileName, StatStruct *buf) {
174
186
#if defined(_WIN32)
175
- return ::_stat (fileName, buf);
187
+ llvm::SmallVector<wchar_t , MAX_PATH> wfilename;
188
+ if (llvm::sys::path::widenPath (fileName, wfilename)) {
189
+ errno = EINVAL;
190
+ return -1 ;
191
+ }
192
+ return ::_wstat (wfilename.data (), buf);
176
193
#else
177
194
return ::stat (fileName, buf);
178
195
#endif
@@ -181,19 +198,21 @@ int sys::stat(const char *fileName, StatStruct *buf) {
181
198
// Create a symlink named linkPath which contains the string pointsTo
182
199
int sys::symlink (const char *pointsTo, const char *linkPath) {
183
200
#if defined(_WIN32)
184
- llvm::SmallVector<llvm::UTF16, 20 > wPointsTo;
185
- llvm::convertUTF8ToUTF16String (pointsTo, wPointsTo);
186
- llvm::SmallVector<llvm::UTF16, 20 > wLinkPath;
187
- llvm::convertUTF8ToUTF16String (linkPath, wLinkPath);
188
- DWORD attributes = GetFileAttributesW ((LPCWSTR)wPointsTo.data ());
201
+ llvm::SmallVector<wchar_t , MAX_PATH> wPointsTo;
202
+ if (llvm::sys::path::widenPath (pointsTo, wPointsTo))
203
+ return -1 ;
204
+ llvm::SmallVector<wchar_t , MAX_PATH> wLinkPath;
205
+ if (llvm::sys::path::widenPath (linkPath, wLinkPath))
206
+ return -1 ;
207
+ DWORD attributes = GetFileAttributesW (wPointsTo.data ());
189
208
DWORD directoryFlag = (attributes != INVALID_FILE_ATTRIBUTES &&
190
209
attributes & FILE_ATTRIBUTE_DIRECTORY)
191
210
? SYMBOLIC_LINK_FLAG_DIRECTORY
192
211
: 0 ;
193
212
// Note that CreateSymbolicLinkW takes its arguments in reverse order
194
213
// compared to symlink/_symlink
195
214
return !::CreateSymbolicLinkW (
196
- (LPCWSTR) wLinkPath.data (), (LPCWSTR) wPointsTo.data (),
215
+ wLinkPath.data (), wPointsTo.data (),
197
216
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE | directoryFlag);
198
217
#else
199
218
return ::symlink (pointsTo, linkPath);
@@ -202,7 +221,12 @@ int sys::symlink(const char *pointsTo, const char *linkPath) {
202
221
203
222
int sys::unlink (const char *fileName) {
204
223
#if defined(_WIN32)
205
- return ::_unlink (fileName);
224
+ llvm::SmallVector<wchar_t , MAX_PATH> wfilename;
225
+ if (llvm::sys::path::widenPath (fileName, wfilename)) {
226
+ errno = EINVAL;
227
+ return -1 ;
228
+ }
229
+ return ::_wunlink (wfilename.data ());
206
230
#else
207
231
return ::unlink (fileName);
208
232
#endif
@@ -263,14 +287,15 @@ int sys::raiseOpenFileLimit(llbuild_rlim_t limit) {
263
287
sys::MATCH_RESULT sys::filenameMatch (const std::string& pattern,
264
288
const std::string& filename) {
265
289
#if defined(_WIN32)
266
- llvm::SmallVector<llvm::UTF16, 20 > wpattern;
267
- llvm::SmallVector<llvm::UTF16, 20 > wfilename;
290
+ llvm::SmallVector<wchar_t , MAX_PATH > wpattern;
291
+ llvm::SmallVector<wchar_t , MAX_PATH > wfilename;
268
292
269
- llvm::convertUTF8ToUTF16String (pattern, wpattern);
270
- llvm::convertUTF8ToUTF16String (filename, wfilename);
293
+ if (llvm::sys::path::widenPath (pattern, wpattern) ||
294
+ llvm::sys::path::widenPath (filename, wfilename))
295
+ return sys::MATCH_ERROR;
271
296
272
297
bool result =
273
- PathMatchSpecW ((LPCWSTR) wfilename.data (), (LPCWSTR) wpattern.data ());
298
+ PathMatchSpecW (wfilename.data (), wpattern.data ());
274
299
return result ? sys::MATCH : sys::NO_MATCH;
275
300
#else
276
301
int result = fnmatch (pattern.c_str (), filename.c_str (), 0 );
@@ -342,9 +367,17 @@ std::string sys::makeTmpDir() {
342
367
#if defined(_WIN32)
343
368
char path[MAX_PATH];
344
369
tmpnam_s (path, MAX_PATH);
345
- llvm::SmallVector<llvm::UTF16, 20 > wPath;
346
- llvm::convertUTF8ToUTF16String (path, wPath);
347
- CreateDirectoryW ((LPCWSTR)wPath.data (), NULL );
370
+ llvm::SmallVector<wchar_t , MAX_PATH> wPath;
371
+ if (llvm::sys::path::widenPath (path, wPath))
372
+ return std::string ();
373
+ if (!CreateDirectoryW (wPath.data (), NULL )) {
374
+ DWORD error = GetLastError ();
375
+ if (error != ERROR_ALREADY_EXISTS) {
376
+ fprintf (stderr, " Failed to create temporary directory '%s': error code %lu\n " ,
377
+ path, (unsigned long )error);
378
+ return std::string ();
379
+ }
380
+ }
348
381
return std::string (path);
349
382
#else
350
383
if (const char *tmpDir = std::getenv (" TMPDIR" )) {
@@ -371,15 +404,10 @@ std::string sys::getPathSeparators() {
371
404
372
405
sys::ModuleTraits<>::Handle sys::OpenLibrary (const char *path) {
373
406
#if defined(_WIN32)
374
- int cchLength =
375
- MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, path, strlen (path),
376
- nullptr , 0 );
377
- std::u16string buffer (cchLength + 1 , 0 );
378
- MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, path, strlen (path),
379
- const_cast <LPWSTR>(reinterpret_cast <LPCWSTR>(buffer.data ())),
380
- buffer.size ());
381
-
382
- return LoadLibraryW (reinterpret_cast <LPCWSTR>(buffer.data ()));
407
+ llvm::SmallVector<wchar_t , MAX_PATH> wPath;
408
+ if (llvm::sys::path::widenPath (path, wPath))
409
+ return nullptr ;
410
+ return LoadLibraryW (wPath.data ());
383
411
#else
384
412
return dlopen (path, RTLD_LAZY);
385
413
#endif
0 commit comments