php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #73343 extra call to read in session_regenerate_id in custom session handler
Submitted: 2016-10-18 23:51 UTC Modified: 2016-10-26 00:32 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: ryan dot brothers at gmail dot com Assigned: yohgaki (profile)
Status: Not a bug Package: Session related
PHP Version: 7.1.0RC3 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
31 + 39 = ?
Subscribe to this entry?

 
 [2016-10-18 23:51 UTC] ryan dot brothers at gmail dot com
Description:
------------
When using a custom session handler in PHP 7 or 7.1, when session_regenerate_id() is called, the read function is called on the new session_id.  This does not occur in PHP 5.6.  This extra call to read is causing an issue in my custom session handler.  From my testing, it appears to ignore the result of the read call anyway as in the below, abc remains 1.  Is there a reason for this extra call to read?  Thanks for your help.

Test script:
---------------
<?php
class test_session_handler implements SessionHandlerInterface
{
	public function open($save_path, $session_name) { return true; }

	public function close() { return true; }

	public function read($id)
	{
		if ($GLOBALS['in_session_regenerate_id'] == true)
		{
			echo 'read in session_regenerate_id<br>';

			return 'abc|i:2;';
		}
		else
		{
			echo 'read<br>';

			return 'abc|i:1;';
		}
	}

	public function write($session_id, $session_data) { return true; }

	public function destroy($session_id) { return true; }

	public function gc($maxlifetime) { return true; }
}

ob_start();

$GLOBALS['in_session_regenerate_id'] = false;

session_set_save_handler(new test_session_handler());
session_start();

echo 'start session_regenerate_id<br>';

$GLOBALS['in_session_regenerate_id'] = true;

session_regenerate_id(true);

echo 'end session_regenerate_id<br>';

echo $_SESSION['abc'];


Expected result:
----------------
read
start session_regenerate_id
end session_regenerate_id
1


Actual result:
--------------
read
start session_regenerate_id
read in session_regenerate_id
end session_regenerate_id
1


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-10-25 17:05 UTC] cmb@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: yohgaki
 [2016-10-25 17:05 UTC] cmb@php.net
This behavioral change has been introduced by fixing bug #61470.
Is the additional read desired or necessary, Yasuo? If so, this
should probably be documented.
 [2016-10-25 18:28 UTC] yohgaki@php.net
-Type: Bug +Type: Documentation Problem
 [2016-10-25 18:28 UTC] yohgaki@php.net
As a result of a bug fix, session_regenerate_id() save old session and start new session from 7.1

I've added UPGRADING.
 [2016-10-25 18:59 UTC] yohgaki@php.net
-Status: Verified +Status: Not a bug
 [2016-10-25 18:59 UTC] yohgaki@php.net
Oops. This change was made in PHP 7.0 and documented already.
 [2016-10-25 19:14 UTC] yohgaki@php.net
BTW, the second read() is mandatory because new session data must be locked. The second read() should not return anything because it must be new session. It's called just to lock new session.

If you have problem with this, you have something wrong in your save handler.

i.e. It's basically the same as

session_start();
session_commit();
$old = $_SESSION;
session_id($newid);
session_start();
$_SESSIOND = $old;

It does more things internally to keep reference to $_SESSION, but this is the basic picture.
 [2016-10-25 20:03 UTC] ryan dot brothers at gmail dot com
Thanks, I updated my session handler to handle this.  I was just more curious why read was being called with the output being completely ignored.  Yes, the second read() should not return anything, but if it does return something, it looks like it is being ignored anyway.
 [2016-10-26 00:32 UTC] yohgaki@php.net
> if it does return something, it looks like it is being ignored anyway.

Yes. It should not read anything, even when something is went wrong (i.e. session id collision) and it returned other session's content, session module must ignore the returned content to avoid possible security(confidentiality) issue.

I may be better to add E_WARNING for this, but it will never happen under normal condition.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 05:01:28 2024 UTC