com php-src: Fix #70013: Reference to $_SESSION is lost after a call to session_regenerate_id(): ext/session/session.c ext/session/tests/bug6769
4.phpt ext/session/tests/bug70013.phpt

From: Date: Sun, 06 Sep 2015 18:57:03 +0000
Subject: com php-src: Fix #70013: Reference to $_SESSION is lost after a call to session_regenerate_id(): ext/session/session.c ext/session/tests/bug6769
4.phpt ext/session/tests/bug70013.phpt
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-88936@lists.php.net to get a copy of this message
Commit: f34b858ed018d4c33bc0c3f03acc0bf143d35534 Author: Yasuo Ohgaki <yohgaki@php.net> Sun, 6 Sep 2015 17:14:34 +0900 Parents: 22e23e7cb8ca9aa134d138b5fed031af6c842b44 Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=f34b858ed018d4c33bc0c3f03acc0bf143d35534 Log: Fix #70013: Reference to $_SESSION is lost after a call to session_regenerate_id() Bugs: https://bugs.php.net/70013 Changed paths: M ext/session/session.c M ext/session/tests/bug67694.phpt A ext/session/tests/bug70013.phpt Diff: diff --git a/ext/session/session.c b/ext/session/session.c index 46b817b...8c60463 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -2019,7 +2019,7 @@ static PHP_FUNCTION(session_id) static PHP_FUNCTION(session_regenerate_id) { zend_bool del_ses = 0; - zend_string *data = NULL; + zend_string *data; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &del_ses) == FAILURE) { return; @@ -2035,25 +2035,70 @@ static PHP_FUNCTION(session_regenerate_id) RETURN_FALSE; } - /* Keep current session data */ - data = php_session_encode(); - - if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id)) == FAILURE) { - php_error_docref(NULL, E_WARNING, "Session object destruction failed"); + /* Process old session data */ + if (del_ses) { + if (PS(mod)->s_destroy(&PS(mod_data), PS(id)) == FAILURE) { + PS(mod)->s_close(&PS(mod_data)); + PS(session_status) = php_session_none; + php_error_docref(NULL, E_WARNING, "Session object destruction failed. ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + RETURN_FALSE; + } + } else { + int ret; + data = php_session_encode(); + if (data) { + ret = PS(mod)->s_write(&PS(mod_data), PS(id), data, PS(gc_maxlifetime)); + zend_string_release(data); + } else { + ret = PS(mod)->s_write(&PS(mod_data), PS(id), ZSTR_EMPTY_ALLOC(), PS(gc_maxlifetime)); + } + PS(mod)->s_close(&PS(mod_data)); + if (ret == FAILURE) { + PS(session_status) = php_session_none; + php_error_docref(NULL, E_WARNING, "Session write failed. ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + RETURN_FALSE; + } } - php_rshutdown_session_globals(); - php_rinit_session_globals(); - php_session_initialize(); - /* Restore session data */ - if (data) { - if (PS(session_vars)) { - zend_string_release(PS(session_vars)); - PS(session_vars) = NULL; + /* New session data */ + if (PS(session_vars)) { + zend_string_release(PS(session_vars)); + PS(session_vars) = NULL; + } + zend_string_release(PS(id)); + PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); + if (!PS(id)) { + PS(session_status) = php_session_none; + php_error_docref(NULL, E_RECOVERABLE_ERROR, "Failed to create session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + RETURN_FALSE; + } + if (PS(use_strict_mode) && PS(mod)->s_validate_sid && + PS(mod)->s_validate_sid(&PS(mod_data), PS(id)) == FAILURE) { + zend_string_release(PS(id)); + PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); + if (!PS(id)) { + PS(session_status) = php_session_none; + php_error_docref(NULL, E_RECOVERABLE_ERROR, "Failed to create session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + RETURN_FALSE; } - php_session_decode(data); + } + if (PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name)) == FAILURE) { + PS(session_status) = php_session_none; + php_error_docref(NULL, E_RECOVERABLE_ERROR, "Failed to create session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + RETURN_FALSE; + } + /* Read is required to make new session data at this point. */ + if (PS(mod)->s_read(&PS(mod_data), PS(id), &data, PS(gc_maxlifetime)) == FAILURE) { + PS(session_status) = php_session_none; + php_error_docref(NULL, E_RECOVERABLE_ERROR, "Failed to create session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + RETURN_FALSE; + } + if (data) { zend_string_release(data); } + + php_session_reset_id(); + RETURN_TRUE; } /* }}} */ diff --git a/ext/session/tests/bug67694.phpt b/ext/session/tests/bug67694.phpt index bf7089f..a82a9fc 100644 --- a/ext/session/tests/bug67694.phpt +++ b/ext/session/tests/bug67694.phpt @@ -11,7 +11,7 @@ date.timezone = UTC <?php include('skipif.inc'); ?> --FILE-- <?php - +ob_start(); $data = date('r'); session_start(); diff --git a/ext/session/tests/bug70013.phpt b/ext/session/tests/bug70013.phpt new file mode 100644 index 0000000..739e562 --- /dev/null +++ b/ext/session/tests/bug70013.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #70013 (Reference to $_SESSION is lost after a call to session_regenerate_id()) +--SKIPIF-- +<?php include('skipif.inc'); ?> +--INI-- +session.save_handler=files +--FILE-- +<?php +ob_start(); +session_start(); + +$session = &$_SESSION; + +$session['test'] = 1; +session_regenerate_id(false); +$session['test'] = 2; + +var_dump($session['test'] === $_SESSION['test']); + +$session['test'] = 3; +session_regenerate_id(true); +$session['test'] = 4; + +var_dump($session['test'] === $_SESSION['test']); +?> +--EXPECT-- +bool(true) +bool(true)

« previous php.cvs (#88936) next »