Skip to content

Commit

Permalink
Merge pull request #3254 from seferov/array-type-convert
Browse files Browse the repository at this point in the history
Throw ConversionException when unserialization fail for array and object types
  • Loading branch information
morozov authored Aug 18, 2018
2 parents 319e20f + ceb2616 commit d2159ea
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 29 deletions.
16 changes: 11 additions & 5 deletions lib/Doctrine/DBAL/Types/ArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

use Doctrine\DBAL\Platforms\AbstractPlatform;
use function is_resource;
use function restore_error_handler;
use function serialize;
use function set_error_handler;
use function stream_get_contents;
use function unserialize;

Expand Down Expand Up @@ -59,12 +61,16 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
}

$value = (is_resource($value)) ? stream_get_contents($value) : $value;
$val = unserialize($value);
if ($val === false && $value != 'b:0;') {
throw ConversionException::conversionFailed($value, $this->getName());
}

return $val;
set_error_handler(function (int $code, string $message) : void {
throw ConversionException::conversionFailedUnserialization($this->getName(), $message);
});

try {
return unserialize($value);
} finally {
restore_error_handler();
}
}

/**
Expand Down
9 changes: 9 additions & 0 deletions lib/Doctrine/DBAL/Types/ConversionException.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,13 @@ public static function conversionFailedSerialization($value, $format, $error)
$error
));
}

public static function conversionFailedUnserialization(string $format, string $error) : self
{
return new self(sprintf(
"Could not convert database value to '%s' as an error was triggered by the unserialization: '%s'",
$format,
$error
));
}
}
16 changes: 11 additions & 5 deletions lib/Doctrine/DBAL/Types/ObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

use Doctrine\DBAL\Platforms\AbstractPlatform;
use function is_resource;
use function restore_error_handler;
use function serialize;
use function set_error_handler;
use function stream_get_contents;
use function unserialize;

Expand Down Expand Up @@ -58,12 +60,16 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
}

$value = (is_resource($value)) ? stream_get_contents($value) : $value;
$val = unserialize($value);
if ($val === false && $value !== 'b:0;') {
throw ConversionException::conversionFailed($value, $this->getName());
}

return $val;
set_error_handler(function (int $code, string $message) : void {
throw ConversionException::conversionFailedUnserialization($this->getName(), $message);
});

try {
return unserialize($value);
} finally {
restore_error_handler();
}
}

/**
Expand Down
11 changes: 1 addition & 10 deletions tests/Doctrine/Tests/DBAL/Types/ArrayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
use const E_ALL;
use const E_STRICT;
use function error_reporting;
use function serialize;

class ArrayTest extends \Doctrine\Tests\DbalTestCase
Expand All @@ -28,12 +25,6 @@ protected function setUp()
$this->_type = Type::getType('array');
}

protected function tearDown()
{
error_reporting(-1); // reactive all error levels
}


public function testArrayConvertsToDatabaseValue()
{
self::assertInternalType(
Expand All @@ -52,8 +43,8 @@ public function testArrayConvertsToPHPValue()

public function testConversionFailure()
{
error_reporting( (E_ALL | E_STRICT) - \E_NOTICE );
$this->expectException('Doctrine\DBAL\Types\ConversionException');
$this->expectExceptionMessage("Could not convert database value to 'array' as an error was triggered by the unserialization: 'unserialize(): Error at offset 0 of 7 bytes'");
$this->_type->convertToPHPValue('abcdefg', $this->_platform);
}

Expand Down
10 changes: 1 addition & 9 deletions tests/Doctrine/Tests/DBAL/Types/ObjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
use const E_ALL;
use const E_STRICT;
use function error_reporting;
use function serialize;

class ObjectTest extends \Doctrine\Tests\DbalTestCase
Expand All @@ -27,11 +24,6 @@ protected function setUp()
$this->_type = Type::getType('object');
}

protected function tearDown()
{
error_reporting(-1); // reactive all error levels
}

public function testObjectConvertsToDatabaseValue()
{
self::assertInternalType('string', $this->_type->convertToDatabaseValue(new \stdClass(), $this->_platform));
Expand All @@ -44,8 +36,8 @@ public function testObjectConvertsToPHPValue()

public function testConversionFailure()
{
error_reporting( (E_ALL | E_STRICT) - \E_NOTICE );
$this->expectException('Doctrine\DBAL\Types\ConversionException');
$this->expectExceptionMessage("Could not convert database value to 'object' as an error was triggered by the unserialization: 'unserialize(): Error at offset 0 of 7 bytes'");
$this->_type->convertToPHPValue('abcdefg', $this->_platform);
}

Expand Down

0 comments on commit d2159ea

Please sign in to comment.