[PECL-CVS] [pecl-networking-gearman] memory-audit: Fix several memory access issues
[email protected] (Rasmus Lerdorf) Tue, 10 Feb 2026 04:27:03 +0000
| Newsgroups | php.pecl.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: Rasmus Lerdorf (rlerdorf)
Date: 2026-02-09T23:24:35-05:00
Commit: https://github.com/php/pecl-networking-gearman/commit/892359d5c94e9d2a2a2182ec9c32b7623e2ba776
Raw diff: https://github.com/php/pecl-networking-gearman/commit/892359d5c94e9d2a2a2182ec9c32b7623e2ba776.diff
Fix several memory access issues
Changed paths:
M php_gearman.c
M php_gearman_client.c
M php_gearman_job.c
M php_gearman_task.c
M php_gearman_worker.c
M php_gearman_worker.h
Diff:
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 */