]> granicus.if.org Git - llvm/commitdiff
Switch to using an API that handles non-ASCII paths appropriately on Windows.
authorAaron Ballman <aaron@aaronballman.com>
Tue, 21 Jun 2016 14:24:48 +0000 (14:24 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Tue, 21 Jun 2016 14:24:48 +0000 (14:24 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273262 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/Windows/Path.inc
unittests/Support/Path.cpp

index 8e5931ce6d802f7da65a7cbee9d5ded6c3bf0af9..fab6aeca54a94e381759e466ef594a860380ab2e 100644 (file)
@@ -820,33 +820,34 @@ std::error_code getPathFromOpenFD(int FD, SmallVectorImpl<char> &ResultPath) {
     return make_error_code(errc::bad_file_descriptor);
 
   DWORD CharCount;
+  SmallVector<wchar_t, 1024> TempPath;
   do {
-    // FIXME: We should be using the W version of this API and converting the
-    // resulting path to UTF-8 to handle non-ASCII file paths.
-    CharCount = ::GetFinalPathNameByHandleA(FileHandle, ResultPath.begin(),
-                                            ResultPath.capacity(),
+    CharCount = ::GetFinalPathNameByHandleW(FileHandle, TempPath.begin(),
+                                            TempPath.capacity(),
                                             FILE_NAME_NORMALIZED);
-    if (CharCount < ResultPath.capacity())
+    if (CharCount < TempPath.capacity())
       break;
 
     // Reserve sufficient space for the path as well as the null character. Even
     // though the API does not document that it is required, if we reserve just
     // CharCount space, the function call will not store the resulting path and
     // still report success.
-    ResultPath.reserve(CharCount + 1);
+    TempPath.reserve(CharCount + 1);
   } while (true);
 
   if (CharCount == 0)
     return mapWindowsError(::GetLastError());
 
-  ResultPath.set_size(CharCount);
+  TempPath.set_size(CharCount);
 
   // On earlier Windows releases, the character count includes the terminating
   // null.
-  if (ResultPath.back() == '\0')
-    ResultPath.pop_back();
+  if (TempPath.back() == L'\0') {
+    --CharCount;
+    TempPath.pop_back();
+  }
 
-  return std::error_code();
+  return windows::UTF16ToUTF8(TempPath.data(), CharCount, ResultPath);
 }
 } // end namespace fs
 
index 74b74ac4195cdb15e3202553c17010a1b78bcdf3..1a6ffa50e983ef4d9f26ec53226ab26fe15391bd 100644 (file)
@@ -1057,6 +1057,32 @@ TEST_F(FileSystemTest, PathFromFDWin32) {
   ::close(FileDescriptor);
 }
 
+TEST_F(FileSystemTest, PathFromFDUnicode) {
+  // Create a temp file.
+  int FileDescriptor;
+  SmallString<64> TempPath;
+
+  // Test Unicode: "<temp directory>/(pi)r^2<temp rand chars>.aleth.0"
+  ASSERT_NO_ERROR(
+    fs::createTemporaryFile("\xCF\x80r\xC2\xB2",
+                            "\xE2\x84\xB5.0", FileDescriptor, TempPath));
+
+  // Make sure it exists.
+  ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
+
+  SmallVector<char, 8> ResultPath;
+  std::error_code ErrorCode =
+    fs::getPathFromOpenFD(FileDescriptor, ResultPath);
+
+  if (!ErrorCode) {
+    fs::UniqueID D1, D2;
+    ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
+    ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
+    ASSERT_EQ(D1, D2);
+  }
+  ::close(FileDescriptor);
+}
+
 TEST_F(FileSystemTest, OpenFileForRead) {
   // Create a temp file.
   int FileDescriptor;