[gtk/wip/chergert/fix-menutracker: 2/2] menutrackeritem: protect against use-after-free
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/fix-menutracker: 2/2] menutrackeritem: protect against use-after-free
- Date: Fri, 24 Jun 2022 21:31:09 +0000 (UTC)
commit 4d883861b13448869234d3b76fe8ea8a0daba1a2
Author: Christian Hergert <chergert redhat com>
Date: Fri Jun 24 14:28:18 2022 -0700
menutrackeritem: protect against use-after-free
With recent updates to GLib, I now see cases where we can hit a state that
has finalized before notify (which will bump the ref count back up). This
is evident in GNOME Text Editor when showing a language submenu from a
popover, and then dismissing the popover and subsequently the tab.
With the previous commit, we at least get a warning like this, which helped
track down the issue.
Gtk-CRITICAL **: gtk_action_observable_unregister_observer: assertion 'GTK_IS_ACTION_OBSERVABLE
(observable)' failed
GLib-GObject-CRITICAL **: g_object_ref: assertion '!object_already_finalized' failed
This patch fixes both of those criticals.
Fixes #5009
gtk/gtkmenutrackeritem.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkmenutrackeritem.c b/gtk/gtkmenutrackeritem.c
index 11db1f4abb..8b459c7a41 100644
--- a/gtk/gtkmenutrackeritem.c
+++ b/gtk/gtkmenutrackeritem.c
@@ -870,16 +870,25 @@ gtk_menu_tracker_opener_finalize (GObject *object)
{
GtkMenuTrackerOpener *opener = (GtkMenuTrackerOpener *)object;
- gtk_action_observable_unregister_observer (opener->item->observable,
- opener->submenu_action,
- (GtkActionObserver *)opener);
+ if (opener->item != NULL)
+ {
+ GtkMenuTrackerItem *item = g_object_ref (opener->item);
+
+ g_clear_weak_pointer (&opener->item);
+
+ gtk_action_observable_unregister_observer (item->observable,
+ opener->submenu_action,
+ (GtkActionObserver *)opener);
- if (GTK_IS_ACTION_MUXER (opener->item->observable))
- gtk_action_muxer_change_action_state (GTK_ACTION_MUXER (opener->item->observable),
- opener->submenu_action,
- g_variant_new_boolean (FALSE));
+ if (GTK_IS_ACTION_MUXER (item->observable))
+ gtk_action_muxer_change_action_state (GTK_ACTION_MUXER (item->observable),
+ opener->submenu_action,
+ g_variant_new_boolean (FALSE));
- gtk_menu_tracker_item_set_submenu_shown (opener->item, FALSE);
+ gtk_menu_tracker_item_set_submenu_shown (item, FALSE);
+
+ g_object_unref (item);
+ }
g_clear_pointer (&opener->submenu_action, g_free);
@@ -992,7 +1001,8 @@ gtk_menu_tracker_opener_new (GtkMenuTrackerItem *item,
opener = g_object_new (gtk_menu_tracker_opener_get_type (), NULL);
opener->first_time = TRUE;
- opener->item = item;
+
+ g_set_weak_pointer (&opener->item, item);
if (item->action_namespace)
opener->submenu_action = g_strjoin (".", item->action_namespace, submenu_action, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]