From 01b195e0c674d7de5c1320866b2cadce86085c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 30 Jan 2025 18:42:06 +0100 Subject: [PATCH] gvariant: Do not byteswap empty GVariant values If a value has no size, we'd end up to use g_variant_store() with a NULL value, and this is not allowed by the API, leading to errors: stderr: ../glib/gvariant-core.c:1429:9: runtime error: null pointer passed as argument 1, which is declared to never be null #0 0x7f9c139ce559 in g_variant_store ../glib/gvariant-core.c:732 #1 0x7f9c13c60b01 in g_variant_byteswap ../glib/gvariant.c:6211 #2 0x564ae412e9b9 in test_byteswap ../glib/tests/gvariant.c:2321 #3 0x564ae412e9b9 in test_byteswaps ../glib/tests/gvariant.c:2374 #4 0x7f9c13bc1000 in test_case_run ../glib/gtestutils.c:3115 #5 0x7f9c13bc1000 in g_test_run_suite_internal ../glib/gtestutils.c:3210 #6 0x7f9c13bc0d7b in g_test_run_suite_internal ../glib/gtestutils.c:3229 #7 0x7f9c13bc0d7b in g_test_run_suite_internal ../glib/gtestutils.c:3229 #8 0x7f9c13bc2019 in g_test_run_suite ../glib/gtestutils.c:3310 #9 0x7f9c13bc216f in g_test_run ../glib/gtestutils.c:2379 #10 0x564ae410f326 in main ../glib/tests/gvariant.c:6045 --- glib/gvariant.c | 6 ++++-- glib/tests/gvariant.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/glib/gvariant.c b/glib/gvariant.c index bdcbe412b..432c0a57d 100644 --- a/glib/gvariant.c +++ b/glib/gvariant.c @@ -6187,12 +6187,14 @@ g_variant_byteswap (GVariant *value) GVariantTypeInfo *type_info; guint alignment; GVariant *new; + gsize size; type_info = g_variant_get_type_info (value); + size = g_variant_get_size (value); g_variant_type_info_query (type_info, &alignment, NULL); - if (alignment && g_variant_is_normal_form (value)) + if (alignment && size > 0 && g_variant_is_normal_form (value)) { /* (potentially) contains multi-byte numeric data, but is also already in * normal form so we can use a faster byteswapping codepath on the @@ -6201,7 +6203,7 @@ g_variant_byteswap (GVariant *value) GBytes *bytes; serialised.type_info = g_variant_get_type_info (value); - serialised.size = g_variant_get_size (value); + serialised.size = size; serialised.data = g_malloc (serialised.size); serialised.depth = g_variant_get_depth (value); serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */ diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c index 12a35dad9..e215e9861 100644 --- a/glib/tests/gvariant.c +++ b/glib/tests/gvariant.c @@ -2367,6 +2367,19 @@ test_byteswaps (void) g_variant_type_info_assert_no_infos (); } +static void +test_byteswap_zero_sized (void) +{ + GVariant *variant; + GVariant *swapped; + + variant = g_variant_new_from_data (G_VARIANT_TYPE_STRING, NULL, 0, TRUE, NULL, NULL); + swapped = g_variant_byteswap (variant); + + g_variant_unref (variant); + g_variant_unref (swapped); +} + static void test_serialiser_children (void) { @@ -5939,6 +5952,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/byteswap/zero-sized", test_byteswap_zero_sized); g_test_add_func ("/gvariant/serialiser/children", test_serialiser_children); for (i = 1; i <= 20; i += 4)