From b01113741e35f68e3a40b792e0daa2676f7eafd2 Mon Sep 17 00:00:00 2001 From: Ell Date: Sat, 20 Apr 2019 14:30:43 -0400 Subject: [PATCH] Issue #3275 - Crash when opening an image after closing existing image In gimp_open_dialog_set_image(), use a weak pointer for storing the current image, to avoid a segfault in file_open_dialog_response() if the active image at the time of the open action has been closed before confirming the dialog. --- app/dialogs/file-open-dialog.c | 11 ++++++---- app/widgets/gimpopendialog.c | 38 ++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/app/dialogs/file-open-dialog.c b/app/dialogs/file-open-dialog.c index b28c07b08c..379cf12a72 100644 --- a/app/dialogs/file-open-dialog.c +++ b/app/dialogs/file-open-dialog.c @@ -139,10 +139,13 @@ file_open_dialog_response (GtkWidget *dialog, { if (! file_dialog->image) { - file_dialog->image = file_open_dialog_open_image (dialog, - gimp, - file, - file_dialog->file_proc); + gimp_open_dialog_set_image ( + open_dialog, + file_open_dialog_open_image (dialog, + gimp, + file, + file_dialog->file_proc), + TRUE); if (file_dialog->image) { diff --git a/app/widgets/gimpopendialog.c b/app/widgets/gimpopendialog.c index 8a203935e9..7525ab1d7e 100644 --- a/app/widgets/gimpopendialog.c +++ b/app/widgets/gimpopendialog.c @@ -37,15 +37,25 @@ #include "gimp-intl.h" +/* local function prototypes */ + +static void gimp_open_dialog_dispose (GObject *object); + + G_DEFINE_TYPE (GimpOpenDialog, gimp_open_dialog, GIMP_TYPE_FILE_DIALOG) #define parent_class gimp_open_dialog_parent_class +/* private functions */ + static void gimp_open_dialog_class_init (GimpOpenDialogClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gimp_open_dialog_dispose; } static void @@ -53,6 +63,14 @@ gimp_open_dialog_init (GimpOpenDialog *dialog) { } +static void +gimp_open_dialog_dispose (GObject *object) +{ + gimp_open_dialog_set_image (GIMP_OPEN_DIALOG (object), NULL, FALSE); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + /* public functions */ @@ -83,9 +101,25 @@ gimp_open_dialog_set_image (GimpOpenDialog *dialog, GimpImage *image, gboolean open_as_layers) { + GimpFileDialog *file_dialog; + g_return_if_fail (GIMP_IS_OPEN_DIALOG (dialog)); g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image)); - GIMP_FILE_DIALOG (dialog)->image = image; - dialog->open_as_layers = open_as_layers; + file_dialog = GIMP_FILE_DIALOG (dialog); + + if (file_dialog->image) + { + g_object_remove_weak_pointer (G_OBJECT (file_dialog->image), + (gpointer *) &file_dialog->image); + } + + file_dialog->image = image; + dialog->open_as_layers = open_as_layers; + + if (file_dialog->image) + { + g_object_add_weak_pointer (G_OBJECT (file_dialog->image), + (gpointer *) &file_dialog->image); + } }