From d1b343c015d4e13d669fda6a54efbf6d5a267c78 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Thu, 2 Nov 2017 19:07:23 +0100 Subject: [PATCH] [Serializer] Fix extra attributes when no group specified --- .../Normalizer/AbstractNormalizer.php | 12 +++++- .../Normalizer/AbstractObjectNormalizer.php | 1 - .../AbstractObjectNormalizerTest.php | 39 +++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 6777889526b67..39a43d317114e 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -31,6 +31,7 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N const OBJECT_TO_POPULATE = 'object_to_populate'; const GROUPS = 'groups'; const ATTRIBUTES = 'attributes'; + const ALLOW_EXTRA_ATTRIBUTES = 'allow_extra_attributes'; /** * @var int @@ -201,7 +202,14 @@ protected function handleCircularReference($object) */ protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false) { - if (!$this->classMetadataFactory || !isset($context[static::GROUPS]) || !is_array($context[static::GROUPS])) { + if (!$this->classMetadataFactory) { + return false; + } + + $groups = false; + if (isset($context[static::GROUPS]) && is_array($context[static::GROUPS])) { + $groups = $context[static::GROUPS]; + } elseif (!isset($context[static::ALLOW_EXTRA_ATTRIBUTES]) || $context[static::ALLOW_EXTRA_ATTRIBUTES]) { return false; } @@ -210,7 +218,7 @@ protected function getAllowedAttributes($classOrObject, array $context, $attribu $name = $attributeMetadata->getName(); if ( - count(array_intersect($attributeMetadata->getGroups(), $context[static::GROUPS])) && + (false === $groups || count(array_intersect($attributeMetadata->getGroups(), $groups))) && $this->isAllowedAttribute($classOrObject, $name, null, $context) ) { $allowedAttributes[] = $attributesAsString ? $name : $attributeMetadata; diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index a8c51de7ce1c9..68e86da1f21e2 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -31,7 +31,6 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer { const ENABLE_MAX_DEPTH = 'enable_max_depth'; const DEPTH_KEY_PATTERN = 'depth_%s::%s'; - const ALLOW_EXTRA_ATTRIBUTES = 'allow_extra_attributes'; private $propertyTypeExtractor; private $attributesCache = array(); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php index 1040111cfe620..3ca418d55ed6b 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -11,7 +11,10 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; +use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; +use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; +use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; class AbstractObjectNormalizerTest extends TestCase @@ -51,6 +54,21 @@ public function testDenormalizeWithExtraAttributes() array('allow_extra_attributes' => false) ); } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\ExtraAttributesException + * @expectedExceptionMessage Extra attributes are not allowed ("fooFoo", "fooBar" are unknown). + */ + public function testDenormalizeWithExtraAttributesAndNoGroupsWithMetadataFactory() + { + $normalizer = new AbstractObjectNormalizerWithMetadata(); + $normalizer->denormalize( + array('fooFoo' => 'foo', 'fooBar' => 'bar', 'bar' => 'bar'), + Dummy::class, + 'any', + array('allow_extra_attributes' => false) + ); + } } class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer @@ -85,3 +103,24 @@ class Dummy public $bar; public $baz; } + +class AbstractObjectNormalizerWithMetadata extends AbstractObjectNormalizer +{ + public function __construct() + { + parent::__construct(new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()))); + } + + protected function extractAttributes($object, $format = null, array $context = array()) + { + } + + protected function getAttributeValue($object, $attribute, $format = null, array $context = array()) + { + } + + protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array()) + { + $object->$attribute = $value; + } +}