diff options
author | Georges Basile Stavracas Neto <georges.stavracas@gmail.com> | 2018-08-02 06:29:33 +0000 |
---|---|---|
committer | Georges Basile Stavracas Neto <georges.stavracas@gmail.com> | 2018-08-16 07:50:31 +0000 |
commit | c1726717bd22707c3d77d36afc16eb190b0c04ed (patch) | |
tree | 950e0436fc96a9e1a17158bc01bec18d3bd7dad6 | |
parent | c9f875bd770bf99ee61ba6b7098e5ca018925f82 (diff) | |
download | gtk+-cherry-pick-5596feae.tar.gz |
listbox: Store child iter in a variable when removingcherry-pick-5596feae
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)
-rw-r--r-- | gtk/gtklistbox.c | 14 |
1 files 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); |