[glib: 10/11] gobject/gsignalgroup: fix memory leaks on error




commit bb890b57d210701d4cab70f625121f2d0741d12c
Author: Marc-André Lureau <marcandre lureau redhat com>
Date:   Tue May 17 15:21:53 2022 +0200

    gobject/gsignalgroup: fix memory leaks on error
    
    Spotted by ASAN during the tests:
    
    Direct leak of 72 byte(s) in 1 object(s) allocated from:
        #0 0x7ff0b4562077 in calloc (/lib64/libasan.so.8+0xba077)
        #1 0x7ff0b3e8b508 in g_malloc0 ../glib/gmem.c:155
        #2 0x7ff0b375052f in g_closure_new_simple ../gobject/gclosure.c:220
        #3 0x7ff0b375b422 in g_cclosure_new ../gobject/gclosure.c:976
        #4 0x7ff0b37d159e in g_signal_group_connect_full ../gobject/gsignalgroup.c:790
        #5 0x7ff0b37d159e in g_signal_group_connect ../gobject/gsignalgroup.c:886
        #6 0x4045d8 in test_signal_group_invalid ../gobject/tests/signalgroup.c:331
        #7 0x7ff0b3f369a5 in test_case_run ../glib/gtestutils.c:2930
        #8 0x7ff0b3f369a5 in g_test_run_suite_internal ../glib/gtestutils.c:3018
        #9 0x7ff0b3f364ed in g_test_run_suite_internal ../glib/gtestutils.c:3035
        #10 0x7ff0b3f364ed in g_test_run_suite_internal ../glib/gtestutils.c:3035
        #11 0x7ff0b3f37879 in g_test_run_suite ../glib/gtestutils.c:3112
        #12 0x7ff0b3f37995 in g_test_run ../glib/gtestutils.c:2231
        #13 0x40253c in main ../gobject/tests/signalgroup.c:664
        #14 0x7ff0b2de758f in __libc_start_call_main (/lib64/libc.so.6+0x2d58f)
    
    Direct leak of 72 byte(s) in 1 object(s) allocated from:
        #0 0x7f012addf077 in calloc (/lib64/libasan.so.8+0xba077)
        #1 0x7f012a708508 in g_malloc0 ../glib/gmem.c:155
        #2 0x7f0129fcd52f in g_closure_new_simple ../gobject/gclosure.c:220
        #3 0x7f0129fd8422 in g_cclosure_new ../gobject/gclosure.c:976
        #4 0x7f012a04e5ae in g_signal_group_connect_full ../gobject/gsignalgroup.c:791
        #5 0x7f012a04e5ae in g_signal_group_connect ../gobject/gsignalgroup.c:887
        #6 0x4043cc in test_signal_group_invalid ../gobject/tests/signalgroup.c:308
        #7 0x7f012a7b39a5 in test_case_run ../glib/gtestutils.c:2930
        #8 0x7f012a7b39a5 in g_test_run_suite_internal ../glib/gtestutils.c:3018
        #9 0x7f012a7b34ed in g_test_run_suite_internal ../glib/gtestutils.c:3035
        #10 0x7f012a7b34ed in g_test_run_suite_internal ../glib/gtestutils.c:3035
        #11 0x7f012a7b4879 in g_test_run_suite ../glib/gtestutils.c:3112
        #12 0x7f012a7b4995 in g_test_run ../glib/gtestutils.c:2231
        #13 0x40253c in main ../gobject/tests/signalgroup.c:664
        #14 0x7f012966458f in __libc_start_call_main (/lib64/libc.so.6+0x2d58f)
    
    Signed-off-by: Marc-André Lureau <marcandre lureau redhat com>

 gobject/gsignalgroup.c | 69 +++++++++++++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 29 deletions(-)
