bug #26534 allow_extra_attributes does not throw an exception as documented (deviantintegral)

This PR was squashed before being merged into the 3.4 branch (closes #26534).

Discussion
----------

allow_extra_attributes does not throw an exception as documented

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | none
| License       | MIT
| Doc PR        | none

The example at [Deserializing an object](https://symfony.com/doc/current/components/serializer.html#deserializing-an-object) does not actually work. It looks like this is a bug and not a docs issue. https://github.com/symfony/symfony/issues/24783 reported the same bug, but it looks like the fix at https://github.com/symfony/symfony/pull/24816 isn't complete.

Here's a failing test that copies the existing example.

Commits
-------

a67b650f12 allow_extra_attributes does not throw an exception as documented
This commit is contained in:
Maxime Steinhausser 2018-06-21 21:59:58 +02:00
commit 60246bc5e1
2 changed files with 26 additions and 1 deletions

View File

@ -200,11 +200,17 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
* @param array $context
* @param bool $attributesAsString If false, return an array of {@link AttributeMetadataInterface}
*
* @throws \Symfony\Component\Serializer\Exception\LogicException if the 'allow_extra_attributes' context variable is false and no class metadata factory is provided
*
* @return string[]|AttributeMetadataInterface[]|bool
*/
protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false)
{
if (!$this->classMetadataFactory) {
if (isset($context[static::ALLOW_EXTRA_ATTRIBUTES]) && !$context[static::ALLOW_EXTRA_ATTRIBUTES]) {
throw new LogicException(sprintf("A class metadata factory must be provided in the constructor when setting '%s' to false.", static::ALLOW_EXTRA_ATTRIBUTES));
}
return false;
}

View File

@ -19,6 +19,7 @@ use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
@ -52,7 +53,8 @@ class AbstractObjectNormalizerTest extends TestCase
*/
public function testDenormalizeWithExtraAttributes()
{
$normalizer = new AbstractObjectNormalizerDummy();
$factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new AbstractObjectNormalizerDummy($factory);
$normalizer->denormalize(
array('fooFoo' => 'foo', 'fooBar' => 'bar'),
__NAMESPACE__.'\Dummy',
@ -144,6 +146,23 @@ class AbstractObjectNormalizerTest extends TestCase
return $denormalizer;
}
/**
* Test that additional attributes throw an exception if no metadata factory is specified.
*
* @see https://symfony.com/doc/current/components/serializer.html#deserializing-an-object
*
* @expectedException \Symfony\Component\Serializer\Exception\LogicException
* @expectedExceptionMessage A class metadata factory must be provided in the constructor when setting 'allow_extra_attributes' to false.
*/
public function testExtraAttributesException()
{
$normalizer = new ObjectNormalizer();
$normalizer->denormalize(array(), \stdClass::class, 'xml', array(
'allow_extra_attributes' => false,
));
}
}
class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer