diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-01-12 13:34:04 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-01-12 13:48:23 +0100 |
commit | 4c67ae2dd9a49348ed5b2d733a60ed0b06c5d203 (patch) | |
tree | 18976038386581cffb4a33ebd74a8e862339aa27 /src | |
parent | 0471a897ae4e08e3a3b69fd31c337f4c530eb500 (diff) |
Make QQmlImport::removeDynamicPlugin() safer
Consistently never unload plugins on macOS, also remove half-broken
plugins from the map, and always unregister any types in them.
Unloading plugins on macOS is ill-advised as it will actually unmap the
memory, making string data (among other things) inaccessible. We've
already done the same change to qmlClearEnginePlugins().
Change-Id: I8fa40db5c3cd83f12e6d85d0efc3b9679dd4381e
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlimport.cpp | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index a9107b908a..4e6a4a8928 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -202,26 +202,31 @@ private: Q_GLOBAL_STATIC(PathPluginMap, qmlPluginsByPath); // stores the uri and the PluginLoaders -void qmlClearEnginePlugins() +static bool unloadPlugin(const std::pair<const QString, QmlPlugin> &plugin) { - PathPluginMapPtr plugins(qmlPluginsByPath()); -#if QT_CONFIG(library) - for (const auto &plugin : qAsConst(*plugins)) { - const auto &loader = plugin.second.loader; - if (loader) { - auto extensionPlugin = qobject_cast<QQmlExtensionPlugin *>(loader->instance()); - if (extensionPlugin) { - extensionPlugin->unregisterTypes(); - } -#ifndef Q_OS_MACOS - if (!loader->unload()) { - qWarning("Unloading %s failed: %s", qPrintable(plugin.first), - qPrintable(loader->errorString())); - } -#endif - } + const auto &loader = plugin.second.loader; + if (!loader) + return false; + + if (auto extensionPlugin = qobject_cast<QQmlExtensionPlugin *>(loader->instance())) + extensionPlugin->unregisterTypes(); + +#if QT_CONFIG(library) && !defined(Q_OS_MACOS) + if (!loader->unload()) { + qWarning("Unloading %s failed: %s", qPrintable(plugin.first), + qPrintable(loader->errorString())); + return false; } #endif + + return true; +} + +void qmlClearEnginePlugins() +{ + PathPluginMapPtr plugins(qmlPluginsByPath()); + for (const auto &plugin : qAsConst(*plugins)) + unloadPlugin(plugin); plugins->clear(); } @@ -2389,19 +2394,10 @@ bool QQmlImportDatabase::removeDynamicPlugin(const QString &filePath) if (it == plugins->end()) return false; - auto &loader = it->second.loader; - if (!loader) - return false; - -#if QT_CONFIG(library) - if (!loader->unload()) { - qWarning("Unloading %s failed: %s", qPrintable(it->first), - qPrintable(loader->errorString())); - } -#endif + const bool success = unloadPlugin(*it); plugins->erase(it); - return true; + return success; } QStringList QQmlImportDatabase::dynamicPlugins() const |