/* Regression test for object registration and unregistration * * Copyright © 2009 Collabora Ltd. * Copyright © 2009-2011 Nokia Corporation * * In preparation for dbus-glib relicensing (if it ever happens), this file is * licensed under (at your option) either the AFL v2.1, the GPL v2 or later, * or an MIT/X11-style license: * * 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. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include "test/lib/util.h" GMainLoop *loop = NULL; typedef struct { DBusGConnection *bus; DBusGConnection *bus2; } Fixture; static void setup (Fixture *f, gconstpointer path_to_use) { f->bus = dbus_g_bus_get_private (DBUS_BUS_SESSION, NULL, NULL); g_assert (f->bus != NULL); f->bus2 = dbus_g_bus_get_private (DBUS_BUS_SESSION, NULL, NULL); g_assert (f->bus2 != NULL); } static void teardown (Fixture *f, gconstpointer test_data G_GNUC_UNUSED) { if (f->bus != NULL) { test_run_until_disconnected (f->bus, NULL); dbus_g_connection_unref (f->bus); } if (f->bus2 != NULL) { test_run_until_disconnected (f->bus2, NULL); dbus_g_connection_unref (f->bus2); } dbus_shutdown (); } static void destroy_cb (DBusGProxy *proxy G_GNUC_UNUSED, gpointer user_data) { gboolean *destroyed = user_data; *destroyed = TRUE; } static void test_name_owner_changed (Fixture *f, gconstpointer test_data G_GNUC_UNUSED) { DBusGProxy *peer; DBusGProxy *named; gboolean destroyed = FALSE; g_test_bug ("41126"); /* bus has a proxy for bus2... */ named = dbus_g_proxy_new_for_name (f->bus, dbus_bus_get_unique_name (dbus_g_connection_get_connection (f->bus2)), "/", "org.freedesktop.DBus.Peer"); /* ... and also a proxy for the peer (i.e. the dbus-daemon) */ peer = dbus_g_proxy_new_for_peer (f->bus, "/", "org.freedesktop.DBus.Peer"); g_signal_connect (G_OBJECT (named), "destroy", G_CALLBACK (destroy_cb), &destroyed); /* Disconnect bus2, to provoke a NameOwnerChanged signal on bus */ test_run_until_disconnected (f->bus2, NULL); dbus_g_connection_unref (f->bus2); f->bus2 = NULL; /* Wait for that NameOwnerChanged to be processed */ while (!destroyed) g_main_context_iteration (NULL, TRUE); g_signal_handlers_disconnect_by_func (named, destroy_cb, &destroyed); /* The first part of the bug was that we'd never get here, because checking * whether 'peer' was affected by the NameOwnerChanged caused a NULL * dereference and segfault. If we get here, all is OK. * * The second part of the bug was that if the last proxy in existence was * for a peer, when it was unregistered there would be no owner_match_rules, * causing a crash. Unref named before peer, to exercise that. */ g_object_unref (named); g_object_unref (peer); } int main (int argc, char **argv) { g_setenv ("DBUS_FATAL_WARNINGS", "1", TRUE); g_type_init (); g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); dbus_g_type_specialized_init (); g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id="); g_test_init (&argc, &argv, NULL); g_test_add ("/peer-on-bus/name-owner-changed", Fixture, NULL, setup, test_name_owner_changed, teardown); return g_test_run (); }