Tue, 12 Mar 2024 02:25:03 -0500
Fix leaks of plugin actions
All action groups and action menus leak because the plugin info is created, directly returned, and nothing owns them any more.
Instead, steal the reference in the plugin info setters, so that they are owned by it.
Then clean up a bunch of additional refs that aren't needed.
Testing Done:
Ran in valgrind, and no longer saw leaks from `notification-sound.c`.
Also enabled and disabled that plugin and saw no errors.
Reviewed at https://reviews.imfreedom.org/r/3023/
--- a/libpurple/plugins/notification-sound/notification-sound.c Tue Mar 12 02:21:44 2024 -0500 +++ b/libpurple/plugins/notification-sound/notification-sound.c Tue Mar 12 02:25:03 2024 -0500 @@ -223,6 +223,7 @@ g_menu_append(section, _("Unmute"), "unmute"); g_menu_append_section(menu, NULL, G_MENU_MODEL(section)); + g_clear_object(§ion); section = g_menu_new(); g_menu_append(section, _("Mute for 30 minutes"), "mute(30)"); @@ -231,6 +232,7 @@ g_menu_append(section, _("Mute for 4 hours"), "mute(240)"); g_menu_append_section(menu, NULL, G_MENU_MODEL(section)); + g_clear_object(§ion); /* Create our action group. */ group = g_simple_action_group_new();
--- a/libpurple/purpleplugininfo.c Tue Mar 12 02:21:44 2024 -0500 +++ b/libpurple/purpleplugininfo.c Tue Mar 12 02:25:03 2024 -0500 @@ -70,6 +70,9 @@ if(g_set_object(&priv->action_group, group)) { g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_ACTION_GROUP]); + /* This is only passed as a construct-only property, so we want to + * steal the reference. */ + g_clear_object(&group); } } @@ -85,6 +88,9 @@ if(g_set_object(&priv->menu_model, menu_model)) { g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_ACTION_MENU]); + /* This is only passed as a construct-only property, so we want to + * steal the reference. */ + g_clear_object(&menu_model); } } @@ -133,12 +139,12 @@ g_value_set_flags(value, purple_plugin_info_get_flags(info)); break; case PROP_ACTION_GROUP: - g_value_take_object(value, - purple_plugin_info_get_action_group(info)); + g_value_set_object(value, + purple_plugin_info_get_action_group(info)); break; case PROP_ACTION_MENU: - g_value_take_object(value, - purple_plugin_info_get_action_menu(info)); + g_value_set_object(value, + purple_plugin_info_get_action_menu(info)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); @@ -187,7 +193,9 @@ priv = purple_plugin_info_get_instance_private(PURPLE_PLUGIN_INFO(object)); - g_free(priv->error); + g_clear_pointer(&priv->error, g_free); + g_clear_object(&priv->action_group); + g_clear_object(&priv->menu_model); G_OBJECT_CLASS(purple_plugin_info_parent_class)->finalize(object); } @@ -312,7 +320,7 @@ priv = purple_plugin_info_get_instance_private(info); if(G_IS_ACTION_GROUP(priv->action_group)) { - return g_object_ref(priv->action_group); + return priv->action_group; } return NULL; @@ -327,7 +335,7 @@ priv = purple_plugin_info_get_instance_private(info); if(G_IS_MENU_MODEL(priv->menu_model)) { - return g_object_ref(priv->menu_model); + return priv->menu_model; } return NULL;
--- a/libpurple/purpleplugininfo.h Tue Mar 12 02:21:44 2024 -0500 +++ b/libpurple/purpleplugininfo.h Tue Mar 12 02:25:03 2024 -0500 @@ -269,7 +269,7 @@ * * Gets the [class:Gio.ActionGroup] from @info if one is set. * - * Returns: (transfer full): The action group. + * Returns: (transfer none): The action group. * * Since: 3.0 */ @@ -282,7 +282,7 @@ * * Gets the [class:Gio.MenuModel] from @info if one is set. * - * Returns: (transfer full): The menu model. + * Returns: (transfer none): The menu model. * * Since: 3.0 */
--- a/pidgin/pidginpluginsmenu.c Tue Mar 12 02:21:44 2024 -0500 +++ b/pidgin/pidginpluginsmenu.c Tue Mar 12 02:25:03 2024 -0500 @@ -57,7 +57,6 @@ prefix = gplugin_plugin_info_get_id(info); pidgin_application_add_action_group(PIDGIN_APPLICATION(application), prefix, group); - g_object_unref(group); g_queue_push_tail(menu->plugins, g_object_ref(plugin)); }