From b5adfee320de8d8aa13ee9d97f040f4d416f40d5 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 11 Dec 2015 17:26:31 +0800 Subject: [PATCH] Fixed bug memleak in header_register_callback --- NEWS | 1 + main/SAPI.c | 18 +++++++++--------- main/SAPI.h | 1 - tests/basic/header_register_callback.phpt | 8 ++++++++ 4 files changed, 18 insertions(+), 10 deletions(-) create mode 100644 tests/basic/header_register_callback.phpt diff --git a/NEWS b/NEWS index 8f3d442e51..ed32b6cb97 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ PHP NEWS ?? Jan 2016 PHP 7.0.2 - Core: + . Fixed bug memleak in header_register_callback. (Laruence) . Fixed bug #71067 (Local object in class method stays in memory for each call). (Laruence) . Fixed bug #66909 (configure fails utf8_to_mutf7 test). (Michael Orlitzky) diff --git a/main/SAPI.c b/main/SAPI.c index c0ea144015..9d189f61fb 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -142,14 +142,14 @@ PHP_FUNCTION(header_register_callback) } /* }}} */ -static void sapi_run_header_callback(void) +static void sapi_run_header_callback(zval *callback) { int error; zend_fcall_info fci; char *callback_error = NULL; zval retval; - if (zend_fcall_info_init(&SG(callback_func), 0, &fci, &SG(fci_cache), NULL, &callback_error) == SUCCESS) { + if (zend_fcall_info_init(callback, 0, &fci, &SG(fci_cache), NULL, &callback_error) == SUCCESS) { fci.retval = &retval; error = zend_call_function(&fci, &SG(fci_cache)); @@ -446,7 +446,6 @@ SAPI_API void sapi_activate(void) SG(sapi_headers).http_status_line = NULL; SG(sapi_headers).mimetype = NULL; SG(headers_sent) = 0; - SG(callback_run) = 0; ZVAL_UNDEF(&SG(callback_func)); SG(read_post_bytes) = 0; SG(request_info).request_body = NULL; @@ -543,8 +542,6 @@ SAPI_API void sapi_deactivate(void) sapi_send_headers_free(); SG(sapi_started) = 0; SG(headers_sent) = 0; - SG(callback_run) = 0; - zval_ptr_dtor(&SG(callback_func)); SG(request_info).headers_read = 0; SG(global_request_time) = 0; } @@ -851,7 +848,7 @@ SAPI_API int sapi_send_headers(void) int retval; int ret = FAILURE; - if (SG(headers_sent) || SG(request_info).no_headers || SG(callback_run)) { + if (SG(headers_sent) || SG(request_info).no_headers) { return SUCCESS; } @@ -871,9 +868,12 @@ SAPI_API int sapi_send_headers(void) SG(sapi_headers).send_default_content_type = 0; } - if (Z_TYPE(SG(callback_func)) != IS_UNDEF && !SG(callback_run)) { - SG(callback_run) = 1; - sapi_run_header_callback(); + if (Z_TYPE(SG(callback_func)) != IS_UNDEF) { + zval cb; + ZVAL_COPY_VALUE(&cb, &SG(callback_func)); + ZVAL_UNDEF(&SG(callback_func)); + sapi_run_header_callback(&cb); + zval_ptr_dtor(&cb); } SG(headers_sent) = 1; diff --git a/main/SAPI.h b/main/SAPI.h index 67ee50dec2..7a80e70427 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -136,7 +136,6 @@ typedef struct _sapi_globals_struct { HashTable known_post_content_types; zval callback_func; zend_fcall_info_cache fci_cache; - zend_bool callback_run; } sapi_globals_struct; diff --git a/tests/basic/header_register_callback.phpt b/tests/basic/header_register_callback.phpt new file mode 100644 index 0000000000..641ee9e3e7 --- /dev/null +++ b/tests/basic/header_register_callback.phpt @@ -0,0 +1,8 @@ +--TEST-- +Test header_register_callback +--FILE-- + +--EXPECT-- +sent -- 2.40.0