After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 573380 - gtk_tree_model_iter_parent() fails if the same iterator is used for iter and child.
gtk_tree_model_iter_parent() fails if the same iterator is used for iter and ...
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkTreeView
2.15.x
Other All
: Normal minor
: ---
Assigned To: gtktreeview-bugs
gtktreeview-bugs
Depends on:
Blocks:
 
 
Reported: 2009-02-27 11:41 UTC by Michael Hasselmann
Modified: 2016-04-05 15:02 UTC
See Also:
GNOME target: ---
GNOME version: 2.23/2.24


Attachments
documentation patch (1.18 KB, patch)
2016-04-01 09:29 UTC, Wouter Verhelst
committed Details | Review

Description Michael Hasselmann 2009-02-27 11:41:42 UTC
Documentation 
Section: GtkTreeModel
Sets iter to be the parent of child. If child is at the toplevel, and doesn't have a parent, then iter is set to an invalid iterator and FALSE is returned. child will remain a valid node after this function has been called.

Correct version:
Sets iter to be the parent of child. If child is at the toplevel, and doesn't have a parent, then iter is set to an invalid iterator and FALSE is returned. child will remain a valid node after this function has been called. If iter and child point to the same iterator this function will fail.


Other information:
Another solution could be to make a local copy of child before iter is initialized.
Comment 1 Murray Cumming 2009-02-27 11:48:58 UTC
>  If iter and child point to the same iterator this function will fail.

If that's intended then I (not a GKT+ maintainer) would like to see a g_warning() for it in the code.

> Another solution could be to make a local copy of child before iter is
initialized.

Yes. To be clear, this would allow the caller to forget the child iter, just changing it to be the parent iter. 
Comment 2 Mathias Hasselmann (IRC: tbf) 2009-02-28 20:36:07 UTC
The problem is, that the invariant "child != iter" is specified but not enforced. The straight forward fix would be to verify this precondition:

   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
   g_return_val_if_fail (iter != NULL, FALSE);
   g_return_val_if_fail (child != NULL, FALSE);
+  g_return_val_if_fail (iter != child, FALSE);
 
   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
   g_return_val_if_fail (iface->iter_parent != NULL, FALSE);
 
Well, but it seems to be possible to allow "child == iter" by adding similarly efficient code:

diff --git a/gtk/gtktreemodel.c b/gtk/gtktreemodel.c
index c8cc7b2..3af92bb 100644
--- a/gtk/gtktreemodel.c
+++ b/gtk/gtktreemodel.c
@@ -1304,14 +1304,21 @@ gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
                            GtkTreeIter  *child)
 {
   GtkTreeModelIface *iface;
+  GtkTreeIter local_child;
 
   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
   g_return_val_if_fail (iter != NULL, FALSE);
   g_return_val_if_fail (child != NULL, FALSE);
-  
+
   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
   g_return_val_if_fail (iface->iter_parent != NULL, FALSE);
 
+  if (G_UNLIKELY (iter == child))
+    {
+      local_child = *child;
+      child = &local_child;
+    }
+
   INITIALIZE_TREE_ITER (iter);
 
   return (* iface->iter_parent) (tree_model, iter, child);
Comment 3 Wouter Verhelst 2016-03-31 09:25:01 UTC
This bug has existed since 2009, and no resolution has occurred.

Can at least the documentation be updated? I just spent an inordinate amount of time tracking down why my code didn't work because of this...
Comment 4 Murray Cumming 2016-04-01 09:11:57 UTC
A patch might be helpful.
Comment 5 Wouter Verhelst 2016-04-01 09:29:20 UTC
Created attachment 325136 [details] [review]
documentation patch
Comment 6 Matthias Clasen 2016-04-02 16:32:10 UTC
Review of attachment 325136 [details] [review]:

Sure