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
This commit is contained in:

committed by
John Ralls

parent
93bf85e92f
commit
91f2ad4a2f
@ -370,7 +370,6 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard,
|
|||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
gboolean have_owner)
|
gboolean have_owner)
|
||||||
{
|
{
|
||||||
GtkClipboardOwner *owner;
|
|
||||||
NSSet *types;
|
NSSet *types;
|
||||||
NSAutoreleasePool *pool;
|
NSAutoreleasePool *pool;
|
||||||
|
|
||||||
@ -406,26 +405,35 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard,
|
|||||||
*/
|
*/
|
||||||
if (user_data && user_data == clipboard->user_data)
|
if (user_data && user_data == clipboard->user_data)
|
||||||
{
|
{
|
||||||
owner = [clipboard->owner retain];
|
clipboard->owner->setting_same_owner = TRUE;
|
||||||
|
|
||||||
owner->setting_same_owner = TRUE;
|
|
||||||
clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
|
clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
|
||||||
owner: owner];
|
owner: clipboard->owner];
|
||||||
owner->setting_same_owner = FALSE;
|
clipboard->owner->setting_same_owner = FALSE;
|
||||||
}
|
}
|
||||||
else
|
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]
|
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];
|
[types release];
|
||||||
[pool release];
|
[pool release];
|
||||||
|
|
||||||
clipboard->owner = owner;
|
|
||||||
clipboard->user_data = user_data;
|
clipboard->user_data = user_data;
|
||||||
clipboard->have_owner = have_owner;
|
clipboard->have_owner = have_owner;
|
||||||
if (have_owner)
|
if (have_owner)
|
||||||
@ -538,6 +546,8 @@ clipboard_unset (GtkClipboard *clipboard)
|
|||||||
g_free (clipboard->storable_targets);
|
g_free (clipboard->storable_targets);
|
||||||
clipboard->storable_targets = NULL;
|
clipboard->storable_targets = NULL;
|
||||||
|
|
||||||
|
if (clipboard->owner)
|
||||||
|
[clipboard->owner release];
|
||||||
clipboard->owner = NULL;
|
clipboard->owner = NULL;
|
||||||
clipboard->get_func = NULL;
|
clipboard->get_func = NULL;
|
||||||
clipboard->clear_func = NULL;
|
clipboard->clear_func = NULL;
|
||||||
|
Reference in New Issue
Block a user