[gtk+] Bug 586374 – code does not follow documentation
- From: Kristian Rietveld <kristian src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+] Bug 586374 – code does not follow documentation
- Date: Thu, 30 Jul 2009 19:38:28 +0000 (UTC)
commit d743b2fbeab01f9a9904712a5b751afd0519696d
Author: Kristian Rietveld <kris gtk org>
Date: Thu Jul 30 21:23:47 2009 +0200
Bug 586374 â?? code does not follow documentation
Properly invalidate iterators in iter_next, iter_children,
iter_nth_child and iter_parent when FALSE is returned. ListStore was
actually already mostly in order as the GSequence pointers are very
strictly checked, but to be a little stricter we've added stamp = 0
lines. TreeStore did not invalidate its iterators, so stamp = 0 lines
were added where appropriate. Unit tests have been added to check this.
Fixes bug 586374, reported by Mike Gemunde.
gtk/gtkliststore.c | 21 +++++++++++--
gtk/gtktreestore.c | 20 ++++++++++--
gtk/tests/liststore.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++
gtk/tests/treestore.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 194 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c
index 470c9f8..dd28629 100644
--- a/gtk/gtkliststore.c
+++ b/gtk/gtkliststore.c
@@ -494,10 +494,16 @@ static gboolean
gtk_list_store_iter_next (GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
+ gboolean retval;
+
g_return_val_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp, FALSE);
iter->user_data = g_sequence_iter_next (iter->user_data);
- return !g_sequence_iter_is_end (iter->user_data);
+ retval = g_sequence_iter_is_end (iter->user_data);
+ if (retval)
+ iter->stamp = 0;
+
+ return !retval;
}
static gboolean
@@ -509,7 +515,10 @@ gtk_list_store_iter_children (GtkTreeModel *tree_model,
/* this is a list, nodes have no children */
if (parent)
- return FALSE;
+ {
+ iter->stamp = 0;
+ return FALSE;
+ }
if (g_sequence_get_length (list_store->seq) > 0)
{
@@ -518,7 +527,10 @@ gtk_list_store_iter_children (GtkTreeModel *tree_model,
return TRUE;
}
else
- return FALSE;
+ {
+ iter->stamp = 0;
+ return FALSE;
+ }
}
static gboolean
@@ -551,6 +563,8 @@ gtk_list_store_iter_nth_child (GtkTreeModel *tree_model,
GtkListStore *list_store = (GtkListStore *) tree_model;
GSequenceIter *child;
+ iter->stamp = 0;
+
if (parent)
return FALSE;
@@ -570,6 +584,7 @@ gtk_list_store_iter_parent (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *child)
{
+ iter->stamp = 0;
return FALSE;
}
diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c
index 1fb178d..9708408 100644
--- a/gtk/gtktreestore.c
+++ b/gtk/gtktreestore.c
@@ -620,7 +620,10 @@ gtk_tree_store_iter_next (GtkTreeModel *tree_model,
return TRUE;
}
else
- return FALSE;
+ {
+ iter->stamp = 0;
+ return FALSE;
+ }
}
static gboolean
@@ -646,7 +649,10 @@ gtk_tree_store_iter_children (GtkTreeModel *tree_model,
return TRUE;
}
else
- return FALSE;
+ {
+ iter->stamp = 0;
+ return FALSE;
+ }
}
static gboolean
@@ -708,7 +714,10 @@ gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
return TRUE;
}
else
- return FALSE;
+ {
+ iter->stamp = 0;
+ return FALSE;
+ }
}
static gboolean
@@ -733,7 +742,10 @@ gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
return TRUE;
}
else
- return FALSE;
+ {
+ iter->stamp = 0;
+ return FALSE;
+ }
}
diff --git a/gtk/tests/liststore.c b/gtk/tests/liststore.c
index 588f725..6452fc2 100644
--- a/gtk/tests/liststore.c
+++ b/gtk/tests/liststore.c
@@ -850,6 +850,72 @@ list_store_test_move_before_single (void)
g_object_unref (store);
}
+
+/* iter invalidation */
+
+static void
+list_store_test_iter_next_invalid (ListStore *fixture,
+ gconstpointer user_data)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ path = gtk_tree_path_new_from_indices (4, -1);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+ gtk_tree_path_free (path);
+
+ g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store),
+ &iter) == FALSE);
+ g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
+ g_assert (iter.stamp == 0);
+}
+
+static void
+list_store_test_iter_children_invalid (ListStore *fixture,
+ gconstpointer user_data)
+{
+ GtkTreeIter iter, child;
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+ g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
+
+ g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
+ &child, &iter) == FALSE);
+ g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
+ g_assert (child.stamp == 0);
+}
+
+static void
+list_store_test_iter_nth_child_invalid (ListStore *fixture,
+ gconstpointer user_data)
+{
+ GtkTreeIter iter, child;
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+ g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
+
+ g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
+ &child, &iter, 0) == FALSE);
+ g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
+ g_assert (child.stamp == 0);
+}
+
+static void
+list_store_test_iter_parent_invalid (ListStore *fixture,
+ gconstpointer user_data)
+{
+ GtkTreeIter iter, child;
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child);
+ g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == TRUE);
+
+ g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
+ &iter, &child) == FALSE);
+ g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
+ g_assert (iter.stamp == 0);
+}
+
+
/* main */
int
@@ -958,5 +1024,19 @@ main (int argc,
g_test_add_func ("/list-store/move-before-single",
list_store_test_move_before_single);
+ /* iter invalidation */
+ g_test_add ("/list-store/iter-next-invalid", ListStore, NULL,
+ list_store_setup, list_store_test_iter_next_invalid,
+ list_store_teardown);
+ g_test_add ("/list-store/iter-children-invalid", ListStore, NULL,
+ list_store_setup, list_store_test_iter_children_invalid,
+ list_store_teardown);
+ g_test_add ("/list-store/iter-nth-child-invalid", ListStore, NULL,
+ list_store_setup, list_store_test_iter_nth_child_invalid,
+ list_store_teardown);
+ g_test_add ("/list-store/iter-parent-invalid", ListStore, NULL,
+ list_store_setup, list_store_test_iter_parent_invalid,
+ list_store_teardown);
+
return g_test_run ();
}
diff --git a/gtk/tests/treestore.c b/gtk/tests/treestore.c
index e3a85c9..c9dbcff 100644
--- a/gtk/tests/treestore.c
+++ b/gtk/tests/treestore.c
@@ -853,6 +853,72 @@ tree_store_test_move_before_single (void)
g_object_unref (store);
}
+
+/* iter invalidation */
+
+static void
+tree_store_test_iter_next_invalid (TreeStore *fixture,
+ gconstpointer user_data)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ path = gtk_tree_path_new_from_indices (4, -1);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+ gtk_tree_path_free (path);
+
+ g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store),
+ &iter) == FALSE);
+ g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE);
+ g_assert (iter.stamp == 0);
+}
+
+static void
+tree_store_test_iter_children_invalid (TreeStore *fixture,
+ gconstpointer user_data)
+{
+ GtkTreeIter iter, child;
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+ g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == TRUE);
+
+ g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
+ &child, &iter) == FALSE);
+ g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == FALSE);
+ g_assert (child.stamp == 0);
+}
+
+static void
+tree_store_test_iter_nth_child_invalid (TreeStore *fixture,
+ gconstpointer user_data)
+{
+ GtkTreeIter iter, child;
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+ g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == TRUE);
+
+ g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
+ &child, &iter, 0) == FALSE);
+ g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == FALSE);
+ g_assert (child.stamp == 0);
+}
+
+static void
+tree_store_test_iter_parent_invalid (TreeStore *fixture,
+ gconstpointer user_data)
+{
+ GtkTreeIter iter, child;
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child);
+ g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == TRUE);
+
+ g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
+ &iter, &child) == FALSE);
+ g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE);
+ g_assert (iter.stamp == 0);
+}
+
+
/* main */
int
@@ -961,5 +1027,19 @@ main (int argc,
g_test_add_func ("/tree-store/move-before-single",
tree_store_test_move_before_single);
+ /* iter invalidation */
+ g_test_add ("/tree-store/iter-next-invalid", TreeStore, NULL,
+ tree_store_setup, tree_store_test_iter_next_invalid,
+ tree_store_teardown);
+ g_test_add ("/tree-store/iter-children-invalid", TreeStore, NULL,
+ tree_store_setup, tree_store_test_iter_children_invalid,
+ tree_store_teardown);
+ g_test_add ("/tree-store/iter-nth-child-invalid", TreeStore, NULL,
+ tree_store_setup, tree_store_test_iter_nth_child_invalid,
+ tree_store_teardown);
+ g_test_add ("/tree-store/iter-parent-invalid", TreeStore, NULL,
+ tree_store_setup, tree_store_test_iter_parent_invalid,
+ tree_store_teardown);
+
return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]