Bonjour - fix crashing when deleting browser (recent regression)

When the browser is deleted, Resolver::cleanUp() is called for each
resolver in the resolvers list and it modifies resolvers which can break
the iterator in the caller.  Use erase() to get a valid iterator and return
it to use in the callers loop.
This commit is contained in:
Jonathan Bagg
2026-02-10 13:14:26 -05:00
parent 3e5749e061
commit 81701d6a92
2 changed files with 7 additions and 5 deletions
+6 -4
View File
@@ -43,14 +43,16 @@ void Resolver::addressReady()
cleanUp();
}
void Resolver::cleanUp()
QHash<QString, Resolver*>::iterator Resolver::cleanUp()
{
DNSServiceRefDeallocate(DNSresolverRef);
DNSServiceRefDeallocate(DNSaddressRef);
// the QSocketNotifiers resolverNotifier and addressNotifier get deleted when the QSharedPointer gets deleted along with the Resolver. No need to clear them here.
QString key = zcs->name() + QString::number(zcs->interfaceIndex());
ref->resolvers.remove(key);
QHash<QString, Resolver*>::iterator it = ref->resolvers.find(key);
it = ref->resolvers.erase(it);
delete this;
return it;
}
QZeroConfPrivate::QZeroConfPrivate(QZeroConf *parent)
@@ -232,8 +234,8 @@ void QZeroConfPrivate::cleanUp(DNSServiceRef toClean)
if (toClean == browser) {
browser = nullptr;
browserNotifier.clear();
for (auto resolver : resolvers)
resolver->cleanUp();
for (QHash<QString, Resolver*>::iterator it = resolvers.begin(); it != resolvers.end(); )
it = (*it)->cleanUp(); // cleanUp() modifies resolvers, so it returns a valid iterator
resolvers.clear();
for (auto service : pub->services)
emit pub->serviceRemoved(service);
+1 -1
View File
@@ -42,7 +42,7 @@ class Resolver : public QObject
{
Q_OBJECT
public:
void cleanUp();
QHash<QString, Resolver*>::iterator cleanUp();
QZeroConfService zcs;
QZeroConfPrivate *ref = nullptr;
DNSServiceRef DNSresolverRef = nullptr;