From 11574e0bf14227349cb3245c4de246140f5cfdf8 Mon Sep 17 00:00:00 2001 From: Markus Frosch Date: Wed, 27 May 2015 16:05:10 +0200 Subject: [PATCH] Fix multi line handling for compat check results When a multi line result is submitted via the command pipe, any multi line output is escaped to a actual string '\n', because any external command only can be a single line. Example: [1432735140] PROCESS_SERVICE_CHECK_RESULT;host;service;3;Test1\nTest2|test=1 We need to unescape this values, just like we use to escape multi line output for IDO and status.dat. fixes #9324 Signed-off-by: Michael Friedrich --- lib/compat/checkresultreader.cpp | 4 +++- lib/icinga/compatutility.cpp | 7 +++++++ lib/icinga/compatutility.hpp | 1 + lib/icinga/externalcommandprocessor.cpp | 3 ++- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/compat/checkresultreader.cpp b/lib/compat/checkresultreader.cpp index ac2b30c15..10b3db566 100644 --- a/lib/compat/checkresultreader.cpp +++ b/lib/compat/checkresultreader.cpp @@ -17,6 +17,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ +#include "icinga/compatutility.hpp" #include "compat/checkresultreader.hpp" #include "icinga/service.hpp" #include "icinga/pluginutility.hpp" @@ -133,7 +134,8 @@ void CheckResultReader::ProcessCheckResultFile(const String& path) const } CheckResult::Ptr result = new CheckResult(); - std::pair co = PluginUtility::ParseCheckOutput(attrs["output"]); + String output = CompatUtility::UnEscapeString(attrs["output"]); + std::pair co = PluginUtility::ParseCheckOutput(output); result->SetOutput(co.first); result->SetPerformanceData(PluginUtility::SplitPerfdata(co.second)); result->SetState(PluginUtility::ExitStatusToState(Convert::ToLong(attrs["return_code"]))); diff --git a/lib/icinga/compatutility.cpp b/lib/icinga/compatutility.cpp index d2cbd8630..b88aafe9b 100644 --- a/lib/icinga/compatutility.cpp +++ b/lib/icinga/compatutility.cpp @@ -728,6 +728,13 @@ String CompatUtility::EscapeString(const String& str) return result; } +String CompatUtility::UnEscapeString(const String& str) +{ + String result = str; + boost::algorithm::replace_all(result, "\\n", "\n"); + return result; +} + std::pair CompatUtility::ConvertTimestamp(double time) { unsigned long time_sec = static_cast(time); diff --git a/lib/icinga/compatutility.hpp b/lib/icinga/compatutility.hpp index edba4b9f9..5ee326c12 100644 --- a/lib/icinga/compatutility.hpp +++ b/lib/icinga/compatutility.hpp @@ -118,6 +118,7 @@ public: static int MapExternalCommandType(const String& name); static String EscapeString(const String& str); + static String UnEscapeString(const String& str); private: CompatUtility(void); diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index ee6b6799e..539964969 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -354,7 +354,8 @@ void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const std: int exitStatus = Convert::ToDouble(arguments[2]); CheckResult::Ptr result = new CheckResult(); - std::pair co = PluginUtility::ParseCheckOutput(arguments[3]); + String output = CompatUtility::UnEscapeString(arguments[3]); + std::pair co = PluginUtility::ParseCheckOutput(output); result->SetOutput(co.first); result->SetPerformanceData(PluginUtility::SplitPerfdata(co.second)); result->SetState(PluginUtility::ExitStatusToState(exitStatus));