[seahorse] search-provider: Don't assume handles are still valid



commit 073a95859c73a12852b0480c64a1a39deac50b15
Author: Stef Walter <stefw gnome org>
Date:   Wed Jul 30 15:51:41 2014 +0200

    search-provider: Don't assume handles are still valid
    
    We were crashing when we got back search provider handles from
    the shell for objects that no longer existed.
    
    We can't just call gcr_collection_contains() as it assumes that
    it's receiving a valid GObject.
    
    So hold a table of all the handles we've returned and update
    it via weak references.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=733957

 libseahorse/seahorse-search-provider.c |   49 ++++++++++++++++++++++++++------
 1 files changed, 40 insertions(+), 9 deletions(-)
---
diff --git a/libseahorse/seahorse-search-provider.c b/libseahorse/seahorse-search-provider.c
index 7133314..ec9a24d 100644
--- a/libseahorse/seahorse-search-provider.c
+++ b/libseahorse/seahorse-search-provider.c
@@ -44,6 +44,7 @@ struct _SeahorseSearchProvider {
 
        SeahorsePredicate base_predicate;
        GcrCollection *collection;
+       GHashTable *handles;
 };
 
 struct _SeahorseSearchProviderClass {
@@ -113,6 +114,16 @@ init_predicate (SeahorsePredicate  *predicate,
        predicate->custom_target = terms;
 }
 
+static void
+on_object_gone (gpointer data,
+               GObject *where_the_object_was)
+{
+       GHashTable *handles = data;
+       gchar *str = g_strdup_printf ("%p", (gpointer)where_the_object_was);
+       g_hash_table_remove (handles, str);
+       g_free (str);
+}
+
 static gboolean
 handle_get_initial_result_set (SeahorseShellSearchProvider2 *skeleton,
                                GDBusMethodInvocation        *invocation,
@@ -133,6 +144,10 @@ handle_get_initial_result_set (SeahorseShellSearchProvider2 *skeleton,
                if (seahorse_predicate_match (&predicate, l->data)) {
                        char *str = g_strdup_printf("%p", l->data);
 
+                       if (!g_hash_table_contains (self->handles, str)) {
+                               g_hash_table_insert (self->handles, g_strdup (str), l->data);
+                               g_object_weak_ref (l->data, on_object_gone, self->handles);
+                       }
                        g_ptr_array_add (array, str);
                }
        }
@@ -168,9 +183,8 @@ handle_get_subsearch_result_set (SeahorseShellSearchProvider2 *skeleton,
        for (i = 0; previous_results[i]; i++) {
                GObject *object;
 
-               sscanf (previous_results[i], "%p", &object);
-
-               if (!gcr_collection_contains (self->collection, object)) {
+               object = g_hash_table_lookup (self->handles, previous_results[i]);
+               if (!object || !gcr_collection_contains (self->collection, object)) {
                        /* Bogus value */
                        continue;
                }
@@ -208,9 +222,8 @@ handle_get_result_metas (SeahorseShellSearchProvider2 *skeleton,
        for (i = 0; results[i]; i++) {
                GObject *object;
 
-               sscanf (results[i], "%p", &object);
-
-               if (!gcr_collection_contains (self->collection, object)) {
+               object = g_hash_table_lookup (self->handles, results[i]);
+               if (!object || !gcr_collection_contains (self->collection, object)) {
                        /* Bogus value */
                        continue;
                }
@@ -266,9 +279,8 @@ handle_activate_result (SeahorseShellSearchProvider2 *skeleton,
        GObject *object;
        SeahorseKeyManager *key_manager;
 
-       sscanf (identifier, "%p", &object);
-
-       if (!gcr_collection_contains (self->collection, object) ||
+       object = g_hash_table_lookup (self->handles, identifier);
+       if (!object || !gcr_collection_contains (self->collection, object) ||
            !SEAHORSE_IS_VIEWABLE (object)) {
                /* Bogus value */
                return TRUE;
@@ -381,6 +393,8 @@ seahorse_search_provider_init (SeahorseSearchProvider *self)
        filtered = seahorse_collection_new_for_predicate (base,
                                                          &self->base_predicate, NULL);
        self->collection = GCR_COLLECTION (filtered);
+
+       self->handles = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 }
 
 gboolean
@@ -422,11 +436,28 @@ seahorse_search_provider_dispose (GObject *object)
 }
 
 static void
+seahorse_search_provider_finalize (GObject *object)
+{
+       SeahorseSearchProvider *self = SEAHORSE_SEARCH_PROVIDER (object);
+       GHashTableIter iter;
+       gpointer value;
+
+       g_hash_table_iter_init (&iter, self->handles);
+       while (g_hash_table_iter_next (&iter, NULL, &value))
+               g_object_weak_unref (value, on_object_gone, self->handles);
+       g_hash_table_destroy (self->handles);
+
+       G_OBJECT_CLASS (seahorse_search_provider_parent_class)->finalize (object);
+}
+
+
+static void
 seahorse_search_provider_class_init (SeahorseSearchProviderClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
        object_class->dispose = seahorse_search_provider_dispose;
+       object_class->finalize = seahorse_search_provider_finalize;
 }
 
 SeahorseSearchProvider *


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