[nautilus] batch-rename: cancel metadata check when closing dialog



commit aa3ede95b62dc9180cb5745ec5cd9730fb963df3
Author: Ernestas Kulik <ernestask gnome org>
Date:   Thu Jun 29 16:24:55 2017 +0300

    batch-rename: cancel metadata check when closing dialog
    
    Opening the batch rename dialog and immediately closing it results in a
    crash, due to the async operation not being canceled, thus resulting in
    invalid memory access on callback.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=784336

 src/nautilus-batch-rename-dialog.c    |   10 +++++++-
 src/nautilus-batch-rename-utilities.c |   42 +++++++++++++++++++-------------
 src/nautilus-batch-rename-utilities.h |    3 +-
 3 files changed, 36 insertions(+), 19 deletions(-)
---
diff --git a/src/nautilus-batch-rename-dialog.c b/src/nautilus-batch-rename-dialog.c
index 185fe4c..e3ad0bc 100644
--- a/src/nautilus-batch-rename-dialog.c
+++ b/src/nautilus-batch-rename-dialog.c
@@ -102,6 +102,8 @@ struct _NautilusBatchRenameDialog
 
     gint row_height;
     gboolean rename_clicked;
+
+    GCancellable *metadata_cancellable;
 };
 
 typedef struct
@@ -1774,7 +1776,8 @@ nautilus_batch_rename_dialog_initialize_actions (NautilusBatchRenameDialog *dial
                                          metadata_tags_constants[ORIGINAL_FILE_NAME].action_name);
     g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
 
-    check_metadata_for_selection (dialog, dialog->selection);
+    check_metadata_for_selection (dialog, dialog->selection,
+                                  dialog->metadata_cancellable);
 }
 
 static void
@@ -2051,6 +2054,9 @@ nautilus_batch_rename_dialog_finalize (GObject *object)
 
     g_hash_table_destroy (dialog->tag_info_table);
 
+    g_cancellable_cancel (dialog->metadata_cancellable);
+    g_clear_object (&dialog->metadata_cancellable);
+
     G_OBJECT_CLASS (nautilus_batch_rename_dialog_parent_class)->finalize (object);
 }
 
@@ -2301,4 +2307,6 @@ nautilus_batch_rename_dialog_init (NautilusBatchRenameDialog *self)
                       "leave-notify-event",
                       G_CALLBACK (on_leave_event),
                       self);
+
+    self->metadata_cancellable = g_cancellable_new ();
 }
diff --git a/src/nautilus-batch-rename-utilities.c b/src/nautilus-batch-rename-utilities.c
index d7cdbb3..ded9682 100644
--- a/src/nautilus-batch-rename-utilities.c
+++ b/src/nautilus-batch-rename-utilities.c
@@ -40,6 +40,8 @@ typedef struct
     GList *selection_metadata;
 
     gboolean has_metadata[G_N_ELEMENTS (metadata_tags_constants)];
+
+    GCancellable *cancellable;
 } QueryData;
 
 enum
@@ -747,7 +749,7 @@ cursor_next (QueryData           *query_data,
              TrackerSparqlCursor *cursor)
 {
     tracker_sparql_cursor_next_async (cursor,
-                                      NULL,
+                                      query_data->cancellable,
                                       on_cursor_callback,
                                       query_data);
 }
@@ -800,7 +802,7 @@ on_cursor_callback (GObject      *object,
     gboolean success;
     QueryData *query_data;
     MetadataType metadata_type;
-    GError *error;
+    g_autoptr (GError) error = NULL;
     GList *l;
     FileMetadata *file_metadata;
     GDateTime *date_time;
@@ -822,7 +824,6 @@ on_cursor_callback (GObject      *object,
     const gchar *title;
     const gchar *album_name;
 
-    error = NULL;
     file_metadata = NULL;
 
     cursor = TRACKER_SPARQL_CURSOR (object);
@@ -831,17 +832,21 @@ on_cursor_callback (GObject      *object,
     success = tracker_sparql_cursor_next_finish (cursor, result, &error);
     if (!success)
     {
-        if (error)
+        if (error != NULL)
         {
             g_warning ("Error on batch rename tracker query cursor: %s", error->message);
-            g_error_free (error);
         }
 
         g_clear_object (&cursor);
 
-        nautilus_batch_rename_dialog_query_finished (query_data->dialog,
-                                                     query_data->date_order_hash_table,
-                                                     query_data->selection_metadata);
+        /* The dialog is going away at the time of cancellation */
+        if (error == NULL ||
+            (error != NULL && error->code != G_IO_ERROR_CANCELLED))
+        {
+            nautilus_batch_rename_dialog_query_finished (query_data->dialog,
+                                                         query_data->date_order_hash_table,
+                                                         query_data->selection_metadata);
+        }
 
         g_free (query_data);
 
@@ -999,9 +1004,7 @@ batch_rename_dialog_query_callback (GObject      *object,
     TrackerSparqlConnection *connection;
     TrackerSparqlCursor *cursor;
     QueryData *query_data;
-    GError *error;
-
-    error = NULL;
+    g_autoptr (GError) error = NULL;
 
     connection = TRACKER_SPARQL_CONNECTION (object);
     query_data = user_data;
@@ -1013,11 +1016,14 @@ batch_rename_dialog_query_callback (GObject      *object,
     if (error != NULL)
     {
         g_warning ("Error on batch rename query for metadata: %s", error->message);
-        g_error_free (error);
 
-        nautilus_batch_rename_dialog_query_finished (query_data->dialog,
-                                                     query_data->date_order_hash_table,
-                                                     query_data->selection_metadata);
+        /* The dialog is being finalized at this point */
+        if (error->code != G_IO_ERROR_CANCELLED)
+        {
+            nautilus_batch_rename_dialog_query_finished (query_data->dialog,
+                                                         query_data->date_order_hash_table,
+                                                         query_data->selection_metadata);
+        }
 
         g_free (query_data);
     }
@@ -1029,7 +1035,8 @@ batch_rename_dialog_query_callback (GObject      *object,
 
 void
 check_metadata_for_selection (NautilusBatchRenameDialog *dialog,
-                              GList                     *selection)
+                              GList                     *selection,
+                              GCancellable              *cancellable)
 {
     TrackerSparqlConnection *connection;
     GString *query;
@@ -1135,11 +1142,12 @@ check_metadata_for_selection (NautilusBatchRenameDialog *dialog,
     {
         query_data->has_metadata[i] = TRUE;
     }
+    query_data->cancellable = cancellable;
 
     /* Make an asynchronous query to the store */
     tracker_sparql_connection_query_async (connection,
                                            query->str,
-                                           NULL,
+                                           cancellable,
                                            batch_rename_dialog_query_callback,
                                            query_data);
 
diff --git a/src/nautilus-batch-rename-utilities.h b/src/nautilus-batch-rename-utilities.h
index 178f1ae..6c6a60e 100644
--- a/src/nautilus-batch-rename-utilities.h
+++ b/src/nautilus-batch-rename-utilities.h
@@ -42,7 +42,8 @@ GList* nautilus_batch_rename_dialog_sort        (GList                       *se
                                                  GHashTable                  *creation_date_table);
 
 void check_metadata_for_selection               (NautilusBatchRenameDialog *dialog,
-                                                 GList                     *selection);
+                                                 GList                     *selection,
+                                                 GCancellable              *cancellable);
 
 gboolean selection_has_single_parent            (GList *selection);
 


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