vfs: Don't always load plugins, check metadata
authorChristian Kamm <mail@ckamm.de>
Mon, 26 Nov 2018 09:41:14 +0000 (10:41 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:26 +0000 (10:58 +0100)
src/common/common.cmake
src/common/vfs.cpp
src/common/vfspluginmetadata.json.in [new file with mode: 0644]
src/libsync/vfs/suffix/vfs_suffix.h

index 88c870933ff58861fa6711e92ae704dd77c886e4..f47e7745efbc6caa1d5ed22cb36d04df094b0514 100644 (file)
@@ -12,3 +12,5 @@ set(common_SOURCES
     ${CMAKE_CURRENT_LIST_DIR}/vfs.cpp
     ${CMAKE_CURRENT_LIST_DIR}/plugin.cpp
 )
+
+configure_file(${CMAKE_CURRENT_LIST_DIR}/vfspluginmetadata.json.in ${CMAKE_CURRENT_BINARY_DIR}/vfspluginmetadata.json)
index d9881e4f9b0862d8534381eb6b9837bfb12b1162..a1ad02efeb216904e17c5728e0c464e4e7405642 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "vfs.h"
 #include "plugin.h"
+#include "version.h"
 
 #include <QPluginLoader>
 #include <QLoggingCategory>
@@ -74,6 +75,8 @@ static QString modeToPluginName(Vfs::Mode mode)
     return QString();
 }
 
+Q_LOGGING_CATEGORY(lcPlugin, "plugins", QtInfoMsg)
+
 bool OCC::isVfsPluginAvailable(Vfs::Mode mode)
 {
     if (mode == Vfs::Off)
@@ -81,7 +84,30 @@ bool OCC::isVfsPluginAvailable(Vfs::Mode mode)
     auto name = modeToPluginName(mode);
     if (name.isEmpty())
         return false;
-    return QPluginLoader(pluginFileName("vfs", name)).load();
+    auto pluginPath = pluginFileName("vfs", name);
+    QPluginLoader loader(pluginPath);
+
+    auto basemeta = loader.metaData();
+    if (basemeta.isEmpty() || !basemeta.contains("IID")) {
+        qCDebug(lcPlugin) << "Plugin doesn't exist" << pluginPath;
+        return false;
+    }
+    if (basemeta["IID"].toString() != "org.owncloud.PluginFactory") {
+        qCWarning(lcPlugin) << "Plugin has wrong IID" << pluginPath << basemeta["IID"];
+        return false;
+    }
+
+    auto metadata = basemeta["MetaData"].toObject();
+    if (metadata["type"].toString() != "vfs") {
+        qCWarning(lcPlugin) << "Plugin has wrong type" << pluginPath << metadata["type"];
+        return false;
+    }
+    if (metadata["version"].toString() != MIRALL_VERSION_STRING) {
+        qCWarning(lcPlugin) << "Plugin has wrong version" << pluginPath << metadata["version"];
+        return false;
+    }
+
+    return true;
 }
 
 Vfs::Mode OCC::bestAvailableVfsMode()
@@ -94,8 +120,6 @@ Vfs::Mode OCC::bestAvailableVfsMode()
     return Vfs::Off;
 }
 
-Q_LOGGING_CATEGORY(lcPlugin, "plugins", QtInfoMsg)
-
 std::unique_ptr<Vfs> OCC::createVfsFromPlugin(Vfs::Mode mode)
 {
     if (mode == Vfs::Off)
@@ -104,8 +128,13 @@ std::unique_ptr<Vfs> OCC::createVfsFromPlugin(Vfs::Mode mode)
     auto name = modeToPluginName(mode);
     if (name.isEmpty())
         return nullptr;
-
     auto pluginPath = pluginFileName("vfs", name);
+
+    if (!isVfsPluginAvailable(mode)) {
+        qCWarning(lcPlugin) << "Could not load plugin: not existant or bad metadata" << pluginPath;
+        return nullptr;
+    }
+
     QPluginLoader loader(pluginPath);
     auto plugin = loader.instance();
     if (!plugin) {
diff --git a/src/common/vfspluginmetadata.json.in b/src/common/vfspluginmetadata.json.in
new file mode 100644 (file)
index 0000000..82c447a
--- /dev/null
@@ -0,0 +1,4 @@
+{
+    "type": "vfs",
+    "version": "@MIRALL_VERSION_STRING@"
+}
index 32a8bed925aecf2874cd2954497275f15a96962a..6d45fc75cbc7151c6bbdc8787587f47844235bdb 100644 (file)
@@ -51,7 +51,7 @@ public:
 class SuffixVfsPluginFactory : public QObject, public DefaultPluginFactory<VfsSuffix>
 {
     Q_OBJECT
-    Q_PLUGIN_METADATA(IID "org.owncloud.PluginFactory")
+    Q_PLUGIN_METADATA(IID "org.owncloud.PluginFactory" FILE "vfspluginmetadata.json")
     Q_INTERFACES(OCC::PluginFactory)
 };