[gtk/cherry-pick-5596feae] listbox: Store child iter in a variable when removing



commit c1726717bd22707c3d77d36afc16eb190b0c04ed
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Aug 2 06:29:33 2018 +0000

    listbox: Store child iter in a variable when removing
    
    Unparenting a GtkListBoxRow can drop its last reference, which
    will free its memory. Right after unparenting, though, we were
    accessing the row's iter - which assumes that the row is still
    alive. This causes a crash when, for example, binding two or
    more models to the listbox.
    
    Fix that by storing the iter in a variable, and not trying to
    access it after unparenting. After unparenting, the variables
    that are potentially garbage were explicitly assigned NULL for
    clarity.
    
    Fixes https://gitlab.gnome.org/GNOME/gtk/issues/1258
    
    
    (cherry picked from commit 5596feae9b51563a33f1bffc6a370e6ba556adb7)

 gtk/gtklistbox.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtklistbox.c b/gtk/gtklistbox.c
index 6fc931498a..eed5abbadf 100644
--- a/gtk/gtklistbox.c
+++ b/gtk/gtklistbox.c
@@ -2480,6 +2480,7 @@ gtk_list_box_remove (GtkContainer *container,
   gboolean was_visible;
   gboolean was_selected;
   GtkListBoxRow *row;
+  GSequenceIter *iter;
   GSequenceIter *next;
 
   was_visible = gtk_widget_get_visible (child);
@@ -2503,7 +2504,8 @@ gtk_list_box_remove (GtkContainer *container,
     }
 
   row = GTK_LIST_BOX_ROW (child);
-  if (g_sequence_iter_get_sequence (ROW_PRIV (row)->iter) != priv->children)
+  iter = ROW_PRIV (row)->iter;
+  if (g_sequence_iter_get_sequence (iter) != priv->children)
     {
       g_warning ("Tried to remove non-child %p", child);
       return;
@@ -2539,9 +2541,15 @@ gtk_list_box_remove (GtkContainer *container,
   if (row == priv->drag_highlighted_row)
     gtk_list_box_drag_unhighlight_row (box);
 
-  next = gtk_list_box_get_next_visible (box, ROW_PRIV (row)->iter);
+  next = gtk_list_box_get_next_visible (box, iter);
   gtk_widget_unparent (child);
-  g_sequence_remove (ROW_PRIV (row)->iter);
+  g_sequence_remove (iter);
+
+  /* After unparenting, those values are garbage */
+  iter = NULL;
+  row = NULL;
+  child = NULL;
+
   if (gtk_widget_get_visible (widget))
     gtk_list_box_update_header (box, next);
 


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