]> granicus.if.org Git - icinga2/commitdiff
Fix filter parsing for values containing white spaces.
authorMichael Friedrich <michael.friedrich@netways.de>
Tue, 5 Nov 2013 11:31:30 +0000 (12:31 +0100)
committerMichael Friedrich <michael.friedrich@netways.de>
Tue, 5 Nov 2013 16:14:29 +0000 (17:14 +0100)
Refs #4433

components/livestatus/logtable.cpp
components/livestatus/query.cpp

index 6aedda052b085ee7868b08e682879109a15874ed..8af7f13df09dde4c278d79acb10bc225914e19a3 100644 (file)
@@ -334,6 +334,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
 
        /* States - TODO refactor */
        if (boost::algorithm::contains(type, "INITIAL HOST STATE")) {
+               if (tokens.size() < 5)
+                       return Dictionary::Ptr();
+
                log_class = LogClassState;
                log_type = LogTypeHostInitialState;
 
@@ -344,6 +347,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                plugin_output = tokens[4];
        }
        else if (boost::algorithm::contains(type, "CURRENT HOST STATE")) {
+               if (tokens.size() < 5)
+                       return Dictionary::Ptr();
+
                log_class = LogClassState;
                log_type = LogTypeHostCurrentState;
 
@@ -354,6 +360,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                plugin_output = tokens[4];
        }
        else if (boost::algorithm::contains(type, "HOST ALERT")) {
+               if (tokens.size() < 5)
+                       return Dictionary::Ptr();
+
                log_class = LogClassAlert;
                log_type = LogTypeHostAlert;
 
@@ -364,6 +373,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                plugin_output = tokens[4];
        }
        else if (boost::algorithm::contains(type, "HOST DOWNTIME ALERT")) {
+               if (tokens.size() < 3)
+                       return Dictionary::Ptr();
+
                log_class = LogClassAlert;
                log_type = LogTypeHostDowntimeAlert;
 
@@ -372,6 +384,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                comment = tokens[2];
        }
        else if (boost::algorithm::contains(type, "HOST FLAPPING ALERT")) {
+               if (tokens.size() < 3)
+                       return Dictionary::Ptr();
+
                log_class = LogClassAlert;
                log_type = LogTypeHostFlapping;
 
@@ -380,6 +395,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                comment = tokens[2];
        }
        else if (boost::algorithm::contains(type, "INITIAL SERVICE STATE")) {
+               if (tokens.size() < 6)
+                       return Dictionary::Ptr();
+
                log_class = LogClassState;
                log_type = LogTypeServiceInitialState;
 
@@ -391,6 +409,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                plugin_output = tokens[5];
        }
        else if (boost::algorithm::contains(type, "CURRENT SERVICE STATE")) {
+               if (tokens.size() < 6)
+                       return Dictionary::Ptr();
+
                log_class = LogClassState;
                log_type = LogTypeServiceCurrentState;
 
@@ -402,6 +423,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                plugin_output = tokens[5];
        }
        else if (boost::algorithm::contains(type, "SERVICE ALERT")) {
+               if (tokens.size() < 6)
+                       return Dictionary::Ptr();
+
                log_class = LogClassAlert;
                log_type = LogTypeServiceAlert;
 
@@ -413,6 +437,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                plugin_output = tokens[5];
        }
        else if (boost::algorithm::contains(type, "SERVICE DOWNTIME ALERT")) {
+               if (tokens.size() < 4)
+                       return Dictionary::Ptr();
+
                log_class = LogClassAlert;
                log_type = LogTypeServiceDowntimeAlert;
 
@@ -422,6 +449,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                comment = tokens[3];
        }
        else if (boost::algorithm::contains(type, "SERVICE FLAPPING ALERT")) {
+               if (tokens.size() < 4)
+                       return Dictionary::Ptr();
+
                log_class = LogClassAlert;
                log_type = LogTypeServiceFlapping;
 
@@ -431,6 +461,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                comment = tokens[3];
        }
        else if (boost::algorithm::contains(type, "TIMEPERIOD TRANSITION")) {
+               if (tokens.size() < 4)
+                       return Dictionary::Ptr();
+
                log_class = LogClassState;
                log_type = LogTypeTimeperiodTransition;
 
@@ -441,6 +474,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
        }
        /* Notifications - TODO refactor */
        else if (boost::algorithm::contains(type, "HOST NOTIFICATION")) {
+               if (tokens.size() < 6)
+                       return Dictionary::Ptr();
+
                log_class = LogClassNotification;
                log_type = LogTypeHostNotification;
 
@@ -452,6 +488,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                plugin_output = tokens[5];
        }
        else if (boost::algorithm::contains(type, "SERVICE NOTIFICATION")) {
+               if (tokens.size() < 7)
+                       return Dictionary::Ptr();
+
                log_class = LogClassNotification;
                log_type = LogTypeHostNotification;
 
@@ -465,6 +504,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
        }
        /* Passive Checks - TODO refactor */
        else if (boost::algorithm::contains(type, "PASSIVE HOST CHECK")) {
+               if (tokens.size() < 3)
+                       return Dictionary::Ptr();
+
                log_class = LogClassPassive;
 
                host_name = tokens[0];
@@ -472,6 +514,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
                plugin_output = tokens[2];
        }
        else if (boost::algorithm::contains(type, "PASSIVE SERVICE CHECK")) {
+               if (tokens.size() < 4)
+                       return Dictionary::Ptr();
+
                log_class = LogClassPassive;
 
                host_name = tokens[0];
index f4a9a100ef28059ff1ac98bd5771493144aeb84e..7c0bde33dfa4fb9d5b75c96321c83bdc42acb795 100644 (file)
@@ -59,6 +59,12 @@ Query::Query(const std::vector<String>& lines)
                return;
        }
 
