summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@coaxion.net>2019-09-24 17:01:50 +0000
committerSebastian Dröge <slomo@coaxion.net>2019-09-24 17:01:50 +0000
commita96c449d6fb0fd67d8757f73b2a84028a30e195b (patch)
treea145064ae7cabe9bcebae0693189a3b07883bf47
parenta902addf6da43252fa9055226d8b6aca52e29487 (diff)
parentefe5b701926e01e278ad22afd59a94f2fa7b3fe3 (diff)
downloadglib-a96c449d6fb0fd67d8757f73b2a84028a30e195b.tar.gz
Merge branch '1865-variant-get-child-serialisation' into 'master'
gvariant: Handle empty serialisations in get_child_value() Closes #1865 See merge request GNOME/glib!1043
-rw-r--r--glib/gvariant-core.c6
-rw-r--r--glib/tests/gvariant.c42
2 files changed, 48 insertions, 0 deletions
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
@@ -2304,6 +2304,46 @@ test_byteswaps (void)
}
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)
{
GVariantSerialised serialised;
@@ -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)
{