This is an automated email from the ASF dual-hosted git repository. yjhjstz pushed a commit to branch string_replace_fix in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 28a4066fdee2bf91045f4a863e22a08200881ec8 Author: Maxim Smyatkin <[email protected]> AuthorDate: Sat May 16 21:19:06 2026 +0300 Fix infinite loops in replaceStringInfoString The function had a few problems: - replace ="a" and replacement="ab" would give an infinite loop leading to OOM. We have a similar case in pg_dump: replace="range", replacement="multirange" - Copying the whole string each time there is a match - Empty replace pattern also leads to infinite loop We can still do better: for example count number of matches and do a single allocation, or even run the replacement inplace. But it's probably not worth it. --- src/common/stringinfo.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/common/stringinfo.c b/src/common/stringinfo.c index f177516c26f..e458f821a0c 100644 --- a/src/common/stringinfo.c +++ b/src/common/stringinfo.c @@ -364,16 +364,32 @@ enlargeStringInfo(StringInfo str, int needed) void replaceStringInfoString(StringInfo str, char *replace, char *replacement) { - char *ptr; + char *match_ptr = NULL; + char *start_ptr = str->data; + char *dup = NULL; + size_t replace_len = strlen(replace); - while ((ptr = strstr(str->data, replace)) != NULL) - { - char *dup = pstrdup(str->data); + // prevent empty loop, cuz strstr will always return start_ptr + if (replace_len == 0) + return; - resetStringInfo(str); - appendBinaryStringInfo(str, dup, ptr - str->data); + while ((match_ptr = strstr(start_ptr, replace)) != NULL) + { + if (dup == NULL) + { + dup = pstrdup(str->data); + start_ptr = dup; + match_ptr = dup + (match_ptr - str->data); + resetStringInfo(str); + } + + appendBinaryStringInfo(str, start_ptr, match_ptr - start_ptr); appendStringInfoString(str, replacement); - appendStringInfoString(str, dup + (ptr - str->data) + strlen(replace)); + start_ptr = match_ptr + replace_len; + } + if (dup != NULL) + { + appendStringInfoString(str, start_ptr); pfree(dup); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
