File glib2-CVE-2024-34397-add-ref-count-types.patch of Package glib2.35579

diff -urpN glib-2.48.2.orig/docs/reference/glib/glib-docs.xml glib-2.48.2/docs/reference/glib/glib-docs.xml
--- glib-2.48.2.orig/docs/reference/glib/glib-docs.xml	2016-08-17 10:20:46.000000000 -0500
+++ glib-2.48.2/docs/reference/glib/glib-docs.xml	2024-05-17 15:35:01.788445478 -0500
@@ -118,6 +118,7 @@
     <xi:include href="xml/gvariant.xml"/>
     <xi:include href="gvariant-varargs.xml"/>
     <xi:include href="gvariant-text.xml"/>
+    <xi:include href="xml/refcount.xml"/>
   </chapter>
 
   <chapter id="deprecated">
diff -urpN glib-2.48.2.orig/docs/reference/glib/glib-sections.txt glib-2.48.2/docs/reference/glib/glib-sections.txt
--- glib-2.48.2.orig/docs/reference/glib/glib-sections.txt	2024-05-15 16:35:43.252475797 -0500
+++ glib-2.48.2/docs/reference/glib/glib-sections.txt	2024-05-17 15:35:01.791778826 -0500
@@ -3378,3 +3378,18 @@ g_hostname_is_ascii_encoded
 <SUBSECTION>
 g_hostname_is_ip_address
 </SECTION>
+
+<SECTION>
+<FILE>refcount</FILE>
+grefcount
+g_ref_count_init
+g_ref_count_inc
+g_ref_count_dec
+g_ref_count_compare
+<SUBSECTION>
+gatomicrefcount
+g_atomic_ref_count_init
+g_atomic_ref_count_inc
+g_atomic_ref_count_dec
+g_atomic_ref_count_compare
+</SECTION>
diff -urpN glib-2.48.2.orig/glib/glib.h glib-2.48.2/glib/glib.h
--- glib-2.48.2.orig/glib/glib.h	2016-08-17 10:20:47.000000000 -0500
+++ glib-2.48.2/glib/glib.h	2024-05-17 15:35:01.791778826 -0500
@@ -69,6 +69,7 @@
 #include <glib/gquark.h>
 #include <glib/gqueue.h>
 #include <glib/grand.h>
+#include <glib/grefcount.h>
 #include <glib/gregex.h>
 #include <glib/gscanner.h>
 #include <glib/gsequence.h>
