From 892359d5c94e9d2a2a2182ec9c32b7623e2ba776 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Mon, 9 Feb 2026 23:24:35 -0500 Subject: [PATCH] Fix several memory access issues --- php_gearman.c | 1 + php_gearman_client.c | 15 +++++++-------- php_gearman_job.c | 2 +- php_gearman_task.c | 9 +++++---- php_gearman_worker.c | 19 +++++++++++++------ php_gearman_worker.h | 1 + 6 files changed, 28 insertions(+), 19 deletions(-) diff --git a/php_gearman.c b/php_gearman.c index fc8bf74..474039e 100644 --- a/php_gearman.c +++ b/php_gearman.c @@ -112,6 +112,7 @@ PHP_MINIT_FUNCTION(gearman) { gearman_worker_ce->create_object = gearman_worker_obj_new; memcpy(&gearman_worker_obj_handlers, zend_get_std_object_handlers(), sizeof(gearman_worker_obj_handlers)); gearman_worker_obj_handlers.offset = XtOffsetOf(gearman_worker_obj, std); + gearman_worker_obj_handlers.free_obj = gearman_worker_free_obj; INIT_CLASS_ENTRY(ce, "GearmanJob", class_GearmanJob_methods); gearman_job_ce = zend_register_internal_class(&ce); diff --git a/php_gearman_client.c b/php_gearman_client.c index 38290a9..f2ae566 100644 --- a/php_gearman_client.c +++ b/php_gearman_client.c @@ -83,7 +83,9 @@ PHP_METHOD(GearmanClient, __destruct) if (intern->flags & GEARMAN_CLIENT_OBJ_CREATED) { context = gearman_client_context(&(intern->client)); - efree(context); + if (context) { + efree(context); + } gearman_client_free(&intern->client); intern->flags &= ~GEARMAN_CLIENT_OBJ_CREATED; @@ -416,7 +418,7 @@ static void gearman_client_do_work_handler(void* (*do_work_func)( RETURN_EMPTY_STRING(); } - ZVAL_STRINGL(return_value, (char *)result, (long)result_size); + ZVAL_STRINGL(return_value, (char *)result, result_size); efree(result); } /* }}} */ @@ -492,11 +494,6 @@ static void gearman_client_do_background_work_handler(gearman_return_t (*do_back RETURN_EMPTY_STRING(); } - if (! job_handle) { - zend_string_release(job_handle); - RETURN_EMPTY_STRING(); - } - RETURN_STR(job_handle); } /* }}} */ @@ -1251,7 +1248,9 @@ PHP_FUNCTION(gearman_client_set_context) { obj = Z_GEARMAN_CLIENT_P(zobj); old_context = gearman_client_context(&(obj->client)); - efree(old_context); + if (old_context) { + efree(old_context); + } gearman_client_set_context(&(obj->client), (void*) estrndup(data, data_len)); RETURN_TRUE; diff --git a/php_gearman_job.c b/php_gearman_job.c index c840f1e..97036c9 100644 --- a/php_gearman_job.c +++ b/php_gearman_job.c @@ -316,7 +316,7 @@ PHP_FUNCTION(gearman_job_workload) { workload = gearman_job_workload(obj->job); workload_len = gearman_job_workload_size(obj->job); - RETURN_STRINGL((char *)workload, (long) workload_len); + RETURN_STRINGL((char *)workload, workload_len); } /* }}} */ diff --git a/php_gearman_task.c b/php_gearman_task.c index 8e7ea72..c3a9590 100644 --- a/php_gearman_task.c +++ b/php_gearman_task.c @@ -293,7 +293,7 @@ PHP_FUNCTION(gearman_task_data) { data = gearman_task_data(obj->task); data_len = gearman_task_data_size(obj->task); - RETURN_STRINGL((char *)data, (long) data_len); + RETURN_STRINGL((char *)data, data_len); } RETURN_FALSE; } @@ -378,12 +378,13 @@ PHP_FUNCTION(gearman_task_recv_data) { !gearman_client_has_option(&Z_GEARMAN_CLIENT_P(&obj->zclient)->client, GEARMAN_CLIENT_UNBUFFERED_RESULT)) { php_error_docref(NULL, E_WARNING, "%s", gearman_client_error(&Z_GEARMAN_CLIENT_P(&obj->zclient)->client)); + efree(data_buffer); RETURN_FALSE; } array_init(return_value); - add_next_index_long(return_value, (long)data_len); - add_next_index_stringl(return_value, (char *)data_buffer, - (long)data_len); + add_next_index_long(return_value, data_len); + add_next_index_stringl(return_value, (char *)data_buffer, data_len); + efree(data_buffer); } /* }}} */ diff --git a/php_gearman_worker.c b/php_gearman_worker.c index c49e1e2..3c04998 100644 --- a/php_gearman_worker.c +++ b/php_gearman_worker.c @@ -57,6 +57,17 @@ PHP_METHOD(GearmanWorker, __construct) { } /* }}} */ +void gearman_worker_free_obj(zend_object *object) { + gearman_worker_obj *intern = gearman_worker_fetch_object(object); + if (!intern) { + return; + } + + zval_dtor(&intern->cb_list); + + zend_object_std_dtor(&intern->std); +} + /* {{{ proto object GearmanWorker::__destruct() Destroys a worker object */ PHP_METHOD(GearmanWorker, __destruct) { @@ -70,8 +81,6 @@ PHP_METHOD(GearmanWorker, __destruct) { gearman_worker_free(&(intern->worker)); intern->flags &= ~GEARMAN_WORKER_OBJ_CREATED; } - - zval_dtor(&intern->cb_list); } /* }}} */ @@ -473,7 +482,7 @@ static void *_php_worker_function_callback(gearman_job_st *job, void *context, size_t *result_size, gearman_return_t *ret_ptr) { - zval zjob, message; + zval zjob; gearman_job_obj *jobj; gearman_worker_cb_obj *worker_cb = (gearman_worker_cb_obj *)context; char *result = NULL; @@ -516,9 +525,7 @@ static void *_php_worker_function_callback(gearman_job_st *job, if (EG(exception)) { *ret_ptr = GEARMAN_WORK_EXCEPTION; - ZVAL_STRING(&message, "Unable to add worker function"); - - jobj->ret = gearman_job_send_exception(jobj->job, Z_STRVAL(message), Z_STRLEN(message)); + jobj->ret = gearman_job_send_exception(jobj->job, "Unable to add worker function", sizeof("Unable to add worker function") - 1); if (jobj->ret != GEARMAN_SUCCESS && jobj->ret != GEARMAN_IO_WAIT) { php_error_docref(NULL, E_WARNING, "Unable to add worker function: %s", diff --git a/php_gearman_worker.h b/php_gearman_worker.h index 91f5048..27f94cc 100644 --- a/php_gearman_worker.h +++ b/php_gearman_worker.h @@ -31,6 +31,7 @@ extern zend_class_entry *gearman_worker_ce; extern zend_object_handlers gearman_worker_obj_handlers; zend_object *gearman_worker_obj_new(zend_class_entry *ce); +void gearman_worker_free_obj(zend_object *object); typedef struct { zval zname; /* name associated with callback */