mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-01 19:36:37 +02:00
garray: Add more element_size > 0 checks
The functions g_array_new and g_array_sized_new already protect themselves against a zero element size. Do the same in g_array_new_take and g_array_new_take_zero_terminated to avoid a NULL pointer dereference and an endless loop.
This commit is contained in:
@@ -185,7 +185,7 @@ g_array_new_take (gpointer data,
|
|||||||
|
|
||||||
g_return_val_if_fail (data != NULL || len == 0, NULL);
|
g_return_val_if_fail (data != NULL || len == 0, NULL);
|
||||||
g_return_val_if_fail (len <= G_MAXUINT, NULL);
|
g_return_val_if_fail (len <= G_MAXUINT, NULL);
|
||||||
g_return_val_if_fail (element_size <= G_MAXUINT, NULL);
|
g_return_val_if_fail (element_size > 0 && element_size <= G_MAXUINT, NULL);
|
||||||
|
|
||||||
array = g_array_sized_new (FALSE, clear, element_size, 0);
|
array = g_array_sized_new (FALSE, clear, element_size, 0);
|
||||||
rarray = (GRealArray *) array;
|
rarray = (GRealArray *) array;
|
||||||
@@ -237,7 +237,7 @@ g_array_new_take_zero_terminated (gpointer data,
|
|||||||
GArray *array;
|
GArray *array;
|
||||||
gsize len = 0;
|
gsize len = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (element_size <= G_MAXUINT, NULL);
|
g_return_val_if_fail (element_size > 0 && element_size <= G_MAXUINT, NULL);
|
||||||
|
|
||||||
if (data != NULL)
|
if (data != NULL)
|
||||||
{
|
{
|
||||||
|
@@ -321,6 +321,21 @@ array_new_take_zero_terminated (void)
|
|||||||
g_clear_pointer (&old_data_copy, g_free);
|
g_clear_pointer (&old_data_copy, g_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check that zero terminated arrays with zero size elements are not allowed. */
|
||||||
|
static void
|
||||||
|
array_new_take_zero_terminated_zero_size (void)
|
||||||
|
{
|
||||||
|
gpointer str = g_strdup ("not null");
|
||||||
|
|
||||||
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||||
|
"*assertion 'element_size > 0 && element_size <= G_MAXUINT' failed");
|
||||||
|
g_assert_null (
|
||||||
|
g_array_new_take_zero_terminated (str, FALSE, 0));
|
||||||
|
g_test_assert_expected_messages ();
|
||||||
|
|
||||||
|
g_free (str);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check that a non-existing array becomes a zero-terminated one when requested. */
|
/* Check that a non-existing array becomes a zero-terminated one when requested. */
|
||||||
static void
|
static void
|
||||||
array_new_take_zero_terminated_null (void)
|
array_new_take_zero_terminated_null (void)
|
||||||
@@ -357,13 +372,24 @@ array_new_take_overflow (void)
|
|||||||
g_test_assert_expected_messages ();
|
g_test_assert_expected_messages ();
|
||||||
|
|
||||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||||
"*assertion 'element_size <= G_MAXUINT' failed");
|
"*assertion 'element_size > 0 && element_size <= G_MAXUINT' failed");
|
||||||
g_assert_null (
|
g_assert_null (
|
||||||
g_array_new_take (NULL, 0, FALSE, (gsize) G_MAXUINT + 1));
|
g_array_new_take (NULL, 0, FALSE, (gsize) G_MAXUINT + 1));
|
||||||
g_test_assert_expected_messages ();
|
g_test_assert_expected_messages ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check that arrays with zero size elements are not allowed. */
|
||||||
|
static void
|
||||||
|
array_new_take_zero_size (void)
|
||||||
|
{
|
||||||
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||||
|
"*assertion 'element_size > 0 && element_size <= G_MAXUINT' failed");
|
||||||
|
g_assert_null (
|
||||||
|
g_array_new_take (NULL, 0, FALSE, 0));
|
||||||
|
g_test_assert_expected_messages ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Check g_array_steal() function */
|
/* Check g_array_steal() function */
|
||||||
static void
|
static void
|
||||||
array_steal (void)
|
array_steal (void)
|
||||||
@@ -3240,7 +3266,9 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/array/new/take", array_new_take);
|
g_test_add_func ("/array/new/take", array_new_take);
|
||||||
g_test_add_func ("/array/new/take/empty", array_new_take_empty);
|
g_test_add_func ("/array/new/take/empty", array_new_take_empty);
|
||||||
g_test_add_func ("/array/new/take/overflow", array_new_take_overflow);
|
g_test_add_func ("/array/new/take/overflow", array_new_take_overflow);
|
||||||
|
g_test_add_func ("/array/new/take/zero-size", array_new_take_zero_size);
|
||||||
g_test_add_func ("/array/new/take-zero-terminated", array_new_take_zero_terminated);
|
g_test_add_func ("/array/new/take-zero-terminated", array_new_take_zero_terminated);
|
||||||
|
g_test_add_func ("/array/new/take-zero-terminated/zero-size", array_new_take_zero_terminated_zero_size);
|
||||||
g_test_add_func ("/array/new/take-zero-terminated/null", array_new_take_zero_terminated_null);
|
g_test_add_func ("/array/new/take-zero-terminated/null", array_new_take_zero_terminated_null);
|
||||||
g_test_add_func ("/array/ref-count", array_ref_count);
|
g_test_add_func ("/array/ref-count", array_ref_count);
|
||||||
g_test_add_func ("/array/steal", array_steal);
|
g_test_add_func ("/array/steal", array_steal);
|
||||||
|
Reference in New Issue
Block a user