[evolution] Attachment load/save should keep a reference to its top-level window



commit fc55a93871860a5fed160b1a4c8290464bace5ab
Author: Milan Crha <mcrha redhat com>
Date:   Thu Apr 30 10:50:24 2015 +0200

    Attachment load/save should keep a reference to its top-level window
    
    Saving in a separate message window and closing it before the save is done
    can cause use-after-free in the callback of the save, expecting the parent
    window object being a valid GtkWindow.

 e-util/e-attachment-view.c               |   42 +++++++++++++++++++++++++----
 modules/mail/e-mail-attachment-handler.c |   22 +++++++++++++--
 2 files changed, 55 insertions(+), 9 deletions(-)
---
diff --git a/e-util/e-attachment-view.c b/e-util/e-attachment-view.c
index 8bdffdf..61fedfc 100644
--- a/e-util/e-attachment-view.c
+++ b/e-util/e-attachment-view.c
@@ -251,6 +251,21 @@ action_remove_cb (GtkAction *action,
 }
 
 static void
+call_attachment_save_handle_error (GObject *source_object,
+                                  GAsyncResult *result,
+                                  gpointer user_data)
+{
+       GtkWindow *window = user_data;
+
+       g_return_if_fail (E_IS_ATTACHMENT (source_object));
+       g_return_if_fail (!window || GTK_IS_WINDOW (window));
+
+       e_attachment_save_handle_error (E_ATTACHMENT (source_object), result, window);
+
+       g_clear_object (&window);
+}
+
+static void
 action_save_all_cb (GtkAction *action,
                     EAttachmentView *view)
 {
@@ -280,7 +295,7 @@ action_save_all_cb (GtkAction *action,
 
                e_attachment_save_async (
                        attachment, destination, (GAsyncReadyCallback)
-                       e_attachment_save_handle_error, parent);
+                       call_attachment_save_handle_error, parent ? g_object_ref (parent) : NULL);
        }
 
        g_object_unref (destination);
@@ -317,7 +332,7 @@ action_save_as_cb (GtkAction *action,
 
                e_attachment_save_async (
                        attachment, destination, (GAsyncReadyCallback)
-                       e_attachment_save_handle_error, parent);
+                       call_attachment_save_handle_error, parent ? g_object_ref (parent) : NULL);
        }
 
        g_object_unref (destination);
@@ -509,6 +524,21 @@ static GtkActionEntry inline_entries[] = {
 };
 
 static void
+call_attachment_load_handle_error (GObject *source_object,
+                                  GAsyncResult *result,
+                                  gpointer user_data)
+{
+       GtkWindow *window = user_data;
+
+       g_return_if_fail (E_IS_ATTACHMENT (source_object));
+       g_return_if_fail (!window || GTK_IS_WINDOW (window));
+
+       e_attachment_load_handle_error (E_ATTACHMENT (source_object), result, window);
+
+       g_clear_object (&window);
+}
+
+static void
 attachment_view_netscape_url (EAttachmentView *view,
                               GdkDragContext *drag_context,
                               gint x,
@@ -552,7 +582,7 @@ attachment_view_netscape_url (EAttachmentView *view,
        e_attachment_store_add_attachment (store, attachment);
        e_attachment_load_async (
                attachment, (GAsyncReadyCallback)
-               e_attachment_load_handle_error, parent);
+               call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
        g_object_unref (attachment);
 
        g_strfreev (strv);
@@ -606,7 +636,7 @@ attachment_view_text_calendar (EAttachmentView *view,
        e_attachment_store_add_attachment (store, attachment);
        e_attachment_load_async (
                attachment, (GAsyncReadyCallback)
-               e_attachment_load_handle_error, parent);
+               call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
        g_object_unref (attachment);
 
        g_object_unref (mime_part);
@@ -660,7 +690,7 @@ attachment_view_text_x_vcard (EAttachmentView *view,
        e_attachment_store_add_attachment (store, attachment);
        e_attachment_load_async (
                attachment, (GAsyncReadyCallback)
-               e_attachment_load_handle_error, parent);
+               call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
        g_object_unref (attachment);
 
        g_object_unref (mime_part);
@@ -701,7 +731,7 @@ attachment_view_uris (EAttachmentView *view,
                e_attachment_store_add_attachment (store, attachment);
                e_attachment_load_async (
                        attachment, (GAsyncReadyCallback)
-                       e_attachment_load_handle_error, parent);
+                       call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
                g_object_unref (attachment);
        }
 
diff --git a/modules/mail/e-mail-attachment-handler.c b/modules/mail/e-mail-attachment-handler.c
index edce6a5..40c7e07 100644
--- a/modules/mail/e-mail-attachment-handler.c
+++ b/modules/mail/e-mail-attachment-handler.c
@@ -224,6 +224,21 @@ static GtkActionEntry standard_entries[] = {
 };
 
 static void
+call_attachment_load_handle_error (GObject *source_object,
+                                  GAsyncResult *result,
+                                  gpointer user_data)
+{
+       GtkWindow *window = user_data;
+
+       g_return_if_fail (E_IS_ATTACHMENT (source_object));
+       g_return_if_fail (!window || GTK_IS_WINDOW (window));
+
+       e_attachment_load_handle_error (E_ATTACHMENT (source_object), result, window);
+
+       g_clear_object (&window);
+}
+
+static void
 mail_attachment_handler_message_rfc822 (EAttachmentView *view,
                                         GdkDragContext *drag_context,
                                         gint x,
@@ -275,7 +290,7 @@ mail_attachment_handler_message_rfc822 (EAttachmentView *view,
        e_attachment_store_add_attachment (store, attachment);
        e_attachment_load_async (
                attachment, (GAsyncReadyCallback)
-               e_attachment_load_handle_error, parent);
+               call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
        g_object_unref (attachment);
 
        success = TRUE;
@@ -380,7 +395,8 @@ mail_attachment_handler_x_uid_list (EAttachmentView *view,
                e_attachment_store_add_attachment (store, attachment);
                e_attachment_load_async (
                        attachment, (GAsyncReadyCallback)
-                       e_attachment_load_handle_error, parent);
+                       call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
+
                g_object_unref (attachment);
 
                g_object_unref (message);
@@ -433,7 +449,7 @@ mail_attachment_handler_x_uid_list (EAttachmentView *view,
        e_attachment_store_add_attachment (store, attachment);
        e_attachment_load_async (
                attachment, (GAsyncReadyCallback)
-               e_attachment_load_handle_error, parent);
+               call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
        g_object_unref (attachment);
 
        g_object_unref (mime_part);


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