a70522e
From 073a95859c73a12852b0480c64a1a39deac50b15 Mon Sep 17 00:00:00 2001
a70522e
From: Stef Walter <stefw@gnome.org>
a70522e
Date: Wed, 30 Jul 2014 15:51:41 +0200
a70522e
Subject: [PATCH] search-provider: Don't assume handles are still valid
a70522e
a70522e
We were crashing when we got back search provider handles from
a70522e
the shell for objects that no longer existed.
a70522e
a70522e
We can't just call gcr_collection_contains() as it assumes that
a70522e
it's receiving a valid GObject.
a70522e
a70522e
So hold a table of all the handles we've returned and update
a70522e
it via weak references.
a70522e
a70522e
https://bugzilla.gnome.org/show_bug.cgi?id=733957
a70522e
---
a70522e
 libseahorse/seahorse-search-provider.c | 49 +++++++++++++++++++++++++++-------
a70522e
 1 file changed, 40 insertions(+), 9 deletions(-)
a70522e
a70522e
diff --git a/libseahorse/seahorse-search-provider.c b/libseahorse/seahorse-search-provider.c
a70522e
index 7133314..ec9a24d 100644
a70522e
--- a/libseahorse/seahorse-search-provider.c
a70522e
+++ b/libseahorse/seahorse-search-provider.c
a70522e
@@ -44,6 +44,7 @@ struct _SeahorseSearchProvider {
a70522e
 
a70522e
 	SeahorsePredicate base_predicate;
a70522e
 	GcrCollection *collection;
a70522e
+	GHashTable *handles;
a70522e
 };
a70522e
 
a70522e
 struct _SeahorseSearchProviderClass {
a70522e
@@ -113,6 +114,16 @@ init_predicate (SeahorsePredicate  *predicate,
a70522e
 	predicate->custom_target = terms;
a70522e
 }
a70522e
 
a70522e
+static void
a70522e
+on_object_gone (gpointer data,
a70522e
+		GObject *where_the_object_was)
a70522e
+{
a70522e
+	GHashTable *handles = data;
a70522e
+	gchar *str = g_strdup_printf ("%p", (gpointer)where_the_object_was);
a70522e
+	g_hash_table_remove (handles, str);
a70522e
+	g_free (str);
a70522e
+}
a70522e
+
a70522e
 static gboolean
a70522e
 handle_get_initial_result_set (SeahorseShellSearchProvider2 *skeleton,
a70522e
                                GDBusMethodInvocation        *invocation,
a70522e
@@ -133,6 +144,10 @@ handle_get_initial_result_set (SeahorseShellSearchProvider2 *skeleton,
a70522e
 		if (seahorse_predicate_match (&predicate, l->data)) {
a70522e
 			char *str = g_strdup_printf("%p", l->data);
a70522e
 
a70522e
+			if (!g_hash_table_contains (self->handles, str)) {
a70522e
+				g_hash_table_insert (self->handles, g_strdup (str), l->data);
a70522e
+				g_object_weak_ref (l->data, on_object_gone, self->handles);
a70522e
+			}
a70522e
 			g_ptr_array_add (array, str);
a70522e
 		}
a70522e
 	}
a70522e
@@ -168,9 +183,8 @@ handle_get_subsearch_result_set (SeahorseShellSearchProvider2 *skeleton,
a70522e
 	for (i = 0; previous_results[i]; i++) {
a70522e
 		GObject *object;
a70522e
 
a70522e
-		sscanf (previous_results[i], "%p", &object);
a70522e
-
a70522e
-		if (!gcr_collection_contains (self->collection, object)) {
a70522e
+		object = g_hash_table_lookup (self->handles, previous_results[i]);
a70522e
+		if (!object || !gcr_collection_contains (self->collection, object)) {
a70522e
 			/* Bogus value */
a70522e
 			continue;
a70522e
 		}
a70522e
@@ -208,9 +222,8 @@ handle_get_result_metas (SeahorseShellSearchProvider2 *skeleton,
a70522e
 	for (i = 0; results[i]; i++) {
a70522e
 		GObject *object;
a70522e
 
a70522e
-		sscanf (results[i], "%p", &object);
a70522e
-
a70522e
-		if (!gcr_collection_contains (self->collection, object)) {
a70522e
+		object = g_hash_table_lookup (self->handles, results[i]);
a70522e
+		if (!object || !gcr_collection_contains (self->collection, object)) {
a70522e
 			/* Bogus value */
a70522e
 			continue;
a70522e
 		}
a70522e
@@ -266,9 +279,8 @@ handle_activate_result (SeahorseShellSearchProvider2 *skeleton,
a70522e
 	GObject *object;
a70522e
 	SeahorseKeyManager *key_manager;
a70522e
 
a70522e
-	sscanf (identifier, "%p", &object);
a70522e
-
a70522e
-	if (!gcr_collection_contains (self->collection, object) ||
a70522e
+	object = g_hash_table_lookup (self->handles, identifier);
a70522e
+	if (!object || !gcr_collection_contains (self->collection, object) ||
a70522e
 	    !SEAHORSE_IS_VIEWABLE (object)) {
a70522e
 		/* Bogus value */
a70522e
 		return TRUE;
a70522e
@@ -381,6 +393,8 @@ seahorse_search_provider_init (SeahorseSearchProvider *self)
a70522e
 	filtered = seahorse_collection_new_for_predicate (base,
a70522e
 	                                                  &self->base_predicate, NULL);
a70522e
 	self->collection = GCR_COLLECTION (filtered);
a70522e
+
a70522e
+	self->handles = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
a70522e
 }
a70522e
 
a70522e
 gboolean
a70522e
@@ -422,11 +436,28 @@ seahorse_search_provider_dispose (GObject *object)
a70522e
 }
a70522e
 
a70522e
 static void
a70522e
+seahorse_search_provider_finalize (GObject *object)
a70522e
+{
a70522e
+	SeahorseSearchProvider *self = SEAHORSE_SEARCH_PROVIDER (object);
a70522e
+	GHashTableIter iter;
a70522e
+	gpointer value;
a70522e
+
a70522e
+	g_hash_table_iter_init (&iter, self->handles);
a70522e
+	while (g_hash_table_iter_next (&iter, NULL, &value))
a70522e
+		g_object_weak_unref (value, on_object_gone, self->handles);
a70522e
+	g_hash_table_destroy (self->handles);
a70522e
+
a70522e
+	G_OBJECT_CLASS (seahorse_search_provider_parent_class)->finalize (object);
a70522e
+}
a70522e
+
a70522e
+
a70522e
+static void
a70522e
 seahorse_search_provider_class_init (SeahorseSearchProviderClass *klass)
a70522e
 {
a70522e
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
a70522e
 
a70522e
 	object_class->dispose = seahorse_search_provider_dispose;
a70522e
+	object_class->finalize = seahorse_search_provider_finalize;
a70522e
 }
a70522e
 
a70522e
 SeahorseSearchProvider *
a70522e
-- 
a70522e
2.1.0
a70522e