From 69ed8e0c82e4965c9cdd96f6847e163f7a032842 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 27 Aug 2019 13:32:24 +0300 Subject: Fix backslash escaping in windows process arguments --- libbutl/process.cxx | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'libbutl/process.cxx') 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 (); } -- cgit v1.1