diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2012-01-27 23:46:00 -0500 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2012-01-27 23:46:00 -0500 |
commit | 27df0a84564d3a886661aae0faae74c2157cd31b (patch) | |
tree | c025f58c1491f888b630ab01ef54c298e15c437d | |
parent | 61e98256df80822f9504a2037d5cbb029c39506d (diff) |
On Windows, only quote LLProcess arguments if they seem to need it.
On Posix platforms, the OS argument mechanism makes quoting/reparsing
unnecessary anyway, so this only affects Windows.
Add optional 'triggers' parameter to LLStringUtils::quote() (default: space
and double-quote). Only if the passed string contains a character in
'triggers' will it be double-quoted.
This is observed to fix a Windows-specific problem in which plugin child
process would fail to start because it wasn't expecting a quoted number.
Use LLStringUtils::quote() more consistently in LLProcess implementation for
logging.
-rw-r--r-- | indra/llcommon/llprocess.cpp | 14 | ||||
-rw-r--r-- | indra/llcommon/llstring.h | 26 |
2 files changed, 28 insertions, 12 deletions
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 2c7512419d..2b7a534fb3 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -87,12 +87,12 @@ std::ostream& operator<<(std::ostream& out, const LLProcess::Params& params) std::string cwd(params.cwd); if (! cwd.empty()) { - out << "cd '" << cwd << "': "; + out << "cd " << LLStringUtil::quote(cwd) << ": "; } - out << '"' << std::string(params.executable) << '"'; + out << LLStringUtil::quote(params.executable); BOOST_FOREACH(const std::string& arg, params.args) { - out << " \"" << arg << '"'; + out << ' ' << LLStringUtil::quote(arg); } return out; } @@ -132,8 +132,8 @@ public: if (! AssignProcessToJobObject(mJob, hProcess)) { - LL_WARNS("LLProcess") << WindowsErrorString(STRINGIZE("AssignProcessToJobObject(\"" - << prog << "\")")) << LL_ENDL; + LL_WARNS("LLProcess") << WindowsErrorString(STRINGIZE("AssignProcessToJobObject(" + << prog << ")")) << LL_ENDL; } } @@ -206,7 +206,7 @@ void LLProcess::launch(const LLSDParamAdapter<Params>& params) mProcessID = pinfo.hProcess; CloseHandle(pinfo.hThread); // stops leaks - nothing else - mDesc = STRINGIZE('"' << std::string(params.executable) << "\" (" << pinfo.dwProcessId << ')'); + mDesc = STRINGIZE(LLStringUtil::quote(params.executable) << " (" << pinfo.dwProcessId << ')'); LL_INFOS("LLProcess") << "Launched " << params << " (" << pinfo.dwProcessId << ")" << LL_ENDL; // Now associate the new child process with our Job Object -- unless @@ -356,7 +356,7 @@ void LLProcess::launch(const LLSDParamAdapter<Params>& params) // parent process mProcessID = child; - mDesc = STRINGIZE('"' << std::string(params.executable) << "\" (" << mProcessID << ')'); + mDesc = STRINGIZE(LLStringUtil::quote(params.executable) << " (" << mProcessID << ')'); LL_INFOS("LLProcess") << "Launched " << params << " (" << mProcessID << ")" << LL_ENDL; } diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 4c3936f9ab..7b24b5e279 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -303,11 +303,17 @@ public: static void stripNonprintable(string_type& string); /** - * Double-quote an argument string, unless it's already double-quoted. If we - * quote it, escape any embedded double-quote with the escape string (default + * Double-quote an argument string if needed, unless it's already + * double-quoted. Decide whether it's needed based on the presence of any + * character in @a triggers (default space or double-quote). If we quote + * it, escape any embedded double-quote with the @a escape string (default * backslash). + * + * Passing triggers="" means always quote, unless it's already double-quoted. */ - static string_type quote(const string_type& str, const string_type& escape="\\"); + static string_type quote(const string_type& str, + const string_type& triggers=" \"", + const string_type& escape="\\"); /** * @brief Unsafe way to make ascii characters. You should probably @@ -1060,7 +1066,9 @@ void LLStringUtilBase<T>::stripNonprintable(string_type& string) } template<class T> -std::basic_string<T> LLStringUtilBase<T>::quote(const string_type& str, const string_type& escape) +std::basic_string<T> LLStringUtilBase<T>::quote(const string_type& str, + const string_type& triggers, + const string_type& escape) { size_type len(str.length()); // If the string is already quoted, assume user knows what s/he's doing. @@ -1069,7 +1077,15 @@ std::basic_string<T> LLStringUtilBase<T>::quote(const string_type& str, const st return str; } - // Not already quoted: do it. + // Not already quoted: do we need to? triggers.empty() is a special case + // meaning "always quote." + if ((! triggers.empty()) && str.find_first_of(triggers) == string_type::npos) + { + // no trigger characters, don't bother quoting + return str; + } + + // For whatever reason, we must quote this string. string_type result; result.push_back('"'); for (typename string_type::const_iterator ci(str.begin()), cend(str.end()); ci != cend; ++ci) |