File glib2-CVE-2026-1489.patch of Package glib2.42479

diff -urp glib-2.62.6.orig/glib/guniprop.c glib-2.62.6/glib/guniprop.c
--- glib-2.62.6.orig/glib/guniprop.c	2020-03-18 08:16:11.000000000 -0500
+++ glib-2.62.6/glib/guniprop.c	2026-01-27 16:36:12.873445041 -0600
@@ -746,14 +746,36 @@ get_locale_type (void)
   return LOCALE_NORMAL;
 }
 
-static gint
-output_marks (const char **p_inout,
-	      char        *out_buffer,
-	      gboolean     remove_dot)
+__attribute__ ((__always_inline__)) static inline void
+increase_size (size_t *sizeptr, size_t add)
+{
+  g_assert (G_MAXSIZE - *(sizeptr) >= add);
+  *(sizeptr) += add;
+}
+
+__attribute__ ((__always_inline__)) static inline void
+append_utf8_char_to_buffer (gunichar  c,
+                            char     *out_buffer,
+                            size_t   *in_out_len)
+{
+  gint utf8_len;
+  char *buffer;
+
+  buffer = out_buffer ? out_buffer + *(in_out_len) : NULL;
+  utf8_len = g_unichar_to_utf8 (c, buffer);
+
+  g_assert (utf8_len >= 0);
+  increase_size (in_out_len, utf8_len);
+}
+
+static void
+append_mark (const char **p_inout,
+             char        *out_buffer,
+             size_t      *in_out_len,
+             gboolean     remove_dot)
 {
   const char *p = *p_inout;
-  gint len = 0;
-  
+
   while (*p)
     {
       gunichar c = g_utf8_get_char (p);
@@ -761,7 +783,7 @@ output_marks (const char **p_inout,
       if (ISMARK (TYPE (c)))
 	{
 	  if (!remove_dot || c != 0x307 /* COMBINING DOT ABOVE */)
-	    len += g_unichar_to_utf8 (c, out_buffer ? out_buffer + len : NULL);
+            append_utf8_char_to_buffer (c, out_buffer, in_out_len);
 	  p = g_utf8_next_char (p);
 	}
       else
@@ -769,14 +791,14 @@ output_marks (const char **p_inout,
     }
 
   *p_inout = p;
-  return len;
 }
 
-static gint
-output_special_case (gchar *out_buffer,
-		     int    offset,
-		     int    type,
-		     int    which)
+static void
+append_special_case (char   *out_buffer,
+                     size_t *in_out_len,
+                     int     offset,
+                     int     type,
+                     int     which)
 {
   const gchar *p = special_case_table + offset;
   gint len;
@@ -788,10 +810,12 @@ output_special_case (gchar *out_buffer,
     p += strlen (p) + 1;
 
   len = strlen (p);
+  g_assert (len < G_MAXSIZE - *in_out_len);
+
   if (out_buffer)
-    memcpy (out_buffer, p, len);
+    memcpy (out_buffer + *in_out_len, p, len);
 
-  return len;
+  increase_size (in_out_len, len);
 }
 
 static gsize
@@ -832,11 +856,13 @@ real_toupper (const gchar *str,
 		  decomp_len = g_unichar_fully_decompose (c, FALSE, decomp, G_N_ELEMENTS (decomp));
 		  for (i=0; i < decomp_len; i++)
 		    {
+
 		      if (decomp[i] != 0x307 /* COMBINING DOT ABOVE */)
-			len += g_unichar_to_utf8 (g_unichar_toupper (decomp[i]), out_buffer ? out_buffer + len : NULL);
+                        append_utf8_char_to_buffer (g_unichar_toupper (decomp[i]),
+                                                    out_buffer, &len);
 		    }
-		  
-		  len += output_marks (&p, out_buffer ? out_buffer + len : NULL, TRUE);
+
+                  append_mark (&p, out_buffer, &len, TRUE);
 
 		  continue;
 		}
@@ -849,17 +875,17 @@ real_toupper (const gchar *str,
       if (locale_type == LOCALE_TURKIC && c == 'i')
 	{
 	  /* i => LATIN CAPITAL LETTER I WITH DOT ABOVE */
-	  len += g_unichar_to_utf8 (0x130, out_buffer ? out_buffer + len : NULL); 
+          append_utf8_char_to_buffer (0x130, out_buffer, &len);
 	}
       else if (c == 0x0345)	/* COMBINING GREEK YPOGEGRAMMENI */
 	{
 	  /* Nasty, need to move it after other combining marks .. this would go away if
 	   * we normalized first.
 	   */
-	  len += output_marks (&p, out_buffer ? out_buffer + len : NULL, FALSE);
+          append_mark (&p, out_buffer, &len, TRUE);
 
 	  /* And output as GREEK CAPITAL LETTER IOTA */
-	  len += g_unichar_to_utf8 (0x399, out_buffer ? out_buffer + len : NULL); 	  
+          append_utf8_char_to_buffer (0x399, out_buffer, &len);
 	}
       else if (IS (t,
 		   OR (G_UNICODE_LOWERCASE_LETTER,
@@ -870,8 +896,8 @@ real_toupper (const gchar *str,
 
 	  if (val >= 0x1000000)
 	    {
-	      len += output_special_case (out_buffer ? out_buffer + len : NULL, val - 0x1000000, t,
-					  t == G_UNICODE_LOWERCASE_LETTER ? 0 : 1);
+              append_special_case (out_buffer, &len, val - 0x1000000, t,
+                                   t == G_UNICODE_LOWERCASE_LETTER ? 0 : 1);
 	    }
 	  else
 	    {
@@ -891,7 +917,7 @@ real_toupper (const gchar *str,
 	      /* Some lowercase letters, e.g., U+000AA, FEMININE ORDINAL INDICATOR,
 	       * do not have an uppercase equivalent, in which case val will be
 	       * zero. */
-	      len += g_unichar_to_utf8 (val ? val : c, out_buffer ? out_buffer + len : NULL);
+              append_utf8_char_to_buffer (val ? val : c, out_buffer, &len);
 	    }
 	}
       else
@@ -901,7 +927,7 @@ real_toupper (const gchar *str,
 	  if (out_buffer)
 	    memcpy (out_buffer + len, last, char_len);
 
-	  len += char_len;
+          increase_size (&len, char_len);
 	}
 
     }
@@ -939,6 +965,8 @@ g_utf8_strup (const gchar *str,
    * We use a two pass approach to keep memory management simple
    */
   result_len = real_toupper (str, len, NULL, locale_type);
+  g_assert (result_len < G_MAXSIZE);
+
   result = g_malloc (result_len + 1);
   real_toupper (str, len, result, locale_type);
   result[result_len] = '\0';
@@ -993,13 +1021,13 @@ real_tolower (const gchar *str,
           if (g_utf8_get_char (p) == 0x0307)
             {
               /* I + COMBINING DOT ABOVE => i (U+0069) */
-              len += g_unichar_to_utf8 (0x0069, out_buffer ? out_buffer + len : NULL); 
+              append_utf8_char_to_buffer (0x0069, out_buffer, &len);
               p = g_utf8_next_char (p);
             }
           else
             {
               /* I => LATIN SMALL LETTER DOTLESS I */
-              len += g_unichar_to_utf8 (0x131, out_buffer ? out_buffer + len : NULL); 
+              append_utf8_char_to_buffer (0x131, out_buffer, &len);
             }
         }
       /* Introduce an explicit dot above when lowercasing capital I's and J's
@@ -1007,19 +1035,19 @@ real_tolower (const gchar *str,
       else if (locale_type == LOCALE_LITHUANIAN && 
                (c == 0x00cc || c == 0x00cd || c == 0x0128))
         {
-          len += g_unichar_to_utf8 (0x0069, out_buffer ? out_buffer + len : NULL); 
-          len += g_unichar_to_utf8 (0x0307, out_buffer ? out_buffer + len : NULL); 
+          append_utf8_char_to_buffer (0x0069, out_buffer, &len);
+          append_utf8_char_to_buffer (0x0307, out_buffer, &len);
 
           switch (c)
             {
             case 0x00cc: 
-              len += g_unichar_to_utf8 (0x0300, out_buffer ? out_buffer + len : NULL); 
+              append_utf8_char_to_buffer (0x0300, out_buffer, &len);
               break;
             case 0x00cd: 
-              len += g_unichar_to_utf8 (0x0301, out_buffer ? out_buffer + len : NULL); 
+              append_utf8_char_to_buffer (0x0301, out_buffer, &len);
               break;
             case 0x0128: 
-              len += g_unichar_to_utf8 (0x0303, out_buffer ? out_buffer + len : NULL); 
+              append_utf8_char_to_buffer (0x0303, out_buffer, &len);
               break;
             }
         }
@@ -1028,8 +1056,8 @@ real_tolower (const gchar *str,
                 c == 'J' || c == G_UNICHAR_FULLWIDTH_J || c == 0x012e) &&
                has_more_above (p))
         {
-          len += g_unichar_to_utf8 (g_unichar_tolower (c), out_buffer ? out_buffer + len : NULL); 
-          len += g_unichar_to_utf8 (0x0307, out_buffer ? out_buffer + len : NULL); 
+          append_utf8_char_to_buffer (g_unichar_tolower (c), out_buffer, &len);
+          append_utf8_char_to_buffer (0x0307, out_buffer, &len);
         }
       else if (c == 0x03A3)	/* GREEK CAPITAL LETTER SIGMA */
 	{
@@ -1052,7 +1080,7 @@ real_tolower (const gchar *str,
 	  else
 	    val = 0x3c2;	/* GREEK SMALL FINAL SIGMA */
 
-	  len += g_unichar_to_utf8 (val, out_buffer ? out_buffer + len : NULL);
+          append_utf8_char_to_buffer (val, out_buffer, &len);
 	}
       else if (IS (t,
 		   OR (G_UNICODE_UPPERCASE_LETTER,
@@ -1063,7 +1091,7 @@ real_tolower (const gchar *str,
 
 	  if (val >= 0x1000000)
 	    {
-	      len += output_special_case (out_buffer ? out_buffer + len : NULL, val - 0x1000000, t, 0);
+              append_special_case (out_buffer, &len, val - 0x1000000, t, 0);
 	    }
 	  else
 	    {
@@ -1082,7 +1110,7 @@ real_tolower (const gchar *str,
 
 	      /* Not all uppercase letters are guaranteed to have a lowercase
 	       * equivalent.  If this is the case, val will be zero. */
-	      len += g_unichar_to_utf8 (val ? val : c, out_buffer ? out_buffer + len : NULL);
+              append_utf8_char_to_buffer (val ? val : c, out_buffer, &len);
 	    }
 	}
       else
@@ -1092,7 +1120,7 @@ real_tolower (const gchar *str,
 	  if (out_buffer)
 	    memcpy (out_buffer + len, last, char_len);
 
-	  len += char_len;
+          increase_size (&len, char_len);
 	}
 
     }
@@ -1129,6 +1157,8 @@ g_utf8_strdown (const gchar *str,
    * We use a two pass approach to keep memory management simple
    */
   result_len = real_tolower (str, len, NULL, locale_type);
+  g_assert (result_len < G_MAXSIZE);
+
   result = g_malloc (result_len + 1);
   real_tolower (str, len, result, locale_type);
   result[result_len] = '\0';
openSUSE Build Service is sponsored by