Skip to content

Commit d2159ea

Browse files
authored
Merge pull request #3254 from seferov/array-type-convert
Throw ConversionException when unserialization fail for array and object types
2 parents 319e20f + ceb2616 commit d2159ea

File tree

5 files changed

+33
-29
lines changed

5 files changed

+33
-29
lines changed

lib/Doctrine/DBAL/Types/ArrayType.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121

2222
use Doctrine\DBAL\Platforms\AbstractPlatform;
2323
use function is_resource;
24+
use function restore_error_handler;
2425
use function serialize;
26+
use function set_error_handler;
2527
use function stream_get_contents;
2628
use function unserialize;
2729

@@ -59,12 +61,16 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
5961
}
6062

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

67-
return $val;
65+
set_error_handler(function (int $code, string $message) : void {
66+
throw ConversionException::conversionFailedUnserialization($this->getName(), $message);
67+
});
68+
69+
try {
70+
return unserialize($value);
71+
} finally {
72+
restore_error_handler();
73+
}
6874
}
6975

7076
/**

lib/Doctrine/DBAL/Types/ConversionException.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,13 @@ public static function conversionFailedSerialization($value, $format, $error)
120120
$error
121121
));
122122
}
123+
124+
public static function conversionFailedUnserialization(string $format, string $error) : self
125+
{
126+
return new self(sprintf(
127+
"Could not convert database value to '%s' as an error was triggered by the unserialization: '%s'",
128+
$format,
129+
$error
130+
));
131+
}
123132
}

lib/Doctrine/DBAL/Types/ObjectType.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121

2222
use Doctrine\DBAL\Platforms\AbstractPlatform;
2323
use function is_resource;
24+
use function restore_error_handler;
2425
use function serialize;
26+
use function set_error_handler;
2527
use function stream_get_contents;
2628
use function unserialize;
2729

@@ -58,12 +60,16 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
5860
}
5961

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

66-
return $val;
64+
set_error_handler(function (int $code, string $message) : void {
65+
throw ConversionException::conversionFailedUnserialization($this->getName(), $message);
66+
});
67+
68+
try {
69+
return unserialize($value);
70+
} finally {
71+
restore_error_handler();
72+
}
6773
}
6874

6975
/**

tests/Doctrine/Tests/DBAL/Types/ArrayTest.php

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
use Doctrine\DBAL\Platforms\AbstractPlatform;
66
use Doctrine\DBAL\Types\Type;
77
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
8-
use const E_ALL;
9-
use const E_STRICT;
10-
use function error_reporting;
118
use function serialize;
129

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

31-
protected function tearDown()
32-
{
33-
error_reporting(-1); // reactive all error levels
34-
}
35-
36-
3728
public function testArrayConvertsToDatabaseValue()
3829
{
3930
self::assertInternalType(
@@ -52,8 +43,8 @@ public function testArrayConvertsToPHPValue()
5243

5344
public function testConversionFailure()
5445
{
55-
error_reporting( (E_ALL | E_STRICT) - \E_NOTICE );
5646
$this->expectException('Doctrine\DBAL\Types\ConversionException');
47+
$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'");
5748
$this->_type->convertToPHPValue('abcdefg', $this->_platform);
5849
}
5950

tests/Doctrine/Tests/DBAL/Types/ObjectTest.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
use Doctrine\DBAL\Types\Type;
66
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
7-
use const E_ALL;
8-
use const E_STRICT;
9-
use function error_reporting;
107
use function serialize;
118

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

30-
protected function tearDown()
31-
{
32-
error_reporting(-1); // reactive all error levels
33-
}
34-
3527
public function testObjectConvertsToDatabaseValue()
3628
{
3729
self::assertInternalType('string', $this->_type->convertToDatabaseValue(new \stdClass(), $this->_platform));
@@ -44,8 +36,8 @@ public function testObjectConvertsToPHPValue()
4436

4537
public function testConversionFailure()
4638
{
47-
error_reporting( (E_ALL | E_STRICT) - \E_NOTICE );
4839
$this->expectException('Doctrine\DBAL\Types\ConversionException');
40+
$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'");
4941
$this->_type->convertToPHPValue('abcdefg', $this->_platform);
5042
}
5143

0 commit comments

Comments
 (0)