[gnome-software] Use g_set_object() to fix potential crashes when setting GsApp



commit 7b507859470d87ed9a7505bb64c5c0d47778493d
Author: Rafal Luzynski <digitalfreak lingonborough com>
Date:   Sun Sep 27 02:44:12 2015 +0200

    Use g_set_object() to fix potential crashes when setting GsApp
    
    We should not g_object_unref() and then g_object_ref() if we are
    not sure if the two objects are different. This may cause a dangling
    pointer issue.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=755664

 src/gs-app-tile.c      |    4 ++--
 src/gs-feature-tile.c  |    4 +---
 src/gs-popular-tile.c  |    3 +--
 src/gs-shell-details.c |   21 +++++++++++++--------
 4 files changed, 17 insertions(+), 15 deletions(-)
---
diff --git a/src/gs-app-tile.c b/src/gs-app-tile.c
index c037af3..177452e 100644
--- a/src/gs-app-tile.c
+++ b/src/gs-app-tile.c
@@ -131,10 +131,10 @@ gs_app_tile_set_app (GsAppTile *tile, GsApp *app)
        if (tile->app)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
 
-       g_clear_object (&tile->app);
+       g_set_object (&tile->app, app);
        if (!app)
                return;
-       tile->app = g_object_ref (app);
+
        if (gs_app_get_rating_kind (tile->app) == GS_APP_RATING_KIND_USER) {
                gs_star_widget_set_rating (GS_STAR_WIDGET (tile->stars),
                                           GS_APP_RATING_KIND_USER,
diff --git a/src/gs-feature-tile.c b/src/gs-feature-tile.c
index a37f759..567261b 100644
--- a/src/gs-feature-tile.c
+++ b/src/gs-feature-tile.c
@@ -102,12 +102,10 @@ gs_feature_tile_set_app (GsFeatureTile *tile, GsApp *app)
        if (tile->app)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
 
-       g_clear_object (&tile->app);
+       g_set_object (&tile->app, app);
        if (!app)
                return;
 
-       tile->app = g_object_ref (app);
-
        gtk_stack_set_visible_child_name (GTK_STACK (tile->stack), "content");
 
        g_signal_connect (tile->app, "notify::state",
diff --git a/src/gs-popular-tile.c b/src/gs-popular-tile.c
index d086d58..f812fd1 100644
--- a/src/gs-popular-tile.c
+++ b/src/gs-popular-tile.c
@@ -108,10 +108,9 @@ gs_popular_tile_set_app (GsPopularTile *tile, GsApp *app)
        if (tile->app)
                g_signal_handlers_disconnect_by_func (tile->app, app_state_changed, tile);
 
-       g_clear_object (&tile->app);
+       g_set_object (&tile->app, app);
        if (!app)
                return;
-       tile->app = g_object_ref (app);
 
        if (gs_app_get_rating_kind (tile->app) == GS_APP_RATING_KIND_USER) {
                gs_star_widget_set_rating (GS_STAR_WIDGET (tile->stars),
diff --git a/src/gs-shell-details.c b/src/gs-shell-details.c
index 57c79b0..3e7240e 100644
--- a/src/gs-shell-details.c
+++ b/src/gs-shell-details.c
@@ -911,15 +911,16 @@ gs_shell_details_filename_to_app_cb (GObject *source,
        g_autoptr(GError) error = NULL;
        g_autofree gchar *tmp = NULL;
 
-       /* save app */
+       /* disconnect the old handlers */
        if (self->app != NULL) {
                g_signal_handlers_disconnect_by_func (self->app, gs_shell_details_notify_state_changed_cb, 
self);
                g_signal_handlers_disconnect_by_func (self->app, gs_shell_details_progress_changed_cb, self);
-               g_object_unref (self->app);
        }
-       self->app = gs_plugin_loader_filename_to_app_finish(plugin_loader,
-                                                           res,
-                                                           &error);
+       /* save app */
+       g_set_object (&self->app,
+                     gs_plugin_loader_filename_to_app_finish(plugin_loader,
+                                                             res,
+                                                             &error));
        if (self->app == NULL) {
                GtkWidget *dialog;
 
@@ -1021,16 +1022,20 @@ gs_shell_details_reload (GsShellDetails *self)
 void
 gs_shell_details_set_app (GsShellDetails *self, GsApp *app)
 {
+       g_return_if_fail (GS_IS_SHELL_DETAILS (self));
+       g_return_if_fail (GS_IS_APP (app));
+
        /* get extra details about the app */
        gs_shell_details_set_state (self, GS_SHELL_DETAILS_STATE_LOADING);
 
-       /* save app */
+       /* disconnect the old handlers */
        if (self->app != NULL) {
                g_signal_handlers_disconnect_by_func (self->app, gs_shell_details_notify_state_changed_cb, 
self);
                g_signal_handlers_disconnect_by_func (self->app, gs_shell_details_progress_changed_cb, self);
-               g_object_unref (self->app);
        }
-       self->app = g_object_ref (app);
+       /* save app */
+       g_set_object (&self->app, app);
+
        g_signal_connect_object (self->app, "notify::state",
                                 G_CALLBACK (gs_shell_details_notify_state_changed_cb),
                                 self, 0);


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