From: Sven Herzberg Date: Wed, 13 Jan 2010 13:47:58 +0000 (+0100) Subject: properly abort instead of looping infinitely X-Git-Tag: 2.23.2~23 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7448eb71c3ac85a08c8f0fceaf9747e6298ae5c9;p=platform%2Fupstream%2Fglib.git properly abort instead of looping infinitely Fixes: Bug 568760 - nautilus freezes due to a bug in garray.c:322 * glib/garray.c: increase the size of potential return values by using an unsigned result; properly check if we still handle valid size proposals, return the original request if there's no usable size left * tests/array-test.c: reproduce the error condition of the bug report --- diff --git a/glib/garray.c b/glib/garray.c index b439000..d4eae12 100644 --- a/glib/garray.c +++ b/glib/garray.c @@ -67,9 +67,9 @@ struct _GRealArray g_array_elt_zero ((array), (array)->len, 1); \ }G_STMT_END -static gint g_nearest_pow (gint num) G_GNUC_CONST; -static void g_array_maybe_expand (GRealArray *array, - gint len); +static guint g_nearest_pow (gint num) G_GNUC_CONST; +static void g_array_maybe_expand (GRealArray *array, + gint len); GArray* g_array_new (gboolean zero_terminated, @@ -387,16 +387,18 @@ g_array_sort_with_data (GArray *farray, user_data); } - -static gint +/* Returns the smallest power of 2 greater than n, or n if + * such power does not fit in a guint + */ +static guint g_nearest_pow (gint num) { - gint n = 1; + guint n = 1; - while (n < num) + while (n < num && n > 0) n <<= 1; - return n; + return n ? n : num; } static void diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c index 86308e0..949120b 100644 --- a/glib/tests/array-test.c +++ b/glib/tests/array-test.c @@ -28,6 +28,7 @@ #undef G_LOG_DOMAIN #include +#include #include #include "glib.h" @@ -100,6 +101,26 @@ array_ref_count (void) } static void +array_large_size (void) +{ + GArray* array; + + g_test_bug ("568760"); + + array = g_array_new (TRUE, TRUE, sizeof (char)); + + /* it might take really long until the allocation happens */ + if (g_test_trap_fork (10 /* s */ * 1000 /* ms */ * 1000 /* µs */, 0)) + { + g_array_set_size (array, 1073750016); + exit (0); /* success */ + } + g_test_trap_assert_passed (); + + g_array_free (array, TRUE); +} + +static void pointer_array_add (void) { GPtrArray *gparray; @@ -288,10 +309,13 @@ main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); + g_test_bug_base ("http://bugs.gnome.org/%s"); + /* array tests */ g_test_add_func ("/array/append", array_append); g_test_add_func ("/array/prepend", array_prepend); g_test_add_func ("/array/ref-count", array_ref_count); + g_test_add_func ("/array/large-size", array_large_size); /* pointer arrays */ g_test_add_func ("/pointerarray/add", pointer_array_add);