From ceb261682a2ae01137b5565bfa3d45359559234c Mon Sep 17 00:00:00 2001 From: Farhad Safarov Date: Fri, 17 Aug 2018 12:48:44 +0400 Subject: [PATCH] Throw ConversionException when unserialization fail for array and object types cs fix object type conversionFailedUnserialization type hinting & finally restore error handler cs: use function type hint sort use alphabetically code quality improvements --- lib/Doctrine/DBAL/Types/ArrayType.php | 16 +++++++++++----- lib/Doctrine/DBAL/Types/ConversionException.php | 9 +++++++++ lib/Doctrine/DBAL/Types/ObjectType.php | 16 +++++++++++----- tests/Doctrine/Tests/DBAL/Types/ArrayTest.php | 11 +---------- tests/Doctrine/Tests/DBAL/Types/ObjectTest.php | 10 +--------- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/lib/Doctrine/DBAL/Types/ArrayType.php b/lib/Doctrine/DBAL/Types/ArrayType.php index 7fc4fcc9be6..16d48aa1d7f 100644 --- a/lib/Doctrine/DBAL/Types/ArrayType.php +++ b/lib/Doctrine/DBAL/Types/ArrayType.php @@ -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; @@ -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(); + } } /** diff --git a/lib/Doctrine/DBAL/Types/ConversionException.php b/lib/Doctrine/DBAL/Types/ConversionException.php index df2eb74a38f..cab786de5d3 100644 --- a/lib/Doctrine/DBAL/Types/ConversionException.php +++ b/lib/Doctrine/DBAL/Types/ConversionException.php @@ -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 + )); + } } diff --git a/lib/Doctrine/DBAL/Types/ObjectType.php b/lib/Doctrine/DBAL/Types/ObjectType.php index 95fe84a5a19..0547377c9c2 100644 --- a/lib/Doctrine/DBAL/Types/ObjectType.php +++ b/lib/Doctrine/DBAL/Types/ObjectType.php @@ -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; @@ -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(); + } } /** diff --git a/tests/Doctrine/Tests/DBAL/Types/ArrayTest.php b/tests/Doctrine/Tests/DBAL/Types/ArrayTest.php index f230491409a..c6599e66d65 100644 --- a/tests/Doctrine/Tests/DBAL/Types/ArrayTest.php +++ b/tests/Doctrine/Tests/DBAL/Types/ArrayTest.php @@ -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 @@ -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( @@ -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); } diff --git a/tests/Doctrine/Tests/DBAL/Types/ObjectTest.php b/tests/Doctrine/Tests/DBAL/Types/ObjectTest.php index 63ded4ca082..bd4fcd8057d 100644 --- a/tests/Doctrine/Tests/DBAL/Types/ObjectTest.php +++ b/tests/Doctrine/Tests/DBAL/Types/ObjectTest.php @@ -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 @@ -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)); @@ -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); }