Skip to content

Commit c84e388

Browse files
Merge branch '5.4' into 6.0
* 5.4: [PropertyInfo] CS fix [Serializer] Try all possible denormalization route with union types when ALLOW_EXTRA_ATTRIBUTES=false CS fix [Cache] Respect $save option in ChainAdapter [ExpressionLanguage] fix tests (bis) [ExpressionLanguage] fix tests [Cache] Respect $save option in ArrayAdapter [HttpKernel] Disable session tracking while collecting profiler data [MonologBridge] Fixed support of elasticsearch 7.+ in ElasticsearchLogstashHandler [DoctrineBridge] Extend type guessing on enum fields [Messenger] move resetting services at worker stopped into ResetServicesListener [Mailer] Fix Error Handling for OhMySMTP Bridge Fix for missing sender name in case with usage of the EnvelopeListener
2 parents 534369a + e9c80ee commit c84e388

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

Normalizer/AbstractObjectNormalizer.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ public function denormalize(mixed $data, string $type, string $format = null, ar
416416
}
417417
}
418418

419-
if (!empty($extraAttributes)) {
419+
if ($extraAttributes) {
420420
throw new ExtraAttributesException($extraAttributes);
421421
}
422422

@@ -440,6 +440,7 @@ private function validateAndDenormalize(array $types, string $currentClass, stri
440440
{
441441
$expectedTypes = [];
442442
$isUnionType = \count($types) > 1;
443+
$extraAttributesException = null;
443444
foreach ($types as $type) {
444445
if (null === $data && $type->isNullable()) {
445446
return null;
@@ -575,9 +576,19 @@ private function validateAndDenormalize(array $types, string $currentClass, stri
575576
if (!$isUnionType) {
576577
throw $e;
577578
}
579+
} catch (ExtraAttributesException $e) {
580+
if (!$isUnionType) {
581+
throw $e;
582+
}
583+
584+
$extraAttributesException ??= $e;
578585
}
579586
}
580587

588+
if ($extraAttributesException) {
589+
throw $extraAttributesException;
590+
}
591+
581592
if ($context[self::DISABLE_TYPE_ENFORCEMENT] ?? $this->defaultContext[self::DISABLE_TYPE_ENFORCEMENT] ?? false) {
582593
return $data;
583594
}

Tests/SerializerTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\Serializer\Encoder\DecoderInterface;
2121
use Symfony\Component\Serializer\Encoder\EncoderInterface;
2222
use Symfony\Component\Serializer\Encoder\JsonEncoder;
23+
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
2324
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
2425
use Symfony\Component\Serializer\Exception\LogicException;
2526
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
@@ -32,6 +33,7 @@
3233
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
3334
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
3435
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
36+
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
3537
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
3638
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
3739
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
@@ -751,6 +753,35 @@ public function testUnionTypeDeserializable()
751753
$this->assertEquals(new DummyUnionType(), $actual, 'Union type denormalization third case failed.');
752754
}
753755

756+
public function testUnionTypeDeserializableWithoutAllowedExtraAttributes()
757+
{
758+
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
759+
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
760+
$serializer = new Serializer(
761+
[
762+
new ObjectNormalizer($classMetadataFactory, null, null, $extractor, new ClassDiscriminatorFromClassMetadata($classMetadataFactory)),
763+
],
764+
['json' => new JsonEncoder()]
765+
);
766+
767+
$actual = $serializer->deserialize('{ "v": { "a": 0 }}', DummyUnionWithAAndB::class, 'json', [
768+
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
769+
]);
770+
771+
$this->assertEquals(new DummyUnionWithAAndB(new DummyATypeForUnion()), $actual);
772+
773+
$actual = $serializer->deserialize('{ "v": { "b": 1 }}', DummyUnionWithAAndB::class, 'json', [
774+
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
775+
]);
776+
777+
$this->assertEquals(new DummyUnionWithAAndB(new DummyBTypeForUnion()), $actual);
778+
779+
$this->expectException(ExtraAttributesException::class);
780+
$serializer->deserialize('{ "v": { "b": 1, "c": "i am not allowed" }}', DummyUnionWithAAndB::class, 'json', [
781+
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
782+
]);
783+
}
784+
754785
/**
755786
* @requires PHP 8.2
756787
*/
@@ -1215,6 +1246,30 @@ public function setChanged($changed): static
12151246
}
12161247
}
12171248

1249+
class DummyATypeForUnion
1250+
{
1251+
public $a = 0;
1252+
}
1253+
1254+
class DummyBTypeForUnion
1255+
{
1256+
public $b = 1;
1257+
}
1258+
1259+
class DummyUnionWithAAndB
1260+
{
1261+
/** @var DummyATypeForUnion|DummyBTypeForUnion */
1262+
public $v;
1263+
1264+
/**
1265+
* @param DummyATypeForUnion|DummyBTypeForUnion $v
1266+
*/
1267+
public function __construct($v)
1268+
{
1269+
$this->v = $v;
1270+
}
1271+
}
1272+
12181273
class Baz
12191274
{
12201275
public $list;

0 commit comments

Comments
 (0)