summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2011-09-28 17:35:42 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2012-04-17 11:03:06 +0100
commit92c613b8f429a4fe6c762805f1a4f3588511e6a7 (patch)
treed16dbdc096dd6c1948c9bcc36dc969be414229cb
parent539bd92b8703134057c039f965ff7a5b5434c3a7 (diff)
downloaddbus-glib-92c613b8f429a4fe6c762805f1a4f3588511e6a7.tar.gz
Add a manual test for various invalid behaviour
Most of this has been sitting in a branch since fd.o #30171; fixing fd.o #40151, another case of library-user error leading to undefined behaviour and a hard-to-diagnose crash, seems a good time to get this merged. Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk> Bug: https://bugs.freedesktop.org/show_bug.cgi?id=40151 Reviewed-by: Will Thompson <will.thompson@collabora.co.uk>
-rw-r--r--.gitignore1
-rw-r--r--configure.ac1
-rw-r--r--test/Makefile.am4
-rw-r--r--test/manual/Makefile.am27
-rw-r--r--test/manual/invalid-usage.c295
5 files changed, 326 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 4611ba2..7495223 100644
--- a/.gitignore
+++ b/.gitignore
@@ -224,3 +224,4 @@ tools/dbus-glib-bindings.h
/test/interfaces/test-server
/test/interfaces/test-service
/test/interfaces/test-client
+/test/manual/test-invalid-usage
diff --git a/configure.ac b/configure.ac
index c9b2863..caa65a0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -450,6 +450,7 @@ test/interfaces/Makefile
test/data/valid-service-files/debug-glib.service
test/data/valid-service-files/debug-echo.service
test/data/valid-service-files/interfaces-test.service
+test/manual/Makefile
tools/Makefile
dbus-glib-1.pc
dbus-glib-1-uninstalled.pc
diff --git a/test/Makefile.am b/test/Makefile.am
index 7ba11a8..e0531f6 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,5 +1,5 @@
-SUBDIRS = . core interfaces
-DIST_SUBDIRS = core interfaces
+SUBDIRS = . core interfaces manual
+DIST_SUBDIRS = core interfaces manual
INCLUDES = \
-I$(top_srcdir) \
diff --git a/test/manual/Makefile.am b/test/manual/Makefile.am
new file mode 100644
index 0000000..5a8dfd1
--- /dev/null
+++ b/test/manual/Makefile.am
@@ -0,0 +1,27 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/test/core \
+ -I$(top_builddir)/test/core \
+ $(DBUS_CFLAGS) \
+ $(DBUS_GLIB_CFLAGS) \
+ $(NULL)
+
+LDADD = \
+ $(top_builddir)/dbus/libdbus-glib-1.la \
+ $(DBUS_LIBS) \
+ $(DBUS_GLIB_LIBS) \
+ $(NULL)
+
+noinst_PROGRAMS = \
+ test-invalid-usage \
+ $(NULL)
+
+# This "test" exercises invalid usage. It is deliberately not run in
+# TESTS, because it's (by design) full of bugs.
+test_invalid_usage_SOURCES = \
+ ../core/my-object-marshal.c \
+ ../core/my-object-marshal.h \
+ ../core/my-object.c \
+ ../core/my-object.h \
+ invalid-usage.c
diff --git a/test/manual/invalid-usage.c b/test/manual/invalid-usage.c
new file mode 100644
index 0000000..59a8314
--- /dev/null
+++ b/test/manual/invalid-usage.c
@@ -0,0 +1,295 @@
+/* Manual test for various invalid usages which should not crash us (in order
+ * to be nice to fallible programmers), unless checks have been disabled (in
+ * which case, you asked for it, you got it).
+ *
+ * Copyright © 2006-2010 Red Hat, Inc.
+ * Copyright © 2006-2010 Collabora Ltd.
+ * Copyright © 2006-2011 Nokia Corporation
+ * Copyright © 2006 Steve Frécinaux
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <glib.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <string.h>
+
+#include "my-object.h"
+#include "test-service-glib-bindings.h"
+
+/* my-object wants this to exist */
+GMainLoop *loop = NULL;
+
+typedef struct {
+ GError *error;
+ DBusGConnection *conn;
+ DBusGProxy *proxy;
+ DBusGProxy *proxy_for_self;
+ GObject *object;
+} Fixture;
+
+static void
+setup (Fixture *f,
+ gconstpointer context)
+{
+ /* this test is all about (mostly critical) warnings, so don't crash out on
+ * programming errors */
+ g_setenv ("DBUS_FATAL_WARNINGS", "0", TRUE);
+ g_log_set_always_fatal (G_LOG_LEVEL_ERROR);
+
+ dbus_g_type_specialized_init ();
+
+ /* This is a bug: you're not meant to register any domain more than
+ * once. It shouldn't crash, though. */
+ dbus_g_error_domain_register (MY_OBJECT_ERROR, NULL, MY_TYPE_ERROR);
+
+ f->conn = dbus_g_bus_get_private (DBUS_BUS_SESSION, NULL, &f->error);
+ g_assert_no_error (f->error);
+ g_assert (f->conn != NULL);
+
+ f->proxy = dbus_g_proxy_new_for_name (f->conn, "com.example.Test",
+ "/com/example/Test/Object", "com.example.Test.Fallible");
+ g_assert (f->proxy != NULL);
+
+ f->object = g_object_new (MY_TYPE_OBJECT, NULL);
+ g_assert (MY_IS_OBJECT (f->object));
+ dbus_g_connection_register_g_object (f->conn, "/com/example/Test/Object",
+ f->object);
+
+ f->proxy_for_self = dbus_g_proxy_new_for_name (f->conn,
+ dbus_bus_get_unique_name (dbus_g_connection_get_connection (f->conn)),
+ "/com/example/Test/Object", "org.freedesktop.DBus.GLib.Tests.MyObject");
+ g_assert (f->proxy_for_self != NULL);
+}
+
+static void
+test_invalid_gtype (Fixture *f,
+ gconstpointer context)
+{
+ /* G_TYPE_GTYPE is not handled by the dbus-glib type system (and would make
+ * no sense anyway) */
+ dbus_g_proxy_call_no_reply (f->proxy, "Fail",
+ G_TYPE_GTYPE, G_TYPE_STRING,
+ G_TYPE_INVALID);
+}
+
+static void
+test_invalid_utf8 (Fixture *f,
+ gconstpointer context)
+{
+ g_test_bug ("30171");
+
+ /* This provokes a libdbus warning, which is fatal-by-default */
+ dbus_g_proxy_call_no_reply (f->proxy, "Fail",
+ G_TYPE_STRING, "\xfe\xfe\xfe",
+ G_TYPE_INVALID);
+}
+
+static void
+test_invalid_bool (Fixture *f,
+ gconstpointer context)
+{
+ g_test_bug ("30171");
+
+ /* This provokes a libdbus warning, which is fatal-by-default */
+ dbus_g_proxy_call_no_reply (f->proxy, "Fail",
+ G_TYPE_BOOLEAN, (gboolean) (-42),
+ G_TYPE_INVALID);
+}
+
+static void
+test_invalid_path (Fixture *f,
+ gconstpointer context)
+{
+ g_test_bug ("30171");
+
+ /* This provokes a libdbus warning, which is fatal-by-default */
+ dbus_g_proxy_call_no_reply (f->proxy, "Fail",
+ DBUS_TYPE_G_OBJECT_PATH, "$%#*!",
+ G_TYPE_INVALID);
+}
+
+static void
+test_invalid_utf8s (Fixture *f,
+ gconstpointer context)
+{
+ gchar *bad_strings[] = { "\xfe\xfe\xfe", NULL };
+ GStrv bad_strv = bad_strings;
+
+ g_test_bug ("30171");
+
+ /* This provokes a libdbus warning, which is fatal-by-default */
+ dbus_g_proxy_call_no_reply (f->proxy, "Fail",
+ G_TYPE_STRV, bad_strv,
+ G_TYPE_INVALID);
+}
+
+static void
+test_invalid_bools (Fixture *f,
+ gconstpointer context)
+{
+ GArray *array;
+ gboolean maybe = (gboolean) (-23);
+
+ g_test_bug ("30171");
+
+ array = g_array_new (FALSE, FALSE, sizeof (gboolean));
+
+ g_array_append_val (array, maybe);
+
+ /* This provokes a libdbus warning, which is fatal-by-default */
+ dbus_g_proxy_call_no_reply (f->proxy, "Fail",
+ dbus_g_type_get_collection ("GArray", G_TYPE_BOOLEAN), array,
+ G_TYPE_INVALID);
+
+ g_array_free (array, TRUE);
+}
+
+static void
+test_invalid_paths (Fixture *f,
+ gconstpointer context)
+{
+ GPtrArray *array;
+
+ g_test_bug ("30171");
+
+ array = g_ptr_array_new ();
+ g_ptr_array_add (array, "bees");
+
+ /* This provokes a libdbus warning, which is fatal-by-default */
+ dbus_g_proxy_call_no_reply (f->proxy, "Fail",
+ dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), array,
+ G_TYPE_INVALID);
+
+ g_ptr_array_free (array, TRUE);
+}
+
+static void
+throw_error_cb (DBusGProxy *proxy,
+ GError *error,
+ gpointer user_data)
+{
+ GError **error_out = user_data;
+
+ g_assert (error != NULL);
+ *error_out = g_error_copy (error);
+}
+
+static void
+test_error_out_of_range (Fixture *f,
+ gconstpointer context)
+{
+ GError *error = NULL;
+
+ g_test_bug ("40151");
+
+ /* This is a bug: -1 isn't a valid code for the domain. */
+ my_object_save_error ((MyObject *) f->object, MY_OBJECT_ERROR, -1,
+ "stop being so negative");
+
+ if (!org_freedesktop_DBus_GLib_Tests_MyObject_throw_error_async (
+ f->proxy_for_self, throw_error_cb, &error))
+ g_error ("Failed to start async ThrowError call");
+
+ while (error == NULL)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_error (error, DBUS_GERROR, DBUS_GERROR_REMOTE_EXCEPTION);
+ g_clear_error (&error);
+
+ /* This is a bug: 666 isn't a valid code for the domain. */
+ my_object_save_error ((MyObject *) f->object, MY_OBJECT_ERROR, 666,
+ "demonic possession detected");
+
+ if (!org_freedesktop_DBus_GLib_Tests_MyObject_throw_error_async (
+ f->proxy_for_self, throw_error_cb, &error))
+ g_error ("Failed to start async ThrowError call");
+
+ while (error == NULL)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_error (error, DBUS_GERROR, DBUS_GERROR_REMOTE_EXCEPTION);
+ g_clear_error (&error);
+}
+
+static void
+teardown (Fixture *f,
+ gconstpointer context G_GNUC_UNUSED)
+{
+ g_clear_error (&f->error);
+
+ if (f->proxy != NULL)
+ {
+ g_object_unref (f->proxy);
+ f->proxy = NULL;
+ }
+
+ if (f->object != NULL)
+ {
+ g_object_unref (f->object);
+ f->object = NULL;
+ }
+
+ if (f->proxy_for_self != NULL)
+ {
+ g_object_unref (f->proxy_for_self);
+ f->proxy_for_self = NULL;
+ }
+
+ if (f->conn != NULL)
+ {
+ dbus_connection_close (dbus_g_connection_get_connection (f->conn));
+ dbus_g_connection_unref (f->conn);
+ f->conn = NULL;
+ }
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+
+ g_type_init ();
+
+ g_test_add ("/invalid/gtype", Fixture, NULL, setup, test_invalid_gtype,
+ teardown);
+ g_test_add ("/invalid/utf8", Fixture, NULL, setup, test_invalid_utf8,
+ teardown);
+ g_test_add ("/invalid/bool", Fixture, NULL, setup, test_invalid_bool,
+ teardown);
+ g_test_add ("/invalid/path", Fixture, NULL, setup, test_invalid_path,
+ teardown);
+ g_test_add ("/invalid/utf8s", Fixture, NULL, setup, test_invalid_utf8s,
+ teardown);
+ g_test_add ("/invalid/bools", Fixture, NULL, setup, test_invalid_bools,
+ teardown);
+ g_test_add ("/invalid/paths", Fixture, NULL, setup, test_invalid_paths,
+ teardown);
+ g_test_add ("/invalid/error/out-of-range", Fixture, NULL, setup,
+ test_error_out_of_range, teardown);
+
+ return g_test_run ();
+}