---
diff --git a/gobject/gsignalgroup.c b/gobject/gsignalgroup.c
index 01a0a12c8b..e773fc040d 100644
--- a/gobject/gsignalgroup.c
+++ b/gobject/gsignalgroup.c
@@ -705,36 +705,22 @@ g_signal_group_new (GType target_type)
                        NULL);
 }
 
-/**
- * g_signal_group_connect_closure:
- * @self: a #GSignalGroup
- * @detailed_signal: a string of the form `signal-name` with optional `::signal-detail`
- * @closure: (not nullable): the closure to connect.
- * @after: whether the handler should be called before or after the
- *  default handler of the signal.
- *
- * Connects @closure to the signal @detailed_signal on #GSignalGroup:target.
- *
- * You cannot connect a signal handler after #GSignalGroup:target has been set.
- *
- * Since: 2.74
- */
-void
-g_signal_group_connect_closure (GSignalGroup   *self,
-                                const gchar    *detailed_signal,
-                                GClosure       *closure,
-                                gboolean        after)
+static gboolean
+g_signal_group_connect_closure_ (GSignalGroup   *self,
+                                 const gchar    *detailed_signal,
+                                 GClosure       *closure,
+                                 gboolean        after)
 {
   GObject *target;
   SignalHandler *handler;
   guint signal_id;
   GQuark signal_detail;
 
-  g_return_if_fail (G_IS_SIGNAL_GROUP (self));
-  g_return_if_fail (detailed_signal != NULL);
-  g_return_if_fail (g_signal_parse_name (detailed_signal, self->target_type,
-                                         &signal_id, &signal_detail, TRUE) != 0);
-  g_return_if_fail (closure != NULL);
+  g_return_val_if_fail (G_IS_SIGNAL_GROUP (self), FALSE);
+  g_return_val_if_fail (detailed_signal != NULL, FALSE);
+  g_return_val_if_fail (g_signal_parse_name (detailed_signal, self->target_type,
+                                             &signal_id, &signal_detail, TRUE) != 0, FALSE);
+  g_return_val_if_fail (closure != NULL, FALSE);
 
   g_rec_mutex_lock (&self->mutex);
 
@@ -742,7 +728,7 @@ g_signal_group_connect_closure (GSignalGroup   *self,
     {
       g_critical ("Cannot add signals after setting target");
       g_rec_mutex_unlock (&self->mutex);
-      return;
+      return FALSE;
     }
 
   handler = g_slice_new0 (SignalHandler);
@@ -768,6 +754,30 @@ g_signal_group_connect_closure (GSignalGroup   *self,
   g_signal_group_gc_handlers (self);
 
   g_rec_mutex_unlock (&self->mutex);
+  return TRUE;
+}
+
+/**
+ * g_signal_group_connect_closure:
+ * @self: a #GSignalGroup
+ * @detailed_signal: a string of the form `signal-name` with optional `::signal-detail`
+ * @closure: (not nullable): the closure to connect.
+ * @after: whether the handler should be called before or after the
+ *  default handler of the signal.
+ *
+ * Connects @closure to the signal @detailed_signal on #GSignalGroup:target.
+ *
+ * You cannot connect a signal handler after #GSignalGroup:target has been set.
+ *
+ * Since: 2.74
+ */
+void
+g_signal_group_connect_closure (GSignalGroup   *self,
+                                const gchar    *detailed_signal,
+                                GClosure       *closure,
+                                gboolean        after)
+{
+  g_signal_group_connect_closure_ (self, detailed_signal, closure, after);
 }
 
 static void
@@ -798,10 +808,11 @@ g_signal_group_connect_full (GSignalGroup   *self,
       g_object_watch_closure (data, closure);
     }
 
-  g_signal_group_connect_closure (self,
-                                  detailed_signal,
-                                  closure,
-                                  (flags & G_CONNECT_AFTER) != 0);
+  if (!g_signal_group_connect_closure_ (self,
+                                        detailed_signal,
+                                        closure,
+                                        (flags & G_CONNECT_AFTER) != 0))
+    g_closure_unref (closure);
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]