+       String msg;
+       BOOST_FOREACH(const String& line, lines) {
+               msg += line + "\n";
+       }
+       Log(LogDebug, "livestatus", msg);
+
        /* default separators */
        m_Separators.push_back("\n");
        m_Separators.push_back(";");
@@ -253,8 +259,28 @@ int Query::GetExternalCommands(void)
 
 Filter::Ptr Query::ParseFilter(const String& params, unsigned long& from, unsigned long& until)
 {
+       /*
+        * time >= 1382696656
+        * type = SERVICE FLAPPING ALERT
+        */
        std::vector<String> tokens;
-       boost::algorithm::split(tokens, params, boost::is_any_of(" "));
+       size_t sp_index;
+       String temp_buffer = params;
+
+       /* extract attr and op */
+       for (int i = 0; i < 2; i++) {
+               sp_index = temp_buffer.FindFirstOf(" ");
+
+               /* 'attr op' or 'attr op val' is valid */
+               if (i < 1 && sp_index == String::NPos)
+                       BOOST_THROW_EXCEPTION(std::runtime_error("Livestatus filter '" + params + "' does not contain all required fields."));
+
+               tokens.push_back(temp_buffer.SubStr(0, sp_index));
+               temp_buffer = temp_buffer.SubStr(sp_index + 1);
+       }
+       
+       /* add the rest as value */
+       tokens.push_back(temp_buffer);
 
        if (tokens.size() == 2)
                tokens.push_back("");
@@ -262,8 +288,10 @@ Filter::Ptr Query::ParseFilter(const String& params, unsigned long& from, unsign
        if (tokens.size() < 3)
                return Filter::Ptr();
 
-       String op = tokens[1];
        bool negate = false;
+       String attr = tokens[0];
+       String op = tokens[1];
+       String val = tokens[2];
 
        if (op == "!=") {
                op = "=";
@@ -279,19 +307,21 @@ Filter::Ptr Query::ParseFilter(const String& params, unsigned long& from, unsign
                negate = true;
        }
 
-       Filter::Ptr filter = boost::make_shared<AttributeFilter>(tokens[0], op, tokens[2]);
+       Filter::Ptr filter = boost::make_shared<AttributeFilter>(attr, op, val);
 
        if (negate)
                filter = boost::make_shared<NegateFilter>(filter);
 
        /* pre-filter log time duration */
-       if (tokens[0] == "time") {
+       if (attr == "time") {
                if (op == "<" || op == "<=") {
-                       until = Convert::ToLong(tokens[2]);
+                       until = Convert::ToLong(val);
                } else if (op == ">" || op == ">=") {
-                       from = Convert::ToLong(tokens[2]);
+                       from = Convert::ToLong(val);
                }
        }
+       
+       Log(LogDebug, "livestatus", "Parsed filter with attr: '" + attr + "' op: '" + op + "' val: '" + val + "'.");
 
        return filter;
 }
@@ -371,7 +401,7 @@ void Query::ExecuteGetHelper(const Stream::Ptr& stream)
 
        std::vector<Value> objects = table->FilterRows(m_Filter);
        std::vector<String> columns;
-       
+
        if (m_Columns.size() > 0)
                columns = m_Columns;
        else
@@ -399,7 +429,7 @@ void Query::ExecuteGetHelper(const Stream::Ptr& stream)
                        BOOST_FOREACH(const Value& object, objects) {
                                aggregator->Apply(table, object);
                        }
-                       
+
                        stats[index] = aggregator->GetResult();
                        index++;
                }
@@ -434,6 +464,7 @@ void Query::ExecuteCommandHelper(const Stream::Ptr& stream)
 
 void Query::ExecuteErrorHelper(const Stream::Ptr& stream)
 {
+       Log(LogDebug, "livestatus", "ERROR: Code: '" + Convert::ToString(m_ErrorCode) + "' Message: '" + m_ErrorMessage + "'.");
        SendResponse(stream, m_ErrorCode, m_ErrorMessage);
 }