#2908: [Windows] Process arguments quoting is broken.

This commit is contained in:
Günter Obiltschnig
2020-02-14 09:03:03 +01:00
parent 7656b71aa6
commit 1cfe6b0f02

View File

@@ -21,6 +21,7 @@
#include "Poco/File.h" #include "Poco/File.h"
#include "Poco/Path.h" #include "Poco/Path.h"
#include "Poco/String.h" #include "Poco/String.h"
#include "Poco/Ascii.h"
namespace namespace
@@ -159,21 +160,30 @@ void ProcessImpl::timesImpl(long& userTime, long& kernelTime)
} }
static bool argNeedsEscaping(const std::string& arg) bool ProcessImpl::mustEscapeArg(const std::string& arg)
{ {
bool containsQuotableChar = std::string::npos != arg.find_first_of(" \t\n\v\""); bool result = false;
// Assume args that start and end with quotes are already quoted and do not require further quoting. bool inQuotes = false;
// There is probably code out there written before launch() escaped the arguments that does its own for (char c: arg)
// escaping of arguments. This ensures we do not interfere with those arguments. {
bool isAlreadyQuoted = arg.size() > 1 && '\"' == arg[0] && '\"' == arg[arg.size() - 1]; if (Poco::Ascii::isSpace(c) && !inQuotes)
return containsQuotableChar && !isAlreadyQuoted; {
result = true;
break;
}
else if (c == '"')
{
inQuotes = !inQuotes;
}
}
return result && !inQuotes;
} }
// Based on code from https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ // Based on code from https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/
static std::string escapeArg(const std::string& arg) std::string ProcessImpl::escapeArg(const std::string& arg)
{ {
if (argNeedsEscaping(arg)) if (mostEscapeArg(arg))
{ {
std::string quotedArg("\""); std::string quotedArg("\"");
for (std::string::const_iterator it = arg.begin(); ; ++it) for (std::string::const_iterator it = arg.begin(); ; ++it)