From cecc5ef778dca4e15b7459ac9895fd8ba11b245b Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 6 Dec 2023 23:40:49 +0000 Subject: [PATCH] tests: Add more tests of header validation in D-Bus message serialisation See the previous commit. These additions were kept in a separate commit to make the changes to the existing tests in the previous commit clearer. Signed-off-by: Philip Withnall Helps: #3093 --- gio/tests/gdbus-serialization.c | 159 +++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 3 deletions(-) diff --git a/gio/tests/gdbus-serialization.c b/gio/tests/gdbus-serialization.c index b500d72df..16bf35788 100644 --- a/gio/tests/gdbus-serialization.c +++ b/gio/tests/gdbus-serialization.c @@ -914,19 +914,106 @@ test_message_serialize_header_checks (void) g_object_unref (message); /* - * check that we can't serialize messages with SIGNATURE set to a non-signature-typed value + * check we can't serialize messages with an INVALID header */ message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember"); - g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, g_variant_new_boolean (FALSE)); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_INVALID, g_variant_new_boolean (FALSE)); blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); - g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: SIGNATURE header field is invalid; expected a value of type ‘g’"); + g_assert_cmpstr (error->message, ==, "Cannot serialize message: SIGNAL message: INVALID header field supplied"); g_assert_null (blob); g_clear_error (&error); g_clear_object (&message); + /* + * check that we can't serialize messages with various fields set to incorrectly typed values + */ + const struct + { + GDBusMessageHeaderField field; + const char *invalid_value; /* as a GVariant in text form */ + const char *expected_error_message; + } + field_type_tests[] = + { + { + G_DBUS_MESSAGE_HEADER_FIELD_PATH, + "'/correct/value/but/wrong/type'", + "Cannot serialize message: SIGNAL message: PATH header field is invalid; expected a value of type ‘o’" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE, + "@u 5", + "Cannot serialize message: SIGNAL message: INTERFACE header field is invalid; expected a value of type ‘s’" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_INTERFACE, + "'valid type, but not an interface name'", + "Cannot serialize message: SIGNAL message: INTERFACE header field does not contain a valid interface name" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, + "@u 5", + "Cannot serialize message: SIGNAL message: MEMBER header field is invalid; expected a value of type ‘s’" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, + "'valid type, but not a member name'", + "Cannot serialize message: SIGNAL message: MEMBER header field does not contain a valid member name" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, + "@u 5", + "Cannot serialize message: SIGNAL message: ERROR_NAME header field is invalid; expected a value of type ‘s’" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_ERROR_NAME, + "'valid type, but not an error name'", + "Cannot serialize message: SIGNAL message: ERROR_NAME header field does not contain a valid error name" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_REPLY_SERIAL, + "'oops'", + "Cannot serialize message: SIGNAL message: REPLY_SERIAL header field is invalid; expected a value of type ‘u’" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_DESTINATION, + "@u 5", + "Cannot serialize message: SIGNAL message: DESTINATION header field is invalid; expected a value of type ‘s’" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_SENDER, + "@u 5", + "Cannot serialize message: SIGNAL message: SENDER header field is invalid; expected a value of type ‘s’" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, + "false", + "Cannot serialize message: SIGNAL message: SIGNATURE header field is invalid; expected a value of type ‘g’" + }, + { + G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS, + "'five'", + "Cannot serialize message: SIGNAL message: NUM_UNIX_FDS header field is invalid; expected a value of type ‘u’" + }, + }; + + for (size_t i = 0; i < G_N_ELEMENTS (field_type_tests); i++) + { + message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember"); + g_dbus_message_set_header (message, field_type_tests[i].field, g_variant_new_parsed (field_type_tests[i].invalid_value)); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error); + + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (error->message, ==, field_type_tests[i].expected_error_message); + g_assert_null (blob); + + g_clear_error (&error); + g_clear_object (&message); + } + /* * check we can't serialize signal messages with INTERFACE, PATH or MEMBER unset / set to reserved value */ @@ -1045,6 +1132,70 @@ test_message_serialize_header_checks (void) g_object_unref (message); } +static void +test_message_serialize_header_checks_valid (void) +{ + GDBusMessage *message = NULL, *reply = NULL; + GError *local_error = NULL; + guchar *blob; + gsize blob_size; + + g_test_summary ("Test that validation allows well-formed messages of all the different types"); + + /* Method call */ + message = g_dbus_message_new_method_call ("Some.Name", "/the/path", "org.some.Interface", "TheMethod"); + g_dbus_message_set_serial (message, 666); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (blob); + g_free (blob); + + /* Method return */ + reply = g_dbus_message_new_method_reply (message); + blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (blob); + g_free (blob); + g_clear_object (&reply); + + /* Error */ + reply = g_dbus_message_new_method_error (message, "Error.Name", "Some error message"); + blob = g_dbus_message_to_blob (reply, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (blob); + g_free (blob); + + g_clear_object (&reply); + g_clear_object (&message); + + /* Signal */ + message = g_dbus_message_new_signal ("/the/path", "org.some.Interface", "SignalName"); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (blob); + g_free (blob); + g_clear_object (&message); + + /* Also check that an unknown message type is allowed */ + message = g_dbus_message_new (); + g_dbus_message_set_message_type (message, 123); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (blob); + g_free (blob); + g_clear_object (&message); + + /* Even one with a well-defined field on it */ + message = g_dbus_message_new (); + g_dbus_message_set_message_type (message, 123); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_NUM_UNIX_FDS, g_variant_new_uint32 (0)); + blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error); + g_assert_no_error (local_error); + g_assert_nonnull (blob); + g_free (blob); + g_clear_object (&message); +} + /* ---------------------------------------------------------------------------------------------------- */ static void @@ -1755,6 +1906,8 @@ main (int argc, test_message_serialize_invalid); g_test_add_func ("/gdbus/message-serialize/header-checks", test_message_serialize_header_checks); + g_test_add_func ("/gdbus/message-serialize/header-checks/valid", + test_message_serialize_header_checks_valid); g_test_add_func ("/gdbus/message-serialize/double-array", test_message_serialize_double_array); g_test_add_func ("/gdbus/message-serialize/empty-structure",