Closed
Description
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