diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2018-08-16 22:45:42 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2018-08-16 22:45:42 +0200 |
commit | 1a0087a7d7b06b6c63653936127c4f542fc9b5b9 (patch) | |
tree | 16bf655c0d4bbf10d8ccccb3e1c58a0923923c32 | |
parent | ca90f28bebb64a67fcf99fc9b16222ca8c752089 (diff) | |
download | weechat-1a0087a7d7b06b6c63653936127c4f542fc9b5b9.zip |
core: fix string evaluation with regex replacement when the string is empty
-rw-r--r-- | ChangeLog.adoc | 1 | ||||
-rw-r--r-- | src/core/wee-eval.c | 28 | ||||
-rw-r--r-- | tests/unit/core/test-eval.cpp | 12 |
3 files changed, 33 insertions, 8 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc index a1bea3229..837f572fe 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -25,6 +25,7 @@ New features:: Bug fixes:: + * core: fix string evaluation with regex replacement when the string is empty * core: fix check of tags in lines (command /filter and hook_print) * core: fix clear of completion item in case of partial completion (issue #1162) * core: send signal "key_pressed" for mouse code only if the string is UTF-8 valid (issue #1220) diff --git a/src/core/wee-eval.c b/src/core/wee-eval.c index 29ffd2748..fffc07fb0 100644 --- a/src/core/wee-eval.c +++ b/src/core/wee-eval.c @@ -1100,6 +1100,7 @@ eval_replace_regex (const char *string, regex_t *regex, const char *replace, { char *result, *result2, *str_replace; int length, length_replace, start_offset, i, rc, end; + int empty_replace_allowed; struct t_eval_regex eval_regex; if (!string || !regex || !replace) @@ -1114,7 +1115,11 @@ eval_replace_regex (const char *string, regex_t *regex, const char *replace, eval_context->regex = &eval_regex; start_offset = 0; - while (result && result[start_offset]) + + /* we allow one empty replace if input string is empty */ + empty_replace_allowed = (result[0]) ? 0 : 1; + + while (result) { for (i = 0; i < 100; i++) { @@ -1122,16 +1127,20 @@ eval_replace_regex (const char *string, regex_t *regex, const char *replace, } rc = regexec (regex, result + start_offset, 100, eval_regex.match, 0); + + /* no match found: exit the loop */ + if ((rc != 0) || (eval_regex.match[0].rm_so < 0)) + break; + /* - * no match found: exit the loop (if rm_eo == 0, it is an empty match - * at beginning of string: we consider there is no match, to prevent an - * infinite loop) + * if empty string is matching, continue only if empty replace is + * still allowed (to prevent infinite loop) */ - if ((rc != 0) - || (eval_regex.match[0].rm_so < 0) - || (eval_regex.match[0].rm_eo <= 0)) + if (eval_regex.match[0].rm_eo <= 0) { - break; + if (!empty_replace_allowed) + break; + empty_replace_allowed = 0; } /* adjust the start/end offsets */ @@ -1183,6 +1192,9 @@ eval_replace_regex (const char *string, regex_t *regex, const char *replace, break; start_offset = eval_regex.match[0].rm_so + length_replace; + + if (!result[start_offset]) + break; } return result; diff --git a/tests/unit/core/test-eval.cpp b/tests/unit/core/test-eval.cpp index 7fa22969d..742eb99bd 100644 --- a/tests/unit/core/test-eval.cpp +++ b/tests/unit/core/test-eval.cpp @@ -452,6 +452,18 @@ TEST(CoreEval, EvalReplaceRegex) NULL, NULL); CHECK(options); + /* replace regex by empty string (on empty string) */ + hashtable_remove (pointers, "regex"); + hashtable_set (options, "regex", ".*"); + hashtable_set (options, "regex_replace", ""); + WEE_CHECK_EVAL("", ""); + + /* replace regex (on empty string) */ + hashtable_remove (pointers, "regex"); + hashtable_set (options, "regex", ".*"); + hashtable_set (options, "regex_replace", "test"); + WEE_CHECK_EVAL("test", ""); + /* replace regex by empty string */ hashtable_remove (pointers, "regex"); hashtable_set (options, "regex", ".*"); |