mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-01-09 11:00:20 +01:00
Fix missing dbus_message_unref() in error reply path
The error message was leaked when blocking on a pending call after the connection was disconnected. Reviewed-by: Philip Withnall <withnall@endlessm.com> [smcv: re-word commit message] Reviewed-by: Simon McVittie <smcv@collabora.com> Bug: https://bugs.freedesktop.org/show_bug.cgi?id=101481
This commit is contained in:
parent
1cd23aa0c9
commit
ad17155f26
3 changed files with 122 additions and 1 deletions
|
|
@ -2476,6 +2476,8 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
|
|||
|
||||
/* on OOM error_msg is set to NULL */
|
||||
complete_pending_call_and_unlock (connection, pending, error_msg);
|
||||
if (error_msg != NULL)
|
||||
dbus_message_unref (error_msg);
|
||||
dbus_pending_call_unref (pending);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ AM_TESTS_ENVIRONMENT = \
|
|||
TESTS += \
|
||||
run-test.sh \
|
||||
run-test-systemserver.sh \
|
||||
test-pending-call-disconnected \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
|
@ -41,10 +42,11 @@ if DBUS_ENABLE_EMBEDDED_TESTS
|
|||
|
||||
## we use noinst_PROGRAMS not check_PROGRAMS for TESTS so that we
|
||||
## build even when not doing "make check"
|
||||
noinst_PROGRAMS=test-pending-call-dispatch test-pending-call-timeout test-threads-init test-ids test-shutdown test-privserver test-privserver-client test-autolaunch
|
||||
noinst_PROGRAMS=test-pending-call-dispatch test-pending-call-timeout test-pending-call-disconnected test-threads-init test-ids test-shutdown test-privserver test-privserver-client test-autolaunch
|
||||
|
||||
test_pending_call_dispatch_LDADD=$(top_builddir)/dbus/libdbus-1.la
|
||||
test_pending_call_timeout_LDADD=$(top_builddir)/dbus/libdbus-1.la
|
||||
test_pending_call_disconnected_LDADD=$(top_builddir)/dbus/libdbus-1.la
|
||||
test_threads_init_LDADD=$(top_builddir)/dbus/libdbus-1.la
|
||||
test_ids_LDADD=$(top_builddir)/dbus/libdbus-1.la
|
||||
|
||||
|
|
|
|||
117
test/name-test/test-pending-call-disconnected.c
Normal file
117
test/name-test/test-pending-call-disconnected.c
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright © 2006 Red Hat Inc.
|
||||
* Copyright © 2017 Shin-ichi MORITA <shin1morita@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* Test to make sure that pending calls unref error messages
|
||||
* when blocked after disconnected.
|
||||
**/
|
||||
|
||||
#include <config.h>
|
||||
#include <dbus/dbus.h>
|
||||
#include <dbus/dbus-sysdeps.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static size_t count = 0;
|
||||
|
||||
static void
|
||||
free_data (void *data)
|
||||
{
|
||||
--count;
|
||||
printf ("# Freed: %s\n", (const char*)data);
|
||||
}
|
||||
|
||||
/* This test outputs TAP syntax: http://testanything.org/ */
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
dbus_int32_t slot_connection = -1;
|
||||
dbus_int32_t slot_message = -1;
|
||||
dbus_int32_t slot_pending = -1;
|
||||
DBusError error;
|
||||
DBusConnection *conn;
|
||||
DBusMessage *method;
|
||||
DBusPendingCall *pending;
|
||||
DBusMessage *reply;
|
||||
|
||||
printf ("# Testing pending call error\n");
|
||||
|
||||
dbus_connection_allocate_data_slot (&slot_connection);
|
||||
dbus_message_allocate_data_slot (&slot_message);
|
||||
dbus_pending_call_allocate_data_slot (&slot_pending);
|
||||
|
||||
dbus_error_init (&error);
|
||||
conn = dbus_bus_get_private (DBUS_BUS_SESSION, &error);
|
||||
dbus_connection_set_data (conn, slot_connection, (void*)"connection", free_data);
|
||||
++count;
|
||||
dbus_connection_set_exit_on_disconnect (conn, FALSE);
|
||||
|
||||
method = dbus_message_new_method_call ("org.freedesktop.TestSuiteEchoService",
|
||||
"/org/freedesktop/TestSuite",
|
||||
"org.freedesktop.TestSuite",
|
||||
"Exit");
|
||||
dbus_message_set_data (method, slot_message, (void*)"method", free_data);
|
||||
++count;
|
||||
|
||||
dbus_connection_send_with_reply (conn, method, &pending, -1);
|
||||
dbus_message_unref (method);
|
||||
dbus_pending_call_set_data (pending, slot_pending, (void*)"pending", free_data);
|
||||
++count;
|
||||
|
||||
dbus_connection_close (conn);
|
||||
|
||||
dbus_pending_call_block (pending);
|
||||
reply = dbus_pending_call_steal_reply (pending);
|
||||
dbus_pending_call_unref (pending);
|
||||
if (reply == NULL)
|
||||
{
|
||||
printf ("Bail out! Reply is NULL ***\n");
|
||||
exit (1);
|
||||
}
|
||||
dbus_message_set_data (reply, slot_message, (void*)"reply", free_data);
|
||||
++count;
|
||||
if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_ERROR)
|
||||
{
|
||||
printf ("Bail out! Reply is not error ***\n");
|
||||
exit (1);
|
||||
}
|
||||
dbus_message_unref (reply);
|
||||
|
||||
dbus_connection_unref (conn);
|
||||
|
||||
dbus_connection_free_data_slot (&slot_connection);
|
||||
dbus_message_free_data_slot (&slot_message);
|
||||
dbus_pending_call_free_data_slot (&slot_pending);
|
||||
|
||||
if (count != 0)
|
||||
{
|
||||
printf ("not ok # Not all refs were unrefed ***\n");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("ok\n# Testing completed\n1..1\n");
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue