gvariant: Fix g_variant_byteswap() returning non-normal data sometimes

If `g_variant_byteswap()` was called on a non-normal variant of a type
which doesn’t need byteswapping, it would return a non-normal output.

That contradicts the documentation, which says that the return value is
always in normal form.

Fix the code so it matches the documentation.

Includes a unit test.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #2797
This commit is contained in:
Philip Withnall 2022-10-27 16:13:54 +01:00
parent 5f4485c4ff
commit 4c4cf568f0
2 changed files with 29 additions and 3 deletions

View File

@ -6084,14 +6084,16 @@ g_variant_byteswap (GVariant *value)
g_variant_serialised_byteswap (serialised);
bytes = g_bytes_new_take (serialised.data, serialised.size);
new = g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE);
new = g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE));
g_bytes_unref (bytes);
}
else
/* contains no multi-byte data */
new = value;
new = g_variant_get_normal_form (value);
return g_variant_ref_sink (new);
g_assert (g_variant_is_trusted (new));
return g_steal_pointer (&new);
}
/**

View File

@ -3826,6 +3826,29 @@ test_gv_byteswap (void)
g_free (string);
}
static void
test_gv_byteswap_non_normal_non_aligned (void)
{
const guint8 data[] = { 0x02 };
GVariant *v = NULL;
GVariant *v_byteswapped = NULL;
g_test_summary ("Test that calling g_variant_byteswap() on a variant which "
"is in non-normal form and doesnt need byteswapping returns "
"the same variant in normal form.");
v = g_variant_new_from_data (G_VARIANT_TYPE_BOOLEAN, data, sizeof (data), FALSE, NULL, NULL);
g_assert_false (g_variant_is_normal_form (v));
v_byteswapped = g_variant_byteswap (v);
g_assert_true (g_variant_is_normal_form (v_byteswapped));
g_assert_cmpvariant (v, v_byteswapped);
g_variant_unref (v);
g_variant_unref (v_byteswapped);
}
static void
test_parser (void)
{
@ -5711,6 +5734,7 @@ main (int argc, char **argv)
g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
g_test_add_func ("/gvariant/hashing", test_hashing);
g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
g_test_add_func ("/gvariant/byteswap/non-normal-non-aligned", test_gv_byteswap_non_normal_non_aligned);
g_test_add_func ("/gvariant/parser", test_parses);
g_test_add_func ("/gvariant/parser/integer-bounds", test_parser_integer_bounds);
g_test_add_func ("/gvariant/parser/recursion", test_parser_recursion);