gdbusmessage: Disallow empty structures/tuples in D-Bus messages

They are disallowed in the specification:
https://dbus.freedesktop.org/doc/dbus-specification.html#container-types

Helps: #2557
This commit is contained in:
Sebastian Wilhelmi 2022-01-06 21:04:56 +00:00 committed by Philip Withnall
parent 77233f6f07
commit 6499ad5356
2 changed files with 107 additions and 0 deletions

View File

@ -1907,6 +1907,16 @@ parse_value_from_blob (GMemoryBuffer *buf,
g_variant_builder_init (&builder, type);
element_type = g_variant_type_first (type);
if (!element_type)
{
g_variant_builder_clear (&builder);
g_set_error_literal (&local_error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
_("Empty structures (tuples) are not allowed in D-Bus"));
goto fail;
}
while (element_type != NULL)
{
GVariant *item;
@ -2617,6 +2627,15 @@ append_value_to_blob (GVariant *value,
default:
if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type))
{
if (!g_variant_type_first (type))
{
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_ARGUMENT,
_("Empty structures (tuples) are not allowed in D-Bus"));
goto fail;
}
padding_added = ensure_output_padding (mbuf, 8);
if (value != NULL)
{

View File

@ -1529,6 +1529,90 @@ test_message_parse_truncated (void)
g_free (blob);
}
static void
test_message_parse_empty_structure (void)
{
const guint8 data[] =
{
'l', /* little-endian byte order */
0x02, /* message type (method return) */
0x00, /* message flags (none) */
0x01, /* major protocol version */
0x08, 0x00, 0x00, 0x00, /* body length (in bytes) */
0x00, 0x00, 0x00, 0x00, /* message serial */
/* a{yv} of header fields */
0x20, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */
0x01, /* array key (PATH) */
0x01, /* signature length */
'o', /* type (OBJECT_PATH) */
0x00, /* nul terminator */
0x05, 0x00, 0x00, 0x00, /* length 5 */
'/', 'p', 'a', 't', 'h', 0x00, 0x00, 0x00, /* string '/path' and padding */
0x03, /* array key (MEMBER) */
0x01, /* signature length */
's', /* type (STRING) */
0x00, /* nul terminator */
0x06, 0x00, 0x00, 0x00, /* length 6 */
'M', 'e', 'm', 'b', 'e', 'r', 0x00, 0x00, /* string 'Member' and padding */
0x08, /* array key (SIGNATURE) */
0x01, /* signature length */
'g', /* type (SIGNATURE) */
0x00, /* nul terminator */
0x03, /* length 3 */
'a', '(', ')', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* type 'a()' and padding */
0x08, 0x00, 0x00, 0x00, /* array length: 4 bytes */
0x00, 0x00, 0x00, 0x00, /* padding to 8 bytes */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* array data */
0x00
};
gsize size = sizeof (data);
GDBusMessage *message = NULL;
GError *local_error = NULL;
g_test_summary ("Test that empty structures are rejected when parsing.");
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2557");
message = g_dbus_message_new_from_blob ((guchar *) data, size,
G_DBUS_CAPABILITY_FLAGS_NONE,
&local_error);
g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (local_error->message, ==, "Empty structures (tuples) are not allowed in D-Bus");
g_assert_null (message);
g_clear_error (&local_error);
}
static void
test_message_serialize_empty_structure (void)
{
GDBusMessage *message;
GVariantBuilder builder;
gsize size = 0;
GError *local_error = NULL;
g_test_summary ("Test that empty structures are rejected when serializing.");
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2557");
message = g_dbus_message_new ();
g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a())"));
g_variant_builder_open (&builder, G_VARIANT_TYPE ("a()"));
g_variant_builder_add (&builder, "()");
g_variant_builder_close (&builder);
g_dbus_message_set_message_type (message, G_DBUS_MESSAGE_TYPE_METHOD_CALL);
g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH,
g_variant_new_object_path ("/path"));
g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER,
g_variant_new_string ("Member"));
g_dbus_message_set_body (message, g_variant_builder_end (&builder));
g_dbus_message_to_blob (message, &size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error);
g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_cmpstr (local_error->message, ==, "Empty structures (tuples) are not allowed in D-Bus");
g_clear_error (&local_error);
g_clear_object (&message);
}
/* ---------------------------------------------------------------------------------------------------- */
int
@ -1550,6 +1634,8 @@ main (int argc,
test_message_serialize_header_checks);
g_test_add_func ("/gdbus/message-serialize/double-array",
test_message_serialize_double_array);
g_test_add_func ("/gdbus/message-serialize/empty-structure",
test_message_serialize_empty_structure);
g_test_add_func ("/gdbus/message-parse/empty-arrays-of-arrays",
test_message_parse_empty_arrays_of_arrays);
@ -1567,6 +1653,8 @@ main (int argc,
test_message_parse_deep_body_nesting);
g_test_add_func ("/gdbus/message-parse/truncated",
test_message_parse_truncated);
g_test_add_func ("/gdbus/message-parse/empty-structure",
test_message_parse_empty_structure);
return g_test_run();
}