]> granicus.if.org Git - php/commitdiff
Fixed bug memleak in header_register_callback
authorXinchen Hui <laruence@gmail.com>
Fri, 11 Dec 2015 09:26:31 +0000 (17:26 +0800)
committerXinchen Hui <laruence@gmail.com>
Fri, 11 Dec 2015 09:26:31 +0000 (17:26 +0800)
NEWS
main/SAPI.c
main/SAPI.h
tests/basic/header_register_callback.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 8f3d442e5162e6c91fcd987b22f2d76959a00933..ed32b6cb971be5dfff7a0b43a246c3af8a0e6201 100644 (file)
--- 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)
index c0ea144015a28a45a790ce44b6fadac9e9082917..9d189f61fb8bfbeeecc9cf01b8db16a541db47ea 100644 (file)
@@ -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;
index 67ee50dec28381307ed82a7afd06400d3f200d2f..7a80e70427467aa1654d95ab58b20256ae3ebf01 100644 (file)
@@ -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 (file)
index 0000000..641ee9e
--- /dev/null
@@ -0,0 +1,8 @@
+--TEST--
+Test header_register_callback
+--FILE--
+<?php
+header_register_callback(function() { echo "sent";});
+?>
+--EXPECT--
+sent