Fix incorrectly escaped arguments for CreateProcess

fixes #10245
This commit is contained in:
Gunnar Beutner 2015-09-30 10:54:34 +02:00
parent 19e7524b31
commit 254c076dd4
6 changed files with 43 additions and 1 deletions

View File

@ -23,6 +23,7 @@ dirname(path) | Returns the directory portion of the specified
basename(path) | Returns the filename portion of the specified path. basename(path) | Returns the filename portion of the specified path.
escape\_shell\_arg(text) | Escapes a string for use as a single shell argument. escape\_shell\_arg(text) | Escapes a string for use as a single shell argument.
escape\_shell\_cmd(text) | Escapes shell meta characters in a string. escape\_shell\_cmd(text) | Escapes shell meta characters in a string.
escape\_create\_process\_arg(text)| (Windows only) Escapes a string for use as an argument for CreateProcess().
exit(integer) | Terminates the application. exit(integer) | Terminates the application.
## <a id="object-accessor-functions"></a> Object Accessor Functions ## <a id="object-accessor-functions"></a> Object Accessor Functions

View File

@ -133,7 +133,7 @@ Process::Arguments Process::PrepareCommand(const Value& command)
if (args != "") if (args != "")
args += " "; args += " ";
args += Utility::EscapeShellArg(argument); args += Utility::EscapeCreateProcessArg(argument);
#else /* _WIN32 */ #else /* _WIN32 */
args.push_back(argument); args.push_back(argument);
#endif /* _WIN32 */ #endif /* _WIN32 */

View File

@ -61,6 +61,7 @@ REGISTER_SAFE_SCRIPTFUNCTION(msi_get_component_path, &ScriptUtils::MsiGetCompone
REGISTER_SAFE_SCRIPTFUNCTION(track_parents, &ScriptUtils::TrackParents); REGISTER_SAFE_SCRIPTFUNCTION(track_parents, &ScriptUtils::TrackParents);
REGISTER_SAFE_SCRIPTFUNCTION(escape_shell_cmd, &Utility::EscapeShellCmd); REGISTER_SAFE_SCRIPTFUNCTION(escape_shell_cmd, &Utility::EscapeShellCmd);
REGISTER_SAFE_SCRIPTFUNCTION(escape_shell_arg, &Utility::EscapeShellArg); REGISTER_SAFE_SCRIPTFUNCTION(escape_shell_arg, &Utility::EscapeShellArg);
REGISTER_SAFE_SCRIPTFUNCTION(escape_create_process_arg, &Utility::EscapeCreateProcessArg);
String ScriptUtils::CastString(const Value& value) String ScriptUtils::CastString(const Value& value)
{ {

View File

@ -241,6 +241,11 @@ public:
return t; return t;
} }
inline void Append(int count, char ch)
{
m_Data.append(count, ch);
}
inline bool Contains(const String& str) const inline bool Contains(const String& str) const
{ {
return (m_Data.find(str) != std::string::npos); return (m_Data.find(str) != std::string::npos);

View File

@ -978,6 +978,40 @@ String Utility::EscapeShellArg(const String& s)
return result; return result;
} }
#ifdef _WIN32
String Utility::EscapeCreateProcessArg(const String& arg)
{
if (arg.FindFirstOf(" \t\n\v\"") == String::NPos)
return arg;
String result = "\"";
for (String::ConstIterator it = arg.Begin(); ; it++) {
int numBackslashes = 0;
while (it != arg.End() && *it == '\\') {
it++;
numBackslashes++;
}
if (it == arg.End()) {
result.Append(numBackslashes * 2, '\\');
break;
} else if (*it == '"') {
result.Append(numBackslashes * 2, '\\');
result.Append(1, *it);
} else {
result.Append(numBackslashes, '\\');
result.Append(1, *it);
}
}
result += "\"";
return result;
}
#endif /* _WIN32 */
#ifdef _WIN32 #ifdef _WIN32
static void WindowsSetThreadName(const char *name) static void WindowsSetThreadName(const char *name)
{ {

View File

@ -103,6 +103,7 @@ public:
static String EscapeShellCmd(const String& s); static String EscapeShellCmd(const String& s);
static String EscapeShellArg(const String& s); static String EscapeShellArg(const String& s);
static String EscapeCreateProcessArg(const String& arg);
static String EscapeString(const String& s, const String& chars, const bool illegal); static String EscapeString(const String& s, const String& chars, const bool illegal);
static String UnescapeString(const String& s); static String UnescapeString(const String& s);