Skip to content

Commit

Permalink
Merge branch '5.4' into 6.0
Browse files Browse the repository at this point in the history
* 5.4:
  [HttpKernel] Fix a PHP 8.1 deprecation notice in HttpCache
  Add an invariable word in french
  [Serializer] Fix denormalization union types with constructor
  • Loading branch information
nicolas-grekas committed Jun 26, 2022
2 parents c84e388 + dc554d7 commit d01114d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
14 changes: 14 additions & 0 deletions Normalizer/AbstractObjectNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
Expand Down Expand Up @@ -434,13 +435,16 @@ abstract protected function setAttributeValue(object $object, string $attribute,
* @param Type[] $types
*
* @throws NotNormalizableValueException
* @throws ExtraAttributesException
* @throws MissingConstructorArgumentsException
* @throws LogicException
*/
private function validateAndDenormalize(array $types, string $currentClass, string $attribute, mixed $data, ?string $format, array $context): mixed
{
$expectedTypes = [];
$isUnionType = \count($types) > 1;
$extraAttributesException = null;
$missingConstructorArgumentException = null;
foreach ($types as $type) {
if (null === $data && $type->isNullable()) {
return null;
Expand Down Expand Up @@ -582,13 +586,23 @@ private function validateAndDenormalize(array $types, string $currentClass, stri
}

$extraAttributesException ??= $e;
} catch (MissingConstructorArgumentsException $e) {
if (!$isUnionType) {
throw $e;
}

$missingConstructorArgumentException ??= $e;
}
}

if ($extraAttributesException) {
throw $extraAttributesException;
}

if ($missingConstructorArgumentException) {
throw $missingConstructorArgumentException;
}

if ($context[self::DISABLE_TYPE_ENFORCEMENT] ?? $this->defaultContext[self::DISABLE_TYPE_ENFORCEMENT] ?? false) {
return $data;
}
Expand Down
32 changes: 24 additions & 8 deletions Tests/SerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -764,20 +764,26 @@ public function testUnionTypeDeserializableWithoutAllowedExtraAttributes()
['json' => new JsonEncoder()]
);

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

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

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

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

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

$this->assertEquals(new DummyUnionWithAAndCAndB(new DummyCTypeForUnion(3)), $actual);

$this->expectException(ExtraAttributesException::class);
$serializer->deserialize('{ "v": { "b": 1, "c": "i am not allowed" }}', DummyUnionWithAAndB::class, 'json', [
$serializer->deserialize('{ "v": { "b": 1, "d": "i am not allowed" }}', DummyUnionWithAAndCAndB::class, 'json', [
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
]);
}
Expand Down Expand Up @@ -1256,13 +1262,23 @@ class DummyBTypeForUnion
public $b = 1;
}

class DummyUnionWithAAndB
class DummyCTypeForUnion
{
public $c = 2;

public function __construct($c)
{
$this->c = $c;
}
}

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

/**
* @param DummyATypeForUnion|DummyBTypeForUnion $v
* @param DummyATypeForUnion|DummyCTypeForUnion|DummyBTypeForUnion $v
*/
public function __construct($v)
{
Expand Down

0 comments on commit d01114d

Please sign in to comment.