diff --git a/lib/icinga/perfdatavalue.cpp b/lib/icinga/perfdatavalue.cpp index 9c4518f90..d643836ca 100644 --- a/lib/icinga/perfdatavalue.cpp +++ b/lib/icinga/perfdatavalue.cpp @@ -20,6 +20,7 @@ #include "icinga/perfdatavalue.hpp" #include "base/convert.hpp" #include "base/exception.hpp" +#include "base/logger.hpp" #include #include #include @@ -113,17 +114,10 @@ PerfdataValue::Ptr PerfdataValue::Parse(const String& perfdata) BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid performance data unit: " + unit)); } - if (tokens.size() > 1 && tokens[1] != "U" && tokens[1] != "") - warn = Convert::ToDouble(tokens[1]); - - if (tokens.size() > 2 && tokens[2] != "U" && tokens[2] != "") - crit = Convert::ToDouble(tokens[2]); - - if (tokens.size() > 3 && tokens[3] != "U" && tokens[3] != "") - min = Convert::ToDouble(tokens[3]); - - if (tokens.size() > 4 && tokens[4] != "U" && tokens[4] != "") - max = Convert::ToDouble(tokens[4]); + warn = ParseWarnCritMinMaxToken(tokens, 1, "warning"); + crit = ParseWarnCritMinMaxToken(tokens, 2, "critical"); + min = ParseWarnCritMinMaxToken(tokens, 3, "minimum"); + max = ParseWarnCritMinMaxToken(tokens, 4, "maximum"); value = value * base; @@ -184,3 +178,15 @@ String PerfdataValue::Format(void) const return result.str(); } + +Value PerfdataValue::ParseWarnCritMinMaxToken(const std::vector& tokens, std::vector::size_type index, const String& description) +{ + if (tokens.size() > index && tokens[index] != "U" && tokens[index] != "" && tokens[index].FindFirstNotOf("+-0123456789.e") == String::NPos) + return Convert::ToDouble(tokens[index]); + else { + if (tokens.size() > index && tokens[index] != "") + Log(LogDebug, "PerfdataValue") + << "Ignoring unsupported perfdata " << description << " range, value: '" << tokens[index] << "'."; + return Empty; + } +} diff --git a/lib/icinga/perfdatavalue.hpp b/lib/icinga/perfdatavalue.hpp index 1be5bd174..3b6a391f1 100644 --- a/lib/icinga/perfdatavalue.hpp +++ b/lib/icinga/perfdatavalue.hpp @@ -39,6 +39,10 @@ public: static PerfdataValue::Ptr Parse(const String& perfdata); String Format(void) const; + +private: + static Value ParseWarnCritMinMaxToken(const std::vector& tokens, + std::vector::size_type index, const String& description); }; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6bb966257..dc4653f08 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -103,6 +103,7 @@ add_boost_test(base icinga_perfdata/multiple icinga_perfdata/uom icinga_perfdata/warncritminmax + icinga_perfdata/ignore_invalid_warn_crit_min_max icinga_perfdata/invalid icinga_perfdata/multi ) diff --git a/test/icinga-perfdata.cpp b/test/icinga-perfdata.cpp index 134c7d585..7b06990b8 100644 --- a/test/icinga-perfdata.cpp +++ b/test/icinga-perfdata.cpp @@ -114,10 +114,23 @@ BOOST_AUTO_TEST_CASE(warncritminmax) BOOST_CHECK(pv->Format() == "test=123456B;1000;2000;3000;4000"); } +BOOST_AUTO_TEST_CASE(ignore_invalid_warn_crit_min_max) +{ + PerfdataValue::Ptr pv = PerfdataValue::Parse("test=123456;1000:2000;0:3000;3000;4000"); + BOOST_CHECK(pv); + BOOST_CHECK(pv->GetValue() == 123456); + BOOST_CHECK(pv->GetWarn() == Empty); + BOOST_CHECK(pv->GetCrit() == Empty); + BOOST_CHECK(pv->GetMin() == 3000); + BOOST_CHECK(pv->GetMax() == 4000); + + BOOST_CHECK(pv->Format() == "test=123456"); +} + BOOST_AUTO_TEST_CASE(invalid) { + BOOST_CHECK_THROW(PerfdataValue::Parse("123456"), boost::exception); BOOST_CHECK_THROW(PerfdataValue::Parse("test=1,23456"), boost::exception); - BOOST_CHECK_THROW(PerfdataValue::Parse("test=123456;10%;20%"), boost::exception); } BOOST_AUTO_TEST_CASE(multi)