[glib/glib-2-62: 1/2] garray: Fix copying an array with reserved elements
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/glib-2-62: 1/2] garray: Fix copying an array with reserved elements
- Date: Fri, 28 Feb 2020 13:46:47 +0000 (UTC)
commit d3c92327ce3871a6daa9b8fd227be38b26d790c3
Author: Philip Withnall <withnall endlessm com>
Date: Thu Feb 27 11:20:26 2020 +0000
garray: Fix copying an array with reserved elements
Spotted by Mohammed Sadiq. `g_array_copy()` was doing a `memcpy()` of
the data from the old array to the new one, based on the reserved
elements in the old array (`array->alloc`). However, the new array was
allocated based on the *assigned* elements in the old array
(`array->len`).
So if the old array had fewer assigned elements than allocated elements,
`memcpy()` would fall off the end of the newly allocated data block.
This was particularly obvious when the old array had no assigned
elements, as the new array’s data pointer would be `NULL`.
Signed-off-by: Philip Withnall <withnall endlessm com>
Fixes: #2049
glib/garray.c | 7 +++++--
glib/tests/array-test.c | 27 +++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
---
diff --git a/glib/garray.c b/glib/garray.c
index 38f64b82d..942e74c9f 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -1118,9 +1118,12 @@ g_array_copy (GArray *array)
new_rarray =
(GRealArray *) g_array_sized_new (rarray->zero_terminated, rarray->clear,
- rarray->elt_size, rarray->len);
+ rarray->elt_size, rarray->alloc / rarray->elt_size);
new_rarray->len = rarray->len;
- memcpy (new_rarray->data, rarray->data, rarray->alloc);
+ if (rarray->len > 0)
+ memcpy (new_rarray->data, rarray->data, rarray->len * rarray->elt_size);
+
+ g_array_zero_terminate (new_rarray);
return (GArray *) new_rarray;
}
diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
index b26704e25..3fcf1136a 100644
--- a/glib/tests/array-test.c
+++ b/glib/tests/array-test.c
@@ -760,6 +760,32 @@ test_array_binary_search (void)
g_array_free (garray, TRUE);
}
+static void
+test_array_copy_sized (void)
+{
+ GArray *array1 = NULL, *array2 = NULL, *array3 = NULL;
+ int val = 5;
+
+ g_test_summary ("Test that copying a newly-allocated sized array works.");
+
+ array1 = g_array_sized_new (FALSE, FALSE, sizeof (int), 1);
+ array2 = g_array_copy (array1);
+
+ g_assert_cmpuint (array2->len, ==, array1->len);
+
+ g_array_append_val (array1, val);
+ array3 = g_array_copy (array1);
+
+ g_assert_cmpuint (array3->len, ==, array1->len);
+ g_assert_cmpuint (g_array_index (array3, int, 0), ==, g_array_index (array1, int, 0));
+ g_assert_cmpuint (array3->len, ==, 1);
+ g_assert_cmpuint (g_array_index (array3, int, 0), ==, val);
+
+ g_array_unref (array3);
+ g_array_unref (array2);
+ g_array_unref (array1);
+}
+
static void
pointer_array_add (void)
{
@@ -1681,6 +1707,7 @@ main (int argc, char *argv[])
g_test_add_func ("/array/ref-count", array_ref_count);
g_test_add_func ("/array/clear-func", array_clear_func);
g_test_add_func ("/array/binary-search", test_array_binary_search);
+ g_test_add_func ("/array/copy-sized", test_array_copy_sized);
for (i = 0; i < G_N_ELEMENTS (array_configurations); i++)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]