From a47dc889463d73dd47ad428ac217e3d84f28e242 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@redhat.com>
Date: Mon, 28 Apr 2025 16:03:08 +0000
Subject: [PATCH 1/2] 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>
---
 glib/gstring.c | 36 +++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/glib/gstring.c b/glib/gstring.c
index 5279ed3cca..d79a4849c0 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -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)
     {
-- 
GitLab


From f32f4aea514e39086a2627e9483d841c9eeb9bc3 Mon Sep 17 00:00:00 2001
From: Peter Bloomfield <peterbloomfield@bellsouth.net>
Date: Fri, 11 Apr 2025 05:52:33 +0000
Subject: [PATCH 2/2] gstring: Make len_unsigned unsigned

---
 glib/gstring.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/glib/gstring.c b/glib/gstring.c
index d79a4849c0..2a399ee21f 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -928,7 +928,7 @@ g_string_overwrite_len (GString     *string,
                         const gchar *val,
                         gssize       len)
 {
-  gssize len_unsigned;
+  gsize len_unsigned;
   gsize end;
 
   g_return_val_if_fail (string != NULL, NULL);
-- 
GitLab

