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

Commit

Permalink
Merge branch 'hotfix/51' into develop
Browse files Browse the repository at this point in the history
Forward port #51
  • Loading branch information
weierophinney committed Jul 5, 2016
2 parents 4d439b4 + 64a3697 commit c80aa9c
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 4 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ All notable changes to this project will be documented in this file, in reverse

### Fixed

- Nothing.
- [#51](https://github.com/zendframework/zend-session/pull/51) provides a fix to
the `DbTableGateway` save handler to prevent infinite recursion when
attempting to destroy an expired record during initial read operations.

## 2.7.2 - 2016-06-24

Expand Down
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 @@ -168,6 +169,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);
}
}

0 comments on commit c80aa9c

Please sign in to comment.