From 8504149fc1c70ecc5c7743c3522ae70de68b0694 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 27 Feb 2019 10:07:57 +0200 Subject: Factor out Windows command line argument quoting to utility function --- libbutl/process.cxx | 55 +++++++++++++++++++++++++++++++++-------------------- libbutl/process.mxx | 10 ++++++++++ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/libbutl/process.cxx b/libbutl/process.cxx index fa2f583..c6bf7cb 100644 --- a/libbutl/process.cxx +++ b/libbutl/process.cxx @@ -1067,6 +1067,37 @@ namespace butl bool locked_ = true; }; + const char* process:: + quote_argument (const char* a, string& s) + { + // On Windows we need to protect values with spaces using quotes. + // Since there could be actual quotes in the value, we need to + // escape them. + // + bool q (*a == '\0' || strchr (a, ' ') != nullptr); + + if (!q && strchr (a, '"') == nullptr) + return a; + + s.clear (); + + if (q) + s += '"'; + + for (size_t i (0), n (strlen (a)); i != n; ++i) + { + if (a[i] != '"') + s += a[i]; + else + s += "\\\""; + } + + if (q) + s += '"'; + + return s.c_str (); + } + // Protected by process_spawn_mutex. See below for the gory details. // static map detect_msys_cache_; @@ -1257,35 +1288,17 @@ namespace butl // string cmd_line; { - auto append = [&cmd_line] (const string& a) + auto append = [&cmd_line, buf = string ()] (const char* a) mutable { if (!cmd_line.empty ()) cmd_line += ' '; - // On Windows we need to protect values with spaces using quotes. - // Since there could be actual quotes in the value, we need to escape - // them. - // - bool quote (a.empty () || a.find (' ') != string::npos); - - if (quote) - cmd_line += '"'; - - for (size_t i (0); i < a.size (); ++i) - { - if (a[i] == '"') - cmd_line += "\\\""; - else - cmd_line += a[i]; - } - - if (quote) - cmd_line += '"'; + cmd_line += quote_argument (a, buf); }; if (batch) { - append (*batch); + append (batch->c_str ()); append ("/c"); append (pp.effect_string ()); } diff --git a/libbutl/process.mxx b/libbutl/process.mxx index 8f9d2de..c18ae43 100644 --- a/libbutl/process.mxx +++ b/libbutl/process.mxx @@ -462,6 +462,16 @@ LIBBUTL_MODEXPORT namespace butl static void print (std::ostream&, const char* const args[], size_t n = 0); + // Quote and escape the specified command line argument. Return the + // original string if neither is necessary and a pointer to the provided + // buffer string containing the escaped version otherwise. + // +#ifdef _WIN32 + static const char* + quote_argument (const char*, std::string& buffer); +#endif + + public: id_type id () const; -- cgit v1.1