From 404b7affff5cee96577eab4526148278ead004fe Mon Sep 17 00:00:00 2001 From: TD-er Date: Sat, 11 Dec 2021 17:49:13 +0100 Subject: [PATCH 1/2] [dashboard] Fix crash on parsing empty command {} (#3873) Fixes: #3873 --- src/src/ESPEasyCore/ESPEasyRules.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/src/ESPEasyCore/ESPEasyRules.cpp b/src/src/ESPEasyCore/ESPEasyRules.cpp index 7d0c1d81c..e76af0bcb 100644 --- a/src/src/ESPEasyCore/ESPEasyRules.cpp +++ b/src/src/ESPEasyCore/ESPEasyRules.cpp @@ -373,7 +373,11 @@ bool check_rules_line_user_errors(String& line) \*********************************************************************************************/ bool get_next_inner_bracket(const String& line, int& startIndex, int& closingIndex, char closingBracket) { - char openingBracket = closingIndex; + if (line.length() <= 1) { + // Not possible to have opening and closing bracket on a line this short. + return false; + } + char openingBracket = closingBracket; switch (closingBracket) { case ']': openingBracket = '['; break; @@ -383,11 +387,15 @@ bool get_next_inner_bracket(const String& line, int& startIndex, int& closingInd // unknown bracket type return false; } - closingIndex = line.indexOf(closingBracket); + // Closing bracket should not be found on the first position. + closingIndex = line.indexOf(closingBracket, 1); - if (closingIndex == -1) { return false; } + if (closingIndex == -1) { + // not found + return false; + } - for (int i = closingIndex; i >= 0; --i) { + for (int i = (closingIndex - 1); i >= 0; --i) { if (line[i] == openingBracket) { startIndex = i; return true; @@ -552,8 +560,8 @@ void parse_string_commands(String& line) { String arg2 = parseStringKeepCase(fullCommand, 3, ':'); String arg3 = parseStringKeepCase(fullCommand, 4, ':'); + String replacement; // maybe just replace with empty to avoid looping? if (cmd_s_lower.length() > 0) { - String replacement; // maybe just replace with empty to avoid looping? // addLog(LOG_LEVEL_INFO, String(F("parse_string_commands cmd: ")) + cmd_s_lower + " " + arg1 + " " + arg2 + " " + arg3); uint64_t iarg1, iarg2 = 0; @@ -635,15 +643,14 @@ void parse_string_commands(String& line) { replacement.replace('}', static_cast(0x03)); } - // Replace the full command including opening and closing brackets. - line.replace(line.substring(startIndex, closingIndex + 1), replacement); - /* if (replacement.length() > 0) { addLog(LOG_LEVEL_INFO, String(F("parse_string_commands cmd: ")) + fullCommand + String(F(" -> ")) + replacement); } */ } + // Replace the full command including opening and closing brackets. + line.replace(line.substring(startIndex, closingIndex + 1), replacement); } // We now have to check if we did mask some parts and unmask them. From 079744f9dd344d43e1f140da63725e5ca5fe1d62 Mon Sep 17 00:00:00 2001 From: TD-er Date: Sat, 11 Dec 2021 22:27:10 +0100 Subject: [PATCH 2/2] [dashboard] Fix parsing {} and leaving the braces when not a command See: https://github.com/letscontrolit/ESPEasy/issues/3873#issuecomment-991730910 --- src/src/ESPEasyCore/ESPEasyRules.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/src/ESPEasyCore/ESPEasyRules.cpp b/src/src/ESPEasyCore/ESPEasyRules.cpp index e76af0bcb..1e31dc72c 100644 --- a/src/src/ESPEasyCore/ESPEasyRules.cpp +++ b/src/src/ESPEasyCore/ESPEasyRules.cpp @@ -388,14 +388,14 @@ bool get_next_inner_bracket(const String& line, int& startIndex, int& closingInd return false; } // Closing bracket should not be found on the first position. - closingIndex = line.indexOf(closingBracket, 1); + closingIndex = line.indexOf(closingBracket, startIndex + 1); if (closingIndex == -1) { // not found return false; } - for (int i = (closingIndex - 1); i >= 0; --i) { + for (int i = (closingIndex - 1); i > startIndex; --i) { if (line[i] == openingBracket) { startIndex = i; return true; @@ -550,7 +550,8 @@ bool parse_math_functions(const String& cmd_s_lower, const String& arg1, const S } void parse_string_commands(String& line) { - int startIndex, closingIndex; + int startIndex = 0; + int closingIndex; while (get_next_inner_bracket(line, startIndex, closingIndex, '}')) { // Command without opening and closing brackets. @@ -560,8 +561,8 @@ void parse_string_commands(String& line) { String arg2 = parseStringKeepCase(fullCommand, 3, ':'); String arg3 = parseStringKeepCase(fullCommand, 4, ':'); - String replacement; // maybe just replace with empty to avoid looping? if (cmd_s_lower.length() > 0) { + String replacement; // maybe just replace with empty to avoid looping? // addLog(LOG_LEVEL_INFO, String(F("parse_string_commands cmd: ")) + cmd_s_lower + " " + arg1 + " " + arg2 + " " + arg3); uint64_t iarg1, iarg2 = 0; @@ -643,14 +644,15 @@ void parse_string_commands(String& line) { replacement.replace('}', static_cast(0x03)); } + // Replace the full command including opening and closing brackets. + line.replace(line.substring(startIndex, closingIndex + 1), replacement); + /* if (replacement.length() > 0) { addLog(LOG_LEVEL_INFO, String(F("parse_string_commands cmd: ")) + fullCommand + String(F(" -> ")) + replacement); } */ } - // Replace the full command including opening and closing brackets. - line.replace(line.substring(startIndex, closingIndex + 1), replacement); } // We now have to check if we did mask some parts and unmask them.