From ff8be8b80eae32311345f90ee5d184076c023017 Mon Sep 17 00:00:00 2001 From: Robert Adam Date: Sun, 21 Nov 2021 17:00:17 +0100 Subject: [PATCH] FIX(client): Duplicate plugin entries Before when installing Mumble (on Windows) it could happen that when viewing the plugin settings, every plugin would be listed multiple times. This was caused by duplicate entries in the plugins search path used by Mumble. The duplicates arose from using non-canonical paths in the set for storing the search paths which allowed to add the same directory twice by describing its path slightly differently. This commit makes sure that all paths are first canonicalized before they are added to the set, such that only distinct paths are maintained. Fixes #5271 --- src/mumble/PluginManager.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/mumble/PluginManager.cpp b/src/mumble/PluginManager.cpp index 8ab8859ad..d938b7758 100644 --- a/src/mumble/PluginManager.cpp +++ b/src/mumble/PluginManager.cpp @@ -49,30 +49,36 @@ PluginManager::PluginManager(QSet< QString > *additionalSearchPaths, QObject *p) : QObject(p), m_pluginCollectionLock(QReadWriteLock::NonRecursive), m_pluginHashMap(), m_positionalData(), m_positionalDataCheckTimer(), m_sentDataMutex(), m_sentData(), m_activePosDataPluginLock(QReadWriteLock::NonRecursive), m_activePositionalDataPlugin(), m_updater() { + std::vector< QString > pluginPaths; + // Setup search-paths if (additionalSearchPaths) { - for (const auto ¤tPath : *additionalSearchPaths) { - m_pluginSearchPaths.insert(currentPath); - } + pluginPaths.insert(pluginPaths.end(), additionalSearchPaths->begin(), additionalSearchPaths->end()); } #ifdef Q_OS_MAC // Path to plugins inside AppBundle - m_pluginSearchPaths.insert(QString::fromLatin1("%1/../Plugins").arg(qApp->applicationDirPath())); + pluginPaths.push_back(QString::fromLatin1("%1/../Plugins").arg(qApp->applicationDirPath())); #endif #ifdef MUMBLE_PLUGIN_PATH // Path to where plugins are/will be installed on the system - m_pluginSearchPaths.insert(QString::fromLatin1(MUMTEXT(MUMBLE_PLUGIN_PATH))); + pluginPaths.push_back(QString::fromLatin1(MUMTEXT(MUMBLE_PLUGIN_PATH))); #endif // Path to "plugins" dir right next to the executable's location. This is the case for when Mumble // is run after compilation without having installed it anywhere special - m_pluginSearchPaths.insert( + pluginPaths.push_back( QString::fromLatin1("%1/plugins").arg(MumbleApplication::instance()->applicationVersionRootPath())); // Path to where the plugin installer will write plugins - m_pluginSearchPaths.insert(PluginInstaller::getInstallDir()); + pluginPaths.push_back(PluginInstaller::getInstallDir()); + + for (const QString ¤tPath : pluginPaths) { + // Transform currentPath to an absolute, canonical path and only then add it to m_pluginSearchPaths in order + // to ensure that each path is contained only once. + m_pluginSearchPaths.insert(QDir(currentPath).canonicalPath()); + } #ifdef Q_OS_WIN // According to MS KB Q131065, we need this to OpenProcess()