diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2022-05-17 15:21:53 +0200 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2022-05-17 17:34:06 +0200 |
commit | bb890b57d210701d4cab70f625121f2d0741d12c (patch) | |
tree | adf8b9d0239c930027a13604de3803274af9157f /gobject/gsignalgroup.c | |
parent | 15ce3c9b37c2767c82de249e60781439c9abaf78 (diff) | |
download | glib-bb890b57d210701d4cab70f625121f2d0741d12c.tar.gz |
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>
Diffstat (limited to 'gobject/gsignalgroup.c')
-rw-r--r-- | gobject/gsignalgroup.c | 69 |
1 files changed, 40 insertions, 29 deletions
diff --git a/gobject/gsignalgroup.c b/gobject/gsignalgroup.c index 01a0a12c8..e773fc040 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); } /** |