static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval)
{
int i;
+ if (PS(in_save_handler)) {
+ PS(in_save_handler) = 0;
+ ZVAL_UNDEF(retval);
+ php_error_docref(NULL, E_WARNING, "Cannot call save handler function recursive manner");
+ return;
+ }
+ PS(in_save_handler) = 1;
if (call_user_function(EG(function_table), 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;
for (i = 0; i < argc; i++) {
zval_ptr_dtor(&argv[i]);
}
zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
zend_bool lazy_write; /* omit session write when it is possible */
zend_string *session_vars; /* serialized original session data */
+ zend_bool in_save_handler; /* state that if session is in save handler or not */
} php_ps_globals;
typedef php_ps_globals zend_ps_globals;
/* TODO: These could be moved to MINIT and removed. These should be initialized by php_rshutdown_session_globals() always when execution is finished. */
PS(id) = NULL;
PS(session_status) = php_session_none;
+ PS(in_save_handler) = 0;
PS(mod_data) = NULL;
PS(mod_user_is_open) = 0;
PS(define_sid) = 1;
}
}
- if (PS(session_status) == php_session_active) {
+ if (!PS(in_save_handler) && PS(session_status) == php_session_active) {
int limit = 3;
while (limit--) {
new_id = PS(mod)->s_create_sid(&PS(mod_data));
{
int i;
- zend_try {
- php_session_flush(1);
- } zend_end_try();
+ if (PS(session_status) == php_session_active) {
+ zend_try {
+ php_session_flush(1);
+ } zend_end_try();
+ }
php_rshutdown_session_globals();
/* this should NOT be done in php_rshutdown_session_globals() */
echo "um, hi\n";
/*
-FIXME: Since session module try to write/close session data in
-RSHUTDOWN, write() is executed twices. This is caused by undefined
-function error and zend_bailout(). Current session module codes
-depends on this behavior. These codes should be modified to remove
-multiple write().
-*/
+ * write() calls die(). This results in calling session_flush() which calls
+ * write() in request shutdown. The code is inside save handler still and
+ * calls save close handler.
+ *
+ * Because session_write_close() fails by die(), write() is called twice.
+ * close() is still called at request shutdown since session is active.
+ */
?>
--EXPECTF--
write: goodbye cruel world
-write: goodbye cruel world
-close: goodbye cruel world
+Warning: Unknown: Cannot call save handler function recursive manner in Unknown on line 0
+
+Warning: Unknown: Failed to write session data using user defined save handler. (session.save_path: ) in Unknown on line 0
+close: goodbye cruel world
#0 [internal function]: write(%s, '')
#1 {main}
thrown in %s on line %d
-close: goodbye cruel world
+
+Warning: Unknown: Cannot call save handler function recursive manner in Unknown on line 0
#0 [internal function]: write('%s', '')
#1 {main}
thrown in %s on line %d
-close: goodbye cruel world
+Warning: Unknown: Cannot call save handler function recursive manner in Unknown on line 0
--TEST--
Bug #69111 Crash in SessionHandler::read()
---XFAIL--
-It is still a leak
--SKIPIF--
<?php include('skipif.inc'); ?>
--FILE--
var_dump($sh->read(@$id));
?>
--EXPECTF--
+Warning: SessionHandler::open(): Session is not active in /home/yohgaki/workspace/ext/git/oss/php.net/github-php-src/ext/session/tests/bug69111.php on line 10
+
+Warning: SessionHandler::write(): Session is not active in /home/yohgaki/workspace/ext/git/oss/php.net/github-php-src/ext/session/tests/bug69111.php on line 11
+
+Warning: SessionHandler::read(): Session is not active in /home/yohgaki/workspace/ext/git/oss/php.net/github-php-src/ext/session/tests/bug69111.php on line 12
bool(false)
updateTimestamp never called when session data is empty
--INI--
session.use_strict_mode=0
+session.save_handler=files
--XFAIL--
-Current session module is designed to write empty session always. In addition,
-current session module only supports SessionHandlerInterface only from PHP 7.0.
+Current session module is designed to write empty session always. In addition, current session module only supports SessionHandlerInterface only from PHP 7.0.
--FILE--
<?php
-class MySessionHandler implements SessionUpdateTimestampHandlerInterface
+class MySessionHandler extends SessionHandler implements SessionUpdateTimestampHandlerInterface
{
public function open($path, $sessname) {
return TRUE;