diff --git a/ext/session/mod_user.c b/ext/session/mod_user.c index 78fb6260540a..71b18612683d 100644 --- a/ext/session/mod_user.c +++ b/ext/session/mod_user.c @@ -30,16 +30,16 @@ static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval) PS(in_save_handler) = 0; ZVAL_UNDEF(retval); php_error_docref(NULL, E_WARNING, "Cannot call session save handler in a recursive manner"); - return; - } - PS(in_save_handler) = 1; - if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) { - zval_ptr_dtor(retval); - ZVAL_UNDEF(retval); - } else if (Z_ISUNDEF_P(retval)) { - ZVAL_NULL(retval); + } else { + PS(in_save_handler) = 1; + if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) { + zval_ptr_dtor(retval); + ZVAL_UNDEF(retval); + } else if (Z_ISUNDEF_P(retval)) { + ZVAL_NULL(retval); + } + PS(in_save_handler) = 0; } - PS(in_save_handler) = 0; for (i = 0; i < argc; i++) { zval_ptr_dtor(&argv[i]); } diff --git a/ext/session/tests/user_session_module/recursive_handler_argv_leak.phpt b/ext/session/tests/user_session_module/recursive_handler_argv_leak.phpt new file mode 100644 index 000000000000..2b954494e87c --- /dev/null +++ b/ext/session/tests/user_session_module/recursive_handler_argv_leak.phpt @@ -0,0 +1,31 @@ +--TEST-- +ps_call_handler() releases argv when a recursive save-handler call is rejected +--INI-- +session.save_path= +session.name=PHPSESSID +--EXTENSIONS-- +session +--FILE-- +tripped) { + $this->tripped = true; + session_destroy(); + } + return true; + } +} + +session_set_save_handler(new H, true); +session_start(); +$_SESSION['x'] = 1; +session_write_close(); +echo "done\n"; +?> +--EXPECTF-- +Warning: session_destroy(): Cannot call session save handler in a recursive manner in %s on line %d + +Warning: session_destroy(): Session object destruction failed in %s on line %d +done