Skip to content

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

Closed
@T-bond

Description

@T-bond

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions