Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Prevent recursion in DbTableGateway save handler. #51

Merged
merged 2 commits into from
Jul 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/SaveHandler/DbTableGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,10 @@ public function close()
* Read session data
*
* @param string $id
* @param bool $destroyExpired Optional; true by default
* @return string
*/
public function read($id)
public function read($id, $destroyExpired = true)
{
$rows = $this->tableGateway->select([
$this->options->getIdColumn() => $id,
Expand All @@ -104,7 +105,9 @@ public function read($id)
$row->{$this->options->getLifetimeColumn()} > time()) {
return (string) $row->{$this->options->getDataColumn()};
}
$this->destroy($id);
if ($destroyExpired) {
$this->destroy($id);
}
}
return '';
}
Expand Down Expand Up @@ -149,7 +152,7 @@ public function write($id, $data)
*/
public function destroy($id)
{
if (! (bool) $this->read($id)) {
if (! (bool) $this->read($id, false)) {
return true;
}

Expand Down
33 changes: 33 additions & 0 deletions test/SaveHandler/DbTableGatewayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Zend\Session\SaveHandler\DbTableGatewayOptions;
use Zend\Db\Adapter\Adapter;
use Zend\Db\TableGateway\TableGateway;
use ZendTest\Session\TestAsset\TestDbTableGatewaySaveHandler;

/**
* Unit testing for DbTableGateway include all tests for
Expand Down Expand Up @@ -167,6 +168,38 @@ public function testDestroyReturnsTrueWhenSessionIsDeleted()

$this->assertTrue($result);
}

public function testExpiredSessionDoesNotCauseARecursion()
{
// puts an expired session in the db
$query = "
INSERT INTO `sessions` (
`{$this->options->getIdColumn()}`,
`{$this->options->getNameColumn()}`,
`{$this->options->getModifiedColumn()}`,
`{$this->options->getLifetimeColumn()}`,
`{$this->options->getDataColumn()}`
) VALUES (
'123', 'zend-session-test', ".(time() - 31).", 30, 'foobar'
);
";
$this->adapter->query($query, Adapter::QUERY_MODE_EXECUTE);

$this->usedSaveHandlers[] = $saveHandler = new TestDbTableGatewaySaveHandler($this->tableGateway, $this->options);
$saveHandler->open('savepath', 'zend-session-test');

$this->assertSame(0, $saveHandler->getNumReadCalls());
$this->assertSame(0, $saveHandler->getNumDestroyCalls());

$success = (boolean) $saveHandler->read('123');
$this->assertFalse($success);

$this->assertSame(2, $saveHandler->getNumReadCalls());
$this->assertSame(1, $saveHandler->getNumDestroyCalls());

// cleans the test record from the db
$this->adapter->query("DELETE FROM `sessions` WHERE `{$this->options->getIdColumn()}` = '123';");
}

/**
* Sets up the database connection and creates the table for session data
Expand Down
41 changes: 41 additions & 0 deletions test/TestAsset/TestDbTableGatewaySaveHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Session\TestAsset;

use Zend\Session\SaveHandler\DbTableGateway;

class TestDbTableGatewaySaveHandler extends DbTableGateway
{
protected $numReadCalls = 0;

protected $numDestroyCalls = 0;

public function getNumReadCalls()
{
return $this->numReadCalls;
}

public function getNumDestroyCalls()
{
return $this->numDestroyCalls;
}

public function read($id, $destroyExpired = true)
{
$this->numReadCalls++;
return parent::read($id, $destroyExpired);
}

public function destroy($id)
{
$this->numDestroyCalls++;
return parent::destroy($id);
}
}