mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-01 03:16:38 +02:00
Merge branch 'gstring_replace_guint' into 'main'
gstring: Support large strings in g_string_replace See merge request GNOME/glib!4790
This commit is contained in:
@@ -1055,7 +1055,12 @@ g_string_erase (GString *string,
|
|||||||
* (beginning of string, end of string and between characters). This did
|
* (beginning of string, end of string and between characters). This did
|
||||||
* not work correctly in earlier versions.
|
* not work correctly in earlier versions.
|
||||||
*
|
*
|
||||||
* Returns: the number of find and replace operations performed.
|
* If @limit is zero and more than `G_MAXUINT` instances of @find are in
|
||||||
|
* the input string, they will all be replaced, but the return value will
|
||||||
|
* be capped at `G_MAXUINT`.
|
||||||
|
*
|
||||||
|
* Returns: the number of find and replace operations performed,
|
||||||
|
* up to `G_MAXUINT`
|
||||||
*
|
*
|
||||||
* Since: 2.68
|
* Since: 2.68
|
||||||
*/
|
*/
|
||||||
@@ -1087,36 +1092,38 @@ g_string_replace (GString *string,
|
|||||||
* handle the case of an empty @find string separately. */
|
* handle the case of an empty @find string separately. */
|
||||||
if (G_UNLIKELY (f_len == 0))
|
if (G_UNLIKELY (f_len == 0))
|
||||||
{
|
{
|
||||||
if (limit == 0 || limit > string->len)
|
size_t r_limit = limit;
|
||||||
|
|
||||||
|
if (r_limit == 0 || r_limit > string->len)
|
||||||
{
|
{
|
||||||
if (string->len > G_MAXSIZE - 1)
|
if (string->len > G_MAXSIZE - 1)
|
||||||
g_error ("inserting in every position in string would overflow");
|
g_error ("inserting in every position in string would overflow");
|
||||||
|
|
||||||
limit = string->len + 1;
|
r_limit = string->len + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r_len > 0 &&
|
if (r_len > 0 &&
|
||||||
(limit > G_MAXSIZE / r_len ||
|
(r_limit > G_MAXSIZE / r_len ||
|
||||||
limit * r_len > G_MAXSIZE - string->len))
|
r_limit * r_len > G_MAXSIZE - string->len))
|
||||||
g_error ("inserting in every position in string would overflow");
|
g_error ("inserting in every position in string would overflow");
|
||||||
|
|
||||||
new_len = string->len + limit * r_len;
|
new_len = string->len + r_limit * r_len;
|
||||||
new_string = g_string_sized_new (new_len);
|
new_string = g_string_sized_new (new_len);
|
||||||
for (size_t i = 0; i < limit; i++)
|
for (size_t i = 0; i < r_limit; i++)
|
||||||
{
|
{
|
||||||
g_string_append_len (new_string, replace, r_len);
|
g_string_append_len (new_string, replace, r_len);
|
||||||
if (i < string->len)
|
if (i < string->len)
|
||||||
g_string_append_c (new_string, string->str[i]);
|
g_string_append_c (new_string, string->str[i]);
|
||||||
}
|
}
|
||||||
if (limit < string->len)
|
if (r_limit < string->len)
|
||||||
g_string_append_len (new_string, string->str + limit, string->len - limit);
|
g_string_append_len (new_string, string->str + r_limit, string->len - r_limit);
|
||||||
|
|
||||||
g_free (string->str);
|
g_free (string->str);
|
||||||
string->allocated_len = new_string->allocated_len;
|
string->allocated_len = new_string->allocated_len;
|
||||||
string->len = new_string->len;
|
string->len = new_string->len;
|
||||||
string->str = g_string_free_and_steal (g_steal_pointer (&new_string));
|
string->str = g_string_free_and_steal (g_steal_pointer (&new_string));
|
||||||
|
|
||||||
return limit;
|
return r_limit > G_MAXUINT ? G_MAXUINT : (guint) r_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Potentially do two passes: the first to calculate the length of the new string,
|
/* Potentially do two passes: the first to calculate the length of the new string,
|
||||||
@@ -1137,6 +1144,7 @@ g_string_replace (GString *string,
|
|||||||
n = 0;
|
n = 0;
|
||||||
while ((next = strstr (cur, find)) != NULL)
|
while ((next = strstr (cur, find)) != NULL)
|
||||||
{
|
{
|
||||||
|
if (n < G_MAXUINT)
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
if (r_len <= f_len)
|
if (r_len <= f_len)
|
||||||
|
Reference in New Issue
Block a user