Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Serializer] Denormalizing union types with ALLOW_EXTRA_ATTRIBUTES throws error when not needed #45860

Closed
T-bond opened this issue Mar 27, 2022 · 0 comments

Comments

@T-bond
Copy link
Contributor

T-bond commented Mar 27, 2022

Symfony version(s) affected

4.4.39, 6.0.6

Description

When ALLOW_EXTRA_ATTRIBUTES are turned off, denormalizing union types will throw an error, if the first type of the union contains an extra attribute, instead checking, if the second (or the other types) can be resolved without an error.

How to reproduce

serializer component needed:
PHPUnit:

$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
$serializer = new Serializer(
  [
      new ObjectNormalizer($classMetadataFactory, null, null, $extractor, new ClassDiscriminatorFromClassMetadata($classMetadataFactory)),
  ],
  ['json' => new JsonEncoder()]
);

$actual = $serializer->deserialize('{ "v": { "a": 0 }}', DummyUnionWithAAndB::class, 'json', [
  AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
]);

$this->assertEquals(new DummyUnionWithAAndB(new DummyATypeForUnion()), $actual);


$actual = $serializer->deserialize('{ "v": { "b": 1 }}', DummyUnionWithAAndB::class, 'json', [
  AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
]);

$this->assertEquals(new DummyUnionWithAAndB(new DummyBTypeForUnion()), $actual);


$this->expectException(ExtraAttributesException::class);
$serializer->deserialize('{ "v": { "b": 1, "c": "i am not allowed" }}', DummyUnionWithAAndB::class, 'json', [
  AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
]);

class DummyATypeForUnion {
    public $a = 0;
}

class DummyBTypeForUnion {
    public $b = 1;
}

class DummyUnionWithAAndB {
    /** @var DummyATypeForUnion|DummyBTypeForUnion */
    public $v;

    /**
     * @param DummyATypeForUnion|DummyBTypeForUnion $v
     */
    public function __construct($v) { $this->v = $v; }

}

Possible Solution

Checking the other types, if they can be denormalized without extra attributes, before throwing an error. (Similarly as in #45838)

Additional Context

No response

@T-bond T-bond added the Bug label Mar 27, 2022
nicolas-grekas added a commit that referenced this issue Jun 19, 2022
…nion types when ALLOW_EXTRA_ATTRIBUTES=false (T-bond)

This PR was squashed before being merged into the 4.4 branch.

Discussion
----------

[Serializer] Try all possible denormalization route with union types when ALLOW_EXTRA_ATTRIBUTES=false

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #45860
| License       | MIT
| Doc PR        | -

I found a similar bug, (I think this is a bug, but it is possible, it is an intended behaviour) to my previous report.

Commits
-------

bd623b9 [Serializer] Try all possible denormalization route with union types when ALLOW_EXTRA_ATTRIBUTES=false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants