summaryrefslogtreecommitdiff
path: root/zend/extensionimpl.cpp
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-01-20 13:45:17 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-01-20 13:45:17 +0100
commit5235f87126cc2bca3907daada9f59e0c7c7bc834 (patch)
tree6b049edd2eca0b74a8acb9ff7ee0c84c93bf1a5c /zend/extensionimpl.cpp
parent821e65d876cc0ce2b32471791b02d9f7cc784c99 (diff)
PHP-CPP now checks whether an already compiled extension is still compatible with the PHP-CPP library. This prevents weird crashes when users update their PHP-CPP library, without recompiling their extensions
Diffstat (limited to 'zend/extensionimpl.cpp')
-rw-r--r--zend/extensionimpl.cpp59
1 files changed, 58 insertions, 1 deletions
diff --git a/zend/extensionimpl.cpp b/zend/extensionimpl.cpp
index 262ecdb..fd97a76 100644
--- a/zend/extensionimpl.cpp
+++ b/zend/extensionimpl.cpp
@@ -220,12 +220,34 @@ int ExtensionImpl::processIdle(int type, int module_number TSRMLS_DC)
}
/**
+ * Function that is called when the PHP engine initializes with a different PHP-CPP
+ * version for the libphpcpp.so file than the version the extension was compiled for
+ * @param type Module type
+ * @param number Module number
+ * @param tsrm_ls
+ * @return int 0 on success
+ */
+int ExtensionImpl::processMismatch(int type, int module_number TSRMLS_DC)
+{
+ // get the extension
+ auto *extension = find(module_number TSRMLS_CC);
+
+ // report a warning
+ warning << "Version mismatch between PHP-CPP and extension " << extension->name() << " " << extension->version() << " (recompile needed?)" << std::endl;
+
+ // done
+ return BOOL2SUCCESS(true);
+}
+
+/**
* Constructor
* @param data Pointer to the extension object created by the extension programmer
* @param name Name of the extension
* @param version Version number
+ * @param apiversion API version number
*/
-ExtensionImpl::ExtensionImpl(Extension *data, const char *name, const char *version) : ExtensionBase(data)
+ExtensionImpl::ExtensionImpl(Extension *data, const char *name, const char *version, int apiversion) :
+ ExtensionBase(data)
{
// keep extension pointer based on the name
name2extension[name] = this;
@@ -262,6 +284,17 @@ ExtensionImpl::ExtensionImpl(Extension *data, const char *name, const char *vers
_entry.globals_ptr = NULL;
#endif
+ // everything is ok if the api versions match
+ if (apiversion == PHPCPP_API_VERSION) return;
+
+ // mismatch between api versions, the extension is invalid, we use a
+ // different startup function to report to the user
+ _entry.module_startup_func = &ExtensionImpl::processMismatch;
+
+ // the other callback functions are no longer necessary
+ _entry.module_shutdown_func = nullptr;
+ _entry.request_startup_func = nullptr;
+ _entry.request_shutdown_func = nullptr;
}
/**
@@ -277,6 +310,26 @@ ExtensionImpl::~ExtensionImpl()
}
/**
+ * The extension name
+ * @return const char *
+ */
+const char *ExtensionImpl::name() const
+{
+ // name is stored in the struct
+ return _entry.name;
+}
+
+/**
+ * The extension version
+ * @return const char *
+ */
+const char *ExtensionImpl::version() const
+{
+ // version is stored in the struct
+ return _entry.version;
+}
+
+/**
* Retrieve the module entry
* @return zend_module_entry
*/
@@ -285,6 +338,10 @@ zend_module_entry *ExtensionImpl::module()
// check if functions were already defined
if (_entry.functions) return &_entry;
+ // if the 'processMismatch' function is installed, the API version is wrong,
+ // and nothing should be initialized
+ if (_entry.module_startup_func == &ExtensionImpl::processMismatch) return &_entry;
+
// the number of functions
int count = _data->functions();