diff --git a/src/Symfony/Component/Serializer/Exception/ExtraAttributesException.php b/src/Symfony/Component/Serializer/Exception/ExtraAttributesException.php new file mode 100644 index 0000000000000..d321618b8eb11 --- /dev/null +++ b/src/Symfony/Component/Serializer/Exception/ExtraAttributesException.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Exception; + +/** + * ExtraAttributesException. + * + * @author Julien DIDIER + */ +class ExtraAttributesException extends RuntimeException +{ + public function __construct(array $extraAttributes, \Exception $previous = null) + { + $msg = sprintf('Extra attributes are not allowed ("%s" are unknown).', implode('", "', $extraAttributes)); + + parent::__construct($msg, 0, $previous); + } +} diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index b5829afd38bca..2d355ae34ef0d 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -13,6 +13,7 @@ use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException; use Symfony\Component\Serializer\Exception\CircularReferenceException; +use Symfony\Component\Serializer\Exception\ExtraAttributesException; use Symfony\Component\Serializer\Exception\LogicException; use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; @@ -171,8 +172,10 @@ public function denormalize($data, $class, $format = null, array $context = arra if (!isset($context['cache_key'])) { $context['cache_key'] = $this->getCacheKey($format, $context); } + $allowedAttributes = $this->getAllowedAttributes($class, $context, true); $normalizedData = $this->prepareForDenormalization($data); + $extraAttributes = array(); $reflectionClass = new \ReflectionClass($class); $object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes, $format); @@ -183,6 +186,10 @@ public function denormalize($data, $class, $format = null, array $context = arra } if (($allowedAttributes !== false && !in_array($attribute, $allowedAttributes)) || !$this->isAllowedAttribute($class, $attribute, $format, $context)) { + if (isset($context['allow_extra_attributes']) && !$context['allow_extra_attributes']) { + $extraAttributes[] = $attribute; + } + continue; } @@ -194,6 +201,10 @@ public function denormalize($data, $class, $format = null, array $context = arra } } + if (!empty($extraAttributes)) { + throw new ExtraAttributesException($extraAttributes); + } + return $object; } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php index c9df3c955f031..681fd92472cae 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -37,6 +37,21 @@ public function testInstantiateObjectDenormalizer() $normalizer = new AbstractObjectNormalizerDummy(); $normalizer->instantiateObject($data, $class, $context, new \ReflectionClass($class), array()); } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\ExtraAttributesException + * @expectedExceptionMessage Extra attributes are not allowed ("fooFoo", "fooBar" are unknown). + */ + public function testDenormalizeWithExtraAttributes() + { + $normalizer = new AbstractObjectNormalizerDummy(); + $normalizer->denormalize( + array('fooFoo' => 'foo', 'fooBar' => 'bar'), + __NAMESPACE__.'\Dummy', + 'any', + array('allow_extra_attributes' => false) + ); + } } class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer