diff --git a/ext/standard/dl.c b/ext/standard/dl.c index 90e538f19d4ac..0df3848852fe2 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -225,15 +225,30 @@ PHPAPI int php_load_extension(const char *filename, int type, int start_now) DL_UNLOAD(handle); return FAILURE; } + + int old_type = module_entry->type; + int old_module_number = module_entry->module_number; + void *old_handle = module_entry->handle; + module_entry->type = type; module_entry->module_number = zend_next_free_module(); module_entry->handle = handle; - if ((module_entry = zend_register_module_ex(module_entry)) == NULL) { + zend_module_entry *added_module_entry; + if ((added_module_entry = zend_register_module_ex(module_entry)) == NULL) { + /* Module loading failed, potentially because the module was already loaded. + * It is especially important in that case to restore the old type, module_number, and handle. + * Overwriting the values for an already-loaded module causes problem when these fields are used + * to uniquely identify module boundaries (e.g. in dom and reflection). */ + module_entry->type = old_type; + module_entry->module_number = old_module_number; + module_entry->handle = old_handle; DL_UNLOAD(handle); return FAILURE; } + module_entry = added_module_entry; + if ((type == MODULE_TEMPORARY || start_now) && zend_startup_module_ex(module_entry) == FAILURE) { DL_UNLOAD(handle); return FAILURE;