From 8cbf02e5373a1ea33f8a0ecd9ff6af622d4a8cd1 Mon Sep 17 00:00:00 2001 From: Max Baldanza Date: Thu, 30 Nov 2023 10:25:28 +0000 Subject: [PATCH] Do not instantiate object if it is not instantiable If you pass an object that can't be instantiable such as enum to deserialize then you get the following error `Error: Cannot instantiate enum` as the object is tried to be created without checking if it's instantiable --- Normalizer/AbstractNormalizer.php | 9 +++++++++ Tests/Normalizer/AbstractNormalizerTest.php | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/Normalizer/AbstractNormalizer.php b/Normalizer/AbstractNormalizer.php index 80ea6903d..37a8005d1 100644 --- a/Normalizer/AbstractNormalizer.php +++ b/Normalizer/AbstractNormalizer.php @@ -458,6 +458,15 @@ protected function instantiateObject(array &$data, string $class, array &$contex unset($context['has_constructor']); + if (!$reflectionClass->isInstantiable()) { + throw NotNormalizableValueException::createForUnexpectedDataType( + sprintf('Failed to create object because the class "%s" is not instantiable.', $class), + $data, + ['unknown'], + $context['deserialization_path'] ?? null, + ); + } + return new $class(); } diff --git a/Tests/Normalizer/AbstractNormalizerTest.php b/Tests/Normalizer/AbstractNormalizerTest.php index 3397cb504..aa62e692d 100644 --- a/Tests/Normalizer/AbstractNormalizerTest.php +++ b/Tests/Normalizer/AbstractNormalizerTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\Serializer\Encoder\JsonEncoder; +use Symfony\Component\Serializer\Exception\NotNormalizableValueException; use Symfony\Component\Serializer\Mapping\AttributeMetadata; use Symfony\Component\Serializer\Mapping\ClassMetadata; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; @@ -32,6 +33,7 @@ use Symfony\Component\Serializer\Tests\Fixtures\NullableOptionalConstructorArgumentDummy; use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy; use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorNormalizer; +use Symfony\Component\Serializer\Tests\Fixtures\UnitEnumDummy; use Symfony\Component\Serializer\Tests\Fixtures\VariadicConstructorTypedArgsDummy; /** @@ -279,4 +281,16 @@ public function testIgnore() $this->assertSame([], $normalizer->normalize($dummy)); } + + /** + * @requires PHP 8.1 + */ + public function testDenormalizeWhenObjectNotInstantiable() + { + $this->expectException(NotNormalizableValueException::class); + + $normalizer = new ObjectNormalizer(); + + $normalizer->denormalize('{}', UnitEnumDummy::class); + } }