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: | Yasuo Ohgaki | 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)