aboutsummaryrefslogtreecommitdiff
path: root/libbutl/process.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-08-27 13:32:24 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-08-27 16:02:20 +0300
commit69ed8e0c82e4965c9cdd96f6847e163f7a032842 (patch)
treed79eeecf03af8558026ce93a69a3cbddac232863 /libbutl/process.cxx
parentdd681cba8b18eba62d3fce475ddcd5f1825b75bf (diff)
Fix backslash escaping in windows process arguments
Diffstat (limited to 'libbutl/process.cxx')
-rw-r--r--libbutl/process.cxx28
1 files changed, 25 insertions, 3 deletions
diff --git a/libbutl/process.cxx b/libbutl/process.cxx
index 3b18355..8b558ff 100644
--- a/libbutl/process.cxx
+++ b/libbutl/process.cxx
@@ -1301,16 +1301,38 @@ namespace butl
if (q)
s += '"';
+ // Note that backslashes don't need escaping, unless they immediately
+ // precede the double quote (see `Parsing C Command-Line Arguments` MSDN
+ // article for more details). For example:
+ //
+ // -DPATH="C:\\foo\\" -> -DPATH=\"C:\\foo\\\\\"
+ // -DPATH=C:\foo bar\ -> "-DPATH=C:\foo bar\\"
+ //
+ size_t nbs (0); // Number of consecutive backslashes.
for (size_t i (0), n (strlen (a)); i != n; ++i)
{
- if (a[i] != '"')
- s += a[i];
+ char c (a[i]);
+
+ if (c != '"')
+ s += c;
else
- s += "\\\"";
+ {
+ if (nbs != 0)
+ s.append (nbs, '\\'); // Escape backslashes.
+
+ s += "\\\""; // Escape quote.
+ }
+
+ nbs = c == '\\' ? nbs + 1 : 0;
}
if (q)
+ {
+ if (nbs != 0)
+ s.append (nbs, '\\'); // Escape backslashes.
+
s += '"';
+ }
return s.c_str ();
}