[gimp] app: fix segfault when closing an image with a floating selection



commit d7e3a1e22653127fd7b0a390ba42ed6d954a25e7
Author: Ell <ell_se yahoo com>
Date:   Tue Mar 5 09:29:02 2019 -0500

    app: fix segfault when closing an image with a floating selection
    
    Add gimp_item_tree_clear(), which removes all the items of a
    GimpItemTree, and clear the layers/channels/vectors item trees in
    gimp_image_dispose(), *before* finalizing the image, so that the
    corresponding items' desctructors are called while the image is
    still alive.  In particular, this allows the destructors to safely
    call gimp_item_is_attached(), which happens when the image has a
    floating selection, since commit
    8d4e5e0ff714a30f2f0a00058d46e376828b80bf.

 app/core/gimpimage.c    |  9 +++------
 app/core/gimpitemtree.c | 30 ++++++++++++++++++++++++++++++
 app/core/gimpitemtree.h |  2 ++
 3 files changed, 35 insertions(+), 6 deletions(-)
---
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 88df99f5c4..28aa0c1f4e 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -1032,12 +1032,9 @@ gimp_image_dispose (GObject *object)
                                         gimp_image_channel_remove,
                                         image);
 
-  gimp_container_foreach (private->layers->container,
-                          (GFunc) gimp_item_removed, NULL);
-  gimp_container_foreach (private->channels->container,
-                          (GFunc) gimp_item_removed, NULL);
-  gimp_container_foreach (private->vectors->container,
-                          (GFunc) gimp_item_removed, NULL);
+  gimp_item_tree_clear (private->layers);
+  gimp_item_tree_clear (private->channels);
+  gimp_item_tree_clear (private->vectors);
 
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
diff --git a/app/core/gimpitemtree.c b/app/core/gimpitemtree.c
index 247f3b8648..2e45d6da57 100644
--- a/app/core/gimpitemtree.c
+++ b/app/core/gimpitemtree.c
@@ -66,6 +66,7 @@ struct _GimpItemTreePrivate
 /*  local function prototypes  */
 
 static void     gimp_item_tree_constructed   (GObject      *object);
+static void     gimp_item_tree_dispose       (GObject      *object);
 static void     gimp_item_tree_finalize      (GObject      *object);
 static void     gimp_item_tree_set_property  (GObject      *object,
                                               guint         property_id,
@@ -96,6 +97,7 @@ gimp_item_tree_class_init (GimpItemTreeClass *klass)
   GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
 
   object_class->constructed      = gimp_item_tree_constructed;
+  object_class->dispose          = gimp_item_tree_dispose;
   object_class->finalize         = gimp_item_tree_finalize;
   object_class->set_property     = gimp_item_tree_set_property;
   object_class->get_property     = gimp_item_tree_get_property;
@@ -158,6 +160,16 @@ gimp_item_tree_constructed (GObject *object)
                                   NULL);
 }
 
+static void
+gimp_item_tree_dispose (GObject *object)
+{
+  GimpItemTree *tree = GIMP_ITEM_TREE (object);
+
+  gimp_item_tree_clear (tree);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
 static void
 gimp_item_tree_finalize (GObject *object)
 {
@@ -384,6 +396,24 @@ gimp_item_tree_get_insert_pos (GimpItemTree  *tree,
   return TRUE;
 }
 
+void
+gimp_item_tree_clear (GimpItemTree *tree)
+{
+  GimpItemTreePrivate *private;
+
+  g_return_if_fail (GIMP_IS_ITEM_TREE (tree));
+
+  private = GIMP_ITEM_TREE_GET_PRIVATE (tree);
+
+  gimp_item_tree_set_active_item (tree, NULL);
+
+  gimp_container_foreach (tree->container,
+                          (GFunc) gimp_item_removed, NULL);
+
+  gimp_container_clear (tree->container);
+  g_hash_table_remove_all (private->name_hash);
+}
+
 void
 gimp_item_tree_add_item (GimpItemTree *tree,
                          GimpItem     *item,
diff --git a/app/core/gimpitemtree.h b/app/core/gimpitemtree.h
index 4d3c6eaf1f..3b9b84a6eb 100644
--- a/app/core/gimpitemtree.h
+++ b/app/core/gimpitemtree.h
@@ -64,6 +64,8 @@ gboolean       gimp_item_tree_get_insert_pos   (GimpItemTree  *tree,
                                                 GimpItem     **parent,
                                                 gint          *position);
 
+void           gimp_item_tree_clear            (GimpItemTree  *tree);
+
 void           gimp_item_tree_add_item         (GimpItemTree  *tree,
                                                 GimpItem      *item,
                                                 GimpItem      *parent,


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