mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-17 19:21:58 +02:00
gstring: carefully handle gssize parameters
Wherever we use gssize to allow passing -1, we need to ensure we don't overflow the value by assigning a gsize to it without checking if the size exceeds the maximum gssize. The safest way to do this is to just use normal gsize everywhere instead and use gssize only for the parameter. Our computers don't have enough RAM to write tests for this. I tried forcing string->len to high values for test purposes, but this isn't valid and will just cause out of bounds reads/writes due to string->allocated_len being unexpectedly small, so I don't think we can test this easily. (cherry picked from commit cc647f9e46d55509a93498af19659baf9c80f2e3) Co-authored-by: Michael Catanzaro <mcatanzaro@redhat.com>
This commit is contained in:
parent
7ca5c651bd
commit
a47dc88946
@ -480,8 +480,9 @@ g_string_insert_len (GString *string,
|
||||
return string;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (val);
|
||||
len_unsigned = len;
|
||||
len_unsigned = strlen (val);
|
||||
else
|
||||
len_unsigned = len;
|
||||
|
||||
if (pos < 0)
|
||||
pos_unsigned = string->len;
|
||||
@ -778,10 +779,12 @@ g_string_insert_c (GString *string,
|
||||
g_string_maybe_expand (string, 1);
|
||||
|
||||
if (pos < 0)
|
||||
pos = string->len;
|
||||
pos_unsigned = string->len;
|
||||
else
|
||||
g_return_val_if_fail ((gsize) pos <= string->len, string);
|
||||
pos_unsigned = pos;
|
||||
{
|
||||
pos_unsigned = pos;
|
||||
g_return_val_if_fail (pos_unsigned <= string->len, string);
|
||||
}
|
||||
|
||||
/* If not just an append, move the old stuff */
|
||||
if (pos_unsigned < string->len)
|
||||
@ -814,6 +817,7 @@ g_string_insert_unichar (GString *string,
|
||||
gssize pos,
|
||||
gunichar wc)
|
||||
{
|
||||
gsize pos_unsigned;
|
||||
gint charlen, first, i;
|
||||
gchar *dest;
|
||||
|
||||
@ -855,15 +859,18 @@ g_string_insert_unichar (GString *string,
|
||||
g_string_maybe_expand (string, charlen);
|
||||
|
||||
if (pos < 0)
|
||||
pos = string->len;
|
||||
pos_unsigned = string->len;
|
||||
else
|
||||
g_return_val_if_fail ((gsize) pos <= string->len, string);
|
||||
{
|
||||
pos_unsigned = pos;
|
||||
g_return_val_if_fail (pos_unsigned <= string->len, string);
|
||||
}
|
||||
|
||||
/* If not just an append, move the old stuff */
|
||||
if ((gsize) pos < string->len)
|
||||
memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
|
||||
if (pos_unsigned < string->len)
|
||||
memmove (string->str + pos_unsigned + charlen, string->str + pos_unsigned, string->len - pos_unsigned);
|
||||
|
||||
dest = string->str + pos;
|
||||
dest = string->str + pos_unsigned;
|
||||
/* Code copied from g_unichar_to_utf() */
|
||||
for (i = charlen - 1; i > 0; --i)
|
||||
{
|
||||
@ -921,6 +928,7 @@ g_string_overwrite_len (GString *string,
|
||||
const gchar *val,
|
||||
gssize len)
|
||||
{
|
||||
gssize len_unsigned;
|
||||
gsize end;
|
||||
|
||||
g_return_val_if_fail (string != NULL, NULL);
|
||||
@ -932,14 +940,16 @@ g_string_overwrite_len (GString *string,
|
||||
g_return_val_if_fail (pos <= string->len, string);
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (val);
|
||||
len_unsigned = strlen (val);
|
||||
else
|
||||
len_unsigned = len;
|
||||
|
||||
end = pos + len;
|
||||
end = pos + len_unsigned;
|
||||
|
||||
if (end > string->len)
|
||||
g_string_maybe_expand (string, end - string->len);
|
||||
|
||||
memcpy (string->str + pos, val, len);
|
||||
memcpy (string->str + pos, val, len_unsigned);
|
||||
|
||||
if (end > string->len)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user