diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index c9c1a0680c..4d81506817 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -219,6 +219,10 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_ current_plugin->SetDynamic(true); current_plugin->DoConfigure(); + if ( current_plugin->APIVersion() != BRO_PLUGIN_API_VERSION ) + reporter->FatalError("plugin's API version does not match Bro (expected %d, got %d in %s)", + BRO_PLUGIN_API_VERSION, current_plugin->APIVersion(), path); + // We execute the pre-script initialization here; this in // fact could be *during* script initialization if we got // triggered via @load-plugin. diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 9a7a0a9ee3..8aaadc1ec7 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -33,13 +33,6 @@ const char* plugin::hook_name(HookType h) return hook_names[int(h)]; } -Configuration::Configuration() - { - name = ""; - description = ""; - api_version = BRO_PLUGIN_API_VERSION; - } - BifItem::BifItem(const std::string& arg_id, Type arg_type) { id = arg_id; diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index 3e4bb4e6b6..978e22b634 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -10,7 +10,10 @@ #include "analyzer/Component.h" #include "file_analysis/Component.h" -static const int BRO_PLUGIN_API_VERSION = 2; +// We allow to override this externally for testing purposes. +#ifndef BRO_PLUGIN_API_VERSION +#define BRO_PLUGIN_API_VERSION 2 +#endif class ODesc; class Func; @@ -75,13 +78,23 @@ public: std::string description; //< A short textual description of the plugin. Mandatory. VersionNumber version; //< THe plugin's version. Optional. - Configuration(); + // We force this to inline so that the API version gets hardcoded + // into the external plugin. (Technically, it's not a "force", just a + // strong hint.). The attribute seems generally available. + inline Configuration() __attribute__((always_inline)); private: friend class Plugin; int api_version; // Current BRO_PLUGIN_API_VERSION. Automatically set. }; +inline Configuration::Configuration() + { + name = ""; + description = ""; + api_version = BRO_PLUGIN_API_VERSION; + } + /** * A class describing an item defined in \c *.bif file. */ diff --git a/testing/btest/Baseline/plugins.api-version-mismatch/output b/testing/btest/Baseline/plugins.api-version-mismatch/output new file mode 100644 index 0000000000..806623cd02 --- /dev/null +++ b/testing/btest/Baseline/plugins.api-version-mismatch/output @@ -0,0 +1 @@ +fatal error in /home/robin/bro/master/scripts/base/init-bare.bro, line 1: plugin's API version does not match Bro (expected 2, got 42 in /home/robin/bro/master/testing/btest/.tmp/plugins.api-version-mismatch//lib/Demo-Foo.linux-x86_64.so) diff --git a/testing/btest/plugins/api-version-mismatch.sh b/testing/btest/plugins/api-version-mismatch.sh new file mode 100644 index 0000000000..a75ff05655 --- /dev/null +++ b/testing/btest/plugins/api-version-mismatch.sh @@ -0,0 +1,7 @@ +# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo +# @TEST-EXEC: bash %INPUT +# @TEST-EXEC: make BRO=${DIST} +# @TEST-EXEC-FAIL: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output 2>&1 +# @TEST-EXEC: btest-diff output + +( echo '#define BRO_PLUGIN_API_VERSION 42'; cat src/Plugin.cc; ) >src/Plugin.cc.tmp && mv src/Plugin.cc.tmp src/Plugin.cc