Bad bug in gsequence
- From: Soeren Sandmann <sandmann daimi au dk>
- To: nautilus-list gnome org
- Cc: federico ximian com
- Subject: Bad bug in gsequence
- Date: 02 Dec 2006 22:56:52 +0100
There is a bad bug in the version of EggSequence that nautilus is
using. Basically it will sometimes cast the data pointer you insert
into it to an EggSequence *, then attempt to read the first member.
If that read succeeds, it will then compare the data to the
end-iterator for the sequence. If they match, various bad things will
happen.
I believe for nautilus this is likely harmless as the dereferenced
memory is valid, and the items inserted are FileEntries whose first
member is a pointer to NautilusFile, which can never match the
end-iterator for the sequence.
The attached patch, by James Livingston, fixes it. It should certainly
be applied to HEAD, and probably also stable.
This is bug http://bugzilla.gnome.org/show_bug.cgi?id=350579 against
libegg/sequence.
Søren
? seq-fix
Index: gsequence.c
===================================================================
RCS file: /cvs/gnome/nautilus/cut-n-paste-code/gsequence/gsequence.c,v
retrieving revision 1.4
diff -u -r1.4 gsequence.c
--- gsequence.c 25 Jul 2006 13:55:49 -0000 1.4
+++ gsequence.c 2 Dec 2006 21:36:32 -0000
@@ -51,6 +51,7 @@
gint pos);
static GSequenceNode *node_find_closest (GSequenceNode *haystack,
GSequenceNode *needle,
+ GSequenceNode *end,
GSequenceIterCompareFunc cmp,
gpointer user_data);
static gint node_get_length (GSequenceNode *node);
@@ -64,6 +65,7 @@
static void node_unlink (GSequenceNode *node);
static void node_insert_sorted (GSequenceNode *node,
GSequenceNode *new,
+ GSequenceNode *end,
GSequenceIterCompareFunc cmp_func,
gpointer cmp_data);
@@ -411,6 +413,7 @@
{
GCompareDataFunc cmp_func;
gpointer cmp_data;
+ GSequenceNode *end_node;
} SortInfo;
/* This function compares two iters using a normal compare
@@ -424,10 +427,10 @@
const SortInfo *info = data;
gint retval;
- if (is_end (node1))
+ if (node1 == info->end_node)
return 1;
- if (is_end (node2))
+ if (node2 == info->end_node)
return -1;
retval = info->cmp_func (node1->data, node2->data, info->cmp_data);
@@ -452,7 +455,7 @@
GCompareDataFunc cmp_func,
gpointer cmp_data)
{
- SortInfo info = { cmp_func, cmp_data };
+ SortInfo info = { cmp_func, cmp_data, seq->end_node };
check_seq_access (seq);
@@ -480,11 +483,12 @@
GCompareDataFunc cmp_func,
gpointer cmp_data)
{
- SortInfo info = { cmp_func, cmp_data };
+ SortInfo info = { cmp_func, cmp_data, NULL };
g_return_val_if_fail (seq != NULL, NULL);
g_return_val_if_fail (cmp_func != NULL, NULL);
+ info.end_node = seq->end_node;
check_seq_access (seq);
return g_sequence_insert_sorted_iter (seq, data, iter_compare, &info);
@@ -495,10 +499,11 @@
GCompareDataFunc cmp_func,
gpointer cmp_data)
{
- SortInfo info = { cmp_func, cmp_data };
+ SortInfo info = { cmp_func, cmp_data, NULL };
g_return_if_fail (!is_end (iter));
+ info.end_node = get_sequence (iter)->end_node;
check_iter_access (iter);
g_sequence_sort_changed_iter (iter, iter_compare, &info);
@@ -533,7 +538,7 @@
node_unlink (node);
- node_insert_sorted (seq->end_node, node, cmp_func, cmp_data);
+ node_insert_sorted (seq->end_node, node, seq->end_node, cmp_func, cmp_data);
}
tmp->access_prohibited = FALSE;
@@ -558,7 +563,7 @@
seq->access_prohibited = TRUE;
node_unlink (iter);
- node_insert_sorted (seq->end_node, iter, iter_cmp, cmp_data);
+ node_insert_sorted (seq->end_node, iter, seq->end_node, iter_cmp, cmp_data);
seq->access_prohibited = FALSE;
}
@@ -574,7 +579,7 @@
check_seq_access (seq);
new_node = node_new (data);
- node_insert_sorted (seq->end_node, new_node, iter_cmp, cmp_data);
+ node_insert_sorted (seq->end_node, new_node, seq->end_node, iter_cmp, cmp_data);
return new_node;
}
@@ -595,7 +600,7 @@
dummy = node_new (data);
- node = node_find_closest (seq->end_node, dummy, cmp_func, cmp_data);
+ node = node_find_closest (seq->end_node, dummy, seq->end_node, cmp_func, cmp_data);
node_free (dummy, NULL);
@@ -624,10 +629,11 @@
GCompareDataFunc cmp_func,
gpointer cmp_data)
{
- SortInfo info = { cmp_func, cmp_data };
+ SortInfo info = { cmp_func, cmp_data, NULL };
g_return_val_if_fail (seq != NULL, NULL);
+ info.end_node = seq->end_node;
check_seq_access (seq);
return g_sequence_search_iter (seq, data, iter_compare, &info);
@@ -1109,6 +1115,7 @@
static GSequenceNode *
node_find_closest (GSequenceNode *haystack,
GSequenceNode *needle,
+ GSequenceNode *end,
GSequenceIterCompareFunc cmp_func,
gpointer cmp_data)
{
@@ -1123,7 +1130,7 @@
{
best = haystack;
- if (is_end (haystack))
+ if (haystack == end)
c = 1;
else
c = cmp_func (haystack, needle, cmp_data);
@@ -1285,12 +1292,13 @@
static void
node_insert_sorted (GSequenceNode *node,
GSequenceNode *new,
+ GSequenceNode *end,
GSequenceIterCompareFunc cmp_func,
gpointer cmp_data)
{
GSequenceNode *closest;
- closest = node_find_closest (node, new, cmp_func, cmp_data);
+ closest = node_find_closest (node, new, end, cmp_func, cmp_data);
node_insert_before (closest, new);
}
Index: gsequence.h
===================================================================
RCS file: /cvs/gnome/nautilus/cut-n-paste-code/gsequence/gsequence.h,v
retrieving revision 1.2
diff -u -r1.2 gsequence.h
--- gsequence.h 25 Jul 2006 13:55:49 -0000 1.2
+++ gsequence.h 2 Dec 2006 21:36:32 -0000
@@ -26,6 +26,7 @@
typedef struct _GSequenceNode GSequenceIter;
+
typedef gint (* GSequenceIterCompareFunc) (GSequenceIter *a,
GSequenceIter *b,
gpointer data);
@@ -65,6 +66,8 @@
gpointer data);
void g_sequence_move (GSequenceIter * src,
GSequenceIter * dest);
+void g_sequence_swap (GSequenceIter * a,
+ GSequenceIter * b);
GSequenceIter *g_sequence_insert_sorted (GSequence *seq,
gpointer data,
GCompareDataFunc cmp_func,
@@ -110,8 +113,6 @@
GSequenceIter *g_sequence_iter_move (GSequenceIter * iter,
gint leap);
GSequence * g_sequence_iter_get_sequence (GSequenceIter * iter);
-void g_sequence_swap (GSequenceIter *a,
- GSequenceIter *b);
/* search */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]