[PATCH] D21420: Properly handle short file names on the command line in Windows

Adrian McCarthy via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 16 14:50:57 PDT 2016


amccarth updated this revision to Diff 61037.
amccarth added a comment.

Better error handling if the long name is longer than MAX_PATH.


http://reviews.llvm.org/D21420

Files:
  lib/Support/Windows/Process.inc

Index: lib/Support/Windows/Process.inc
===================================================================
--- lib/Support/Windows/Process.inc
+++ lib/Support/Windows/Process.inc
@@ -201,6 +201,9 @@
   const int DirSize = Dir.size();
 
   // Search for matching files.
+  // FIXME:  This assumes the wildcard is only in the file name and not in the
+  // directory portion of the file path.  For example, it doesn't handle
+  // "*\foo.c" nor "s?c\bar.cpp".
   WIN32_FIND_DATAW FileData;
   HANDLE FindHandle = FindFirstFileW(Arg, &FileData);
   if (FindHandle == INVALID_HANDLE_VALUE) {
@@ -215,7 +218,7 @@
     if (ec)
       break;
 
-    // Push the filename onto Dir, and remove it afterwards.
+    // Append FileName to Dir, and remove it afterwards.
     llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size()));
     AllocateAndPush(Dir, Args, Allocator);
     Dir.resize(DirSize);
@@ -225,6 +228,23 @@
   return ec;
 }
 
+static std::error_code
+ExpandShortFileName(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
+  SpecificBumpPtrAllocator<char> &Allocator) {
+  SmallVector<wchar_t, MAX_PATH> LongPath;
+  DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity());
+  if (Length == 0)
+    return mapWindowsError(GetLastError());
+  if (Length > LongPath.capacity()) {
+    // We're not going to try to deal with paths longer than MAX_PATH, so we'll
+    // treat this as an error.  GetLastError() returns ERROR_SUCCESS, which
+    // isn't useful, so we'll hardcode an appropriate error value.
+    return mapWindowsError(ERROR_INSUFFICIENT_BUFFER);
+  }
+  LongPath.set_size(Length);
+  return ConvertAndPushArg(LongPath.data(), Args, Allocator);
+}
+
 std::error_code
 Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
                            ArrayRef<const char *>,
@@ -238,7 +258,12 @@
   Args.reserve(ArgCount);
   std::error_code ec;
 
-  for (int i = 0; i < ArgCount; ++i) {
+  // If the first argument is a shortenedd (8.3) name, the driver will have
+  // trouble distinguishing it (e.g., clang.exe v. clang++.exe), so make sure
+  // it's a full name.
+  ec = ExpandShortFileName(UnicodeCommandLine[0], Args, ArgAllocator);
+
+  for (int i = 1; i < ArgCount && !ec; ++i) {
     ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator);
     if (ec)
       break;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21420.61037.patch
Type: text/x-patch
Size: 2353 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160616/6dea225b/attachment.bin>


More information about the llvm-commits mailing list