diff options
author | Lukacs Berki <lberki@google.com> | 2016-06-24 12:35:08 +0000 |
---|---|---|
committer | Lukacs Berki <lberki@google.com> | 2016-06-24 12:38:33 +0000 |
commit | 83c78b1a8c772b13822386c555c6472d2912f320 (patch) | |
tree | 30d92ff6d59d081e4d40cd1152c5037e5769d47d /src | |
parent | 19fd76f4376fab4f11e11099aeaf34d36e1d44df (diff) |
Make Windows command line quoting work.
Fixes #1445.
--
MOS_MIGRATED_REVID=125773835
Diffstat (limited to 'src')
-rw-r--r-- | src/main/cpp/blaze_util_mingw.cc | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/src/main/cpp/blaze_util_mingw.cc b/src/main/cpp/blaze_util_mingw.cc index 287cefb3c6..d4403fba2c 100644 --- a/src/main/cpp/blaze_util_mingw.cc +++ b/src/main/cpp/blaze_util_mingw.cc @@ -146,6 +146,10 @@ void ReplaceAll( // Max command line length is per CreateProcess documentation // (https://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx) +// +// Quoting rules are described here: +// https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ + static const int MAX_CMDLINE_LENGTH = 32768; struct CmdLine { @@ -169,19 +173,39 @@ static void CreateCommandLine(CmdLine* result, const string& exe, cmdline.append(" "); } - string arg = s; - // Quote quotes. - if (s.find("\"") != string::npos) { - ReplaceAll(&arg, "\"", "\\\""); - } + bool has_space = s.find(" ") != string::npos; - // Quotize spaces. - if (arg.find(" ") != string::npos) { + if (has_space) { cmdline.append("\""); - cmdline.append(arg); + } + + std::string::const_iterator it = s.begin(); + while (it != s.end()) { + char ch = *it++; + switch (ch) { + case '"': + // Escape double quotes + cmdline.append("\\\""); + break; + + case '\\': + if (it == s.end()) { + // Backslashes at the end of the string are quoted if we add quotes + cmdline.append(has_space ? "\\\\" : "\\"); + } else { + // Backslashes everywhere else are quoted if they are followed by a + // quote or a backslash + cmdline.append(*it == '"' || *it == '\\' ? "\\\\" : "\\"); + } + break; + + default: + cmdline.append(1, ch); + } + } + + if (has_space) { cmdline.append("\""); - } else { - cmdline.append(arg); } } |