From 2e0265d59422ab35d244f6102a9c6b9aff743c30 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Fri, 8 Apr 2011 16:33:51 -0400 Subject: don't merely free an app, it has to be properly removed from list and such --- src/application-service-appstore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c index 3e827d5..4cafdfc 100644 --- a/src/application-service-appstore.c +++ b/src/application-service-appstore.c @@ -498,7 +498,8 @@ got_all_properties (GObject * source_object, GAsyncResult * res, if (menu == NULL || id == NULL || category == NULL || status == NULL || icon_name == NULL) { g_warning("Notification Item on object %s of %s doesn't have enough properties.", app->dbus_object, app->dbus_name); - g_free(app); // Need to do more than this, but it gives the idea of the flow we're going for. + if (!app->validated) + application_free(app); } else { app->validated = TRUE; -- cgit v1.2.3 From bee98f757e7e8d1f17160ac85c489e679e6ed908 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Mon, 11 Apr 2011 09:52:08 -0400 Subject: catch one more cancel-before-accessing freed memory instance -- this one resulting in a double free --- src/application-service-appstore.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c index 3e827d5..4e32122 100644 --- a/src/application-service-appstore.c +++ b/src/application-service-appstore.c @@ -1110,6 +1110,11 @@ props_cb (GObject * object, GAsyncResult * res, gpointer user_data) GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free (error); + return; // Must exit before accessing freed memory + } + if (app->props_cancel != NULL) { g_object_unref(app->props_cancel); app->props_cancel = NULL; -- cgit v1.2.3 From ce5dcdddf75b496c6b63f3a15f03cb788c4072f3 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Mon, 11 Apr 2011 14:18:15 -0400 Subject: make sure we can cancel GetAll call --- src/application-service-appstore.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c index 3e827d5..0c1028f 100644 --- a/src/application-service-appstore.c +++ b/src/application-service-appstore.c @@ -576,6 +576,7 @@ static void get_all_properties (Application * app) { if (app->props != NULL && app->props_cancel == NULL) { + app->props_cancel = g_cancellable_new(); g_dbus_proxy_call(app->props, "GetAll", g_variant_new("(s)", NOTIFICATION_ITEM_DBUS_IFACE), G_DBUS_CALL_FLAGS_NONE, -1, app->props_cancel, -- cgit v1.2.3 From e029f89cc9469d33969d6ca6a797b8e3216ecf49 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Tue, 12 Apr 2011 13:14:09 -0400 Subject: cancel approver requests too --- src/application-service-appstore.c | 47 +++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c index 3e827d5..9d35d66 100644 --- a/src/application-service-appstore.c +++ b/src/application-service-appstore.c @@ -110,6 +110,7 @@ struct _Application { gchar * guide; gboolean currently_free; guint ordering_index; + GList * approver_cancels; GList * approved_by; visible_state_t visible_state; guint name_watcher; @@ -745,6 +746,11 @@ application_free (Application * app) if (app->guide != NULL) { g_free(app->guide); } + if (app->approver_cancels != NULL) { + g_list_foreach(app->approver_cancels, (GFunc)g_cancellable_cancel, NULL); + g_list_foreach(app->approver_cancels, (GFunc)g_object_unref, NULL); + g_list_free(app->approver_cancels); + } if (app->approved_by != NULL) { g_list_free(app->approved_by); } @@ -997,6 +1003,7 @@ application_service_appstore_application_add (ApplicationServiceAppstore * appst app->guide = NULL; app->currently_free = FALSE; app->ordering_index = 0; + app->approver_cancels = NULL; app->approved_by = NULL; app->visible_state = VISIBLE_STATE_HIDDEN; app->name_watcher = 0; @@ -1283,6 +1290,24 @@ static void remove_approver (gpointer papp, gpointer pproxy) { Application * app = (Application *)papp; + + /* Check for any pending approvals and cancel them */ + GList * iter = app->approver_cancels; + while (iter != NULL) { + GCancellable * cancel = (GCancellable *)iter->data; + GDBusProxy * proxy = (GDBusProxy *)g_object_get_data(G_OBJECT(cancel), "proxy"); + if (proxy == pproxy) { + g_cancellable_cancel(cancel); + g_object_unref(cancel); + + GList * next = iter->next; + app->approver_cancels = g_list_delete_link(app->approver_cancels, iter); + iter = next; + } else { + iter = iter->next; + } + } + app->approved_by = g_list_remove(app->approved_by, pproxy); apply_status(app); return; @@ -1323,19 +1348,29 @@ static void approver_request_cb (GObject *object, GAsyncResult *res, gpointer user_data) { GDBusProxy * proxy = G_DBUS_PROXY(object); - Application * app = (Application *)user_data; + GCancellable * cancel = (GCancellable *)user_data; GError * error = NULL; gboolean approved = TRUE; /* default to approved */ GVariant * result; result = g_dbus_proxy_call_finish(proxy, res, &error); + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free (error); + return; // Must exit before accessing freed memory + } + + Application * app = (Application *)g_object_get_data(G_OBJECT(cancel), "app"); + app->approver_cancels = g_list_remove(app->approver_cancels, cancel); + g_object_unref(cancel); + if (error == NULL) { g_variant_get(result, "(b)", &approved); g_debug("Approver responded: %s", approved ? "approve" : "rejected"); } else { g_debug("Approver responded error: %s", error->message); + g_error_free (error); } if (approved) { @@ -1354,12 +1389,18 @@ check_with_new_approver (gpointer papp, gpointer papprove) { Application * app = (Application *)papp; Approver * approver = (Approver *)papprove; + GCancellable * cancel = NULL; + + cancel = g_cancellable_new(); + g_object_set_data(G_OBJECT(cancel), "app", app); + g_object_set_data(G_OBJECT(cancel), "proxy", approver->proxy); + app->approver_cancels = g_list_prepend(app->approver_cancels, cancel); g_dbus_proxy_call(approver->proxy, "ApproveItem", g_variant_new("(ssuso)", app->id, app->category, 0, app->dbus_name, app->dbus_object), - G_DBUS_CALL_FLAGS_NONE, -1, NULL, - approver_request_cb, app); + G_DBUS_CALL_FLAGS_NONE, -1, cancel, + approver_request_cb, cancel); return; } -- cgit v1.2.3