summaryrefslogtreecommitdiff
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:47:18 +0100
commit5d2b764d1fcbc1992b9fd5e532cd925bd3d69e6b (patch)
tree458f73dd1f86615f7a48e542f028d74c0ad3158d
parent51a5bbf9074855b0f4a353ed309938b196c13525 (diff)
downloaddbus-5d2b764d1fcbc1992b9fd5e532cd925bd3d69e6b.tar.gz
test: Add infrastructure to parse valid raw message blobs
Signed-off-by: Simon McVittie <smcv@collabora.com> (cherry picked from commit 7a2c13d21be702c7b5b7288fb82a60adc5bd7378) [backport to 1.14.x: discard Meson build system updates] (cherry picked from commit 7a8f3c2af94063e4994a9780d00d700aa0ea8aef) [backport to 1.12.x: resolve conflicts in build system; adjust signature of test function for absence of 39ef65d0 in this branch]
-rw-r--r--test/Makefile.am2
-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/message.c158
4 files changed, 185 insertions, 0 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index 168ffaea..99d6485b 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -552,6 +552,8 @@ static_data = \
data/valid-messages/dict.message \
data/valid-messages/emptiness.message \
data/valid-messages/lots-of-arguments.message \
+ data/valid-messages/minimal.message-raw \
+ data/valid-messages/minimal.message-raw.hex \
data/valid-messages/no-padding.message \
data/valid-messages/opposite-endian.message \
data/valid-messages/recursive-types.message \
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/message.c b/test/message.c
index 618528bb..887935dd 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,150 @@ 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)
+{
+ 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))
+ {
+ 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) &&
+ 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 +510,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 +541,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]);