mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 11:26:16 +01:00
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
This commit is contained in:
parent
10be2c12ab
commit
efe5b70192
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user