QDBusConnectionPrivate: Close connection after failed q_dbus_bus_register()
The connection should be closed before executing q_dbus_connection_unref(). Failing to do so results in an assertion inside libdbus: dbus[1573958]: The last reference on a connection was dropped without closing the connection. This is a bug in an application. See dbus_connection_unref() documentation for details. Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection. The q_dbus_bus_register() may fail if maximum number of active connections for a bus was reached. This can be tested by creating a custom bus with "max_completed_connections" parameter set to 0. Add such a test to tst_qdbusconnection. Fixes: QTBUG-34613 Change-Id: I6ae7df19bf8b6546c2a504931ba852dc15d35f78 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
c39fff0da5
commit
d3860918ea
@ -250,6 +250,7 @@ QDBusConnectionPrivate *QDBusConnectionManager::doConnectToBus(const QString &ad
|
|||||||
if (c) {
|
if (c) {
|
||||||
// register on the bus
|
// register on the bus
|
||||||
if (!q_dbus_bus_register(c, error)) {
|
if (!q_dbus_bus_register(c, error)) {
|
||||||
|
q_dbus_connection_close(c);
|
||||||
q_dbus_connection_unref(c);
|
q_dbus_connection_unref(c);
|
||||||
c = nullptr;
|
c = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,6 @@ qt_internal_add_test(tst_qdbusconnection
|
|||||||
tst_qdbusconnection.cpp tst_qdbusconnection.h
|
tst_qdbusconnection.cpp tst_qdbusconnection.h
|
||||||
LIBRARIES
|
LIBRARIES
|
||||||
Qt::DBus
|
Qt::DBus
|
||||||
|
TESTDATA
|
||||||
|
tst_qdbusconnection.conf
|
||||||
)
|
)
|
||||||
|
23
tests/auto/dbus/qdbusconnection/tst_qdbusconnection.conf
Normal file
23
tests/auto/dbus/qdbusconnection/tst_qdbusconnection.conf
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<!-- This configuration file for tst_qdbusconnection.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
|
||||||
|
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||||
|
<busconfig>
|
||||||
|
<type>tst_qdbusconnection</type>
|
||||||
|
|
||||||
|
<listen>unix:tmpdir=/tmp</listen>
|
||||||
|
|
||||||
|
<auth>EXTERNAL</auth>
|
||||||
|
|
||||||
|
<policy context="default">
|
||||||
|
<!-- Allow everything to be sent -->
|
||||||
|
<allow send_destination="*" eavesdrop="true"/>
|
||||||
|
<!-- Allow everything to be received -->
|
||||||
|
<allow eavesdrop="true"/>
|
||||||
|
<!-- Allow anyone to own anything -->
|
||||||
|
<allow own="*"/>
|
||||||
|
</policy>
|
||||||
|
|
||||||
|
<limit name="max_completed_connections">0</limit>
|
||||||
|
</busconfig>
|
@ -1412,6 +1412,34 @@ void tst_QDBusConnection::pendingCallWhenDisconnected()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QDBusConnection::connectionLimit()
|
||||||
|
{
|
||||||
|
#if !QT_CONFIG(process)
|
||||||
|
QSKIP("Test requires QProcess");
|
||||||
|
#else
|
||||||
|
if (!QCoreApplication::instance())
|
||||||
|
QSKIP("Test requires a QCoreApplication");
|
||||||
|
|
||||||
|
QProcess daemon;
|
||||||
|
daemon.start("dbus-daemon",
|
||||||
|
QStringList() << "--config-file" << QFINDTESTDATA("tst_qdbusconnection.conf")
|
||||||
|
<< "--nofork"
|
||||||
|
<< "--print-address");
|
||||||
|
QVERIFY2(daemon.waitForReadyRead(2000),
|
||||||
|
"Daemon didn't print its address in time; error: \"" + daemon.errorString().toLocal8Bit() +
|
||||||
|
"\"; stderr:\n" + daemon.readAllStandardError());
|
||||||
|
|
||||||
|
QString address = QString::fromLocal8Bit(daemon.readAll().trimmed());
|
||||||
|
QDBusConnection con = QDBusConnection::connectToBus(address, "connectionLimit");
|
||||||
|
QVERIFY2(!con.isConnected(), "Unexpected successful connection");
|
||||||
|
QCOMPARE(con.lastError().type(), QDBusError::LimitsExceeded);
|
||||||
|
|
||||||
|
// kill the bus
|
||||||
|
daemon.terminate();
|
||||||
|
daemon.waitForFinished();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QDBusConnection::emptyServerAddress()
|
void tst_QDBusConnection::emptyServerAddress()
|
||||||
{
|
{
|
||||||
QDBusServer server({}, nullptr);
|
QDBusServer server({}, nullptr);
|
||||||
|
@ -120,6 +120,7 @@ private slots:
|
|||||||
void callVirtualObject();
|
void callVirtualObject();
|
||||||
void callVirtualObjectLocal();
|
void callVirtualObjectLocal();
|
||||||
void pendingCallWhenDisconnected();
|
void pendingCallWhenDisconnected();
|
||||||
|
void connectionLimit();
|
||||||
|
|
||||||
void emptyServerAddress();
|
void emptyServerAddress();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user