From f5c5f62d9f820b56e81f8b3829aae8195841c755 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 30 Apr 2020 10:23:09 -0400 Subject: [PATCH 1/4] cally: Fix state set leak cally_actor_action_do_action leaks a state set object in the case where the actor is defunct, insensitive, or hidden. This commit plugs the leak. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1225 --- clutter/clutter/cally/cally-actor.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/clutter/clutter/cally/cally-actor.c b/clutter/clutter/cally/cally-actor.c index 77195c0b0..ff6dba14e 100644 --- a/clutter/clutter/cally/cally-actor.c +++ b/clutter/clutter/cally/cally-actor.c @@ -797,92 +797,95 @@ _cally_actor_get_top_level_origin (ClutterActor *actor, if (xp) *xp = x; if (yp) *yp = y; } /* AtkAction implementation */ static void cally_actor_action_interface_init (AtkActionIface *iface) { g_return_if_fail (iface != NULL); iface->do_action = cally_actor_action_do_action; iface->get_n_actions = cally_actor_action_get_n_actions; iface->get_description = cally_actor_action_get_description; iface->get_keybinding = cally_actor_action_get_keybinding; iface->get_name = cally_actor_action_get_name; iface->set_description = cally_actor_action_set_description; } static gboolean cally_actor_action_do_action (AtkAction *action, gint index) { CallyActor *cally_actor = NULL; AtkStateSet *set = NULL; CallyActorPrivate *priv = NULL; CallyActorActionInfo *info = NULL; + gboolean did_action = FALSE; cally_actor = CALLY_ACTOR (action); priv = cally_actor->priv; set = atk_object_ref_state_set (ATK_OBJECT (cally_actor)); if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT)) - return FALSE; + goto out; if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) || !atk_state_set_contains_state (set, ATK_STATE_SHOWING)) - return FALSE; - - g_object_unref (set); + goto out; info = _cally_actor_get_action_info (cally_actor, index); if (info == NULL) - return FALSE; + goto out; if (info->do_action_func == NULL) - return FALSE; + goto out; if (!priv->action_queue) priv->action_queue = g_queue_new (); g_queue_push_head (priv->action_queue, info); if (!priv->action_idle_handler) priv->action_idle_handler = g_idle_add (idle_do_action, cally_actor); - return TRUE; + did_action = TRUE; + +out: + g_clear_object (&set); + return did_action; } static gboolean idle_do_action (gpointer data) { CallyActor *cally_actor = NULL; CallyActorPrivate *priv = NULL; ClutterActor *actor = NULL; cally_actor = CALLY_ACTOR (data); priv = cally_actor->priv; actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); priv->action_idle_handler = 0; if (actor == NULL) /* state is defunct*/ return FALSE; while (!g_queue_is_empty (priv->action_queue)) { CallyActorActionInfo *info = NULL; info = (CallyActorActionInfo *) g_queue_pop_head (priv->action_queue); info->do_action_func (cally_actor, info->user_data); } return FALSE; } static gint -- 2.26.2