This is an automated email from the ASF dual-hosted git repository.
tuhaihe pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
The following commit(s) were added to refs/heads/main by this push:
new 7f5c3620ce6 Fix infinite loop in replaceStringInfoString (#1750)
7f5c3620ce6 is described below
commit 7f5c3620ce6499713875b5ea9a259da173dd9e64
Author: Smyatkin Maxim <[email protected]>
AuthorDate: Tue Jul 14 08:37:01 2026 +0300
Fix infinite loop in replaceStringInfoString (#1750)
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 0dbca75f248..52d1e30526c 100644
--- a/src/common/stringinfo.c
+++ b/src/common/stringinfo.c
@@ -361,16 +361,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, because 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]