From 60335737a9fd2c972126ce43344437d637085e77 Mon Sep 17 00:00:00 2001 From: Mathias Arlaud Date: Wed, 18 Sep 2024 17:33:32 +0200 Subject: [PATCH 1/2] [Serializer] Catch `NotNormalizableValueException` for variadic parameters --- Normalizer/AbstractNormalizer.php | 11 ++++++++- Tests/Fixtures/DummyWithVariadicParameter.php | 24 +++++++++++++++++++ Tests/SerializerTest.php | 15 ++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 Tests/Fixtures/DummyWithVariadicParameter.php diff --git a/Normalizer/AbstractNormalizer.php b/Normalizer/AbstractNormalizer.php index aeae375f..c28a1f6c 100644 --- a/Normalizer/AbstractNormalizer.php +++ b/Normalizer/AbstractNormalizer.php @@ -358,7 +358,16 @@ protected function instantiateObject(array &$data, string $class, array &$contex $variadicParameters = []; foreach ($data[$key] as $parameterKey => $parameterData) { - $variadicParameters[$parameterKey] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $attributeContext, $format); + try { + $variadicParameters[$parameterKey] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $attributeContext, $format); + } catch (NotNormalizableValueException $exception) { + if (!isset($context['not_normalizable_value_exceptions'])) { + throw $exception; + } + + $context['not_normalizable_value_exceptions'][] = $exception; + $params[$paramName] = $parameterData; + } } $params = array_merge(array_values($params), $variadicParameters); diff --git a/Tests/Fixtures/DummyWithVariadicParameter.php b/Tests/Fixtures/DummyWithVariadicParameter.php new file mode 100644 index 00000000..82711192 --- /dev/null +++ b/Tests/Fixtures/DummyWithVariadicParameter.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Fixtures; + +use Symfony\Component\Uid\Uuid; + +class DummyWithVariadicParameter +{ + public array $variadic; + + public function __construct(Uuid ...$variadic) + { + $this->variadic = $variadic; + } +} diff --git a/Tests/SerializerTest.php b/Tests/SerializerTest.php index f7d364b7..8f60ae1d 100644 --- a/Tests/SerializerTest.php +++ b/Tests/SerializerTest.php @@ -61,6 +61,8 @@ use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumConstructor; use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumProperty; use Symfony\Component\Serializer\Tests\Fixtures\DummyWithObjectOrNull; +use Symfony\Component\Serializer\Tests\Fixtures\DummyWithVariadicParameter; +use Symfony\Component\Serializer\Tests\Fixtures\DummyWithVariadicProperty; use Symfony\Component\Serializer\Tests\Fixtures\FalseBuiltInDummy; use Symfony\Component\Serializer\Tests\Fixtures\FooImplementationDummy; use Symfony\Component\Serializer\Tests\Fixtures\FooInterfaceDummyDenormalizer; @@ -1637,6 +1639,19 @@ public function testPartialDenormalizationWithMissingConstructorTypes() $this->assertSame($expected, $exceptionsAsArray); } + + public function testPartialDenormalizationWithInvalidVariadicParameter() + { + $json = '{"variadic": ["a random string"]}'; + + $serializer = new Serializer([new UidNormalizer(), new ObjectNormalizer()], ['json' => new JsonEncoder()]); + + $this->expectException(PartialDenormalizationException::class); + + $serializer->deserialize($json, DummyWithVariadicParameter::class, 'json', [ + DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true, + ]); + } } class Model From 8be421505938b11a0ca4f656e4322232236386f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Laugks?= Date: Fri, 13 Sep 2024 13:10:52 +0200 Subject: [PATCH 2/2] [Serializer] Fix `ObjectNormalizer` gives warnings on normalizing with public static property --- Normalizer/ObjectNormalizer.php | 2 +- Tests/Normalizer/ObjectNormalizerTest.php | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Normalizer/ObjectNormalizer.php b/Normalizer/ObjectNormalizer.php index a8c887e5..c8473a62 100644 --- a/Normalizer/ObjectNormalizer.php +++ b/Normalizer/ObjectNormalizer.php @@ -197,7 +197,7 @@ protected function isAllowedAttribute($classOrObject, string $attribute, ?string if ($context['_read_attributes'] ?? true) { if (!isset(self::$isReadableCache[$class.$attribute])) { - self::$isReadableCache[$class.$attribute] = (\is_object($classOrObject) && $this->propertyAccessor->isReadable($classOrObject, $attribute)) || $this->propertyInfoExtractor->isReadable($class, $attribute) || $this->hasAttributeAccessorMethod($class, $attribute); + self::$isReadableCache[$class.$attribute] = $this->propertyInfoExtractor->isReadable($class, $attribute) || $this->hasAttributeAccessorMethod($class, $attribute) || (\is_object($classOrObject) && $this->propertyAccessor->isReadable($classOrObject, $attribute)); } return self::$isReadableCache[$class.$attribute]; diff --git a/Tests/Normalizer/ObjectNormalizerTest.php b/Tests/Normalizer/ObjectNormalizerTest.php index e314ac74..5b028e8c 100644 --- a/Tests/Normalizer/ObjectNormalizerTest.php +++ b/Tests/Normalizer/ObjectNormalizerTest.php @@ -927,6 +927,16 @@ public function testDenormalizeWithPropertyPath() $this->assertEquals($expected, $obj); } + + public function testObjectNormalizerWithAttributeLoaderAndObjectHasStaticProperty() + { + $class = new class { + public static string $foo; + }; + + $normalizer = new ObjectNormalizer(new ClassMetadataFactory(new AttributeLoader())); + $this->assertSame([], $normalizer->normalize($class)); + } } class ProxyObjectDummy extends ObjectDummy