[gtk/gtk-3-24] Bug 743717 - Crashes on clipboard operation, influence by clipboard ...



commit 91f2ad4a2fc5c6027d3fa72f1344aecde2230509
Author: Kristian Rietveld <kris loopnest org>
Date:   Sun Jan 1 21:04:04 2017 +0100

    Bug 743717 - Crashes on clipboard operation, influence by clipboard ...
    
    The problem here was that NSPasteboard would release the clipboard
    owner if all data items were transferred. When trying to re-use this
    owner at a later point, GTK+ would attempt a retain call on a released
    object and crash.
    
    Fix this by not immediately releasing the owner after declaring types,
    so by keeping our own reference around.
    
    Closes https://gitlab.gnome.org/GNOME/gtk/issues/529

 gtk/gtkclipboard-quartz.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkclipboard-quartz.c b/gtk/gtkclipboard-quartz.c
index cdf8db0541..c01a9cd627 100644
--- a/gtk/gtkclipboard-quartz.c
+++ b/gtk/gtkclipboard-quartz.c
@@ -370,7 +370,6 @@ gtk_clipboard_set_contents (GtkClipboard         *clipboard,
                            gpointer              user_data,
                            gboolean              have_owner)
 {
-  GtkClipboardOwner *owner;
   NSSet *types;
   NSAutoreleasePool *pool;
 
@@ -406,26 +405,35 @@ gtk_clipboard_set_contents (GtkClipboard         *clipboard,
    */
   if (user_data && user_data == clipboard->user_data)
     {
-      owner = [clipboard->owner retain];
-
-      owner->setting_same_owner = TRUE;
+      clipboard->owner->setting_same_owner = TRUE;
       clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
-                                                              owner: owner];
-      owner->setting_same_owner = FALSE;
+                                                              owner: clipboard->owner];
+      clipboard->owner->setting_same_owner = FALSE;
     }
   else
     {
-      owner = [[GtkClipboardOwner alloc] initWithClipboard:clipboard];
+      GtkClipboardOwner *new_owner;
 
+      /* We do not set the new owner on clipboard->owner immediately,
+       * because declareTypes could (but not always does -- see also the
+       * comment at pasteboardChangedOwner above) cause clipboard_unset
+       * to be called, which releases clipboard->owner.
+       */
+      new_owner = [[GtkClipboardOwner alloc] initWithClipboard:clipboard];
       clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
-                                                              owner: owner];
+                                                              owner: new_owner];
+
+      /* In case pasteboardChangedOwner was not triggered, check to see
+       * whether the previous owner still needs to be released.
+       */
+      if (clipboard->owner)
+        [clipboard->owner release];
+      clipboard->owner = new_owner;
     }
 
-  [owner release];
   [types release];
   [pool release];
 
-  clipboard->owner = owner;
   clipboard->user_data = user_data;
   clipboard->have_owner = have_owner;
   if (have_owner)
@@ -538,6 +546,8 @@ clipboard_unset (GtkClipboard *clipboard)
   g_free (clipboard->storable_targets);
   clipboard->storable_targets = NULL;
 
+  if (clipboard->owner)
+    [clipboard->owner release];
   clipboard->owner = NULL;
   clipboard->get_func = NULL;
   clipboard->clear_func = NULL;


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