summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2022-09-30 14:00:08 +0100
committerSimon McVittie <smcv@collabora.com>2022-10-05 10:24:42 +0100
commit7a2c13d21be702c7b5b7288fb82a60adc5bd7378 (patch)
tree741ab3d73732cdd68a700de1a4563141067477a6 /test
parent236f16e444e88a984cf12b09225e0f8efa6c5b44 (diff)
downloaddbus-7a2c13d21be702c7b5b7288fb82a60adc5bd7378.tar.gz
test: Add infrastructure to parse valid raw message blobs
Signed-off-by: Simon McVittie <smcv@collabora.com>
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/Makefile.am2
-rw-r--r--test/data/meson.build2
-rw-r--r--test/data/valid-messages/minimal.message-rawbin0 -> 24 bytes
-rw-r--r--test/data/valid-messages/minimal.message-raw.hex25
-rw-r--r--test/internals/dbus-message-util.c4
-rw-r--r--test/message.c160
7 files changed, 194 insertions, 0 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index cd338a07..5bd7915c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -228,6 +228,7 @@ set(TESTDIRS
data/valid-config-files/session.d
data/valid-config-files-system
data/valid-config-files-system/system.d
+ data/valid-messages
data/valid-service-files
data/valid-service-files-system
data/invalid-config-files
diff --git a/test/Makefile.am b/test/Makefile.am
index 659aead3..54ec3693 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -762,6 +762,8 @@ static_data = \
data/valid-config-files/standard-session-dirs.conf \
data/valid-config-files-system/many-rules.conf \
data/valid-config-files-system/system.d/test.conf \
+ data/valid-messages/minimal.message-raw \
+ data/valid-messages/minimal.message-raw.hex \
$(NULL)
EXTRA_DIST += $(static_data)
diff --git a/test/data/meson.build b/test/data/meson.build
index 7ad99411..45fb6f91 100644
--- a/test/data/meson.build
+++ b/test/data/meson.build
@@ -110,6 +110,8 @@ data_to_install = [
'valid-config-files/many-rules.conf',
'valid-config-files/minimal.conf',
'valid-config-files/standard-session-dirs.conf',
+ 'valid-messages/minimal.message-raw',
+ 'valid-messages/minimal.message-raw.hex',
]
data_in_to_install = [
diff --git a/test/data/valid-messages/minimal.message-raw b/test/data/valid-messages/minimal.message-raw
new file mode 100644
index 00000000..3b5ee188
--- /dev/null
+++ b/test/data/valid-messages/minimal.message-raw
Binary files differ
diff --git a/test/data/valid-messages/minimal.message-raw.hex b/test/data/valid-messages/minimal.message-raw.hex
new file mode 100644
index 00000000..ab0534da
--- /dev/null
+++ b/test/data/valid-messages/minimal.message-raw.hex
@@ -0,0 +1,25 @@
+# Copyright 2022 Collabora Ltd.
+# SPDX-License-Identifier: MIT
+#
+# To output as binary:
+# sed -e 's/#.*//' test/data/valid-messages/minimal.message-raw.hex |
+# xxd -p -r - test/data/valid-messages/minimal.message-raw
+#
+# This is a minimal valid message.
+
+# Offset % 0x10:
+# 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f
+
+ 6c # little-endian
+ 02 # method call reply
+ 00 # no flags
+ 01 # major protocol version 1
+ 0000 0000 # message body is 0 bytes
+ 0200 0000 # serial number 2
+ 0800 0000 # header is an array of 8 bytes of struct (yv)
+ 05 # in reply to
+ 01 # signature is 1 byte
+ 7500 # "u" \0
+ 0100 0000 # in reply to serial number 1
+
+#sha1 06942854add9c4346a8b1c76a2b02e2e73abe72a
diff --git a/test/internals/dbus-message-util.c b/test/internals/dbus-message-util.c
index df2ab8cf..25237c85 100644
--- a/test/internals/dbus-message-util.c
+++ b/test/internals/dbus-message-util.c
@@ -589,6 +589,10 @@ foreach_message_file (const char *test_data_dir,
_dbus_string_init_const (&test_directory, test_data_dir);
+ if (!process_test_subdir (&test_directory, "valid-messages",
+ DBUS_VALID, func, user_data))
+ goto failed;
+
if (!process_test_subdir (&test_directory, "invalid-messages",
DBUS_INVALID_FOR_UNKNOWN_REASON, func, user_data))
goto failed;
diff --git a/test/message.c b/test/message.c
index 699302f4..58966cb8 100644
--- a/test/message.c
+++ b/test/message.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <glib.h>
+#include <glib/gstdio.h>
#include <dbus/dbus.h>
#include "dbus/dbus-internals.h"
@@ -179,6 +180,152 @@ out:
return !g_test_failed ();
}
+static void iterate_fully (DBusMessageIter *iter,
+ int n_elements);
+
+/* Iterate over @iter. If n_elements >= 0, then @iter is
+ * expected to yield exactly @n_elements elements. */
+static void
+iterate_fully (DBusMessageIter *iter,
+ int n_elements)
+{
+ int i = 0;
+
+ while (TRUE)
+ {
+ int arg_type = dbus_message_iter_get_arg_type (iter);
+ dbus_bool_t should_have_next;
+ dbus_bool_t had_next;
+
+ if (arg_type == DBUS_TYPE_INVALID)
+ return; /* end of iteration */
+
+ if (dbus_type_is_container (arg_type))
+ {
+ DBusMessageIter sub = DBUS_MESSAGE_ITER_INIT_CLOSED;
+ int n_contained = -1;
+
+ switch (arg_type)
+ {
+ case DBUS_TYPE_ARRAY:
+ /* This is only allowed for arrays */
+ n_contained = dbus_message_iter_get_element_count (iter);
+ g_assert_cmpint (n_contained, >=, 0);
+ break;
+
+ case DBUS_TYPE_VARIANT:
+ n_contained = 1;
+ break;
+
+ case DBUS_TYPE_STRUCT:
+ break;
+
+ case DBUS_TYPE_DICT_ENTRY:
+ n_contained = 2;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ dbus_message_iter_recurse (iter, &sub);
+ iterate_fully (&sub, n_contained);
+ }
+ else
+ {
+ DBusBasicValue value;
+
+ dbus_message_iter_get_basic (iter, &value);
+
+ if (arg_type == DBUS_TYPE_UNIX_FD && value.fd >= 0)
+ {
+ GError *error = NULL;
+
+ g_close (value.fd, &error);
+ g_assert_no_error (error);
+ }
+ }
+
+ should_have_next = dbus_message_iter_has_next (iter);
+ had_next = dbus_message_iter_next (iter);
+ g_assert_cmpint (had_next, ==, should_have_next);
+ g_assert_cmpint (had_next, ==,
+ (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_INVALID));
+ i += 1;
+ }
+
+ if (n_elements >= 0)
+ g_assert_cmpuint (n_elements, ==, i);
+}
+
+/* Return TRUE if the right thing happens, but the right thing might include
+ * OOM. */
+static dbus_bool_t
+test_valid_message_blobs (void *message_name,
+ dbus_bool_t have_memory)
+{
+ gchar *path = NULL;
+ gchar *contents = NULL;
+ gsize len = 0;
+ DBusMessage *m = NULL;
+ DBusMessageIter iter = DBUS_MESSAGE_ITER_INIT_CLOSED;
+ GError *error = NULL;
+ DBusError e = DBUS_ERROR_INIT;
+ dbus_bool_t ok = TRUE;
+ gchar *filename = NULL;
+
+ filename = g_strdup_printf ("%s.message-raw", (const char *) message_name);
+ path = g_test_build_filename (G_TEST_DIST, "data", "valid-messages",
+ filename, NULL);
+ g_file_get_contents (path, &contents, &len, &error);
+ g_assert_no_error (error);
+ g_assert_cmpuint (len, <, (gsize) INT_MAX);
+
+ m = dbus_message_demarshal (contents, (int) len, &e);
+
+ if (m == NULL)
+ {
+ if (dbus_error_has_name (&e, DBUS_ERROR_NO_MEMORY) && !have_memory)
+ {
+ g_test_message ("Out of memory (not a problem)");
+ goto out;
+ }
+
+ /* TODO: Validity checking sometimes returns InvalidArgs for OOM */
+ if (dbus_error_has_name (&e, DBUS_ERROR_INVALID_ARGS) &&
+ !have_memory &&
+ strstr (e.message, "Out of memory") != NULL)
+ {
+ g_test_message ("Out of memory (not a problem)");
+ goto out;
+ }
+
+ g_test_message ("Parsing %s reported unexpected error %s: %s",
+ path, e.name, e.message);
+ g_test_fail ();
+ ok = FALSE;
+ goto out;
+ }
+
+ g_test_message ("Successfully parsed %s", path);
+ test_assert_no_error (&e);
+
+ if (dbus_message_iter_init (m, &iter))
+ g_assert_cmpint (dbus_message_iter_get_arg_type (&iter), !=, DBUS_TYPE_INVALID);
+ else
+ g_assert_cmpint (dbus_message_iter_get_arg_type (&iter), ==, DBUS_TYPE_INVALID);
+
+ iterate_fully (&iter, -1);
+
+out:
+ dbus_clear_message (&m);
+ dbus_error_free (&e);
+ g_free (path);
+ g_free (contents);
+ g_free (filename);
+ return ok;
+}
+
/* Return TRUE if the right thing happens, but the right thing might include
* OOM. */
static dbus_bool_t
@@ -365,6 +512,11 @@ add_oom_test (const gchar *name,
g_queue_push_tail (test_cases_to_free, test_case);
}
+static const char *valid_messages[] =
+{
+ "minimal",
+};
+
static const char *invalid_messages[] =
{
"boolean-has-no-value",
@@ -391,6 +543,14 @@ main (int argc,
add_oom_test ("/message/fd", test_fd, NULL);
add_oom_test ("/message/zero-iter", test_zero_iter, NULL);
+ for (i = 0; i < G_N_ELEMENTS (valid_messages); i++)
+ {
+ gchar *path = g_strdup_printf ("/message/valid/%s", valid_messages[i]);
+
+ add_oom_test (path, test_valid_message_blobs, valid_messages[i]);
+ g_free (path);
+ }
+
for (i = 0; i < G_N_ELEMENTS (invalid_messages); i++)
{
gchar *path = g_strdup_printf ("/message/invalid/%s", invalid_messages[i]);