From ac179d0f701df2d92bc67fd6971e75fb3d2454d5 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 6 Jul 2017 17:05:28 +0200 Subject: [PATCH] fix avahi service browser destruction without keeping track of the avahi service resolvers and destroying them when the parent object goes away, callbacks might be called after after the dhe destruction and passing an invalid userdata pointer. --- .../network/avahi/qtavahiservicebrowser_p.cpp | 19 +++++++++++++++---- .../network/avahi/qtavahiservicebrowser_p.h | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/libguh/network/avahi/qtavahiservicebrowser_p.cpp b/libguh/network/avahi/qtavahiservicebrowser_p.cpp index 4bb6eee2..e23f3bce 100644 --- a/libguh/network/avahi/qtavahiservicebrowser_p.cpp +++ b/libguh/network/avahi/qtavahiservicebrowser_p.cpp @@ -35,6 +35,13 @@ QtAvahiServiceBrowserPrivate::QtAvahiServiceBrowserPrivate(QtAvahiClient *client } +QtAvahiServiceBrowserPrivate::~QtAvahiServiceBrowserPrivate() +{ + foreach (AvahiServiceResolver *resolver, m_serviceResolvers) { + avahi_service_resolver_free(resolver); + } +} + void QtAvahiServiceBrowserPrivate::callbackServiceTypeBrowser(AvahiServiceTypeBrowser *browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { Q_UNUSED(browser) @@ -79,9 +86,9 @@ void QtAvahiServiceBrowserPrivate::callbackServiceBrowser(AvahiServiceBrowser *b return; switch (event) { - case AVAHI_BROWSER_NEW: + case AVAHI_BROWSER_NEW: { // Start resolving new service - if (!(avahi_service_resolver_new(serviceBrowser->d_ptr->client->client, + AvahiServiceResolver *resolver = avahi_service_resolver_new(serviceBrowser->d_ptr->client->client, interface, protocol, name, @@ -90,11 +97,14 @@ void QtAvahiServiceBrowserPrivate::callbackServiceBrowser(AvahiServiceBrowser *b AVAHI_PROTO_UNSPEC, (AvahiLookupFlags) 0, QtAvahiServiceBrowserPrivate::callbackServiceResolver, - serviceBrowser))) { - + serviceBrowser); + if (resolver) { + serviceBrowser->d_ptr->m_serviceResolvers.append(resolver); + } else { qCWarning(dcAvahi()) << "Failed to resolve service" << QString(name) << ":" << avahi_strerror(avahi_client_errno(serviceBrowser->d_ptr->client->client)); } break; + } case AVAHI_BROWSER_REMOVE: { // Remove the service foreach (const AvahiServiceEntry &entry, serviceBrowser->m_serviceEntries) { @@ -166,6 +176,7 @@ void QtAvahiServiceBrowserPrivate::callbackServiceResolver(AvahiServiceResolver emit serviceBrowser->serviceEntryAdded(entry); } } + serviceBrowser->d_ptr->m_serviceResolvers.removeAll(resolver); avahi_service_resolver_free(resolver); } diff --git a/libguh/network/avahi/qtavahiservicebrowser_p.h b/libguh/network/avahi/qtavahiservicebrowser_p.h index 393c80e0..1ef3a9e0 100644 --- a/libguh/network/avahi/qtavahiservicebrowser_p.h +++ b/libguh/network/avahi/qtavahiservicebrowser_p.h @@ -35,6 +35,7 @@ class LIBGUH_EXPORT QtAvahiServiceBrowserPrivate { public: QtAvahiServiceBrowserPrivate(QtAvahiClient *client); + ~QtAvahiServiceBrowserPrivate(); // Callback members static void callbackServiceTypeBrowser(AvahiServiceTypeBrowser *browser, @@ -76,6 +77,7 @@ public: QtAvahiClient *client; AvahiServiceTypeBrowser *serviceTypeBrowser; QHash serviceBrowserTable; + QList m_serviceResolvers; }; #endif // QTAVAHISERVICEBROWSERPRIVATE_H