[gimp] Bug 722975 - crash when removing tag from palette while filtering by same tag



commit 7fca15c27dd944890a67bb6db90c0b1fd4238f2f
Author: Michael Natterer <mitch gimp org>
Date:   Sun Jan 26 21:03:28 2014 +0100

    Bug 722975 - crash when removing tag from palette while filtering by same tag
    
    Each of the following cleans up tag refcounting, fixes access to
    released memory, or other small glitches. Not sure which change
    actually fixed the bug:
    
    gimp_data_remove_tag(): remove the found tag, not the passed in tag
    (which is to be treated only as a value for comparison).
    
    gimp_tagged_remove_tag(): don't continue the loop after the tag to
    remove has been found, there can only be one matching tag, and the
    list element has become invalid.
    
    gimptagentry.c: keep references around for the members of
    entry->common_tags, and make sure the references are always dropped
    properly. In assign_tags(), reference the "add" and "remove" lists for
    paranoia and safety reasons.

 app/core/gimpdata.c        |    2 +-
 app/core/gimptagged.c      |    2 ++
 app/widgets/gimptagentry.c |   26 ++++++++++++++------------
 3 files changed, 17 insertions(+), 13 deletions(-)
---
diff --git a/app/core/gimpdata.c b/app/core/gimpdata.c
index ec267d1..9db220f 100644
--- a/app/core/gimpdata.c
+++ b/app/core/gimpdata.c
@@ -421,7 +421,7 @@ gimp_data_remove_tag (GimpTagged *tagged,
       if (gimp_tag_equals (tag, this))
         {
           private->tags = g_list_delete_link (private->tags, list);
-          g_object_unref (tag);
+          g_object_unref (this);
           return TRUE;
         }
     }
diff --git a/app/core/gimptagged.c b/app/core/gimptagged.c
index 9c44940..b04304a 100644
--- a/app/core/gimptagged.c
+++ b/app/core/gimptagged.c
@@ -153,6 +153,8 @@ gimp_tagged_remove_tag (GimpTagged *tagged,
             }
 
           g_object_unref (tag_ref);
+
+          return;
         }
     }
 }
diff --git a/app/widgets/gimptagentry.c b/app/widgets/gimptagentry.c
index 471a873..5e1bdfd 100644
--- a/app/widgets/gimptagentry.c
+++ b/app/widgets/gimptagentry.c
@@ -228,7 +228,7 @@ gimp_tag_entry_dispose (GObject *object)
 
   if (entry->common_tags)
     {
-      g_list_free (entry->common_tags);
+      g_list_free_full (entry->common_tags, (GDestroyNotify) g_object_unref);
       entry->common_tags = NULL;
     }
 
@@ -762,7 +762,7 @@ gimp_tag_entry_assign_tags (GimpTagEntry *tag_entry)
             }
           else
             {
-              add_list = g_list_prepend (add_list, tag);
+              add_list = g_list_prepend (add_list, g_object_ref (tag));
             }
 
           common_tags = g_list_prepend (common_tags, tag);
@@ -779,7 +779,8 @@ gimp_tag_entry_assign_tags (GimpTagEntry *tag_entry)
       if (! g_list_find_custom (dont_remove_list, tag_iter->data,
                                 gimp_tag_compare_func))
         {
-          remove_list = g_list_prepend (remove_list, tag_iter->data);
+          remove_list = g_list_prepend (remove_list,
+                                        g_object_ref (tag_iter->data));
         }
     }
 
@@ -793,20 +794,20 @@ gimp_tag_entry_assign_tags (GimpTagEntry *tag_entry)
 
       for (tag_iter = remove_list; tag_iter; tag_iter = g_list_next (tag_iter))
         {
-          gimp_tagged_remove_tag (tagged, GIMP_TAG (tag_iter->data));
+          gimp_tagged_remove_tag (tagged, tag_iter->data);
         }
 
       for (tag_iter = add_list; tag_iter; tag_iter = g_list_next (tag_iter))
         {
-          gimp_tagged_add_tag (tagged, GIMP_TAG (tag_iter->data));
+          gimp_tagged_add_tag (tagged, tag_iter->data);
         }
     }
 
-  g_list_free (add_list);
-  g_list_free (remove_list);
+  g_list_free_full (add_list, (GDestroyNotify) g_object_unref);
+  g_list_free_full (remove_list, (GDestroyNotify) g_object_unref);
 
   /* common tags list with changes applied. */
-  g_list_free (tag_entry->common_tags);
+  g_list_free_full (tag_entry->common_tags, (GDestroyNotify) g_object_unref);
   tag_entry->common_tags = common_tags;
 }
 
@@ -904,7 +905,7 @@ gimp_tag_entry_set_selected_items (GimpTagEntry *tag_entry,
 
   if (tag_entry->common_tags)
     {
-      g_list_free (tag_entry->common_tags);
+      g_list_free_full (tag_entry->common_tags, (GDestroyNotify) g_object_unref);
       tag_entry->common_tags = NULL;
     }
 
@@ -957,7 +958,7 @@ gimp_tag_entry_load_selection (GimpTagEntry *tag_entry,
         }
     }
 
-  g_hash_table_foreach (refcounts, gimp_tag_entry_find_common_tags,tag_entry);
+  g_hash_table_foreach (refcounts, gimp_tag_entry_find_common_tags, tag_entry);
 
   g_hash_table_destroy (refcounts);
 
@@ -997,7 +998,8 @@ gimp_tag_entry_find_common_tags (gpointer key,
   /* FIXME: more efficient list length */
   if (ref_count == g_list_length (tag_entry->selected_items))
     {
-      tag_entry->common_tags = g_list_prepend (tag_entry->common_tags, key);
+      tag_entry->common_tags = g_list_prepend (tag_entry->common_tags,
+                                               g_object_ref (key));
     }
 }
 
@@ -1216,7 +1218,7 @@ gimp_tag_entry_container_changed (GimpContainer *container,
         {
           if (gimp_tagged_get_tags (GIMP_TAGGED (list->data)) &&
               gimp_container_have (GIMP_CONTAINER (tag_entry->container),
-                                   GIMP_OBJECT(list->data)))
+                                   GIMP_OBJECT (list->data)))
             {
               break;
             }


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