Skip to content

Commit

Permalink
Merge pull request #61 from gquemener/final-serializable-internal-chi…
Browse files Browse the repository at this point in the history
…ld-fix

Adds support of internal child class instantiation
  • Loading branch information
Ocramius authored Oct 21, 2019
2 parents 67dbbd5 + 126eab1 commit ae466f7
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/Doctrine/Instantiator/Instantiator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

namespace Doctrine\Instantiator;

use ArrayIterator;
use Doctrine\Instantiator\Exception\InvalidArgumentException;
use Doctrine\Instantiator\Exception\UnexpectedValueException;
use Exception;
use ReflectionClass;
use ReflectionException;
use Serializable;
use function class_exists;
use function is_subclass_of;
use function restore_error_handler;
use function set_error_handler;
use function sprintf;
Expand Down Expand Up @@ -94,7 +97,7 @@ private function buildFactory(string $className) : callable

$serializedString = sprintf(
'%s:%d:"%s":0:{}',
self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER,
is_subclass_of($className, Serializable::class) ? self::SERIALIZATION_FORMAT_USE_UNSERIALIZER : self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER,
strlen($className),
$className
);
Expand Down Expand Up @@ -130,7 +133,7 @@ private function getReflectionClass(string $className) : ReflectionClass
*/
private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, string $serializedString) : void
{
set_error_handler(static function (int $code, string $message, string $file, int $line) use ($reflectionClass, & $error) : bool {
set_error_handler(static function (int $code, string $message, string $file, int $line) use ($reflectionClass, &$error) : bool {
$error = UnexpectedValueException::fromUncleanUnSerialization(
$reflectionClass,
$message,
Expand Down Expand Up @@ -193,6 +196,8 @@ private function hasInternalAncestors(ReflectionClass $reflectionClass) : bool
*/
private function isSafeToClone(ReflectionClass $reflection) : bool
{
return $reflection->isCloneable() && ! $reflection->hasMethod('__clone');
return $reflection->isCloneable()
&& ! $reflection->hasMethod('__clone')
&& ! $reflection->isSubclassOf(ArrayIterator::class);
}
}
2 changes: 2 additions & 0 deletions tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use DoctrineTest\InstantiatorTestAsset\FinalExceptionAsset;
use DoctrineTest\InstantiatorTestAsset\PharExceptionAsset;
use DoctrineTest\InstantiatorTestAsset\SerializableArrayObjectAsset;
use DoctrineTest\InstantiatorTestAsset\SerializableFinalInternalChildAsset;
use DoctrineTest\InstantiatorTestAsset\SimpleSerializableAsset;
use DoctrineTest\InstantiatorTestAsset\SimpleTraitAsset;
use DoctrineTest\InstantiatorTestAsset\UnCloneableAsset;
Expand Down Expand Up @@ -124,6 +125,7 @@ public function getInstantiableClasses() : array
[SerializableArrayObjectAsset::class],
[WakeUpNoticesAsset::class],
[UnserializeExceptionArrayObjectAsset::class],
[SerializableFinalInternalChildAsset::class],
];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);

namespace DoctrineTest\InstantiatorTestAsset;

use ArrayIterator;

final class SerializableFinalInternalChildAsset extends ArrayIterator
{
}

0 comments on commit ae466f7

Please sign in to comment.