diff --git a/main/SAPI.c b/main/SAPI.c index 4b6b7b0c90e6..32388ddd8abb 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -117,10 +117,10 @@ PHP_FUNCTION(header_register_callback) RETURN_THROWS(); } - if (Z_TYPE(SG(callback_func)) != IS_UNDEF) { - zval_ptr_dtor(&SG(callback_func)); - SG(fci_cache) = empty_fcall_info_cache; - } + zval old_cb; + ZVAL_COPY_VALUE(&old_cb, &SG(callback_func)); + ZVAL_UNDEF(&SG(callback_func)); + SG(fci_cache) = empty_fcall_info_cache; /* Don't store callback if headers have already been sent: * It won't get used and we won't have a chance to release it. */ @@ -128,6 +128,9 @@ PHP_FUNCTION(header_register_callback) ZVAL_COPY(&SG(callback_func), &fci.function_name); } + /* Release the old callback last, its destructor may register a new one or bail out. */ + zval_ptr_dtor(&old_cb); + RETURN_TRUE; } /* }}} */ diff --git a/tests/basic/gh24731.phpt b/tests/basic/gh24731.phpt new file mode 100644 index 000000000000..fd29a9fc047e --- /dev/null +++ b/tests/basic/gh24731.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-24731 (Assertion failure when a bailout interrupts releasing the previous header_register_callback() callback) +--FILE-- + +--EXPECTF-- +Fatal error: Cannot redeclare function f() (previously declared in %s:%d) in %s : eval()'d code on line %d