From f8c767de21cdf3b5422b523bdc1a7ebe84851cbc Mon Sep 17 00:00:00 2001 From: Mathias Arlaud Date: Wed, 22 Nov 2023 04:33:11 +0100 Subject: [PATCH] [Serializer] Fix access to private when Ignore --- .../Normalizer/AbstractObjectNormalizer.php | 16 ++++++---------- .../AbstractObjectNormalizerTest.php | 19 +++++++++++++++++++ .../Serializer/Tests/SerializerTest.php | 2 +- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 141ed4bb019ad..ff956f5dd9116 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -302,22 +302,18 @@ protected function getAttributes(object $object, ?string $format, array $context return $this->attributesCache[$key]; } - $allowedAttributes = $this->getAllowedAttributes($object, $context, true); - - if (false !== $allowedAttributes) { - if ($context['cache_key']) { - $this->attributesCache[$key] = $allowedAttributes; - } - - return $allowedAttributes; - } - $attributes = $this->extractAttributes($object, $format, $context); if ($this->classDiscriminatorResolver && $mapping = $this->classDiscriminatorResolver->getMappingForMappedObject($object)) { array_unshift($attributes, $mapping->getTypeProperty()); } + $allowedAttributes = $this->getAllowedAttributes($object, $context, true); + + if (false !== $allowedAttributes) { + $attributes = array_intersect($attributes, $allowedAttributes); + } + if ($context['cache_key'] && \stdClass::class !== $class) { $this->attributesCache[$key] = $attributes; } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php index bce6e5f9a598c..e08fe22c75472 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Type; +use Symfony\Component\Serializer\Annotation\Ignore; use Symfony\Component\Serializer\Exception\ExtraAttributesException; use Symfony\Component\Serializer\Exception\InvalidArgumentException; use Symfony\Component\Serializer\Exception\LogicException; @@ -444,6 +445,14 @@ public function testNormalizeEmptyObject() $normalizedData = $normalizer->normalize(new EmptyDummy(), 'any', ['preserve_empty_objects' => true]); $this->assertEquals(new \ArrayObject(), $normalizedData); } + + public function testNormalizeWithIgnoreAttributeAndPrivateProperties() + { + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $serializer = new Serializer([new ObjectNormalizer($classMetadataFactory)]); + + $this->assertSame(['foo' => 'foo'], $serializer->normalize(new ObjectDummyWithIgnoreAnnotationAndPrivateProperty())); + } } class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer @@ -484,6 +493,16 @@ class EmptyDummy { } +class ObjectDummyWithIgnoreAnnotationAndPrivateProperty +{ + public string $foo = 'foo'; + + /** @Ignore */ + public string $ignored = 'ignored'; + + private string $private = 'private'; +} + class AbstractObjectNormalizerWithMetadata extends AbstractObjectNormalizer { public function __construct() diff --git a/src/Symfony/Component/Serializer/Tests/SerializerTest.php b/src/Symfony/Component/Serializer/Tests/SerializerTest.php index ab4bbe908ab29..e8217f2819d89 100644 --- a/src/Symfony/Component/Serializer/Tests/SerializerTest.php +++ b/src/Symfony/Component/Serializer/Tests/SerializerTest.php @@ -471,7 +471,7 @@ public function testDeserializeAndSerializeInterfacedObjectsWithTheClassMetadata 'groups' => ['two'], ]); - $this->assertEquals('{"two":2,"type":"one"}', $serialized); + $this->assertEquals('{"type":"one","two":2}', $serialized); } public function testDeserializeAndSerializeNestedInterfacedObjectsWithTheClassMetadataDiscriminator()