Skip to content

Commit 2ba4924

Browse files
committed
Merge branch '5.4' into 6.3
* 5.4: [String] Skip a test when an issue is detected in PCRE2 [Mailer] Stop using the (local) AWS shared configuration in the PHPUnit tests. detect colors on not windows fix xterm detection refactor: hyper check Missing translations for Slovak (sk) symfony#51954 properly handle SYMFONY_DOTENV_VARS being the empty string Avoid incompatibility with symfony/console 7 bug symfony#45057 [Messenger] Avoid reconnecting active Redis connections. [Serializer] fix regression where nullable int cannot be serialized do not overwrite an application's default serialization context
2 parents 27bc8d6 + 52839be commit 2ba4924

File tree

16 files changed

+188
-41
lines changed

16 files changed

+188
-41
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,21 +1927,23 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
19271927
$container->getDefinition('serializer.name_converter.metadata_aware')->setArgument(1, new Reference($config['name_converter']));
19281928
}
19291929

1930+
$defaultContext = $config['default_context'] ?? [];
1931+
1932+
if ($defaultContext) {
1933+
$container->setParameter('serializer.default_context', $defaultContext);
1934+
}
1935+
19301936
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
19311937
$arguments = $container->getDefinition('serializer.normalizer.object')->getArguments();
1932-
$context = ($arguments[6] ?? []) + ['circular_reference_handler' => new Reference($config['circular_reference_handler'])];
1938+
$context = ($arguments[6] ?? $defaultContext) + ['circular_reference_handler' => new Reference($config['circular_reference_handler'])];
19331939
$container->getDefinition('serializer.normalizer.object')->setArgument(5, null);
19341940
$container->getDefinition('serializer.normalizer.object')->setArgument(6, $context);
19351941
}
19361942

19371943
if ($config['max_depth_handler'] ?? false) {
1938-
$defaultContext = $container->getDefinition('serializer.normalizer.object')->getArgument(6);
1939-
$defaultContext += ['max_depth_handler' => new Reference($config['max_depth_handler'])];
1940-
$container->getDefinition('serializer.normalizer.object')->replaceArgument(6, $defaultContext);
1941-
}
1942-
1943-
if (isset($config['default_context']) && $config['default_context']) {
1944-
$container->setParameter('serializer.default_context', $config['default_context']);
1944+
$arguments = $container->getDefinition('serializer.normalizer.object')->getArguments();
1945+
$context = ($arguments[6] ?? $defaultContext) + ['max_depth_handler' => new Reference($config['max_depth_handler'])];
1946+
$container->getDefinition('serializer.normalizer.object')->setArgument(6, $context);
19451947
}
19461948
}
19471949

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer;
13+
14+
class CircularReferenceHandler
15+
{
16+
public function __invoke()
17+
{
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer;
13+
14+
class MaxDepthHandler
15+
{
16+
public function __invoke()
17+
{
18+
}
19+
}

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ framework:
55
http_method_override: false
66
serializer:
77
enabled: true
8+
circular_reference_handler: Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\CircularReferenceHandler
9+
max_depth_handler: Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\MaxDepthHandler
810
default_context:
911
enable_max_depth: true
1012
fake_context_option: foo
@@ -58,3 +60,7 @@ services:
5860
serializer.encoder.csv.alias:
5961
alias: serializer.encoder.csv
6062
public: true
63+
64+
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\CircularReferenceHandler: ~
65+
66+
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serializer\MaxDepthHandler: ~

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
"phpdocumentor/type-resolver": "<1.4.0",
8080
"symfony/asset": "<5.4",
8181
"symfony/clock": "<6.3",
82-
"symfony/console": "<5.4",
82+
"symfony/console": "<5.4|>=7.0",
8383
"symfony/dotenv": "<5.4",
8484
"symfony/dom-crawler": "<6.3",
8585
"symfony/http-client": "<6.3",

src/Symfony/Component/Console/Output/StreamOutput.php

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,17 @@ protected function hasColorSupport(): bool
9696
return false;
9797
}
9898

99-
if ('Hyper' === getenv('TERM_PROGRAM')) {
99+
if (\DIRECTORY_SEPARATOR === '\\'
100+
&& \function_exists('sapi_windows_vt100_support')
101+
&& @sapi_windows_vt100_support($this->stream)
102+
) {
100103
return true;
101104
}
102105

103-
if (\DIRECTORY_SEPARATOR === '\\') {
104-
return (\function_exists('sapi_windows_vt100_support')
105-
&& @sapi_windows_vt100_support($this->stream))
106-
|| false !== getenv('ANSICON')
107-
|| 'ON' === getenv('ConEmuANSI')
108-
|| 'xterm' === getenv('TERM');
109-
}
110-
111-
return stream_isatty($this->stream);
106+
return 'Hyper' === getenv('TERM_PROGRAM')
107+
|| false !== getenv('ANSICON')
108+
|| 'ON' === getenv('ConEmuANSI')
109+
|| str_starts_with((string) getenv('TERM'), 'xterm')
110+
|| stream_isatty($this->stream);
112111
}
113112
}

src/Symfony/Component/Dotenv/Command/DebugCommand.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,13 @@ private function getVariables(array $envFiles, ?string $nameFilter): array
151151

152152
private function getAvailableVars(): array
153153
{
154-
$vars = explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? '');
154+
$dotenvVars = $_SERVER['SYMFONY_DOTENV_VARS'] ?? '';
155+
156+
if ('' === $dotenvVars) {
157+
return [];
158+
}
159+
160+
$vars = explode(',', $dotenvVars);
155161
sort($vars);
156162

157163
return $vars;

src/Symfony/Component/Dotenv/Tests/Command/DebugCommandTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class DebugCommandTest extends TestCase
2727
*/
2828
public function testErrorOnUninitializedDotenv()
2929
{
30+
unset($_SERVER['SYMFONY_DOTENV_VARS']);
31+
3032
$command = new DebugCommand('dev', __DIR__.'/Fixtures/Scenario1');
3133
$command->setHelperSet(new HelperSet([new FormatterHelper()]));
3234
$tester = new CommandTester($command);
@@ -36,6 +38,30 @@ public function testErrorOnUninitializedDotenv()
3638
$this->assertStringContainsString('[ERROR] Dotenv component is not initialized', $output);
3739
}
3840

41+
/**
42+
* @runInSeparateProcess
43+
*/
44+
public function testEmptyDotEnvVarsList()
45+
{
46+
$_SERVER['SYMFONY_DOTENV_VARS'] = '';
47+
48+
$command = new DebugCommand('dev', __DIR__.'/Fixtures/Scenario1');
49+
$command->setHelperSet(new HelperSet([new FormatterHelper()]));
50+
$tester = new CommandTester($command);
51+
$tester->execute([]);
52+
$expectedFormat = <<<'OUTPUT'
53+
%a
54+
---------- ------- ------------ ------%S
55+
Variable Value .env.local .env%S
56+
---------- ------- ------------ ------%S
57+
58+
// Note real values might be different between web and CLI.%S
59+
%a
60+
OUTPUT;
61+
62+
$this->assertStringMatchesFormat($expectedFormat, $tester->getDisplay());
63+
}
64+
3965
public function testScenario1InDevEnv()
4066
{
4167
$output = $this->executeCommand(__DIR__.'/Fixtures/Scenario1', 'dev');

src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiAsyncAwsTransportTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,35 +38,35 @@ public static function getTransportData()
3838
{
3939
return [
4040
[
41-
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY']))),
41+
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY']))),
4242
'ses+api://ACCESS_KEY@us-east-1',
4343
],
4444
[
45-
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'region' => 'us-west-1']))),
45+
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'region' => 'us-west-1']))),
4646
'ses+api://ACCESS_KEY@us-west-1',
4747
],
4848
[
49-
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com']))),
49+
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com']))),
5050
'ses+api://ACCESS_KEY@example.com',
5151
],
5252
[
53-
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com:99']))),
53+
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com:99']))),
5454
'ses+api://ACCESS_KEY@example.com:99',
5555
],
5656
[
57-
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'sessionToken' => 'SESSION_TOKEN']))),
57+
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'sessionToken' => 'SESSION_TOKEN']))),
5858
'ses+api://ACCESS_KEY@us-east-1',
5959
],
6060
[
61-
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'region' => 'us-west-1', 'sessionToken' => 'SESSION_TOKEN']))),
61+
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'region' => 'us-west-1', 'sessionToken' => 'SESSION_TOKEN']))),
6262
'ses+api://ACCESS_KEY@us-west-1',
6363
],
6464
[
65-
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com', 'sessionToken' => 'SESSION_TOKEN']))),
65+
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com', 'sessionToken' => 'SESSION_TOKEN']))),
6666
'ses+api://ACCESS_KEY@example.com',
6767
],
6868
[
69-
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com:99', 'sessionToken' => 'SESSION_TOKEN']))),
69+
new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com:99', 'sessionToken' => 'SESSION_TOKEN']))),
7070
'ses+api://ACCESS_KEY@example.com:99',
7171
],
7272
];
@@ -99,7 +99,7 @@ public function testSend()
9999
]);
100100
});
101101

102-
$transport = new SesApiAsyncAwsTransport(new SesClient(Configuration::create([]), new NullProvider(), $client));
102+
$transport = new SesApiAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false]), new NullProvider(), $client));
103103

104104
$mail = new Email();
105105
$mail->subject('Hello!')

src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesHttpAsyncAwsTransportTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,35 +38,35 @@ public static function getTransportData()
3838
{
3939
return [
4040
[
41-
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY']))),
41+
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY']))),
4242
'ses+https://ACCESS_KEY@us-east-1',
4343
],
4444
[
45-
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'region' => 'us-west-1']))),
45+
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'region' => 'us-west-1']))),
4646
'ses+https://ACCESS_KEY@us-west-1',
4747
],
4848
[
49-
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com']))),
49+
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com']))),
5050
'ses+https://ACCESS_KEY@example.com',
5151
],
5252
[
53-
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com:99']))),
53+
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com:99']))),
5454
'ses+https://ACCESS_KEY@example.com:99',
5555
],
5656
[
57-
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'sessionToken' => 'SESSION_TOKEN']))),
57+
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'sessionToken' => 'SESSION_TOKEN']))),
5858
'ses+https://ACCESS_KEY@us-east-1',
5959
],
6060
[
61-
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'region' => 'us-west-1', 'sessionToken' => 'SESSION_TOKEN']))),
61+
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'region' => 'us-west-1', 'sessionToken' => 'SESSION_TOKEN']))),
6262
'ses+https://ACCESS_KEY@us-west-1',
6363
],
6464
[
65-
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com', 'sessionToken' => 'SESSION_TOKEN']))),
65+
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com', 'sessionToken' => 'SESSION_TOKEN']))),
6666
'ses+https://ACCESS_KEY@example.com',
6767
],
6868
[
69-
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com:99', 'sessionToken' => 'SESSION_TOKEN']))),
69+
new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false, 'accessKeyId' => 'ACCESS_KEY', 'accessKeySecret' => 'SECRET_KEY', 'endpoint' => 'https://example.com:99', 'sessionToken' => 'SESSION_TOKEN']))),
7070
'ses+https://ACCESS_KEY@example.com:99',
7171
],
7272
];
@@ -96,7 +96,7 @@ public function testSend()
9696
]);
9797
});
9898

99-
$transport = new SesHttpAsyncAwsTransport(new SesClient(Configuration::create([]), new NullProvider(), $client));
99+
$transport = new SesHttpAsyncAwsTransport(new SesClient(Configuration::create(['sharedConfigFile' => false]), new NullProvider(), $client));
100100

101101
$mail = new Email();
102102
$mail->subject('Hello!')

src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ public function __construct(array $options, \Redis|Relay|\RedisCluster $redis =
147147
*/
148148
private static function initializeRedis(\Redis|Relay $redis, string $host, int $port, string|array|null $auth, array $params): \Redis|Relay
149149
{
150+
if ($redis->isConnected()) {
151+
return $redis;
152+
}
153+
150154
$connect = isset($params['persistent_id']) ? 'pconnect' : 'connect';
151155
$redis->{$connect}($host, $port, $params['timeout'], $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...(\defined('Redis::SCAN_PREFIX') || \extension_loaded('relay')) ? [['stream' => $params['ssl'] ?? null]] : []);
152156

src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ private function validateAndDenormalize(array $types, string $currentClass, stri
491491
}
492492
break;
493493
case Type::BUILTIN_TYPE_INT:
494-
if (ctype_digit('-' === $data[0] ? substr($data, 1) : $data)) {
494+
if (ctype_digit(isset($data[0]) && '-' === $data[0] ? substr($data, 1) : $data)) {
495495
$data = (int) $data;
496496
} else {
497497
throw NotNormalizableValueException::createForUnexpectedDataType(sprintf('The type of the "%s" attribute for class "%s" must be int ("%s" given).', $attribute, $currentClass, $data), $data, [Type::BUILTIN_TYPE_INT], $context['deserialization_path'] ?? null);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Fixtures;
13+
14+
/**
15+
* @author Nicolas PHILIPPE <nikophil@gmail.com>
16+
*/
17+
class DummyNullableInt
18+
{
19+
public int|null $value = null;
20+
}

src/Symfony/Component/Serializer/Tests/SerializerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
2020
use Symfony\Component\Serializer\Encoder\CsvEncoder;
2121
use Symfony\Component\Serializer\Encoder\JsonEncoder;
22+
use Symfony\Component\Serializer\Encoder\XmlEncoder;
2223
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
2324
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
2425
use Symfony\Component\Serializer\Exception\LogicException;
@@ -57,6 +58,7 @@
5758
use Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberOne;
5859
use Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberThree;
5960
use Symfony\Component\Serializer\Tests\Fixtures\DummyMessageNumberTwo;
61+
use Symfony\Component\Serializer\Tests\Fixtures\DummyNullableInt;
6062
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumConstructor;
6163
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumProperty;
6264
use Symfony\Component\Serializer\Tests\Fixtures\DummyWithObjectOrNull;
@@ -752,6 +754,19 @@ public function testDeserializeWrappedScalar()
752754
$this->assertSame(42, $serializer->deserialize('{"wrapper": 42}', 'int', 'json', [UnwrappingDenormalizer::UNWRAP_PATH => '[wrapper]']));
753755
}
754756

757+
/**
758+
* @requires PHP 8
759+
*/
760+
public function testDeserializeNullableIntInXml()
761+
{
762+
$extractor = new PropertyInfoExtractor([], [new ReflectionExtractor()]);
763+
$serializer = new Serializer([new ObjectNormalizer(null, null, null, $extractor)], ['xml' => new XmlEncoder()]);
764+
765+
$obj = $serializer->deserialize('<?xml version="1.0" encoding="UTF-8"?><DummyNullableInt><value/></DummyNullableInt>', DummyNullableInt::class, 'xml');
766+
$this->assertInstanceOf(DummyNullableInt::class, $obj);
767+
$this->assertNull($obj->value);
768+
}
769+
755770
public function testUnionTypeDeserializable()
756771
{
757772
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));

0 commit comments

Comments
 (0)