[Bugfix] Mergesort used in clist
- From: Thomas Schultz <tststs gmx de>
- To: gtk-devel-list gnome org
- Subject: [Bugfix] Mergesort used in clist
- Date: Fri, 1 Sep 2000 00:22:12 +0200
Hi,
In case this has not yet been fixed: Using GTK 1.2.8, I was experiencing
strange segfaults in a GNOME application and when I investigated into it,
I found that there is a problem with gtk_clist_sort(): After calling it,
row_list->prev will not be NULL, as it ought to be.
I believe that in gtkclist.c, z.next->prev should be set to NULL before
returning. I also think I found a few statements that do nothing but waste
processor cycles:
<---->
{
c->next = a;
a->prev = c;
c = a;
a = a->next;
break;
}
<---->
As the "break;" statement leaves the loop and clearly neither c nor a are
used outside of it, changing them doesn't make sense here (it does in
other places, where this fragment seems to have been copy-pasted from).
You'll find that the same is true in the next block.
<---->
if ((cmp >= 0 && clist->sort_type == GTK_SORT_DESCENDING) ||
(cmp <= 0 && clist->sort_type == GTK_SORT_ASCENDING) ||
(a && !b))
<---->
If you look at the code, you'll notice that this point can never be
reached when (a && !b) is true, so testing on it doesn't make sense
either.
For your convenience, I attached a patch as well as a small example
program to reproduce the bug.
BTW, thanks for a great product that's getting better all the time :-)
Kind regards,
Thomas Schultz
P.S.: I just subscribed to this list; if it is not the right place for
such bugreports, I'd be grateful for a pointer. I also could not find a
"known bugs" page for GTK 1.2.8 - in case this problem is already fixed,
it would certainly have saved me several hours of debugging. Does
something like this exist?
--- gtk/gtkclist.c.orig Thu Aug 31 22:01:28 2000
+++ gtk/gtkclist.c Thu Aug 31 22:24:50 2000
@@ -7350,24 +7350,19 @@
{
c->next = a;
a->prev = c;
- c = a;
- a = a->next;
break;
}
else if (!a && b)
{
c->next = b;
b->prev = c;
- c = b;
- b = b->next;
break;
}
else /* a && b */
{
cmp = clist->compare (clist, GTK_CLIST_ROW (a), GTK_CLIST_ROW (b));
if ((cmp >= 0 && clist->sort_type == GTK_SORT_DESCENDING) ||
- (cmp <= 0 && clist->sort_type == GTK_SORT_ASCENDING) ||
- (a && !b))
+ (cmp <= 0 && clist->sort_type == GTK_SORT_ASCENDING))
{
c->next = a;
a->prev = c;
@@ -7384,6 +7379,7 @@
}
}
+ z.next->prev = NULL;
return z.next;
}
#include <gtk/gtk.h>
/* This callback will crash the application. */
void crash(gpointer data)
{
gtk_clist_sort(GTK_CLIST(data));
while (GTK_CLIST(data)->rows)
{
gtk_clist_remove((GtkCList *) data, 0);
}
}
int main(int argc, gchar *argv[])
{
GtkWidget *window, *vbox, *clist, *button;
gchar *clist_data[2][1] = {{"A"},{"Z"}};
int i;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);
clist = gtk_clist_new(1);
for (i = 0; i < 2; ++i)
gtk_clist_append(GTK_CLIST(clist), clist_data[i]);
gtk_box_pack_start(GTK_BOX(vbox), clist, FALSE, FALSE, 0);
gtk_widget_show(clist);
button = gtk_button_new_with_label("Crash");
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(crash), (gpointer) clist);
gtk_widget_show(button);
gtk_widget_show(window);
gtk_main();
return(0);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]