Merge branch 'PHP-7.1' of git.php.net:/php-src into PHP-7.1

* 'PHP-7.1' of git.php.net:/php-src:
  new entry for #2196
  Improve error message
  Fix test
  Refactor and cleanup implementation.
  Revert "Fix Bug #73461"
  Revert "Protect class based session save handler"
  Protect class based session save handler
  Fix Bug #73461
This commit is contained in:
Xinchen Hui 2016-11-16 15:14:33 +08:00
commit 5ae5ab83fd
8 changed files with 38 additions and 19 deletions

View File

@ -30,12 +30,20 @@ ps_module ps_mod_user = {
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 session save handler in a 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]);
}

View File

@ -205,6 +205,7 @@ typedef struct _php_ps_globals {
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;

View File

@ -106,6 +106,7 @@ static inline void php_rinit_session_globals(void) /* {{{ */
/* 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;
@ -2035,7 +2036,7 @@ static PHP_FUNCTION(session_create_id)
}
}
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));
@ -2565,9 +2566,11 @@ static PHP_RSHUTDOWN_FUNCTION(session) /* {{{ */
{
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() */

View File

@ -40,16 +40,19 @@ session_write_close();
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 session save handler in a 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

View File

@ -48,4 +48,5 @@ Stack trace:
#0 [internal function]: write(%s, '')
#1 {main}
thrown in %s on line %d
close: goodbye cruel world
Warning: Unknown: Cannot call session save handler in a recursive manner in Unknown on line 0

View File

@ -48,5 +48,5 @@ Stack trace:
#0 [internal function]: write('%s', '')
#1 {main}
thrown in %s on line %d
close: goodbye cruel world
Warning: Unknown: Cannot call session save handler in a recursive manner in Unknown on line 0

View File

@ -1,7 +1,5 @@
--TEST--
Bug #69111 Crash in SessionHandler::read()
--XFAIL--
It is still a leak
--SKIPIF--
<?php include('skipif.inc'); ?>
--FILE--
@ -19,4 +17,9 @@ $sh->write("foo", "bar");
var_dump($sh->read(@$id));
?>
--EXPECTF--
Warning: SessionHandler::open(): Session is not active in %s on line 10
Warning: SessionHandler::write(): Session is not active in %s on line 11
Warning: SessionHandler::read(): Session is not active in %s on line 12
bool(false)

View File

@ -2,12 +2,12 @@
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;