]> 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>
Wed, 30 Sep 2015 08:56:31 +0000 (10:56 +0200)
fixes #10245

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

index d8caed59bf92135eb32b55ab2d5d3c7cacf5dbfb..92cdbde8ef197bd7a9d15f70d0bd9500ab1d6b16 100644 (file)
@@ -23,6 +23,7 @@ dirname(path)                   | Returns the directory portion of the specified
 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\_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.
 
 ## <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 5651b29d1688b1c72425e698368d2f90a8c9282a..a916e5a0ba48dfef34173a24971bef59a730b1fc 100644 (file)
@@ -61,6 +61,7 @@ REGISTER_SAFE_SCRIPTFUNCTION(msi_get_component_path, &ScriptUtils::MsiGetCompone
 REGISTER_SAFE_SCRIPTFUNCTION(track_parents, &ScriptUtils::TrackParents);
 REGISTER_SAFE_SCRIPTFUNCTION(escape_shell_cmd, &Utility::EscapeShellCmd);
 REGISTER_SAFE_SCRIPTFUNCTION(escape_shell_arg, &Utility::EscapeShellArg);
+REGISTER_SAFE_SCRIPTFUNCTION(escape_create_process_arg, &Utility::EscapeCreateProcessArg);
 
 String ScriptUtils::CastString(const Value& value)
 {
index 2de4b5a444a310b86c5dcbcfc8072d67dba3b7c0..82c9f1218b8ae1d77ec2cbc758a4f5df655231bf 100644 (file)
@@ -241,6 +241,11 @@ public:
                return t;
        }
 
+       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 3bf58bf33312deb33cd5313dfcf89475db0ddcef..c63998d51c93996f66d055eb73db41bf6c28a5c1 100644 (file)
@@ -978,6 +978,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 3ca6a4ad51572c46b64b3944efdc63434048aaa2..839a5aca82d00a6989e00868df7876b0c609ae14 100644 (file)
@@ -103,6 +103,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, const bool illegal);
        static String UnescapeString(const String& s);