[glib: 1/2] gvariant: Handle empty serialisations in get_child_value()
- From: Sebastian Dröge <sdroege src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/2] gvariant: Handle empty serialisations in get_child_value()
- Date: Tue, 24 Sep 2019 17:02:08 +0000 (UTC)
commit efe5b701926e01e278ad22afd59a94f2fa7b3fe3
Author: Philip Withnall <withnall endlessm com>
Date: Tue Aug 20 15:17:40 2019 +0300
gvariant: Handle empty serialisations in get_child_value()
When g_variant_get_child_value() is called for a child whose
serialisation is an empty byte string (which is possible), `bytes_data`
will be non-`NULL`, but `data` may be `NULL`. This results in a negative
offset being passed to `g_bytes_new_from_bytes()`, and a critical
warning.
So if `data` is `NULL`, set it to point to `bytes_data` so the offset is
calculated as zero. The actual value of the offset doesn’t matter, since
in this situation the size is always zero. An offset of zero is never
going to cause problems.
Signed-off-by: Philip Withnall <withnall endlessm com>
Fixes: #1865
glib/gvariant-core.c | 6 ++++++
glib/tests/gvariant.c | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
---
diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
index 123220c1d..9397573a3 100644
--- a/glib/gvariant-core.c
+++ b/glib/gvariant-core.c
@@ -949,6 +949,12 @@ g_variant_get_data_as_bytes (GVariant *value)
data = value->contents.serialised.data;
size = value->size;
+ if (data == NULL)
+ {
+ g_assert (size == 0);
+ data = bytes_data;
+ }
+
if (data == bytes_data && size == bytes_size)
return g_bytes_ref (value->contents.serialised.bytes);
else
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index ce413bedf..927ae4e12 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -2303,6 +2303,46 @@ test_byteswaps (void)
g_variant_type_info_assert_no_infos ();
}
+static void
+test_serialiser_children (void)
+{
+ GBytes *data1, *data2;
+ GVariant *child1, *child2;
+ GVariantType *mv_type = g_variant_type_new_maybe (G_VARIANT_TYPE_VARIANT);
+ GVariant *variant, *child;
+
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1865");
+ g_test_summary ("Test that getting a child variant before and after "
+ "serialisation of the parent works");
+
+ /* Construct a variable sized array containing a child which serialises to a
+ * zero-length bytestring. */
+ child = g_variant_new_maybe (G_VARIANT_TYPE_VARIANT, NULL);
+ variant = g_variant_new_array (mv_type, &child, 1);
+
+ /* Get the child before serialising. */
+ child1 = g_variant_get_child_value (variant, 0);
+ data1 = g_variant_get_data_as_bytes (child1);
+
+ /* Serialise the parent variant. */
+ g_variant_get_data (variant);
+
+ /* Get the child again after serialising — this uses a different code path. */
+ child2 = g_variant_get_child_value (variant, 0);
+ data2 = g_variant_get_data_as_bytes (child2);
+
+ /* Check things are equal. */
+ g_assert_cmpvariant (child1, child2);
+ g_assert_true (g_bytes_equal (data1, data2));
+
+ g_variant_unref (child2);
+ g_variant_unref (child1);
+ g_variant_unref (variant);
+ g_bytes_unref (data2);
+ g_bytes_unref (data1);
+ g_variant_type_free (mv_type);
+}
+
static void
test_fuzz (gdouble *fuzziness)
{
@@ -5075,6 +5115,7 @@ main (int argc, char **argv)
guint i;
g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("");
g_test_add_func ("/gvariant/type", test_gvarianttype);
g_test_add_func ("/gvariant/type/string-scan/recursion/tuple",
@@ -5088,6 +5129,7 @@ main (int argc, char **argv)
g_test_add_func ("/gvariant/serialiser/variant", test_variants);
g_test_add_func ("/gvariant/serialiser/strings", test_strings);
g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
+ g_test_add_func ("/gvariant/serialiser/children", test_serialiser_children);
for (i = 1; i <= 20; i += 4)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]