diff --git a/loader/compat_php.c b/loader/compat_php.c index 07100312ec..63d672b583 100644 --- a/loader/compat_php.c +++ b/loader/compat_php.c @@ -9,9 +9,11 @@ #define PHP_70_71_72_IS_STR_INTERNED (1 << 1) ZEND_API zval *ZEND_FASTCALL zend_hash_set_bucket_key(HashTable *ht, Bucket *b, zend_string *key) __attribute__((weak)); - ZEND_API zval *ZEND_FASTCALL zend_hash_update(HashTable *ht, zend_string *key, zval *pData) __attribute__((weak)); ZEND_API zval *ZEND_FASTCALL _zend_hash_update(HashTable *ht, zend_string *key, zval *pData) __attribute__((weak)); +ZEND_API zend_result ZEND_FASTCALL zend_hash_str_del(HashTable *ht, const char *str, size_t len) __attribute__((weak)); +ZEND_API zval* ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *key, size_t len) __attribute__((weak)); +ZEND_API void * __zend_malloc(size_t len) __attribute__((weak)); static bool ddloader_zstr_is_interned(int php_api_no, zend_string *key) { if (php_api_no <= 20170718) { // PHP 7.0 - 7.2 @@ -66,6 +68,29 @@ void ddloader_zend_string_release(int php_api_no, zend_string *s) { zend_string_release(s); } +void *ddloader_zend_hash_str_find_ptr(int php_api_no, const HashTable *ht, const char *str, size_t len) { + UNUSED(php_api_no); + zval *zv; + + if (!zend_hash_str_find) { + return NULL; + } + + zv = zend_hash_str_find(ht, str, len); + if (zv) { + return Z_PTR_P(zv); + } else { + return NULL; + } +} + +void ddloader_zend_hash_str_del(int php_api_no, HashTable *ht, const char *str, size_t len) { + UNUSED(php_api_no); + if (zend_hash_str_del) { + zend_hash_str_del(ht, str, len); + } +} + // This is an adaptation of zend_hash_set_bucket_key which is only available only starting from PHP 7.4 // to be compatible with PHP 7.0+ zval *ddloader_zend_hash_set_bucket_key(int php_api_no, HashTable *ht, Bucket *b, zend_string *key) { diff --git a/loader/compat_php.h b/loader/compat_php.h index 6ac783cb62..5bbd17979f 100644 --- a/loader/compat_php.h +++ b/loader/compat_php.h @@ -7,6 +7,8 @@ zend_string *ddloader_zend_string_alloc(int php_api_no, size_t len, int persiste zend_string *ddloader_zend_string_init(int php_api_no, const char *str, size_t len, bool persistent); void ddloader_zend_string_release(int php_api_no, zend_string *s); zval *ddloader_zend_hash_set_bucket_key(int php_api_no, HashTable *ht, Bucket *b, zend_string *key); +void *ddloader_zend_hash_str_find_ptr(int php_api_no, const HashTable *ht, const char *str, size_t len); +void ddloader_zend_hash_str_del(int php_api_no, HashTable *ht, const char *str, size_t len); void ddloader_replace_zend_error_cb(int php_api_no); void ddloader_restore_zend_error_cb(); zval *ddloader_zend_hash_update(HashTable *ht, zend_string *key, zval *pData); diff --git a/loader/dd_library_loader.c b/loader/dd_library_loader.c index 3ff9c009e8..af051f0a7a 100644 --- a/loader/dd_library_loader.c +++ b/loader/dd_library_loader.c @@ -64,7 +64,7 @@ static char *ddtrace_pre_load_hook(void) { } static bool ddloader_is_ext_loaded(const char *name) { - return zend_hash_str_find_ptr(&module_registry, name, strlen(name)) + return ddloader_zend_hash_str_find_ptr(php_api_no, &module_registry, name, strlen(name)) || zend_get_extension(name) ; } @@ -390,14 +390,14 @@ static bool ddloader_check_deps(const zend_module_dep *deps) { } static void ddloader_unregister_module(const char *name) { - zend_module_entry *injected = zend_hash_str_find_ptr(&module_registry, name, strlen(name)); + zend_module_entry *injected = ddloader_zend_hash_str_find_ptr(php_api_no, &module_registry, name, strlen(name)); if (!injected) { return; } // Set the MSHUTDOWN function to NULL to avoid it being called by zend_hash_str_del injected->module_shutdown_func = NULL; - zend_hash_str_del(&module_registry, name, strlen(name)); + ddloader_zend_hash_str_del(php_api_no, &module_registry, name, strlen(name)); } static PHP_MINIT_FUNCTION(ddloader_injected_extension_minit) { @@ -414,7 +414,7 @@ static PHP_MINIT_FUNCTION(ddloader_injected_extension_minit) { return SUCCESS; } - zend_module_entry *module = zend_hash_str_find_ptr(&module_registry, config->ext_name, strlen(config->ext_name)); + zend_module_entry *module = ddloader_zend_hash_str_find_ptr(php_api_no, &module_registry, config->ext_name, strlen(config->ext_name)); if (module) { LOG(INFO, "Extension '%s' is already loaded, unregister the injected extension", config->ext_name); ddloader_unregister_module(config->tmp_name); @@ -446,7 +446,7 @@ static PHP_MINIT_FUNCTION(ddloader_injected_extension_minit) { ddloader_zend_hash_set_bucket_key(php_api_no, &module_registry, bucket, new_name); ddloader_zend_string_release(php_api_no, new_name); - module = zend_hash_str_find_ptr(&module_registry, config->ext_name, strlen(config->ext_name)); + module = ddloader_zend_hash_str_find_ptr(php_api_no, &module_registry, config->ext_name, strlen(config->ext_name)); if (!module) { TELEMETRY(REASON_ERROR, "Extension '%s' not found after renaming. Something wrong happened", config->ext_name); return SUCCESS;