diff -urpN glib-2.48.2.orig/glib/grefcount.c glib-2.48.2/glib/grefcount.c
--- glib-2.48.2.orig/glib/grefcount.c	1969-12-31 18:00:00.000000000 -0600
+++ glib-2.48.2/glib/grefcount.c	2024-05-17 15:35:01.795112174 -0500
@@ -0,0 +1,285 @@
+/* grefcount.c: Reference counting
+ *
+ * Copyright 2018  Emmanuele Bassi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:refcount
+ * @Title: Reference counting
+ * @Short_description: Reference counting types and functions
+ *
+ * Reference counting is a garbage collection mechanism that is based on
+ * assigning a counter to a data type, or any memory area; the counter is
+ * increased whenever a new reference to that data type is acquired, and
+ * decreased whenever the reference is released. Once the last reference
+ * is released, the resources associated to that data type are freed.
+ *
+ * GLib uses reference counting in many of its data types, and provides
+ * the #grefcount and #gatomicrefcount types to implement safe and atomic
+ * reference counting semantics in new data types.
+ *
+ * It is important to note that #grefcount and #gatomicrefcount should be
+ * considered completely opaque types; you should always use the provided
+ * API to increase and decrease the counters, and you should never check
+ * their content directly, or compare their content with other values.
+ *
+ * Since: 2.48
+ */
+
+#include "config.h"
+
+#include "grefcount.h"
+
+#include "gatomic.h"
+#include "gmessages.h"
+
+/**
+ * grefcount:
+ *
+ * A type for implementing non-atomic reference count semantics.
+ *
+ * Use g_ref_count_init() to initialize it; g_ref_count_inc() to
+ * increase the counter, and g_ref_count_dec() to decrease it.
+ *
+ * It is safe to use #grefcount only if you're expecting to operate
+ * on the reference counter from a single thread. It is entirely up
+ * to you to ensure that all reference count changes happen in the
+ * same thread.
+ *
+ * See also: #gatomicrefcount
+ *
+ * Since: 2.48
+ */
+
+/**
+ * gatomicrefcount:
+ *
+ * A type for implementing atomic reference count semantics.
+ *
+ * Use g_atomic_ref_count_init() to initialize it; g_atomic_ref_count_inc()
+ * to increase the counter, and g_atomic_ref_count_dec() to decrease it.
+ *
+ * It is safe to use #gatomicrefcount if you're expecting to operate on the
+ * reference counter from multiple threads.
+ *
+ * See also: #grefcount
+ *
+ * Since: 2.48
+ */
+
+/**
+ * g_ref_count_init:
+ * @rc: the address of a reference count variable
+ *
+ * Initializes a reference count variable.
+ *
+ * Since: 2.48
+ */
+void
+g_ref_count_init (grefcount *rc)
+{
+  g_return_if_fail (rc != NULL);
+
+  /* Non-atomic refcounting is implemented using the negative range
+   * of signed integers:
+   *
+   * G_MININT                 Z¯< 0 > Z⁺                G_MAXINT
+   * |----------------------------|----------------------------|
+   *
+   * Acquiring a reference moves us towards MININT, and releasing a
+   * reference moves us towards 0.
+   */
+  *rc = -1;
+}
+
+/**
+ * g_ref_count_inc:
+ * @rc: the address of a reference count variable
+ *
+ * Increases the reference count.
+ *
+ * Since: 2.48
+ */
+void
+g_ref_count_inc (grefcount *rc)
+{
+  grefcount rrc;
+
+  g_return_if_fail (rc != NULL);
+
+  rrc = *rc;
+
+  g_return_if_fail (rrc < 0);
+
+  /* Check for saturation */
+  if (rrc == G_MININT)
+    {
+      g_critical ("Reference count %p has reached saturation", rc);
+      return;
+    }
+
+  rrc -= 1;
+
+  *rc = rrc;
+}
+
+/**
+ * g_ref_count_dec:
+ * @rc: the address of a reference count variable
+ *
+ * Decreases the reference count.
+ *
+ * Returns: %TRUE if the reference count reached 0, and %FALSE otherwise
+ *
+ * Since: 2.48
+ */
+gboolean
+g_ref_count_dec (grefcount *rc)
+{
+  grefcount rrc;
+
+  g_return_val_if_fail (rc != NULL, FALSE);
+
+  rrc = *rc;
+
+  g_return_val_if_fail (rrc < 0, FALSE);
+
+  rrc += 1;
+  if (rrc == 0)
+    return TRUE;
+
+  *rc = rrc;
+
+  return FALSE;
+}
+
+/**
+ * g_ref_count_compare:
+ * @rc: the address of a reference count variable
+ * @val: the value to compare
+ *
+ * Compares the current value of @rc with @val.
+ *
+ * Returns: %TRUE if the reference count is the same
+ *   as the given value
+ *
+ * Since: 2.48
+ */
+gboolean
+g_ref_count_compare (grefcount *rc,
+                     gint       val)
+{
+  grefcount rrc;
+
+  g_return_val_if_fail (rc != NULL, FALSE);
+  g_return_val_if_fail (val >= 0, FALSE);
+
+  rrc = *rc;
+
+  if (val == G_MAXINT)
+    return rrc == G_MININT;
+
+  return rrc == -val;
+}
+
+/**
+ * g_atomic_ref_count_init:
+ * @arc: the address of an atomic reference count variable
+ *
+ * Atomically initializes a reference count variable.
+ *
+ * Since: 2.48
+ */
+void
+g_atomic_ref_count_init (gatomicrefcount *arc)
+{
+  g_return_if_fail (arc != NULL);
+
+  /* Atomic refcounting is implemented using the positive range
+   * of signed integers:
+   *
+   * G_MININT                 Z¯< 0 > Z⁺                G_MAXINT
+   * |----------------------------|----------------------------|
+   *
+   * Acquiring a reference moves us towards MAXINT, and releasing a
+   * reference moves us towards 0.
+   */
+  g_atomic_int_set (arc, 1);
+}
+
+/**
+ * g_atomic_ref_count_inc:
+ * @arc: the address of an atomic reference count variable
+ *
+ * Atomically increases the reference count.
+ *
+ * Since: 2.48
+ */
+void
+g_atomic_ref_count_inc (gatomicrefcount *arc)
+{
+  g_return_if_fail (arc != NULL);
+  g_return_if_fail (g_atomic_int_get (arc) > 0);
+
+  if (g_atomic_int_get (arc) == G_MAXINT)
+    {
+      g_critical ("Reference count has reached saturation");
+      return;
+    }
+
+  g_atomic_int_inc (arc);
+}
+
+/**
+ * g_atomic_ref_count_dec:
+ * @arc: the address of an atomic reference count variable
+ *
+ * Atomically decreases the reference count.
+ *
+ * Returns: %TRUE if the reference count reached 0, and %FALSE otherwise
+ *
+ * Since: 2.48
+ */
+gboolean
+g_atomic_ref_count_dec (gatomicrefcount *arc)
+{
+  g_return_val_if_fail (arc != NULL, FALSE);
+  g_return_val_if_fail (g_atomic_int_get (arc) > 0, FALSE);
+
+  return g_atomic_int_dec_and_test (arc);
+}
+
+/**
+ * g_atomic_ref_count_compare:
+ * @arc: the address of an atomic reference count variable
+ * @val: the value to compare
+ *
+ * Atomically compares the current value of @arc with @val.
+ *
+ * Returns: %TRUE if the reference count is the same
+ *   as the given value
+ *
+ * Since: 2.48
+ */
+gboolean
+g_atomic_ref_count_compare (gatomicrefcount *arc,
+                            gint             val)
+{
+  g_return_val_if_fail (arc != NULL, FALSE);
+  g_return_val_if_fail (val >= 0, FALSE);
+
+  return g_atomic_int_get (arc) == val;
+}
diff -urpN glib-2.48.2.orig/glib/grefcount.h glib-2.48.2/glib/grefcount.h
--- glib-2.48.2.orig/glib/grefcount.h	1969-12-31 18:00:00.000000000 -0600
+++ glib-2.48.2/glib/grefcount.h	2024-05-17 15:35:01.795112174 -0500
@@ -0,0 +1,52 @@
+/* grefcount.h: Reference counting
+ *
+ * Copyright 2018  Emmanuele Bassi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GREFCOUNT_H__
+#define __GREFCOUNT_H__
+
+#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+GLIB_AVAILABLE_IN_2_48
+void            g_ref_count_init                (grefcount       *rc);
+GLIB_AVAILABLE_IN_2_48
+void            g_ref_count_inc                 (grefcount       *rc);
+GLIB_AVAILABLE_IN_2_48
+gboolean        g_ref_count_dec                 (grefcount       *rc);
+GLIB_AVAILABLE_IN_2_48
+gboolean        g_ref_count_compare             (grefcount       *rc,
+                                                 gint             val);
+
+GLIB_AVAILABLE_IN_2_48
+void            g_atomic_ref_count_init         (gatomicrefcount *arc);
+GLIB_AVAILABLE_IN_2_48
+void            g_atomic_ref_count_inc          (gatomicrefcount *arc);
+GLIB_AVAILABLE_IN_2_48
+gboolean        g_atomic_ref_count_dec          (gatomicrefcount *arc);
+GLIB_AVAILABLE_IN_2_48
+gboolean        g_atomic_ref_count_compare      (gatomicrefcount *arc,
+                                                 gint             val);
+
+G_END_DECLS
+
+#endif /* __GREFCOUNT_H__ */
diff -urpN glib-2.48.2.orig/glib/gtypes.h glib-2.48.2/glib/gtypes.h
--- glib-2.48.2.orig/glib/gtypes.h	2016-08-17 10:20:47.000000000 -0500
+++ glib-2.48.2/glib/gtypes.h	2024-05-17 15:35:01.795112174 -0500
@@ -509,6 +509,9 @@ struct _GTimeVal
   glong tv_usec;
 };
 
+typedef gint            grefcount;
+typedef volatile gint   gatomicrefcount;
+
 G_END_DECLS
 
 /* We prefix variable declarations so they can
diff -urpN glib-2.48.2.orig/glib/Makefile.am glib-2.48.2/glib/Makefile.am
--- glib-2.48.2.orig/glib/Makefile.am	2024-05-15 16:37:38.423344066 -0500
+++ glib-2.48.2/glib/Makefile.am	2024-05-17 15:35:01.791778826 -0500
@@ -155,6 +155,7 @@ libglib_2_0_la_SOURCES = 	\
 	gquark.c		\
 	gqueue.c		\
 	grand.c			\
+	grefcount.c		\
 	gregex.c		\
 	gscanner.c		\
 	gscripttable.h		\
@@ -289,6 +290,7 @@ glibsubinclude_HEADERS = \
 	gquark.h	\
 	gqueue.h	\
 	grand.h		\
+	grefcount.h	\
 	gregex.h	\
 	gscanner.h	\
 	gsequence.h	\
openSUSE Build Service is sponsored by