From 8ceafd2d6c622fdf627013cbe634127f8e172328 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 5 May 2013 21:39:16 -0700 Subject: [PATCH] psppire-data-sheet: Disconnect clipboard owner-change signal on dispose. Otherwise, any clipboard change in ownership (e.g. clicking on some cells and typing Control+C), even after a given PsppireDataSheet closes, still calls into on_owner_change() and commits a use-after-free error. Reported by John Darrington. --- src/ui/gui/psppire-data-sheet.c | 23 ++++++++++++++++++----- src/ui/gui/psppire-data-sheet.h | 3 +++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/ui/gui/psppire-data-sheet.c b/src/ui/gui/psppire-data-sheet.c index 201fa8cd79..01afb5ed87 100644 --- a/src/ui/gui/psppire-data-sheet.c +++ b/src/ui/gui/psppire-data-sheet.c @@ -1203,6 +1203,13 @@ psppire_data_sheet_dispose (GObject *object) { PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (object); + if (data_sheet->clip != NULL && data_sheet->on_owner_change_signal != 0) + { + g_signal_handler_disconnect (data_sheet->clip, + data_sheet->on_owner_change_signal); + data_sheet->on_owner_change_signal = 0; + } + if (data_sheet->dispose_has_run) return; @@ -1221,14 +1228,19 @@ psppire_data_sheet_dispose (GObject *object) static void psppire_data_sheet_map (GtkWidget *widget) { - GtkClipboard *clip; + PsppireDataSheet *data_sheet = PSPPIRE_DATA_SHEET (widget); GTK_WIDGET_CLASS (psppire_data_sheet_parent_class)->map (widget); - clip = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD); - g_signal_connect (clip, "owner-change", G_CALLBACK (on_owner_change), - widget); - on_owner_change (clip, NULL, widget); + data_sheet->clip = gtk_widget_get_clipboard (widget, + GDK_SELECTION_CLIPBOARD); + if (data_sheet->on_owner_change_signal) + g_signal_handler_disconnect (data_sheet->clip, + data_sheet->on_owner_change_signal); + data_sheet->on_owner_change_signal + = g_signal_connect (data_sheet->clip, "owner-change", + G_CALLBACK (on_owner_change), widget); + on_owner_change (data_sheet->clip, NULL, widget); } static void @@ -1690,6 +1702,7 @@ psppire_data_sheet_init (PsppireDataSheet *obj) obj->scroll_to_bottom_signal = 0; obj->scroll_to_right_signal = 0; + obj->on_owner_change_signal = 0; obj->new_variable_column = NULL; obj->container = NULL; diff --git a/src/ui/gui/psppire-data-sheet.h b/src/ui/gui/psppire-data-sheet.h index 5e553ec646..8497e2c115 100644 --- a/src/ui/gui/psppire-data-sheet.h +++ b/src/ui/gui/psppire-data-sheet.h @@ -53,6 +53,9 @@ struct _PsppireDataSheet guint scroll_to_bottom_signal; guint scroll_to_right_signal; + GtkClipboard *clip; + guint on_owner_change_signal; + PsppSheetViewColumn *new_variable_column; GtkBuilder *builder; -- 2.30.2