From a11af1767c634661bf590ead6eaeeb392e97f0ff Mon Sep 17 00:00:00 2001 From: Twan van Laarhoven Date: Thu, 30 Apr 2020 14:08:06 +0200 Subject: [PATCH] Fix #6, fix #7: infinite loops/infinite recursion in regex script functions are now "nice" exceptions --- src/script/functions/regex.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/script/functions/regex.cpp b/src/script/functions/regex.cpp index 242ef488..d4a04350 100644 --- a/src/script/functions/regex.cpp +++ b/src/script/functions/regex.cpp @@ -39,7 +39,13 @@ class ScriptRegex : public ScriptValue, public Regex { if (in_context->matches(context_str)) { return true; // the context matches, done } - begin = match.second; // skip + if (begin == match.second) { + // matched empty string, prevent loop + if (begin == str.end()) break; + ++begin; + } else { + begin = match.second; // skip + } } return false; } @@ -121,6 +127,10 @@ SCRIPT_FUNCTION_WITH_SIMPLIFY(replace_text) { replacer.replacement_string = replacer.replacement_function->toString(); replacer.replacement_function = ScriptValueP(); } + if (replacer.replacement_function == script_replace_text) { + // the replace built in function looks like the "replace" parameter, but that would cause a stack overflow. + throw ScriptErrorNoVariable(variable_to_string(SCRIPT_VAR_replace)); + } // run SCRIPT_PARAM_C(String, input); if (replacer.context || replacer.replacement_function || replacer.recursive) { @@ -153,7 +163,14 @@ SCRIPT_FUNCTION_WITH_SIMPLIFY(filter_text) { // match, append to result ScriptRegex::Results::const_reference pos = results[0]; ret.append(pos.first, pos.second); // the match - start = pos.second; + if (pos.second == start) { + // regex matched the empty string, would cause an infinite loop + queue_message(MESSAGE_WARNING, "Regular expression matches empty string in filter_text"); + if (start == input.end()) break; + ++start; + } else { + start = pos.second; + } } SCRIPT_RETURN(ret); }