Re: com php-src: Fix #70013: Reference to $_SESSION is lost after a call to session_regenerate_id(): ext/session/session.c
ext/session/tests/bug67694.phpt ext/session/tests/bug70013.phpt
| From: | Yasuo Ohgaki | Date: | Tue, 08 Sep 2015 21:52:30 +0000 |
| Subject: | Re: com php-src: Fix #70013: Reference to $_SESSION is lost after a call to session_regenerate_id(): ext/session/session.c ext/session/tests/bug67694.phpt ext/session/tests/bug70013.phpt |
||
| References: | 1 | Groups: | php.cvs |
| Request: | Send a blank email to php-cvs+get-88958@lists.php.net to get a copy of this message | ||
Hi Anatol,
Sorry for the delay. This fixes lost $_SESSION reference issue.
Could you merge this and aa352a34fd1077995ec159ba30a6cf62c70e64c7.
aa352a34fd1077995ec159ba30a6cf62c70e64c7 is not mandatory, but
save handler is better to be closed explicitly always.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
On Mon, Sep 7, 2015 at 3:57 AM, Yasuo Ohgaki <yohgaki@php.net> wrote:
> 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)
>
>
> --
> PHP CVS Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>