Properly quote the quotes :) during cmdline construction on Windows.
authorAnton Korobeynikov <asl@math.spbu.ru>
Sun, 28 Mar 2010 15:07:02 +0000 (15:07 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Sun, 28 Mar 2010 15:07:02 +0000 (15:07 +0000)
Otherwise, e.g. in the invocation like clang -DFOO=\"bar\" FOO macro
got the bar value, not "bar".

Patch by Alexander Esilevich!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99763 91177308-0d34-0410-b5e6-96231b3b80d8

lib/System/Win32/Program.inc

index a3b40d0e3650376378f536994cf2fc3e53a7b739..16bb28e17a21fc75cf8bcdea8f4e69bc0731734b 100644 (file)
@@ -138,6 +138,24 @@ static bool ArgNeedsQuotes(const char *Str) {
   return Str[0] == '\0' || strchr(Str, ' ') != 0;
 }
 
+
+/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
+/// CreateProcess and returns length of quoted arg with escaped quotes
+static unsigned int ArgLenWithQuotes(const char *Str) {
+  unsigned int len = ArgNeedsQuotes(Str) ? 2 : 0;
+
+  while (*Str != '\0') {
+    if (*Str == '\"')
+      ++len;
+
+    ++len;
+    ++Str;
+  }
+
+  return len;
+}
+
+
 bool
 Program::Execute(const Path& path,
                  const char** args,
@@ -165,9 +183,7 @@ Program::Execute(const Path& path,
   // First, determine the length of the command line.
   unsigned len = 0;
   for (unsigned i = 0; args[i]; i++) {
-    len += strlen(args[i]) + 1;
-    if (ArgNeedsQuotes(args[i]))
-      len += 2;
+    len += ArgLenWithQuotes(args[i]) + 1;
   }
 
   // Now build the command line.
@@ -176,12 +192,18 @@ Program::Execute(const Path& path,
 
   for (unsigned i = 0; args[i]; i++) {
     const char *arg = args[i];
-    size_t len = strlen(arg);
+
     bool needsQuoting = ArgNeedsQuotes(arg);
     if (needsQuoting)
       *p++ = '"';
-    memcpy(p, arg, len);
-    p += len;
+
+    while (*arg != '\0') {
+      if (*arg == '\"')
+        *p++ = '\\';
+
+      *p++ = *arg++;
+    }
+
     if (needsQuoting)
       *p++ = '"';
     *p++ = ' ';