Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9531a2b

Browse files
rybakitfabpot
authored andcommitted
[HttpFoundation] Fix PdoSessionHandler to work properly with streams
1 parent a7d52fd commit 9531a2b

File tree

2 files changed

+100
-3
lines changed

2 files changed

+100
-3
lines changed

src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -521,11 +521,11 @@ private function doRead($sessionId)
521521
return '';
522522
}
523523

524-
return $sessionRows[0][0];
524+
return is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0];
525525
}
526526

527527
if (self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) {
528-
// Exlusive-reading of non-existent rows does not block, so we need to do an insert to block
528+
// Exclusive-reading of non-existent rows does not block, so we need to do an insert to block
529529
// until other connections to the session are committed.
530530
try {
531531
$insertStmt = $this->pdo->prepare(
@@ -546,7 +546,11 @@ private function doRead($sessionId)
546546
$selectStmt->execute();
547547
$sessionRows = $selectStmt->fetchAll(\PDO::FETCH_NUM);
548548

549-
return $sessionRows ? $sessionRows[0][0] : '';
549+
if ($sessionRows) {
550+
return is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0];
551+
}
552+
553+
return '';
550554
}
551555

552556
throw $e;

src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,53 @@ public function testReadWriteReadWithNullByte()
135135
$this->assertSame($sessionData, $readData, 'Written value can be read back correctly');
136136
}
137137

138+
public function testReadConvertsStreamToString()
139+
{
140+
$pdo = new MockPdo('pgsql');
141+
$pdo->prepareResult = $this->getMock('PDOStatement');
142+
143+
$content = 'foobar';
144+
$stream = $this->createStream($content);
145+
146+
$pdo->prepareResult->expects($this->once())->method('fetchAll')
147+
->will($this->returnValue(array(array($stream, 42, time()))));
148+
149+
$storage = new PdoSessionHandler($pdo);
150+
$result = $storage->read('foo');
151+
152+
$this->assertSame($content, $result);
153+
}
154+
155+
public function testReadLockedConvertsStreamToString()
156+
{
157+
$pdo = new MockPdo('pgsql');
158+
$selectStmt = $this->getMock('PDOStatement');
159+
$insertStmt = $this->getMock('PDOStatement');
160+
161+
$pdo->prepareResult = function ($statement) use ($selectStmt, $insertStmt) {
162+
return 0 === strpos($statement, 'INSERT') ? $insertStmt : $selectStmt;
163+
};
164+
165+
$content = 'foobar';
166+
$stream = $this->createStream($content);
167+
$exception = null;
168+
169+
$selectStmt->expects($this->atLeast(2))->method('fetchAll')
170+
->will($this->returnCallback(function () use (&$exception, $stream) {
171+
return $exception ? array(array($stream, 42, time())) : array();
172+
}));
173+
174+
$insertStmt->expects($this->once())->method('execute')
175+
->will($this->returnCallback(function () use (&$exception) {
176+
throw $exception = new \PDOException('', '23');
177+
}));
178+
179+
$storage = new PdoSessionHandler($pdo);
180+
$result = $storage->read('foo');
181+
182+
$this->assertSame($content, $result);
183+
}
184+
138185
public function testReadingRequiresExactlySameId()
139186
{
140187
$storage = new PdoSessionHandler($this->getMemorySqlitePdo());
@@ -263,4 +310,50 @@ public function testGetConnectionConnectsIfNeeded()
263310

264311
$this->assertInstanceOf('\PDO', $method->invoke($storage));
265312
}
313+
314+
private function createStream($content)
315+
{
316+
$stream = tmpfile();
317+
fwrite($stream, $content);
318+
fseek($stream, 0);
319+
320+
return $stream;
321+
}
322+
}
323+
324+
class MockPdo extends \PDO
325+
{
326+
public $prepareResult;
327+
private $driverName;
328+
private $errorMode;
329+
330+
public function __construct($driverName = null, $errorMode = null)
331+
{
332+
$this->driverName = $driverName;
333+
$this->errorMode = null !== $errorMode ?: \PDO::ERRMODE_EXCEPTION;
334+
}
335+
336+
public function getAttribute($attribute)
337+
{
338+
if (\PDO::ATTR_ERRMODE === $attribute) {
339+
return $this->errorMode;
340+
}
341+
342+
if (\PDO::ATTR_DRIVER_NAME === $attribute) {
343+
return $this->driverName;
344+
}
345+
346+
return parent::getAttribute($attribute);
347+
}
348+
349+
public function prepare($statement, $driverOptions = array())
350+
{
351+
return is_callable($this->prepareResult)
352+
? call_user_func($this->prepareResult, $statement, $driverOptions)
353+
: $this->prepareResult;
354+
}
355+
356+
public function beginTransaction()
357+
{
358+
}
266359
}

0 commit comments

Comments
 (0)