Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[loader] Fix compatilibity with PHP 5 #2939

Merged
merged 1 commit into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion loader/compat_php.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions loader/compat_php.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 5 additions & 5 deletions loader/dd_library_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
;
}
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
Loading