]> granicus.if.org Git - icinga2/commitdiff
Fix incorrectly escaped arguments for CreateProcess
authorGunnar Beutner <gunnar@beutner.name>
Wed, 30 Sep 2015 08:54:34 +0000 (10:54 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Tue, 13 Oct 2015 10:03:25 +0000 (12:03 +0200)
fixes #10245

doc/20-library-reference.md
lib/base/process.cpp
lib/base/scriptutils.cpp
lib/base/string.hpp
lib/base/utility.cpp
lib/base/utility.hpp

index 22e69504051f28f977465baaded0d430915a9aa6..b452b4a787418eb98c3573ee4cff0488e1be94d8 100644 (file)
@@ -21,6 +21,7 @@ get_time()                      | Returns the current UNIX timestamp.
 parse_performance_data(pd)      | Parses a performance data string and returns an array describing the values.
 dirname(path)                   | Returns the directory portion of the specified path.
 basename(path)                  | Returns the filename portion of the specified path.
+escape\_create\_process\_arg(text)| (Windows only) Escapes a string for use as an argument for CreateProcess().
 exit(integer)                   | Terminates the application.
 
 ## <a id="object-accessor-functions"></a> Object Accessor Functions
index d192044a89fe42b3710f3e65837b65138caf69ec..4f34f9359cac7301eb35d36ecc1365da864ddfe0 100644 (file)
@@ -133,7 +133,7 @@ Process::Arguments Process::PrepareCommand(const Value& command)
                        if (args != "")
                                args += " ";
 
-                       args += Utility::EscapeShellArg(argument);
+                       args += Utility::EscapeCreateProcessArg(argument);
 #else /* _WIN32 */
                        args.push_back(argument);
 #endif /* _WIN32 */
index abfffce40ad123c676a5954a57e2473eb8e615ed..cd2e1165132c6c1f3a5b1b8f251ea0a42353a13a 100644 (file)
@@ -58,6 +58,7 @@ REGISTER_SCRIPTFUNCTION(get_time, &Utility::GetTime);
 REGISTER_SCRIPTFUNCTION(basename, &Utility::BaseName);
 REGISTER_SCRIPTFUNCTION(dirname, &Utility::DirName);
 REGISTER_SCRIPTFUNCTION(msi_get_component_path, &ScriptUtils::MsiGetComponentPathShim);
+REGISTER_SCRIPTFUNCTION(escape_create_process_arg, &Utility::EscapeCreateProcessArg);
 
 String ScriptUtils::CastString(const Value& value)
 {
index ad019dc289925d560fb0b757737c86a625d83aa2..74c93f188254457d8beffb8d1f834f73266d72f2 100644 (file)
@@ -204,6 +204,11 @@ public:
 
        void Trim(void);
 
+       inline void Append(int count, char ch)
+       {
+               m_Data.append(count, ch);
+       }
+
        inline bool Contains(const String& str) const
        {
                return (m_Data.find(str) != std::string::npos);
index 478b405558eb6a110423d6388985dba4aeedbd78..6708a1e6c1b42ec1c934dd5d1ad8e222055aa013 100644 (file)
@@ -1016,6 +1016,40 @@ String Utility::EscapeShellArg(const String& s)
        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
 static void WindowsSetThreadName(const char *name)
 {
index c1702193e6934b831ad3341f78147cfb2a4343ce..0cce4c127c7b53d16e82ccbc8426194a8e64f435 100644 (file)
@@ -108,6 +108,7 @@ public:
 
        static String EscapeShellCmd(const String& s);
        static String EscapeShellArg(const String& s);
+       static String EscapeCreateProcessArg(const String& arg);
 
        static String EscapeString(const String& s, const String& chars);
        static String UnescapeString(const String& s);