From 93eacd9bfdb580d3084b490a367c9d00b2c4d929 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 1 Feb 2023 09:01:28 +0100 Subject: [PATCH 01/33] Update CHANGELOG for 4.4.50 --- CHANGELOG-4.4.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG-4.4.md b/CHANGELOG-4.4.md index 00b3a813dfba2..5a261d439826d 100644 --- a/CHANGELOG-4.4.md +++ b/CHANGELOG-4.4.md @@ -7,6 +7,11 @@ in 4.4 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.4.0...v4.4.1 +* 4.4.50 (2023-02-01) + + * security #cve-2022-24895 [Security/Http] Remove CSRF tokens from storage on successful login (nicolas-grekas) + * security #cve-2022-24894 [HttpKernel] Remove private headers before storing responses with HttpCache (nicolas-grekas) + * 4.4.49 (2022-11-28) * bug #48273 [HttpKernel] Fix message for unresovable arguments of invokable controllers (fancyweb) From d0f26e7850c5e815a949caae4083ac0f83454de6 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 1 Feb 2023 09:01:31 +0100 Subject: [PATCH 02/33] Update VERSION for 4.4.50 --- src/Symfony/Component/HttpKernel/Kernel.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index be36bc6346550..7064edefbe456 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,11 +76,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - public const VERSION = '4.4.49'; - public const VERSION_ID = 40449; + public const VERSION = '4.4.50'; + public const VERSION_ID = 40450; public const MAJOR_VERSION = 4; public const MINOR_VERSION = 4; - public const RELEASE_VERSION = 49; + public const RELEASE_VERSION = 50; public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '11/2022'; From d4a701096401ff6eaab32cbc5428767205b1c220 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 4 May 2023 10:52:02 +0200 Subject: [PATCH 03/33] [HttpClient] fix missing dep --- src/Symfony/Component/HttpClient/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index 086d34e22ff02..42a95e245fa9c 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -33,6 +33,7 @@ "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", + "php-http/message-factory": "^1.0", "symfony/dependency-injection": "^4.3|^5.0", "symfony/http-kernel": "^4.4.13", "symfony/process": "^4.2|^5.0" From f45db039d102c41e1708ceb0bc7602a20b2a9cf0 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 28 Oct 2023 17:57:51 -0700 Subject: [PATCH 04/33] Bump Symfony version to 5.4.31 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 0db848bc1e38a..9fc6b36fc52bc 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -78,12 +78,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ private static $freshCache = []; - public const VERSION = '5.4.30'; - public const VERSION_ID = 50430; + public const VERSION = '5.4.31-DEV'; + public const VERSION_ID = 50431; public const MAJOR_VERSION = 5; public const MINOR_VERSION = 4; - public const RELEASE_VERSION = 30; - public const EXTRA_VERSION = ''; + public const RELEASE_VERSION = 31; + public const EXTRA_VERSION = 'DEV'; public const END_OF_MAINTENANCE = '11/2024'; public const END_OF_LIFE = '11/2025'; From b2cd1a5f356a5327ffba483c1bc1d606cc2b7a35 Mon Sep 17 00:00:00 2001 From: roog Date: Sun, 29 Oct 2023 19:26:22 +0800 Subject: [PATCH 05/33] [Validator] Added Chinese(zh_CN) translations --- .../translations/validators.zh_CN.xlf | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf index a7d49ba98d35c..4579b2e5c5b03 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.zh_CN.xlf @@ -402,6 +402,30 @@ The value of the netmask should be between {{ min }} and {{ max }}. 网络掩码的值应当在 {{ min }} 和 {{ max }} 之间。 + + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + 该文件名过长,最长不应超过{{ filename_max_length }} 个字符。 + + + The password strength is too low. Please use a stronger password. + 该密码强度太低。请使用更复杂的密码。 + + + This value contains characters that are not allowed by the current restriction-level. + 该值包含了当前限制级别不允许的字符。 + + + Using invisible characters is not allowed. + 不允许使用隐藏字符。 + + + Mixing numbers from different scripts is not allowed. + 不可混合使用不同语系的数字。 + + + Using hidden overlay characters is not allowed. + 不允许使用隐藏的覆盖字符。 + From 115a5a1a097a1355875e7a2f8e175e257fc6ad89 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Fri, 27 Oct 2023 17:50:23 +0200 Subject: [PATCH 06/33] [HttpClient] Psr18Client: parse HTTP Reason Phrase for Response --- .../Component/HttpClient/HttplugClient.php | 2 +- .../HttpClient/Internal/HttplugWaitLoop.php | 20 +++++++++++----- .../Component/HttpClient/Psr18Client.php | 23 +++---------------- .../HttpClient/Tests/HttplugClientTest.php | 15 ++++++++++++ .../HttpClient/Tests/Psr18ClientTest.php | 15 ++++++++++++ 5 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/Symfony/Component/HttpClient/HttplugClient.php b/src/Symfony/Component/HttpClient/HttplugClient.php index 2d9eec30f1238..c2fd4635b037a 100644 --- a/src/Symfony/Component/HttpClient/HttplugClient.php +++ b/src/Symfony/Component/HttpClient/HttplugClient.php @@ -101,7 +101,7 @@ public function __construct(HttpClientInterface $client = null, ResponseFactoryI public function sendRequest(RequestInterface $request): Psr7ResponseInterface { try { - return $this->waitLoop->createPsr7Response($this->sendPsr7Request($request)); + return HttplugWaitLoop::createPsr7Response($this->responseFactory, $this->streamFactory, $this->client, $this->sendPsr7Request($request), true); } catch (TransportExceptionInterface $e) { throw new NetworkException($e->getMessage(), $request, $e); } diff --git a/src/Symfony/Component/HttpClient/Internal/HttplugWaitLoop.php b/src/Symfony/Component/HttpClient/Internal/HttplugWaitLoop.php index c61be22e34405..66bbc45711f14 100644 --- a/src/Symfony/Component/HttpClient/Internal/HttplugWaitLoop.php +++ b/src/Symfony/Component/HttpClient/Internal/HttplugWaitLoop.php @@ -79,7 +79,7 @@ public function wait(?ResponseInterface $pendingResponse, float $maxDuration = n if ([, $promise] = $this->promisePool[$response] ?? null) { unset($this->promisePool[$response]); - $promise->resolve($this->createPsr7Response($response, true)); + $promise->resolve(self::createPsr7Response($this->responseFactory, $this->streamFactory, $this->client, $response, true)); } } catch (\Exception $e) { if ([$request, $promise] = $this->promisePool[$response] ?? null) { @@ -114,9 +114,17 @@ public function wait(?ResponseInterface $pendingResponse, float $maxDuration = n return $count; } - public function createPsr7Response(ResponseInterface $response, bool $buffer = false): Psr7ResponseInterface + public static function createPsr7Response(ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory, HttpClientInterface $client, ResponseInterface $response, bool $buffer): Psr7ResponseInterface { - $psrResponse = $this->responseFactory->createResponse($response->getStatusCode()); + $responseParameters = [$response->getStatusCode()]; + + foreach ($response->getInfo('response_headers') as $h) { + if (11 <= \strlen($h) && '/' === $h[4] && preg_match('#^HTTP/\d+(?:\.\d+)? (?:\d\d\d) (.+)#', $h, $m)) { + $responseParameters[1] = $m[1]; + } + } + + $psrResponse = $responseFactory->createResponse(...$responseParameters); foreach ($response->getHeaders(false) as $name => $values) { foreach ($values as $value) { @@ -129,11 +137,11 @@ public function createPsr7Response(ResponseInterface $response, bool $buffer = f } if ($response instanceof StreamableInterface) { - $body = $this->streamFactory->createStreamFromResource($response->toStream(false)); + $body = $streamFactory->createStreamFromResource($response->toStream(false)); } elseif (!$buffer) { - $body = $this->streamFactory->createStreamFromResource(StreamWrapper::createResource($response, $this->client)); + $body = $streamFactory->createStreamFromResource(StreamWrapper::createResource($response, $client)); } else { - $body = $this->streamFactory->createStream($response->getContent(false)); + $body = $streamFactory->createStream($response->getContent(false)); } if ($body->isSeekable()) { diff --git a/src/Symfony/Component/HttpClient/Psr18Client.php b/src/Symfony/Component/HttpClient/Psr18Client.php index 2ec758ae4e140..0cd8f7d24416d 100644 --- a/src/Symfony/Component/HttpClient/Psr18Client.php +++ b/src/Symfony/Component/HttpClient/Psr18Client.php @@ -27,10 +27,12 @@ use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UriFactoryInterface; use Psr\Http\Message\UriInterface; +use Symfony\Component\HttpClient\Internal\HttplugWaitLoop; use Symfony\Component\HttpClient\Response\StreamableInterface; use Symfony\Component\HttpClient\Response\StreamWrapper; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface as HttpClientResponseInterface; use Symfony\Contracts\Service\ResetInterface; if (!interface_exists(RequestFactoryInterface::class)) { @@ -102,26 +104,7 @@ public function sendRequest(RequestInterface $request): ResponseInterface $response = $this->client->request($request->getMethod(), (string) $request->getUri(), $options); - $psrResponse = $this->responseFactory->createResponse($response->getStatusCode()); - - foreach ($response->getHeaders(false) as $name => $values) { - foreach ($values as $value) { - try { - $psrResponse = $psrResponse->withAddedHeader($name, $value); - } catch (\InvalidArgumentException $e) { - // ignore invalid header - } - } - } - - $body = $response instanceof StreamableInterface ? $response->toStream(false) : StreamWrapper::createResource($response, $this->client); - $body = $this->streamFactory->createStreamFromResource($body); - - if ($body->isSeekable()) { - $body->seek(0); - } - - return $psrResponse->withBody($body); + return HttplugWaitLoop::createPsr7Response($this->responseFactory, $this->streamFactory, $this->client, $response, false); } catch (TransportExceptionInterface $e) { if ($e instanceof \InvalidArgumentException) { throw new Psr18RequestException($e, $request); diff --git a/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php b/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php index ba8fcbe3d68eb..48dabb635ef25 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php @@ -285,4 +285,19 @@ public function testInvalidHeaderResponse() $resultResponse = $client->sendRequest($request); $this->assertCount(1, $resultResponse->getHeaders()); } + + public function testResponseReasonPhrase() + { + $responseHeaders = [ + 'HTTP/1.1 103 Very Early Hints', + ]; + $response = new MockResponse('body', ['response_headers' => $responseHeaders]); + + $client = new HttplugClient(new MockHttpClient($response)); + $request = $client->createRequest('POST', 'http://localhost:8057/post') + ->withBody($client->createStream('foo=0123456789')); + + $resultResponse = $client->sendRequest($request); + $this->assertSame('Very Early Hints', $resultResponse->getReasonPhrase()); + } } diff --git a/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php b/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php index 366d555ae03f9..d4bae3ab5c4a3 100644 --- a/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php @@ -101,4 +101,19 @@ public function testInvalidHeaderResponse() $resultResponse = $client->sendRequest($request); $this->assertCount(1, $resultResponse->getHeaders()); } + + public function testResponseReasonPhrase() + { + $responseHeaders = [ + 'HTTP/1.1 103 Very Early Hints', + ]; + $response = new MockResponse('body', ['response_headers' => $responseHeaders]); + + $client = new Psr18Client(new MockHttpClient($response)); + $request = $client->createRequest('POST', 'http://localhost:8057/post') + ->withBody($client->createStream('foo=0123456789')); + + $resultResponse = $client->sendRequest($request); + $this->assertSame('Very Early Hints', $resultResponse->getReasonPhrase()); + } } From 47dcc369449de70d570571b936bfb1f9b4523bb7 Mon Sep 17 00:00:00 2001 From: Tomasz Kowalczyk Date: Mon, 30 Oct 2023 09:02:43 +0100 Subject: [PATCH 07/33] [Validator] updated Romanian translation --- .../Validator/Resources/translations/validators.ro.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.ro.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.ro.xlf index f0ca7477c4b95..6c826a11a8169 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.ro.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.ro.xlf @@ -390,6 +390,10 @@ This value should be a valid expression. Această valoare ar trebui să fie o expresie validă. + + This value is not a valid CSS color. + Această valoare nu este o culoare CSS validă. + This value is not a valid CIDR notation. Această valoare nu este o notație CIDR validă. From 918f67712653f70d3a641b3b0805d0a0bcbf1fc6 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 30 Oct 2023 11:15:41 +0100 Subject: [PATCH 08/33] [Tests] Streamline --- .../DoctrineExtensionTest.php | 4 +-- .../Tests/Form/Type/EntityTypeTest.php | 4 +-- .../Constraints/UniqueEntityValidatorTest.php | 2 +- .../Tests/Handler/ConsoleHandlerTest.php | 2 +- .../ConfigurationTest.php | 4 +-- .../DeprecationTest.php | 6 ++-- .../Bridge/Twig/Tests/AppVariableTest.php | 2 +- .../Twig/Tests/Command/LintCommandTest.php | 2 +- .../Extension/FormExtensionDivLayoutTest.php | 8 ++--- .../CacheWarmer/SerializerCacheWarmerTest.php | 2 +- .../Command/CachePoolClearCommandTest.php | 2 +- .../Command/CachePoolDeleteCommandTest.php | 2 +- .../EventDispatcherDebugCommandTest.php | 2 +- .../Command/SecretsRemoveCommandTest.php | 2 +- .../Tests/Command/SecretsSetCommandTest.php | 2 +- .../Command/TranslationDebugCommandTest.php | 2 +- ...TranslationUpdateCommandCompletionTest.php | 2 +- .../Controller/AbstractControllerTest.php | 2 +- .../Controller/RedirectControllerTest.php | 6 ++-- .../Controller/TemplateControllerTest.php | 14 +++++++-- .../DependencyInjection/ConfigurationTest.php | 6 ++-- .../Functional/ContainerDebugCommandTest.php | 4 +-- .../Functional/RouterDebugCommandTest.php | 2 +- .../SecurityDataCollectorTest.php | 2 +- .../SecurityExtensionTest.php | 12 ++++---- .../Tests/Functional/AuthenticatorTest.php | 4 +-- .../Tests/Functional/CsrfFormLoginTest.php | 2 +- .../Tests/Functional/FormLoginTest.php | 2 +- .../Tests/Functional/RememberMeTest.php | 2 +- .../SecurityRoutingIntegrationTest.php | 7 ++--- .../Tests/Functional/SecurityTest.php | 2 +- .../DependencyInjection/TwigExtensionTest.php | 2 +- .../Controller/ProfilerControllerTest.php | 4 +-- .../Csp/ContentSecurityPolicyHandlerTest.php | 4 +-- .../WebDebugToolbarListenerTest.php | 2 +- .../Tests/Resources/IconTest.php | 2 +- .../Component/Asset/Tests/UrlPackageTest.php | 12 ++++---- .../BrowserKit/Tests/AbstractBrowserTest.php | 29 +++++++++++-------- .../Adapter/RedisAdapterSentinelTest.php | 2 +- .../Console/Tests/ApplicationTest.php | 4 +-- .../Console/Tests/Helper/TableTest.php | 7 +++-- .../CheckTypeDeclarationsPassTest.php | 16 ++++------ .../Tests/AbstractRequestHandlerTestCase.php | 4 +-- .../Component/Form/Tests/CompoundFormTest.php | 2 +- .../ChoiceToValueTransformerTest.php | 2 +- .../DateIntervalToStringTransformerTest.php | 12 +++----- ...TimeImmutableToDateTimeTransformerTest.php | 2 +- ...imeToHtml5LocalDateTimeTransformerTest.php | 4 +-- .../DateTimeToRfc3339TransformerTest.php | 2 +- ...ercentToLocalizedStringTransformerTest.php | 2 +- .../Extension/Core/Type/CheckboxTypeTest.php | 4 +-- .../Extension/Core/Type/ColorTypeTest.php | 4 +-- .../Core/Type/DateIntervalTypeTest.php | 2 +- .../Core/Type/ExtendedChoiceTypeTest.php | 2 +- .../Extension/Core/Type/FileTypeTest.php | 2 +- .../Extension/Core/Type/TextTypeTest.php | 2 +- .../Extension/Core/Type/WeekTypeTest.php | 2 +- .../Form/Tests/FormErrorIteratorTest.php | 2 +- .../Form/Tests/ResolvedFormTypeTest.php | 2 +- .../Component/Form/Tests/SimpleFormTest.php | 2 +- .../Form/Tests/Util/StringUtilTest.php | 6 ++-- .../Normalizer/DateIntervalNormalizerTest.php | 6 ++-- .../Tests/Command/GenerateUuidCommandTest.php | 6 ++-- src/Symfony/Component/Uid/Tests/UlidTest.php | 8 ++--- src/Symfony/Component/Uid/Tests/UuidTest.php | 10 +++---- 65 files changed, 147 insertions(+), 144 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php index da09dc906763e..aa36885cad44e 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -197,7 +197,7 @@ public function testMappingTypeDetection() $this->assertSame($mappingType, \PHP_VERSION_ID < 80000 ? 'annotation' : 'attribute'); } - public static function providerBasicDrivers() + public static function providerBasicDrivers(): array { return [ ['doctrine.orm.cache.apc.class', ['type' => 'apc']], @@ -276,7 +276,7 @@ public function testUnrecognizedCacheDriverException() $this->invokeLoadCacheDriver($objectManager, $container, $cacheName); } - public static function providerBundles() + public static function providerBundles(): iterable { yield ['AnnotationsBundle', \PHP_VERSION_ID < 80000 ? 'annotation' : 'attribute', '/Entity']; yield ['AnnotationsOneLineBundle', \PHP_VERSION_ID < 80000 ? 'annotation' : 'attribute', '/Entity']; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index d8491588fe357..75102ee331410 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -158,7 +158,7 @@ public function testChoiceTranslationDomainIsDisabledByDefault($expanded) } } - public static function choiceTranslationDomainProvider() + public static function choiceTranslationDomainProvider(): array { return [ [false], @@ -240,8 +240,6 @@ public function testConfigureQueryBuilderWithClosureReturningNonQueryBuilder() return new \stdClass(); }, ]); - - $field->submit('2'); } public function testConfigureQueryBuilderWithClosureReturningNullUseDefault() diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 66849208fd44b..75eae2c311d9f 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -479,7 +479,7 @@ public function testValidateResultTypes($entity1, $result) $this->assertNoViolation(); } - public static function resultTypesProvider() + public static function resultTypesProvider(): array { $entity = new SingleIntIdEntity(1, 'foo'); diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php index e3d06b52f4035..4ddaddbde1218 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php @@ -89,7 +89,7 @@ public function testVerbosityMapping($verbosity, $level, $isHandling, array $map $this->assertFalse($handler->handle($infoRecord), 'The handler finished handling the log.'); } - public static function provideVerbosityMappingTests() + public static function provideVerbosityMappingTests(): array { return [ [OutputInterface::VERBOSITY_QUIET, Logger::ERROR, true], diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php index 6116fbe9f0260..726f397f919b3 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php @@ -249,8 +249,8 @@ public function testToleratesForIndividualGroups(string $deprecationsHelper, arr } } - public static function provideDataForToleratesForGroup() { - + public static function provideDataForToleratesForGroup(): iterable + { yield 'total threshold not reached' => ['max[total]=1', [ 'unsilenced' => 0, 'self' => 0, diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php index 5c7cf991b3f2f..01d418ef23829 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php @@ -97,7 +97,7 @@ public function testItMutesOnlySpecificErrorMessagesWhenTheCallingCodeIsInPhpuni $this->assertSame($muted, $deprecation->isMuted()); } - public static function mutedProvider() + public static function mutedProvider(): iterable { yield 'not from phpunit, and not a whitelisted message' => [ false, @@ -147,7 +147,7 @@ public function testItTakesMutesDeprecationFromPhpUnitFiles() $this->assertTrue($deprecation->isMuted()); } - public static function providerGetTypeDetectsSelf() + public static function providerGetTypeDetectsSelf(): array { return [ 'not_from_vendors_file' => [Deprecation::TYPE_SELF, '', 'MyClass1', __FILE__], @@ -182,7 +182,7 @@ public function testGetTypeDetectsSelf(string $expectedType, string $message, st $this->assertSame($expectedType, $deprecation->getType()); } - public static function providerGetTypeUsesRightTrace() + public static function providerGetTypeUsesRightTrace(): array { $vendorDir = self::getVendorDir(); $fakeTrace = [ diff --git a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php index ea3fbfda3a659..9378e87c46939 100644 --- a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php +++ b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php @@ -43,7 +43,7 @@ public function testDebug($debugFlag) $this->assertEquals($debugFlag, $this->appVariable->getDebug()); } - public static function debugDataProvider() + public static function debugDataProvider(): array { return [ 'debug on' => [true], diff --git a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php index a898680fdd3e3..18d09b20b2d95 100644 --- a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php @@ -150,7 +150,7 @@ public function testComplete(array $input, array $expectedSuggestions) $this->assertSame($expectedSuggestions, $tester->complete($input)); } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { yield 'option' => [['--format', ''], ['txt', 'json', 'github']]; } diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php index 3809f3fa1f4cf..5de8fb90e1a93 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionDivLayoutTest.php @@ -100,7 +100,7 @@ public function testThemeBlockInheritanceUsingDynamicExtend() ); } - public static function isSelectedChoiceProvider() + public static function isSelectedChoiceProvider(): array { return [ [true, '0', '0'], @@ -150,7 +150,7 @@ public function testStartTagHasActionAttributeWhenActionIsZero() $this->assertSame('
', $html); } - public static function isRootFormProvider() + public static function isRootFormProvider(): array { return [ [true, new FormView()], @@ -381,14 +381,14 @@ protected function setTheme(FormView $view, array $themes, $useDefaultThemes = t $this->renderer->setTheme($view, $themes, $useDefaultThemes); } - public static function themeBlockInheritanceProvider() + public static function themeBlockInheritanceProvider(): array { return [ [['theme.html.twig']], ]; } - public static function themeInheritanceProvider() + public static function themeInheritanceProvider(): array { return [ [['parent_label.html.twig'], ['child_label.html.twig']], diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/SerializerCacheWarmerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/SerializerCacheWarmerTest.php index 85dbd88104f57..5feb0c8ec1bd7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/SerializerCacheWarmerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/SerializerCacheWarmerTest.php @@ -40,7 +40,7 @@ public function testWarmUp(array $loaders) $this->assertTrue($arrayPool->getItem('Symfony_Bundle_FrameworkBundle_Tests_Fixtures_Serialization_Author')->isHit()); } - public static function loaderProvider() + public static function loaderProvider(): array { return [ [ diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolClearCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolClearCommandTest.php index cc4573fafdc62..08e2766d936a9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolClearCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolClearCommandTest.php @@ -44,7 +44,7 @@ public function testComplete(array $input, array $expectedSuggestions) $this->assertSame($expectedSuggestions, $suggestions); } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { yield 'pool_name' => [ ['f'], diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolDeleteCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolDeleteCommandTest.php index 7cd2366703c3b..41f7b66433bc2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolDeleteCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CachePoolDeleteCommandTest.php @@ -98,7 +98,7 @@ public function testComplete(array $input, array $expectedSuggestions) $this->assertSame($expectedSuggestions, $suggestions); } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { yield 'pool_name' => [ ['f'], diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/EventDispatcherDebugCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/EventDispatcherDebugCommandTest.php index 9bc054f22a942..61c50a7bc8af3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/EventDispatcherDebugCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/EventDispatcherDebugCommandTest.php @@ -31,7 +31,7 @@ public function testComplete(array $input, array $expectedSuggestions) $this->assertSame($expectedSuggestions, $suggestions); } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { yield 'event' => [[''], ['Symfony\Component\Mailer\Event\MessageEvent', 'console.command']]; yield 'event for other dispatcher' => [['--dispatcher', 'other_event_dispatcher', ''], ['other_event', 'App\OtherEvent']]; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/SecretsRemoveCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/SecretsRemoveCommandTest.php index 88c247ec61ebc..2c12b6128d9f5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/SecretsRemoveCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/SecretsRemoveCommandTest.php @@ -37,7 +37,7 @@ public function testComplete(bool $withLocalVault, array $input, array $expected $this->assertSame($expectedSuggestions, $suggestions); } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { yield 'name' => [true, [''], ['SECRET', 'OTHER_SECRET']]; yield '--local name (with local vault)' => [true, ['--local', ''], ['SECRET']]; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/SecretsSetCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/SecretsSetCommandTest.php index 8e8e968c8f710..678fb417c53cf 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/SecretsSetCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/SecretsSetCommandTest.php @@ -32,7 +32,7 @@ public function testComplete(array $input, array $expectedSuggestions) $this->assertSame($expectedSuggestions, $suggestions); } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { yield 'name' => [[''], ['SECRET', 'OTHER_SECRET']]; yield '--local name (with local vault)' => [['--local', ''], ['SECRET', 'OTHER_SECRET']]; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php index 846abd44500e0..e3ac1066af80a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationDebugCommandTest.php @@ -269,7 +269,7 @@ function ($path, $catalogue) use ($extractedMessagesWithDomains) { $this->assertSame($expectedSuggestions, $suggestions); } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { yield 'locale' => [ [''], diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandCompletionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandCompletionTest.php index 91999d288266e..6992ade4d422b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandCompletionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandCompletionTest.php @@ -42,7 +42,7 @@ public function testComplete(array $input, array $expectedSuggestions) $this->assertSame($expectedSuggestions, $suggestions); } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { $bundle = new ExtensionPresentBundle(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php index d8dc199d8ae4b..2de0f7c919fe0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php @@ -409,7 +409,7 @@ public function testdenyAccessUnlessGrantedSetsAttributesAsArray($attribute, $ex } } - public static function provideDenyAccessUnlessGrantedSetsAttributesAsArray() + public static function provideDenyAccessUnlessGrantedSetsAttributesAsArray(): array { $obj = new \stdClass(); $obj->foo = 'bar'; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php index de72396df6ad5..b2da9ef58c5c1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php @@ -103,7 +103,7 @@ public function testRoute($permanent, $keepRequestMethod, $keepQueryParams, $ign $this->assertEquals($expectedCode, $returnResponse->getStatusCode()); } - public static function provider() + public static function provider(): array { return [ [true, false, false, false, 301, ['additional-parameter' => 'value']], @@ -210,7 +210,7 @@ public function testUrlRedirectDefaultPorts() $this->assertRedirectUrl($returnValue, $expectedUrl); } - public static function urlRedirectProvider() + public static function urlRedirectProvider(): array { return [ // Standard ports @@ -262,7 +262,7 @@ public function testUrlRedirect($scheme, $httpPort, $httpsPort, $requestScheme, $this->assertRedirectUrl($returnValue, $expectedUrl); } - public static function pathQueryParamsProvider() + public static function pathQueryParamsProvider(): array { return [ ['http://www.example.com/base/redirect-path', '/redirect-path', ''], diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/TemplateControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/TemplateControllerTest.php index e567342ecf4c9..c403a4c598fd1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/TemplateControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/TemplateControllerTest.php @@ -32,13 +32,23 @@ public function testTwig() $this->assertEquals('bar', $controller('mytemplate')->getContent()); } - public function testNoTwig() + public function testNoTwigTemplateActionMethod() { + $controller = new TemplateController(); + $this->expectException(\LogicException::class); $this->expectExceptionMessage('You cannot use the TemplateController if the Twig Bundle is not available.'); - $controller = new TemplateController(); $controller->templateAction('mytemplate')->getContent(); + } + + public function testNoTwigInvokeMethod() + { + $controller = new TemplateController(); + + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('You cannot use the TemplateController if the Twig Bundle is not available.'); + $controller('mytemplate')->getContent(); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index 47b66baf35861..41f3d7482c3e9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -113,7 +113,7 @@ public function testValidAssetsPackageNameConfiguration($packageName) $this->assertArrayHasKey($packageName, $config['assets']['packages']); } - public static function provideValidAssetsPackageNameConfigurationTests() + public static function provideValidAssetsPackageNameConfigurationTests(): array { return [ ['foobar'], @@ -139,7 +139,7 @@ public function testInvalidAssetsConfiguration(array $assetConfig, $expectedMess ]); } - public static function provideInvalidAssetConfigurationTests() + public static function provideInvalidAssetConfigurationTests(): iterable { // helper to turn config into embedded package config $createPackageConfig = function (array $packageConfig) { @@ -192,7 +192,7 @@ public function testValidLockConfiguration($lockConfig, $processedConfig) $this->assertEquals($processedConfig, $config['lock']); } - public static function provideValidLockConfigurationTests() + public static function provideValidLockConfigurationTests(): iterable { yield [null, ['enabled' => true, 'resources' => ['default' => [class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphore' : 'flock']]]]; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDebugCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDebugCommandTest.php index 63c717b7b41b6..01d0727a2ea10 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDebugCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDebugCommandTest.php @@ -204,7 +204,7 @@ public function testGetDeprecationNoFile() $this->assertStringContainsString('[WARNING] The deprecation file does not exist', $tester->getDisplay()); } - public static function provideIgnoreBackslashWhenFindingService() + public static function provideIgnoreBackslashWhenFindingService(): array { return [ [BackslashClass::class], @@ -232,7 +232,7 @@ public function testComplete(array $input, array $expectedSuggestions, array $no } } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { $serviceId = 'console.command.container_debug'; $hiddenServiceId = '.console.command.container_debug.lazy'; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/RouterDebugCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/RouterDebugCommandTest.php index 6b8eb6b7f0cbf..58130ad4201ac 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/RouterDebugCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/RouterDebugCommandTest.php @@ -100,7 +100,7 @@ public function testComplete(array $input, array $expectedSuggestions) $this->assertSame($expectedSuggestions, $tester->complete($input)); } - public static function provideCompletionSuggestions() + public static function provideCompletionSuggestions(): iterable { yield 'option --format' => [ ['--format', ''], diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php index 9e12116ac2aaa..126a97020c192 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php @@ -400,7 +400,7 @@ public function dispatch(object $event, string $eventName = null): object $this->assertSame($dataCollector->getVoterStrategy(), $strategy, 'Wrong value returned by getVoterStrategy'); } - public static function provideRoles() + public static function provideRoles(): array { return [ // Basic roles diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php index eef68e4c3de46..e25d32347a445 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -526,7 +526,7 @@ public function testSecretRememberMeHandler() $this->assertSame('very', $handler->getArgument(1)); } - public static function sessionConfigurationProvider() + public static function sessionConfigurationProvider(): array { return [ [ @@ -659,7 +659,7 @@ public function testAuthenticatorManagerEnabledEntryPoint(array $firewall, $entr $this->assertEquals($entryPointId, (string) $container->getDefinition('security.exception_listener.main')->getArgument(4)); } - public static function provideEntryPointFirewalls() + public static function provideEntryPointFirewalls(): iterable { // only one entry point available yield [['http_basic' => true], 'security.authenticator.http_basic.main']; @@ -679,7 +679,7 @@ public static function provideEntryPointFirewalls() /** * @dataProvider provideEntryPointRequiredData */ - public function testEntryPointRequired(array $firewall, $messageRegex) + public function testEntryPointRequired(array $firewall, string $messageRegex) { $this->expectException(InvalidConfigurationException::class); $this->expectExceptionMessageMatches($messageRegex); @@ -699,7 +699,7 @@ public function testEntryPointRequired(array $firewall, $messageRegex) $container->compile(); } - public static function provideEntryPointRequiredData() + public static function provideEntryPointRequiredData(): iterable { // more than one entry point available and not explicitly set yield [ @@ -749,7 +749,7 @@ public function testConfigureCustomAuthenticator(array $firewall, array $expecte $this->assertEquals($expectedAuthenticators, array_map('strval', $container->getDefinition('security.authenticator.manager.main')->getArgument(0))); } - public static function provideConfigureCustomAuthenticatorData() + public static function provideConfigureCustomAuthenticatorData(): iterable { yield [ ['custom_authenticator' => TestAuthenticator::class], @@ -829,7 +829,7 @@ public function testUserCheckerWithAuthenticatorManager(array $config, string $e $this->assertEquals($expectedUserCheckerClass, $container->findDefinition($userCheckerId)->getClass()); } - public static function provideUserCheckerConfig() + public static function provideUserCheckerConfig(): iterable { yield [[], InMemoryUserChecker::class]; yield [['user_checker' => TestUserChecker::class], TestUserChecker::class]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php index ca99dbf3eadab..d162f99131399 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php @@ -60,7 +60,7 @@ public function testWithoutUserProvider($email) $this->assertJsonStringEqualsJsonString('{"email":"'.$email.'"}', $client->getResponse()->getContent()); } - public static function provideEmails() + public static function provideEmails(): iterable { yield ['jane@example.org', true]; yield ['john@example.org', false]; @@ -84,7 +84,7 @@ public function testLoginUsersWithMultipleFirewalls(string $username, string $fi $this->assertEquals('Welcome '.$username.'!', $client->getResponse()->getContent()); } - public static function provideEmailsWithFirewalls() + public static function provideEmailsWithFirewalls(): iterable { yield ['jane@example.org', 'main']; yield ['john@example.org', 'custom']; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php index 853fc1dc8d018..8c79b105491a4 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php @@ -217,7 +217,7 @@ public function testLegacyFormLoginRedirectsToProtectedResourceAfterLogin($optio $this->assertStringContainsString('You\'re browsing to path "/protected-resource".', $text); } - public static function provideClientOptions() + public static function provideClientOptions(): iterable { yield [['test_case' => 'CsrfFormLogin', 'root_config' => 'config.yml', 'enable_authenticator_manager' => true]]; yield [['test_case' => 'CsrfFormLogin', 'root_config' => 'routes_as_path.yml', 'enable_authenticator_manager' => true]]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php index 9787047ac3d7d..c17a5cc2ca241 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php @@ -300,7 +300,7 @@ public function testLegacyLoginThrottling() } } - public static function provideClientOptions() + public static function provideClientOptions(): iterable { yield [['test_case' => 'StandardFormLogin', 'root_config' => 'base_config.yml', 'enable_authenticator_manager' => true]]; yield [['test_case' => 'StandardFormLogin', 'root_config' => 'routes_as_path.yml', 'enable_authenticator_manager' => true]]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeTest.php index 26f963df21b35..511803664c357 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeTest.php @@ -175,7 +175,7 @@ public function testLegacySessionLessRememberMeLogout() $this->assertNull($cookieJar->get('REMEMBERME')); } - public static function provideConfigs() + public static function provideConfigs(): iterable { yield [['root_config' => 'config_session.yml']]; yield [['root_config' => 'config_persistent.yml']]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php index ab5977475b08e..f01fa352a2931 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php @@ -125,8 +125,7 @@ public function testInvalidIpsInAccessControl() $this->expectException(\LogicException::class); $this->expectExceptionMessage('The given value "256.357.458.559" in the "security.access_control" config option is not a valid IP address.'); - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'invalid_ip_access_control.yml']); - $client->request('GET', '/unprotected_resource'); + $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'invalid_ip_access_control.yml']); } public function testPublicHomepage() @@ -295,7 +294,7 @@ private function assertRestricted($client, $path) $this->assertEquals(302, $client->getResponse()->getStatusCode()); } - public static function provideClientOptions() + public static function provideClientOptions(): iterable { yield [['test_case' => 'StandardFormLogin', 'root_config' => 'base_config.yml', 'enable_authenticator_manager' => true]]; yield [['test_case' => 'StandardFormLogin', 'root_config' => 'routes_as_path.yml', 'enable_authenticator_manager' => true]]; @@ -307,7 +306,7 @@ public static function provideLegacyClientOptions() yield [['test_case' => 'StandardFormLogin', 'root_config' => 'routes_as_path.yml', 'enable_authenticator_manager' => true]]; } - public static function provideConfigs() + public static function provideConfigs(): iterable { yield [['test_case' => 'StandardFormLogin', 'root_config' => 'base_config.yml']]; yield [['test_case' => 'StandardFormLogin', 'root_config' => 'routes_as_path.yml']]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityTest.php index 8604f0b1f84c4..8cef5976f2604 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityTest.php @@ -114,7 +114,7 @@ public function testLegacyServiceIsFunctional() $this->assertSame($token, $security->getToken()); } - public static function userWillBeMarkedAsChangedIfRolesHasChangedProvider() + public static function userWillBeMarkedAsChangedIfRolesHasChangedProvider(): array { return [ [ diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php index 660c7fd07dcd1..544843ec671d9 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php @@ -230,7 +230,7 @@ public function testStopwatchExtensionAvailability($debug, $stopwatchEnabled, $e $this->assertSame($expected, $stopwatchIsAvailable->getValue($tokenParsers[0])); } - public static function stopwatchExtensionAvailabilityProvider() + public static function stopwatchExtensionAvailabilityProvider(): array { return [ 'debug-and-stopwatch-enabled' => [true, true, true], diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php index 67355d9030a15..ac56ef3e89677 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php @@ -342,7 +342,7 @@ public function testPhpinfoActionWithProfilerDisabled() $twig = $this->createMock(Environment::class); $controller = new ProfilerController($urlGenerator, null, $twig, []); - $controller->phpinfoAction(Request::create('/_profiler/phpinfo')); + $controller->phpinfoAction(); } public function testPhpinfoAction() @@ -355,7 +355,7 @@ public function testPhpinfoAction() $this->assertStringContainsString('PHP License', $client->getResponse()->getContent()); } - public static function provideCspVariants() + public static function provideCspVariants(): array { return [ [true], diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php index 7d5c0761b1dcc..bce62829467b9 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php @@ -46,7 +46,7 @@ public function testOnKernelResponse($nonce, $expectedNonce, Request $request, R } } - public static function provideRequestAndResponses() + public static function provideRequestAndResponses(): array { $nonce = bin2hex(random_bytes(16)); @@ -73,7 +73,7 @@ public static function provideRequestAndResponses() ]; } - public static function provideRequestAndResponsesForOnKernelResponse() + public static function provideRequestAndResponsesForOnKernelResponse(): array { $nonce = bin2hex(random_bytes(16)); diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php index c4972c97c9e3b..9d28a4e20588b 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/EventListener/WebDebugToolbarListenerTest.php @@ -149,7 +149,7 @@ public function testToolbarIsNotInjectedOnRedirection($statusCode) $this->assertEquals('', $response->getContent()); } - public static function provideRedirects() + public static function provideRedirects(): array { return [ [301], diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Resources/IconTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Resources/IconTest.php index afbd6edff0f06..aa083470396bb 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Resources/IconTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Resources/IconTest.php @@ -23,7 +23,7 @@ public function testIconFileContents($iconFilePath) $this->assertMatchesRegularExpression('~.*~s', file_get_contents($iconFilePath), sprintf('The SVG metadata of the %s icon is different than expected (use the same as the other icons).', $iconFilePath)); } - public static function provideIconFilePaths() + public static function provideIconFilePaths(): array { return array_map(function ($filePath) { return (array) $filePath; }, glob(__DIR__.'/../../Resources/views/Icon/*.svg')); } diff --git a/src/Symfony/Component/Asset/Tests/UrlPackageTest.php b/src/Symfony/Component/Asset/Tests/UrlPackageTest.php index b6525d35cfe5e..a71b457eaddc7 100644 --- a/src/Symfony/Component/Asset/Tests/UrlPackageTest.php +++ b/src/Symfony/Component/Asset/Tests/UrlPackageTest.php @@ -25,13 +25,13 @@ class UrlPackageTest extends TestCase /** * @dataProvider getConfigs */ - public function testGetUrl($baseUrls, $format, $path, $expected) + public function testGetUrl($baseUrls, string $format, string $path, string $expected) { $package = new UrlPackage($baseUrls, new StaticVersionStrategy('v1', $format)); $this->assertSame($expected, $package->getUrl($path)); } - public static function getConfigs() + public static function getConfigs(): array { return [ ['http://example.net', '', 'http://example.com/foo', 'http://example.com/foo'], @@ -65,14 +65,14 @@ public static function getConfigs() /** * @dataProvider getContextConfigs */ - public function testGetUrlWithContext($secure, $baseUrls, $format, $path, $expected) + public function testGetUrlWithContext(bool $secure, $baseUrls, string $format, string $path, string $expected) { $package = new UrlPackage($baseUrls, new StaticVersionStrategy('v1', $format), $this->getContext($secure)); $this->assertSame($expected, $package->getUrl($path)); } - public static function getContextConfigs() + public static function getContextConfigs(): array { return [ [false, 'http://example.com', '', 'foo', 'http://example.com/foo?v1'], @@ -114,7 +114,7 @@ public function testWrongBaseUrl($baseUrls) new UrlPackage($baseUrls, new EmptyVersionStrategy()); } - public static function getWrongBaseUrlConfig() + public static function getWrongBaseUrlConfig(): array { return [ ['not-a-url'], @@ -122,7 +122,7 @@ public static function getWrongBaseUrlConfig() ]; } - private function getContext($secure) + private function getContext($secure): ContextInterface { $context = $this->createMock(ContextInterface::class); $context->expects($this->any())->method('isSecure')->willReturn($secure); diff --git a/src/Symfony/Component/BrowserKit/Tests/AbstractBrowserTest.php b/src/Symfony/Component/BrowserKit/Tests/AbstractBrowserTest.php index 6944a3371e323..c732238a7f126 100644 --- a/src/Symfony/Component/BrowserKit/Tests/AbstractBrowserTest.php +++ b/src/Symfony/Component/BrowserKit/Tests/AbstractBrowserTest.php @@ -47,11 +47,12 @@ public function testGetRequest() public function testGetRequestNull() { + $client = $this->getBrowser(); + $this->expectException(BadMethodCallException::class); $this->expectExceptionMessage('The "request()" method must be called before "Symfony\\Component\\BrowserKit\\AbstractBrowser::getRequest()".'); - $client = $this->getBrowser(); - $this->assertNull($client->getRequest()); + $client->getRequest(); } public function testXmlHttpRequest() @@ -95,20 +96,22 @@ public function testGetResponse() public function testGetResponseNull() { + $client = $this->getBrowser(); + $this->expectException(BadMethodCallException::class); $this->expectExceptionMessage('The "request()" method must be called before "Symfony\\Component\\BrowserKit\\AbstractBrowser::getResponse()".'); - $client = $this->getBrowser(); - $this->assertNull($client->getResponse()); + $client->getResponse(); } public function testGetInternalResponseNull() { + $client = $this->getBrowser(); + $this->expectException(BadMethodCallException::class); $this->expectExceptionMessage('The "request()" method must be called before "Symfony\\Component\\BrowserKit\\AbstractBrowser::getInternalResponse()".'); - $client = $this->getBrowser(); - $this->assertNull($client->getInternalResponse()); + $client->getInternalResponse(); } public function testGetContent() @@ -131,11 +134,12 @@ public function testGetCrawler() public function testGetCrawlerNull() { + $client = $this->getBrowser(); + $this->expectException(BadMethodCallException::class); $this->expectExceptionMessage('The "request()" method must be called before "Symfony\\Component\\BrowserKit\\AbstractBrowser::getCrawler()".'); - $client = $this->getBrowser(); - $this->assertNull($client->getCrawler()); + $client->getCrawler(); } public function testRequestHttpHeaders() @@ -384,7 +388,7 @@ public function testSubmitPreserveAuth() $this->assertSame('bar', $server['PHP_AUTH_PW']); } - public function testSubmitPassthrewHeaders() + public function testSubmitPassthroughHeaders() { $client = $this->getBrowser(); $client->setNextResponse(new Response('
')); @@ -623,7 +627,7 @@ public function testFollowMetaRefresh(string $content, string $expectedEndingUrl $this->assertSame($expectedEndingUrl, $client->getRequest()->getUri()); } - public static function getTestsForMetaRefresh() + public static function getTestsForMetaRefresh(): array { return [ ['', 'http://www.example.com/redirected'], @@ -844,10 +848,11 @@ public function testInternalRequest() public function testInternalRequestNull() { + $client = $this->getBrowser(); + $this->expectException(BadMethodCallException::class); $this->expectExceptionMessage('The "request()" method must be called before "Symfony\\Component\\BrowserKit\\AbstractBrowser::getInternalRequest()".'); - $client = $this->getBrowser(); - $this->assertNull($client->getInternalRequest()); + $client->getInternalRequest(); } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php index 601715645a8db..c05c6f3e7341a 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php @@ -48,7 +48,7 @@ public function testExceptionMessageWhenFailingToRetrieveMasterInformation() { $hosts = getenv('REDIS_SENTINEL_HOSTS'); $dsn = 'redis:?host['.str_replace(' ', ']&host[', $hosts).']'; - $this->expectException(\Symfony\Component\Cache\Exception\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Failed to retrieve master information from sentinel "invalid-masterset-name" and dsn "'.$dsn.'".'); AbstractAdapter::createConnection($dsn, ['redis_sentinel' => 'invalid-masterset-name']); } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index d06abcb8c10dc..bf5652ccc47f2 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -1536,7 +1536,7 @@ public function testRunWithErrorAndDispatcher() $tester = new ApplicationTester($application); $tester->run(['command' => 'dym']); - $this->assertStringContainsString('before.dym.error.after.', $tester->getDisplay(), 'The PHP Error did not dispached events'); + $this->assertStringContainsString('before.dym.error.after.', $tester->getDisplay(), 'The PHP error did not dispatch events'); } public function testRunDispatchesAllEventsWithError() @@ -1553,7 +1553,7 @@ public function testRunDispatchesAllEventsWithError() $tester = new ApplicationTester($application); $tester->run(['command' => 'dym']); - $this->assertStringContainsString('before.dym.error.after.', $tester->getDisplay(), 'The PHP Error did not dispached events'); + $this->assertStringContainsString('before.dym.error.after.', $tester->getDisplay(), 'The PHP error did not dispatch events'); } public function testRunWithErrorFailingStatusCode() diff --git a/src/Symfony/Component/Console/Tests/Helper/TableTest.php b/src/Symfony/Component/Console/Tests/Helper/TableTest.php index 1f313a680f04a..e7822a4565590 100644 --- a/src/Symfony/Component/Console/Tests/Helper/TableTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/TableTest.php @@ -1017,15 +1017,16 @@ public function testColumnStyle() public function testThrowsWhenTheCellInAnArray() { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('A cell must be a TableCell, a scalar or an object implementing "__toString()", "array" given.'); - $table = new Table($output = $this->getOutputStream()); + $table = new Table($this->getOutputStream()); $table ->setHeaders(['ISBN', 'Title', 'Author', 'Price']) ->setRows([ ['99921-58-10-7', [], 'Dante Alighieri', '9.95'], ]); + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('A cell must be a TableCell, a scalar or an object implementing "__toString()", "array" given.'); + $table->render(); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php index 91447c7ef4459..90a5248f1e47d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php @@ -265,17 +265,15 @@ public function testProcessSuccessWhenPassingNullToOptionalThatDoesNotAcceptNull public function testProcessFailsWhenPassingBadTypeToOptional() { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarOptionalArgument::__construct()" accepts "stdClass", "string" passed.'); - $container = new ContainerBuilder(); $container->register('bar', BarOptionalArgument::class) ->addArgument('string instead of stdClass'); - (new CheckTypeDeclarationsPass(true))->process($container); + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid definition for service "bar": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarOptionalArgument::__construct()" accepts "stdClass", "string" passed.'); - $this->assertNull($container->get('bar')->foo); + (new CheckTypeDeclarationsPass(true))->process($container); } public function testProcessSuccessScalarType() @@ -604,17 +602,15 @@ public function testProcessDoesNotThrowsExceptionOnValidTypes() public function testProcessThrowsOnIterableTypeWhenScalarPassed() { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Invalid definition for service "bar_call": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setIterable()" accepts "iterable", "int" passed.'); - $container = new ContainerBuilder(); $container->register('bar_call', BarMethodCall::class) ->addMethodCall('setIterable', [2]); - (new CheckTypeDeclarationsPass(true))->process($container); + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid definition for service "bar_call": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\BarMethodCall::setIterable()" accepts "iterable", "int" passed.'); - $this->assertInstanceOf(\stdClass::class, $container->get('bar')->foo); + (new CheckTypeDeclarationsPass(true))->process($container); } public function testProcessResolveExpressions() diff --git a/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTestCase.php b/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTestCase.php index 09c8584431856..d9ca3ef109401 100644 --- a/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTestCase.php +++ b/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTestCase.php @@ -68,7 +68,7 @@ public function getNormalizedIniPostMaxSize(): string $this->request = null; } - public static function methodExceptGetProvider() + public static function methodExceptGetProvider(): array { return [ ['POST'], @@ -78,7 +78,7 @@ public static function methodExceptGetProvider() ]; } - public static function methodProvider() + public static function methodProvider(): array { return array_merge([ ['GET'], diff --git a/src/Symfony/Component/Form/Tests/CompoundFormTest.php b/src/Symfony/Component/Form/Tests/CompoundFormTest.php index b23dab0c48801..4b504a3c74d6b 100644 --- a/src/Symfony/Component/Form/Tests/CompoundFormTest.php +++ b/src/Symfony/Component/Form/Tests/CompoundFormTest.php @@ -574,7 +574,7 @@ public function testSubmitMapsSubmittedChildrenOntoEmptyData() $this->assertSame('Bernhard', $object['name']); } - public static function requestMethodProvider() + public static function requestMethodProvider(): array { return [ ['POST'], diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php index 5253058527516..a34a1f403343f 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php @@ -36,7 +36,7 @@ protected function tearDown(): void $this->transformerWithNull = null; } - public static function transformProvider() + public static function transformProvider(): array { return [ // more extensive test set can be found in FormUtilTest diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateIntervalToStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateIntervalToStringTransformerTest.php index 81e1885aa57fb..1a978737f982e 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateIntervalToStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateIntervalToStringTransformerTest.php @@ -20,9 +20,9 @@ */ class DateIntervalToStringTransformerTest extends DateIntervalTestCase { - public static function dataProviderISO() + public static function dataProviderISO(): array { - $data = [ + return [ ['P%YY%MM%DDT%HH%IM%SS', 'P00Y00M00DT00H00M00S', 'PT0S'], ['P%yY%mM%dDT%hH%iM%sS', 'P0Y0M0DT0H0M0S', 'PT0S'], ['P%yY%mM%dDT%hH%iM%sS', 'P10Y2M3DT16H5M6S', 'P10Y2M3DT16H5M6S'], @@ -30,13 +30,11 @@ public static function dataProviderISO() ['P%yY%mM%dDT%hH', 'P10Y2M3DT16H', 'P10Y2M3DT16H'], ['P%yY%mM%dD', 'P10Y2M3D', 'P10Y2M3DT0H'], ]; - - return $data; } - public static function dataProviderDate() + public static function dataProviderDate(): array { - $data = [ + return [ [ '%y years %m months %d days %h hours %i minutes %s seconds', '10 years 2 months 3 days 16 hours 5 minutes 6 seconds', @@ -52,8 +50,6 @@ public static function dataProviderDate() ['%y years %m months', '10 years 2 months', 'P10Y2M'], ['%y year', '1 year', 'P1Y'], ]; - - return $data; } /** diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php index 800120ae98daa..04f8e74a4a750 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php @@ -30,7 +30,7 @@ public function testTransform(\DateTime $expectedOutput, \DateTimeImmutable $inp $this->assertEquals($expectedOutput->getTimezone(), $actualOutput->getTimezone()); } - public static function provider() + public static function provider(): array { return [ [ diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformerTest.php index 8dffb13e2f927..06f04150c6014 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToHtml5LocalDateTimeTransformerTest.php @@ -20,7 +20,7 @@ class DateTimeToHtml5LocalDateTimeTransformerTest extends BaseDateTimeTransforme { use DateTimeEqualsTrait; - public static function transformProvider() + public static function transformProvider(): array { return [ ['UTC', 'UTC', '2010-02-03 04:05:06 UTC', '2010-02-03T04:05:06'], @@ -32,7 +32,7 @@ public static function transformProvider() ]; } - public static function reverseTransformProvider() + public static function reverseTransformProvider(): array { return [ // format without seconds, as appears in some browsers diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php index 18005e0ed5559..1e9534fc70a7a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php @@ -37,7 +37,7 @@ protected function tearDown(): void $this->dateTimeWithoutSeconds = null; } - public static function allProvider() + public static function allProvider(): array { return [ ['UTC', 'UTC', '2010-02-03 04:05:06 UTC', '2010-02-03T04:05:06Z'], diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php index 34fbd9571cfce..6afa4c35d8248 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php @@ -95,7 +95,7 @@ public function testReverseTransform() $this->assertEquals(2, $transformer->reverseTransform('200')); } - public static function reverseTransformWithRoundingProvider() + public static function reverseTransformWithRoundingProvider(): array { return [ // towards positive infinity (1.6 -> 2, -1.6 -> -1) diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php index 2cb20e1cbb6c5..4682c40e39276 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php @@ -166,7 +166,7 @@ function ($value) { $this->assertEquals($checked, $view->vars['checked']); } - public static function provideCustomModelTransformerData() + public static function provideCustomModelTransformerData(): array { return [ ['checked', true], @@ -186,7 +186,7 @@ public function testCustomFalseValues($falseValue) $this->assertFalse($form->getData()); } - public static function provideCustomFalseValues() + public static function provideCustomFalseValues(): array { return [ [''], diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ColorTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ColorTypeTest.php index dbbc1579ff521..52382cea20648 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ColorTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ColorTypeTest.php @@ -33,7 +33,7 @@ public function testValidationShouldPass(bool $html5, ?string $submittedValue) $this->assertEmpty($form->getErrors()); } - public static function validationShouldPassProvider() + public static function validationShouldPassProvider(): array { return [ [false, 'foo'], @@ -71,7 +71,7 @@ public function testValidationShouldFail(string $expectedValueParameterValue, ?s $this->assertEquals([$expectedFormError], iterator_to_array($form->getErrors())); } - public static function validationShouldFailProvider() + public static function validationShouldFailProvider(): array { return [ ['foo', 'foo'], diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateIntervalTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateIntervalTypeTest.php index cabb5ea5f5f35..58e242234d70e 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateIntervalTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateIntervalTypeTest.php @@ -440,7 +440,7 @@ public function testSubmitNullUsesDateEmptyData($widget, $emptyData, $expectedDa $this->assertEquals($expectedData, $form->getData()); } - public static function provideEmptyData() + public static function provideEmptyData(): array { $expectedData = new \DateInterval('P6Y4M'); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php index 246864bdfde0d..122ff44b5d4d8 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php @@ -58,7 +58,7 @@ public function testChoiceLoaderIsOverridden($type) $this->assertSame('lazy_b', $choices[1]->value); } - public static function provideTestedTypes() + public static function provideTestedTypes(): iterable { yield [CountryTypeTest::TESTED_TYPE]; yield [CurrencyTypeTest::TESTED_TYPE]; diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php index e39a96c25f5d7..b7f3332c1edf9 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php @@ -183,7 +183,7 @@ public function testSubmitNonArrayValueWhenMultiple(RequestHandlerInterface $req $this->assertSame([], $form->getViewData()); } - public static function requestHandlerProvider() + public static function requestHandlerProvider(): array { return [ [new HttpFoundationRequestHandler()], diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php index 7e565c7c9fcef..e14a816362945 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php @@ -32,7 +32,7 @@ public function testSubmitNullReturnsNullWithEmptyDataAsString() $this->assertSame('', $form->getViewData()); } - public static function provideZeros() + public static function provideZeros(): array { return [ [0, '0'], diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/WeekTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/WeekTypeTest.php index b093513b75f4c..a69b96a38ad88 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/WeekTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/WeekTypeTest.php @@ -313,7 +313,7 @@ public function testSubmitNullUsesDateEmptyDataString($widget, $emptyData, $expe $this->assertSame($expectedData, $form->getData()); } - public static function provideEmptyData() + public static function provideEmptyData(): array { return [ 'Compound text field' => ['text', ['year' => '2019', 'week' => '1'], ['year' => 2019, 'week' => 1]], diff --git a/src/Symfony/Component/Form/Tests/FormErrorIteratorTest.php b/src/Symfony/Component/Form/Tests/FormErrorIteratorTest.php index 10f8766c52037..8e9ecac51b712 100644 --- a/src/Symfony/Component/Form/Tests/FormErrorIteratorTest.php +++ b/src/Symfony/Component/Form/Tests/FormErrorIteratorTest.php @@ -55,7 +55,7 @@ public function testFindByCodes($code, $violationsCount) $this->assertCount($violationsCount, $specificFormErrors); } - public static function findByCodesProvider() + public static function findByCodesProvider(): array { return [ ['code1', 2], diff --git a/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php b/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php index ca943fed53a0b..4d4aa5f30b228 100644 --- a/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php +++ b/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php @@ -192,7 +192,7 @@ public function testBlockPrefixDefaultsToFQCNIfNoName($typeClass, $blockPrefix) $this->assertSame($blockPrefix, $resolvedType->getBlockPrefix()); } - public static function provideTypeClassBlockPrefixTuples() + public static function provideTypeClassBlockPrefixTuples(): array { return [ [Fixtures\FooType::class, 'foo'], diff --git a/src/Symfony/Component/Form/Tests/SimpleFormTest.php b/src/Symfony/Component/Form/Tests/SimpleFormTest.php index 0f9556b1a572e..624d0a4fe817a 100644 --- a/src/Symfony/Component/Form/Tests/SimpleFormTest.php +++ b/src/Symfony/Component/Form/Tests/SimpleFormTest.php @@ -86,7 +86,7 @@ public function testGetPropertyPath($name, $propertyPath) $this->assertEquals($propertyPath, $form->getPropertyPath()); } - public static function provideFormNames() + public static function provideFormNames(): iterable { yield [null, null]; yield ['', null]; diff --git a/src/Symfony/Component/Form/Tests/Util/StringUtilTest.php b/src/Symfony/Component/Form/Tests/Util/StringUtilTest.php index 353e3c9667285..8199d6843ed8a 100644 --- a/src/Symfony/Component/Form/Tests/Util/StringUtilTest.php +++ b/src/Symfony/Component/Form/Tests/Util/StringUtilTest.php @@ -16,7 +16,7 @@ class StringUtilTest extends TestCase { - public static function trimProvider() + public static function trimProvider(): array { return [ [' Foo! ', 'Foo!'], @@ -49,7 +49,7 @@ public function testTrimUtf8Separators($hex) $this->assertSame("ab\ncd", StringUtil::trim($symbol)); } - public static function spaceProvider() + public static function spaceProvider(): array { return [ // separators @@ -97,7 +97,7 @@ public function testFqcnToBlockPrefix($fqcn, $expectedBlockPrefix) $this->assertSame($expectedBlockPrefix, $blockPrefix); } - public static function fqcnToBlockPrefixProvider() + public static function fqcnToBlockPrefixProvider(): array { return [ ['TYPE', 'type'], diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DateIntervalNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DateIntervalNormalizerTest.php index 94e94a62bce13..fe59e098bdbf5 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/DateIntervalNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DateIntervalNormalizerTest.php @@ -31,9 +31,9 @@ protected function setUp(): void $this->normalizer = new DateIntervalNormalizer(); } - public static function dataProviderISO() + public static function dataProviderISO(): array { - $data = [ + return [ ['P%YY%MM%DDT%HH%IM%SS', 'P00Y00M00DT00H00M00S', 'PT0S'], ['P%yY%mM%dDT%hH%iM%sS', 'P0Y0M0DT0H0M0S', 'PT0S'], ['P%yY%mM%dDT%hH%iM%sS', 'P10Y2M3DT16H5M6S', 'P10Y2M3DT16H5M6S'], @@ -46,8 +46,6 @@ public static function dataProviderISO() ['%rP%yY%mM%dD', '-P10Y2M3D', '-P10Y2M3DT0H'], ['%rP%yY%mM%dD', 'P10Y2M3D', 'P10Y2M3DT0H'], ]; - - return $data; } public function testSupportsNormalization() diff --git a/src/Symfony/Component/Uid/Tests/Command/GenerateUuidCommandTest.php b/src/Symfony/Component/Uid/Tests/Command/GenerateUuidCommandTest.php index a0ee281c243b6..cbe4429ff0d42 100644 --- a/src/Symfony/Component/Uid/Tests/Command/GenerateUuidCommandTest.php +++ b/src/Symfony/Component/Uid/Tests/Command/GenerateUuidCommandTest.php @@ -132,7 +132,7 @@ public function testInvalidCombinationOfBasedOptions(array $input) $this->assertStringContainsString('Only one of "--time-based", "--name-based" or "--random-based"', $commandTester->getDisplay()); } - public static function provideInvalidCombinationOfBasedOptions() + public static function provideInvalidCombinationOfBasedOptions(): array { return [ [['--time-based' => 'now', '--name-based' => 'foo']], @@ -153,7 +153,7 @@ public function testExtraNodeOption(array $input) $this->assertStringContainsString('Option "--node" can only be used with "--time-based"', $commandTester->getDisplay()); } - public static function provideExtraNodeOption() + public static function provideExtraNodeOption(): array { return [ [['--node' => 'foo']], @@ -173,7 +173,7 @@ public function testExtraNamespaceOption(array $input) $this->assertStringContainsString('Option "--namespace" can only be used with "--name-based"', $commandTester->getDisplay()); } - public static function provideExtraNamespaceOption() + public static function provideExtraNamespaceOption(): array { return [ [['--namespace' => 'foo']], diff --git a/src/Symfony/Component/Uid/Tests/UlidTest.php b/src/Symfony/Component/Uid/Tests/UlidTest.php index 27f06645fccb2..192669c621366 100644 --- a/src/Symfony/Component/Uid/Tests/UlidTest.php +++ b/src/Symfony/Component/Uid/Tests/UlidTest.php @@ -149,7 +149,7 @@ public function testFromBinaryInvalidFormat(string $ulid) Ulid::fromBinary($ulid); } - public static function provideInvalidBinaryFormat() + public static function provideInvalidBinaryFormat(): array { return [ ['01EW2RYKDCT2SAK454KBR2QG08'], @@ -176,7 +176,7 @@ public function testFromBase58InvalidFormat(string $ulid) Ulid::fromBase58($ulid); } - public static function provideInvalidBase58Format() + public static function provideInvalidBase58Format(): array { return [ ["\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08"], @@ -203,7 +203,7 @@ public function testFromBase32InvalidFormat(string $ulid) Ulid::fromBase32($ulid); } - public static function provideInvalidBase32Format() + public static function provideInvalidBase32Format(): array { return [ ["\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08"], @@ -230,7 +230,7 @@ public function testFromRfc4122InvalidFormat(string $ulid) Ulid::fromRfc4122($ulid); } - public static function provideInvalidRfc4122Format() + public static function provideInvalidRfc4122Format(): array { return [ ["\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08"], diff --git a/src/Symfony/Component/Uid/Tests/UuidTest.php b/src/Symfony/Component/Uid/Tests/UuidTest.php index dbf5ea03c1375..1affd73af47f2 100644 --- a/src/Symfony/Component/Uid/Tests/UuidTest.php +++ b/src/Symfony/Component/Uid/Tests/UuidTest.php @@ -206,7 +206,7 @@ public function testEqualsAgainstOtherType($other) $this->assertFalse((new UuidV4(self::A_UUID_V4))->equals($other)); } - public static function provideInvalidEqualType() + public static function provideInvalidEqualType(): iterable { yield [null]; yield [self::A_UUID_V1]; @@ -268,7 +268,7 @@ public function testFromBinaryInvalidFormat(string $ulid) Uuid::fromBinary($ulid); } - public static function provideInvalidBinaryFormat() + public static function provideInvalidBinaryFormat(): array { return [ ['01EW2RYKDCT2SAK454KBR2QG08'], @@ -295,7 +295,7 @@ public function testFromBase58InvalidFormat(string $ulid) Uuid::fromBase58($ulid); } - public static function provideInvalidBase58Format() + public static function provideInvalidBase58Format(): array { return [ ["\x41\x4C\x08\x92\x57\x1B\x11\xEB\xBF\x70\x93\xF9\xB0\x82\x2C\x57"], @@ -322,7 +322,7 @@ public function testFromBase32InvalidFormat(string $ulid) Uuid::fromBase32($ulid); } - public static function provideInvalidBase32Format() + public static function provideInvalidBase32Format(): array { return [ ["\x5B\xA8\x32\x72\x45\x6D\x5A\xC0\xAB\xE3\xAA\x8B\xF7\x01\x96\x73"], @@ -349,7 +349,7 @@ public function testFromRfc4122InvalidFormat(string $ulid) Uuid::fromRfc4122($ulid); } - public static function provideInvalidRfc4122Format() + public static function provideInvalidRfc4122Format(): array { return [ ["\x1E\xB5\x71\xB4\x14\xC0\x68\x93\xBF\x70\x2D\x4C\x83\xCF\x75\x5A"], From f3179876ac4d56a400c80784947bb2fc6674abb9 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Tue, 31 Oct 2023 10:19:53 +0100 Subject: [PATCH 09/33] [Tests] Add `array` return type for provider methods --- .../DataTransformer/DateTimeToRfc3339TransformerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php index 1e9534fc70a7a..11be7d4e7cee5 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php @@ -49,12 +49,12 @@ public static function allProvider(): array ]; } - public static function transformProvider() + public static function transformProvider(): array { return self::allProvider(); } - public static function reverseTransformProvider() + public static function reverseTransformProvider(): array { return array_merge(self::allProvider(), [ // format without seconds, as appears in some browsers @@ -132,7 +132,7 @@ public function testReverseTransformExpectsValidDateString($date) $transformer->reverseTransform($date); } - public static function invalidDateStringProvider() + public static function invalidDateStringProvider(): array { return [ 'invalid month' => ['2010-2010-01'], From 869361711469a2b0a5b20af6d6c0997fbcafddba Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 31 Oct 2023 13:59:09 +0100 Subject: [PATCH 10/33] [Form] Clean up in tests --- .../Core/DataTransformer/ChoiceToValueTransformerTest.php | 6 ------ .../DataTransformer/DateTimeToRfc3339TransformerTest.php | 6 ------ 2 files changed, 12 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php index a34a1f403343f..a7a3d1c845e7f 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php @@ -30,12 +30,6 @@ protected function setUp(): void $this->transformerWithNull = new ChoiceToValueTransformer($listWithNull); } - protected function tearDown(): void - { - $this->transformer = null; - $this->transformerWithNull = null; - } - public static function transformProvider(): array { return [ diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php index 1e9534fc70a7a..268f4d988b8be 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php @@ -31,12 +31,6 @@ protected function setUp(): void $this->dateTimeWithoutSeconds = new \DateTime('2010-02-03 04:05:00 UTC'); } - protected function tearDown(): void - { - $this->dateTime = null; - $this->dateTimeWithoutSeconds = null; - } - public static function allProvider(): array { return [ From d86ec214a45f5c602293d6bf11efc7c058ab2ca2 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 31 Oct 2023 10:30:28 +0100 Subject: [PATCH 11/33] do not install FrameworkBundle 6.4 --- src/Symfony/Bundle/WebProfilerBundle/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index 3f67bb6ff5675..f4cac4eafe5c7 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=7.2.5", "symfony/config": "^4.4|^5.0|^6.0", - "symfony/framework-bundle": "^5.3|^6.0", + "symfony/framework-bundle": "^5.3|^6.0,<6.4", "symfony/http-kernel": "^5.3|^6.0", "symfony/polyfill-php80": "^1.16", "symfony/routing": "^4.4|^5.0|^6.0", From 1a58df87cae70791865b73f2c03d15265eb60a51 Mon Sep 17 00:00:00 2001 From: NickSdot Date: Mon, 21 Aug 2023 22:05:22 +0800 Subject: [PATCH 12/33] Fix block scalar array parsing --- src/Symfony/Component/Yaml/Parser.php | 7 +++- .../Component/Yaml/Tests/ParserTest.php | 38 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index d8886bb1860b3..e4bacd7856c7e 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -199,9 +199,8 @@ private function doParse(string $value, int $flags) || self::preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P.+?))?\s*$#u', $this->trimTag($values['value']), $matches) ) ) { - // this is a compact notation element, add to next block and parse $block = $values['value']; - if ($this->isNextLineIndented()) { + if ($this->isNextLineIndented() || isset($matches['value']) && '>-' === $matches['value']) { $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + \strlen($values['leadspaces']) + 1); } @@ -949,6 +948,10 @@ private function isNextLineIndented(): bool } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment())); if ($EOF) { + for ($i = 0; $i < $movements; ++$i) { + $this->moveToPreviousLine(); + } + return false; } diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 98e5e73ec53e7..741a6ad83c99e 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -2690,6 +2690,44 @@ public static function circularReferenceProvider() return $tests; } + public function testBlockScalarArray() + { + $yaml = <<<'YAML' +anyOf: + - $ref: >- + #/string/bar +anyOfMultiline: + - $ref: >- + #/string/bar + second line +nested: + anyOf: + - $ref: >- + #/string/bar +YAML; + $expected = [ + 'anyOf' => [ + 0 => [ + '$ref' => '#/string/bar', + ], + ], + 'anyOfMultiline' => [ + 0 => [ + '$ref' => '#/string/bar second line', + ], + ], + 'nested' => [ + 'anyOf' => [ + 0 => [ + '$ref' => '#/string/bar', + ], + ], + ], + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + /** * @dataProvider indentedMappingData */ From 6ffb25ca5fc877f4550129f2a311549e72f59dc9 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 2 Nov 2023 09:45:35 +0100 Subject: [PATCH 13/33] remove invalid group --- .../Component/Form/Tests/Resources/TranslationFilesTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php index 1093fc4d4c527..f732ba9e00ccb 100644 --- a/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php +++ b/src/Symfony/Component/Form/Tests/Resources/TranslationFilesTest.php @@ -31,8 +31,6 @@ public function testTranslationFileIsValid($filePath) /** * @dataProvider provideTranslationFiles - * - * @group Legacy */ public function testTranslationFileIsValidWithoutEntityLoader($filePath) { From fdaefc4e8580f1dafb7b5487e7957ea4af2e42d8 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 2 Nov 2023 11:18:11 +0100 Subject: [PATCH 14/33] [PasswordHasher][Tests] Do not invoke methods with additional arguments in tests --- .../Tests/Hasher/NativePasswordHasherTest.php | 32 +++++++------- .../Hasher/PasswordHasherFactoryTest.php | 20 ++++----- .../Tests/Hasher/SodiumPasswordHasherTest.php | 44 +++++++++---------- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/Symfony/Component/PasswordHasher/Tests/Hasher/NativePasswordHasherTest.php b/src/Symfony/Component/PasswordHasher/Tests/Hasher/NativePasswordHasherTest.php index 2b7bd7855a9b7..5dc301916eed3 100644 --- a/src/Symfony/Component/PasswordHasher/Tests/Hasher/NativePasswordHasherTest.php +++ b/src/Symfony/Component/PasswordHasher/Tests/Hasher/NativePasswordHasherTest.php @@ -51,25 +51,25 @@ public function testValidation() { $hasher = new NativePasswordHasher(); $result = $hasher->hash('password', null); - $this->assertTrue($hasher->verify($result, 'password', null)); - $this->assertFalse($hasher->verify($result, 'anotherPassword', null)); - $this->assertFalse($hasher->verify($result, '', null)); + $this->assertTrue($hasher->verify($result, 'password')); + $this->assertFalse($hasher->verify($result, 'anotherPassword')); + $this->assertFalse($hasher->verify($result, '')); } public function testNonArgonValidation() { $hasher = new NativePasswordHasher(); - $this->assertTrue($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'password', null)); - $this->assertFalse($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'anotherPassword', null)); - $this->assertTrue($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'password', null)); - $this->assertFalse($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'anotherPassword', null)); + $this->assertTrue($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'password')); + $this->assertFalse($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'anotherPassword')); + $this->assertTrue($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'password')); + $this->assertFalse($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'anotherPassword')); } public function testConfiguredAlgorithm() { $hasher = new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT); - $result = $hasher->hash('password', null); - $this->assertTrue($hasher->verify($result, 'password', null)); + $result = $hasher->hash('password'); + $this->assertTrue($hasher->verify($result, 'password')); $this->assertStringStartsWith('$2', $result); } @@ -84,8 +84,8 @@ public function testDefaultAlgorithm() public function testConfiguredAlgorithmWithLegacyConstValue() { $hasher = new NativePasswordHasher(null, null, null, '1'); - $result = $hasher->hash('password', null); - $this->assertTrue($hasher->verify($result, 'password', null)); + $result = $hasher->hash('password'); + $this->assertTrue($hasher->verify($result, 'password')); $this->assertStringStartsWith('$2', $result); } @@ -94,8 +94,8 @@ public function testBcryptWithLongPassword() $hasher = new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT); $plainPassword = str_repeat('a', 100); - $this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword, 'salt')); - $this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword, 'salt')); + $this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword)); + $this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword)); } public function testBcryptWithNulByte() @@ -103,8 +103,8 @@ public function testBcryptWithNulByte() $hasher = new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT); $plainPassword = "a\0b"; - $this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword, 'salt')); - $this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword, 'salt')); + $this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword)); + $this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword)); } public function testNeedsRehash() @@ -113,7 +113,7 @@ public function testNeedsRehash() $this->assertTrue($hasher->needsRehash('dummyhash')); - $hash = $hasher->hash('foo', 'salt'); + $hash = $hasher->hash('foo'); $this->assertFalse($hasher->needsRehash($hash)); $hasher = new NativePasswordHasher(5, 11000, 5); diff --git a/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php b/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php index 1b97eedcdac48..5c91460d3050b 100644 --- a/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php +++ b/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php @@ -110,7 +110,7 @@ public function testGetNamedHasherForHasherAware() 'hasher_name' => new MessageDigestPasswordHasher('sha1'), ]); - $hasher = $factory->getPasswordHasher(new HasherAwareUser('user', 'pass')); + $hasher = $factory->getPasswordHasher(new HasherAwareUser()); $expectedHasher = new MessageDigestPasswordHasher('sha1'); $this->assertEquals($expectedHasher->hash('foo', ''), $hasher->hash('foo', '')); } @@ -122,7 +122,7 @@ public function testGetNullNamedHasherForHasherAware() 'hasher_name' => new MessageDigestPasswordHasher('sha256'), ]); - $user = new HasherAwareUser('mathilde', 'krogulec'); + $user = new HasherAwareUser(); $user->hasherName = null; $hasher = $factory->getPasswordHasher($user); $expectedHasher = new MessageDigestPasswordHasher('sha1'); @@ -137,7 +137,7 @@ public function testGetInvalidNamedHasherForHasherAware() 'hasher_name' => new MessageDigestPasswordHasher('sha256'), ]); - $user = new HasherAwareUser('user', 'pass'); + $user = new HasherAwareUser(); $user->hasherName = 'invalid_hasher_name'; $factory->getPasswordHasher($user); } @@ -168,9 +168,9 @@ public function testMigrateFrom() $hasher = $factory->getPasswordHasher(SomeUser::class); $this->assertInstanceOf(MigratingPasswordHasher::class, $hasher); - $this->assertTrue($hasher->verify((new SodiumPasswordHasher())->hash('foo', null), 'foo', null)); - $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT))->hash('foo', null), 'foo', null)); - $this->assertTrue($hasher->verify($digest->hash('foo', null), 'foo', null)); + $this->assertTrue($hasher->verify((new SodiumPasswordHasher())->hash('foo'), 'foo', null)); + $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT))->hash('foo'), 'foo', null)); + $this->assertTrue($hasher->verify($digest->hash('foo'), 'foo', null)); $this->assertStringStartsWith(\SODIUM_CRYPTO_PWHASH_STRPREFIX, $hasher->hash('foo', null)); } @@ -190,8 +190,8 @@ public function testMigrateFromWithCustomInstance() $hasher = $factory->getPasswordHasher(SomeUser::class); $this->assertInstanceOf(MigratingPasswordHasher::class, $hasher); - $this->assertTrue($hasher->verify((new SodiumPasswordHasher())->hash('foo', null), 'foo', null)); - $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT))->hash('foo', null), 'foo', null)); + $this->assertTrue($hasher->verify((new SodiumPasswordHasher())->hash('foo'), 'foo', null)); + $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT))->hash('foo'), 'foo', null)); $this->assertTrue($hasher->verify($digest->hash('foo', null), 'foo', null)); $this->assertStringStartsWith(\SODIUM_CRYPTO_PWHASH_STRPREFIX, $hasher->hash('foo', null)); } @@ -213,8 +213,8 @@ public function testMigrateFromLegacy() $hasher = $factory->getPasswordHasher(SomeUser::class); $this->assertInstanceOf(MigratingPasswordHasher::class, $hasher); - $this->assertTrue($hasher->verify((new SodiumPasswordHasher())->hash('foo', null), 'foo', null)); - $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT))->hash('foo', null), 'foo', null)); + $this->assertTrue($hasher->verify((new SodiumPasswordHasher())->hash('foo'), 'foo', null)); + $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, null, \PASSWORD_BCRYPT))->hash('foo'), 'foo', null)); $this->assertTrue($hasher->verify($plaintext->encodePassword('foo', null), 'foo', null)); $this->assertStringStartsWith(\SODIUM_CRYPTO_PWHASH_STRPREFIX, $hasher->hash('foo', null)); } diff --git a/src/Symfony/Component/PasswordHasher/Tests/Hasher/SodiumPasswordHasherTest.php b/src/Symfony/Component/PasswordHasher/Tests/Hasher/SodiumPasswordHasherTest.php index 67210dea726f7..3dc97c768f6f1 100644 --- a/src/Symfony/Component/PasswordHasher/Tests/Hasher/SodiumPasswordHasherTest.php +++ b/src/Symfony/Component/PasswordHasher/Tests/Hasher/SodiumPasswordHasherTest.php @@ -28,65 +28,65 @@ protected function setUp(): void public function testValidation() { $hasher = new SodiumPasswordHasher(); - $result = $hasher->hash('password', null); - $this->assertTrue($hasher->verify($result, 'password', null)); - $this->assertFalse($hasher->verify($result, 'anotherPassword', null)); - $this->assertFalse($hasher->verify($result, '', null)); + $result = $hasher->hash('password'); + $this->assertTrue($hasher->verify($result, 'password')); + $this->assertFalse($hasher->verify($result, 'anotherPassword')); + $this->assertFalse($hasher->verify($result, '')); } public function testBcryptValidation() { $hasher = new SodiumPasswordHasher(); - $this->assertTrue($hasher->verify('$2y$04$M8GDODMoGQLQRpkYCdoJh.lbiZPee3SZI32RcYK49XYTolDGwoRMm', 'abc', null)); + $this->assertTrue($hasher->verify('$2y$04$M8GDODMoGQLQRpkYCdoJh.lbiZPee3SZI32RcYK49XYTolDGwoRMm', 'abc')); } public function testNonArgonValidation() { $hasher = new SodiumPasswordHasher(); - $this->assertTrue($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'password', null)); - $this->assertFalse($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'anotherPassword', null)); - $this->assertTrue($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'password', null)); - $this->assertFalse($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'anotherPassword', null)); + $this->assertTrue($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'password')); + $this->assertFalse($hasher->verify('$5$abcdefgh$ZLdkj8mkc2XVSrPVjskDAgZPGjtj1VGVaa1aUkrMTU/', 'anotherPassword')); + $this->assertTrue($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'password')); + $this->assertFalse($hasher->verify('$6$abcdefgh$yVfUwsw5T.JApa8POvClA1pQ5peiq97DUNyXCZN5IrF.BMSkiaLQ5kvpuEm/VQ1Tvh/KV2TcaWh8qinoW5dhA1', 'anotherPassword')); } public function testHashLength() { $this->expectException(InvalidPasswordException::class); $hasher = new SodiumPasswordHasher(); - $hasher->hash(str_repeat('a', 4097), 'salt'); + $hasher->hash(str_repeat('a', 4097)); } public function testCheckPasswordLength() { $hasher = new SodiumPasswordHasher(); - $result = $hasher->hash(str_repeat('a', 4096), null); - $this->assertFalse($hasher->verify($result, str_repeat('a', 4097), null)); - $this->assertTrue($hasher->verify($result, str_repeat('a', 4096), null)); + $result = $hasher->hash(str_repeat('a', 4096)); + $this->assertFalse($hasher->verify($result, str_repeat('a', 4097))); + $this->assertTrue($hasher->verify($result, str_repeat('a', 4096))); } public function testBcryptWithLongPassword() { - $hasher = new SodiumPasswordHasher(null, null, 4); + $hasher = new SodiumPasswordHasher(null, null); $plainPassword = str_repeat('a', 100); - $this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword, 'salt')); - $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword, 'salt')); + $this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword)); + $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword)); } public function testBcryptWithNulByte() { - $hasher = new SodiumPasswordHasher(null, null, 4); + $hasher = new SodiumPasswordHasher(null, null); $plainPassword = "a\0b"; - $this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword, 'salt')); - $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword, 'salt')); + $this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' => 4]), $plainPassword)); + $this->assertTrue($hasher->verify((new NativePasswordHasher(null, null, 4, \PASSWORD_BCRYPT))->hash($plainPassword), $plainPassword)); } public function testUserProvidedSaltIsNotUsed() { $hasher = new SodiumPasswordHasher(); - $result = $hasher->hash('password', 'salt'); - $this->assertTrue($hasher->verify($result, 'password', 'anotherSalt')); + $result = $hasher->hash('password'); + $this->assertTrue($hasher->verify($result, 'password')); } public function testNeedsRehash() @@ -95,7 +95,7 @@ public function testNeedsRehash() $this->assertTrue($hasher->needsRehash('dummyhash')); - $hash = $hasher->hash('foo', 'salt'); + $hash = $hasher->hash('foo'); $this->assertFalse($hasher->needsRehash($hash)); $hasher = new SodiumPasswordHasher(5, 11000); From e4be02af376109b3aaa9f672445d69f95b5651c0 Mon Sep 17 00:00:00 2001 From: Dominik Ulrich Date: Thu, 2 Nov 2023 15:45:40 +0100 Subject: [PATCH 15/33] [HttpKernel] Preventing error 500 when function putenv is disabled --- src/Symfony/Component/HttpKernel/Kernel.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 9fc6b36fc52bc..c31a4b7ca33f2 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -778,7 +778,9 @@ private function preBoot(): ContainerInterface $this->startTime = microtime(true); } if ($this->debug && !isset($_ENV['SHELL_VERBOSITY']) && !isset($_SERVER['SHELL_VERBOSITY'])) { - putenv('SHELL_VERBOSITY=3'); + if (\function_exists('putenv')) { + putenv('SHELL_VERBOSITY=3'); + } $_ENV['SHELL_VERBOSITY'] = 3; $_SERVER['SHELL_VERBOSITY'] = 3; } From ce3e282c0e2ba6e1d1daae08ef22396f27a8623d Mon Sep 17 00:00:00 2001 From: Michel Roca Date: Fri, 3 Nov 2023 15:33:45 +0100 Subject: [PATCH 16/33] [Yaml] Fix uid binary parsing --- src/Symfony/Component/Yaml/Inline.php | 2 +- src/Symfony/Component/Yaml/Tests/InlineTest.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index 5b5f96131af98..712add900a5d0 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -531,7 +531,7 @@ private static function parseMapping(string $mapping, int $flags, int &$i = 0, a if ('<<' === $key) { $output += $value; } elseif ($allowOverwrite || !isset($output[$key])) { - if (!$isValueQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) { + if (!$isValueQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && !self::isBinaryString($value) && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) { $references[$matches['ref']] = $matches['value']; $value = $matches['value']; } diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index 07d4e04d4375f..d6e02fad0d4a0 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -368,6 +368,9 @@ public static function getTestsForParse() ['[foo, bar: { foo: bar }]', ['foo', '1' => ['bar' => ['foo' => 'bar']]]], ['[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', ['foo', '@foo.baz', ['%foo%' => 'foo is %foo%', 'bar' => '%foo%'], true, '@service_container']], + + // Binary string not utf8-compliant but starting with and utf8-equivalent "&" character + ['{ uid: !!binary Ju0Yh+uqSXOagJZFTlUt8g== }', ['uid' => hex2bin('26ed1887ebaa49739a8096454e552df2')]], ]; } From dc356499d5ceb86f7cf2b4c7f032eca97061ed74 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 3 Nov 2023 17:09:59 +0100 Subject: [PATCH 17/33] [Security] Fix possible session fixation when only the *token* changes --- .../EventListener/SessionStrategyListener.php | 2 +- .../SessionStrategyListenerTest.php | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php b/src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php index 311a52ffd98bd..c6fcba88e3dcd 100644 --- a/src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php +++ b/src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php @@ -48,7 +48,7 @@ public function onSuccessfulLogin(LoginSuccessEvent $event): void $user = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(); $previousUser = method_exists($previousToken, 'getUserIdentifier') ? $previousToken->getUserIdentifier() : $previousToken->getUsername(); - if ('' !== ($user ?? '') && $user === $previousUser) { + if ('' !== ($user ?? '') && $user === $previousUser && \get_class($token) === \get_class($previousToken)) { return; } } diff --git a/src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php b/src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php index 51b8dc1878ed3..29ef9b68c1824 100644 --- a/src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Security\Core\Authentication\Token\NullToken; +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\User\InMemoryUser; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; @@ -81,6 +82,26 @@ public function testRequestWithSamePreviousUser() $this->listener->onSuccessfulLogin($event); } + public function testRequestWithSamePreviousUserButDifferentTokenType() + { + $this->configurePreviousSession(); + + $token = $this->createMock(NullToken::class); + $token->expects($this->once()) + ->method('getUserIdentifier') + ->willReturn('test'); + $previousToken = $this->createMock(UsernamePasswordToken::class); + $previousToken->expects($this->once()) + ->method('getUserIdentifier') + ->willReturn('test'); + + $this->sessionAuthenticationStrategy->expects($this->once())->method('onAuthentication')->with($this->request, $token); + + $event = new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), new SelfValidatingPassport(new UserBadge('test', function () {})), $token, $this->request, null, 'main_firewall', $previousToken); + + $this->listener->onSuccessfulLogin($event); + } + private function createEvent($firewallName) { return new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), new SelfValidatingPassport(new UserBadge('test', function ($username) { return new InMemoryUser($username, null); })), $this->token, $this->request, null, $firewallName); From 14e2f67676c8e27814399f8a28831e4e56a6f841 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 23 Jan 2023 14:36:51 +0100 Subject: [PATCH 18/33] Remove full DSNs from exception messages --- .../Cache/Adapter/AbstractAdapter.php | 2 +- .../Cache/Adapter/CouchbaseBucketAdapter.php | 2 +- .../Adapter/CouchbaseCollectionAdapter.php | 2 +- .../Cache/Adapter/DoctrineDbalAdapter.php | 2 +- .../Cache/Adapter/MemcachedAdapter.php | 8 ++--- .../Component/Cache/Traits/RedisTrait.php | 36 +++++++++---------- .../Storage/Handler/SessionHandlerFactory.php | 4 +-- .../Store/DoctrineDbalPostgreSqlStore.php | 4 +-- .../Lock/Store/DoctrineDbalStore.php | 2 +- .../Component/Lock/Store/StoreFactory.php | 2 +- .../Component/Lock/Store/ZookeeperStore.php | 4 +-- .../Mailer/Tests/Transport/DsnTest.php | 6 ++-- .../Component/Mailer/Tests/TransportTest.php | 6 ++-- src/Symfony/Component/Mailer/Transport.php | 2 +- .../Component/Mailer/Transport/Dsn.php | 6 ++-- .../Tests/Transport/ConnectionTest.php | 2 +- .../Bridge/AmazonSqs/Transport/Connection.php | 2 +- .../Amqp/Tests/Transport/ConnectionTest.php | 2 +- .../Bridge/Amqp/Transport/Connection.php | 2 +- .../Tests/Transport/ConnectionTest.php | 2 +- .../Beanstalkd/Transport/Connection.php | 2 +- .../DoctrineTransportFactoryTest.php | 2 +- .../Bridge/Doctrine/Transport/Connection.php | 2 +- .../Transport/DoctrineTransportFactory.php | 2 +- .../Redis/Tests/Transport/ConnectionTest.php | 2 +- .../Bridge/Redis/Transport/Connection.php | 6 ++-- .../Messenger/Transport/TransportFactory.php | 2 +- .../MicrosoftTeamsTransportFactory.php | 2 +- .../Bridge/OvhCloud/OvhCloudTransport.php | 4 +-- .../Tests/OvhCloudTransportFactoryTest.php | 19 ++++++++-- .../OvhCloud/Tests/OvhCloudTransportTest.php | 5 +-- .../Telegram/TelegramTransportFactory.php | 4 +-- .../Notifier/Tests/Transport/DsnTest.php | 6 ++-- .../Transport/AbstractTransportFactory.php | 2 +- .../Component/Notifier/Transport/Dsn.php | 6 ++-- .../Semaphore/Store/StoreFactory.php | 2 +- .../Provider/AbstractProviderFactory.php | 2 +- .../Component/Translation/Provider/Dsn.php | 6 ++-- .../Translation/Tests/Provider/DsnTest.php | 6 ++-- 39 files changed, 98 insertions(+), 82 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index 3d01409227fa7..df900555bb515 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -140,7 +140,7 @@ public static function createConnection(string $dsn, array $options = []) return CouchbaseCollectionAdapter::createConnection($dsn, $options); } - throw new InvalidArgumentException(sprintf('Unsupported DSN: "%s".', $dsn)); + throw new InvalidArgumentException('Unsupported DSN: it does not start with "redis[s]:", "memcached:" nor "couchbase:".'); } /** diff --git a/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php b/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php index 36d5249b4addc..fa5f85ad24558 100644 --- a/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/CouchbaseBucketAdapter.php @@ -83,7 +83,7 @@ public static function createConnection($servers, array $options = []): \Couchba foreach ($servers as $dsn) { if (0 !== strpos($dsn, 'couchbase:')) { - throw new InvalidArgumentException(sprintf('Invalid Couchbase DSN: "%s" does not start with "couchbase:".', $dsn)); + throw new InvalidArgumentException('Invalid Couchbase DSN: it does not start with "couchbase:".'); } preg_match($dsnPattern, $dsn, $matches); diff --git a/src/Symfony/Component/Cache/Adapter/CouchbaseCollectionAdapter.php b/src/Symfony/Component/Cache/Adapter/CouchbaseCollectionAdapter.php index 79f648531c230..1c4f9180b0ac6 100644 --- a/src/Symfony/Component/Cache/Adapter/CouchbaseCollectionAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/CouchbaseCollectionAdapter.php @@ -79,7 +79,7 @@ public static function createConnection($dsn, array $options = []) foreach ($dsn as $server) { if (0 !== strpos($server, 'couchbase:')) { - throw new InvalidArgumentException(sprintf('Invalid Couchbase DSN: "%s" does not start with "couchbase:".', $server)); + throw new InvalidArgumentException('Invalid Couchbase DSN: it does not start with "couchbase:".'); } preg_match($dsnPattern, $server, $matches); diff --git a/src/Symfony/Component/Cache/Adapter/DoctrineDbalAdapter.php b/src/Symfony/Component/Cache/Adapter/DoctrineDbalAdapter.php index 2650869e3f8cc..eacf8eb9bcc88 100644 --- a/src/Symfony/Component/Cache/Adapter/DoctrineDbalAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/DoctrineDbalAdapter.php @@ -70,7 +70,7 @@ public function __construct($connOrDsn, string $namespace = '', int $defaultLife $this->conn = $connOrDsn; } elseif (\is_string($connOrDsn)) { if (!class_exists(DriverManager::class)) { - throw new InvalidArgumentException(sprintf('Failed to parse the DSN "%s". Try running "composer require doctrine/dbal".', $connOrDsn)); + throw new InvalidArgumentException('Failed to parse DSN. Try running "composer require doctrine/dbal".'); } if (class_exists(DsnParser::class)) { $params = (new DsnParser([ diff --git a/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php b/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php index 5eb36b80c78fc..2f953aa79b62e 100644 --- a/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php @@ -109,7 +109,7 @@ public static function createConnection($servers, array $options = []) continue; } if (!str_starts_with($dsn, 'memcached:')) { - throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s" does not start with "memcached:".', $dsn)); + throw new InvalidArgumentException('Invalid Memcached DSN: it does not start with "memcached:".'); } $params = preg_replace_callback('#^memcached:(//)?(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) { if (!empty($m[2])) { @@ -119,7 +119,7 @@ public static function createConnection($servers, array $options = []) return 'file:'.($m[1] ?? ''); }, $dsn); if (false === $params = parse_url($params)) { - throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn)); + throw new InvalidArgumentException('Invalid Memcached DSN.'); } $query = $hosts = []; if (isset($params['query'])) { @@ -127,7 +127,7 @@ public static function createConnection($servers, array $options = []) if (isset($query['host'])) { if (!\is_array($hosts = $query['host'])) { - throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn)); + throw new InvalidArgumentException('Invalid Memcached DSN: query parameter "host" must be an array.'); } foreach ($hosts as $host => $weight) { if (false === $port = strrpos($host, ':')) { @@ -146,7 +146,7 @@ public static function createConnection($servers, array $options = []) } } if (!isset($params['host']) && !isset($params['path'])) { - throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn)); + throw new InvalidArgumentException('Invalid Memcached DSN: missing host or path.'); } if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) { $params['weight'] = $m[1]; diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php index 287c0ea962121..eb97957320f65 100644 --- a/src/Symfony/Component/Cache/Traits/RedisTrait.php +++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php @@ -96,11 +96,11 @@ public static function createConnection(string $dsn, array $options = []) } elseif (str_starts_with($dsn, 'rediss:')) { $scheme = 'rediss'; } else { - throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s" does not start with "redis:" or "rediss".', $dsn)); + throw new InvalidArgumentException('Invalid Redis DSN: it does not start with "redis[s]:".'); } if (!\extension_loaded('redis') && !class_exists(\Predis\Client::class)) { - throw new CacheException(sprintf('Cannot find the "redis" extension nor the "predis/predis" package: "%s".', $dsn)); + throw new CacheException('Cannot find the "redis" extension nor the "predis/predis" package.'); } $params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) { @@ -116,7 +116,7 @@ public static function createConnection(string $dsn, array $options = []) }, $dsn); if (false === $params = parse_url($params)) { - throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn)); + throw new InvalidArgumentException('Invalid Redis DSN.'); } $query = $hosts = []; @@ -129,7 +129,7 @@ public static function createConnection(string $dsn, array $options = []) if (isset($query['host'])) { if (!\is_array($hosts = $query['host'])) { - throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn)); + throw new InvalidArgumentException('Invalid Redis DSN: query parameter "host" must be an array.'); } foreach ($hosts as $host => $parameters) { if (\is_string($parameters)) { @@ -153,7 +153,7 @@ public static function createConnection(string $dsn, array $options = []) $params['dbindex'] = $m[1] ?? '0'; $params['path'] = substr($params['path'], 0, -\strlen($m[0])); } elseif (isset($params['host'])) { - throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s", the "dbindex" parameter must be a number.', $dsn)); + throw new InvalidArgumentException('Invalid Redis DSN: query parameter "dbindex" must be a number.'); } } @@ -165,13 +165,13 @@ public static function createConnection(string $dsn, array $options = []) } if (!$hosts) { - throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn)); + throw new InvalidArgumentException('Invalid Redis DSN: missing host.'); } $params += $query + $options + self::$defaultConnectionOptions; if (isset($params['redis_sentinel']) && !class_exists(\Predis\Client::class) && !class_exists(\RedisSentinel::class)) { - throw new CacheException(sprintf('Redis Sentinel support requires the "predis/predis" package or the "redis" extension v5.2 or higher: "%s".', $dsn)); + throw new CacheException('Redis Sentinel support requires the "predis/predis" package or the "redis" extension v5.2 or higher.'); } if (isset($params['lazy'])) { @@ -180,7 +180,7 @@ public static function createConnection(string $dsn, array $options = []) $params['redis_cluster'] = filter_var($params['redis_cluster'], \FILTER_VALIDATE_BOOLEAN); if ($params['redis_cluster'] && isset($params['redis_sentinel'])) { - throw new InvalidArgumentException(sprintf('Cannot use both "redis_cluster" and "redis_sentinel" at the same time: "%s".', $dsn)); + throw new InvalidArgumentException('Cannot use both "redis_cluster" and "redis_sentinel" at the same time.'); } if (null === $params['class'] && \extension_loaded('redis')) { @@ -189,7 +189,7 @@ public static function createConnection(string $dsn, array $options = []) $class = $params['class'] ?? \Predis\Client::class; if (isset($params['redis_sentinel']) && !is_a($class, \Predis\Client::class, true) && !class_exists(\RedisSentinel::class)) { - throw new CacheException(sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and ext-redis >= 5.2 not found: "%s".', $class, $dsn)); + throw new CacheException(sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and ext-redis >= 5.2 not found.', $class)); } } @@ -197,7 +197,7 @@ public static function createConnection(string $dsn, array $options = []) $connect = $params['persistent'] || $params['persistent_id'] ? 'pconnect' : 'connect'; $redis = new $class(); - $initializer = static function ($redis) use ($connect, $params, $dsn, $auth, $hosts, $tls) { + $initializer = static function ($redis) use ($connect, $params, $auth, $hosts, $tls) { $hostIndex = 0; do { $host = $hosts[$hostIndex]['host'] ?? $hosts[$hostIndex]['path']; @@ -243,7 +243,7 @@ public static function createConnection(string $dsn, array $options = []) } while (++$hostIndex < \count($hosts) && !$address); if (isset($params['redis_sentinel']) && !$address) { - throw new InvalidArgumentException(sprintf('Failed to retrieve master information from sentinel "%s" and dsn "%s".', $params['redis_sentinel'], $dsn)); + throw new InvalidArgumentException(sprintf('Failed to retrieve master information from sentinel "%s".', $params['redis_sentinel'])); } try { @@ -262,22 +262,22 @@ public static function createConnection(string $dsn, array $options = []) restore_error_handler(); } if (!$isConnected) { - $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error ?? '', $error) ? sprintf(' (%s)', $error[1]) : ''; - throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$error.'.'); + $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error ?? $redis->getLastError() ?? '', $error) ? sprintf(' (%s)', $error[1]) : ''; + throw new InvalidArgumentException('Redis connection failed: '.$error.'.'); } if ((null !== $auth && !$redis->auth($auth)) || ($params['dbindex'] && !$redis->select($params['dbindex'])) ) { $e = preg_replace('/^ERR /', '', $redis->getLastError()); - throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e.'.'); + throw new InvalidArgumentException('Redis connection failed: '.$e.'.'); } if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) { $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']); } } catch (\RedisException $e) { - throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e->getMessage()); + throw new InvalidArgumentException('Redis connection failed: '.$e->getMessage()); } return true; @@ -302,14 +302,14 @@ public static function createConnection(string $dsn, array $options = []) try { $redis = new $class($hosts, $params); } catch (\RedisClusterException $e) { - throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e->getMessage()); + throw new InvalidArgumentException('Redis connection failed: '.$e->getMessage()); } if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) { $redis->setOption(\Redis::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']); } } elseif (is_a($class, \RedisCluster::class, true)) { - $initializer = static function () use ($class, $params, $dsn, $hosts) { + $initializer = static function () use ($class, $params, $hosts) { foreach ($hosts as $i => $host) { switch ($host['scheme']) { case 'tcp': $hosts[$i] = $host['host'].':'.$host['port']; break; @@ -321,7 +321,7 @@ public static function createConnection(string $dsn, array $options = []) try { $redis = new $class(null, $hosts, $params['timeout'], $params['read_timeout'], (bool) $params['persistent'], $params['auth'] ?? '', ...\defined('Redis::SCAN_PREFIX') ? [$params['ssl'] ?? null] : []); } catch (\RedisClusterException $e) { - throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e->getMessage()); + throw new InvalidArgumentException('Redis connection failed: '.$e->getMessage()); } if (0 < $params['tcp_keepalive'] && \defined('Redis::OPT_TCP_KEEPALIVE')) { diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php index 39dc30c6f6c50..14454d0b80b47 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/SessionHandlerFactory.php @@ -63,7 +63,7 @@ public static function createHandler($connection): AbstractSessionHandler case str_starts_with($connection, 'rediss:'): case str_starts_with($connection, 'memcached:'): if (!class_exists(AbstractAdapter::class)) { - throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection)); + throw new \InvalidArgumentException('Unsupported Redis or Memcached DSN. Try running "composer require symfony/cache".'); } $handlerClass = str_starts_with($connection, 'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class; $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]); @@ -72,7 +72,7 @@ public static function createHandler($connection): AbstractSessionHandler case str_starts_with($connection, 'pdo_oci://'): if (!class_exists(DriverManager::class)) { - throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require doctrine/dbal".', $connection)); + throw new \InvalidArgumentException('Unsupported PDO OCI DSN. Try running "composer require doctrine/dbal".'); } $connection[3] = '-'; $params = class_exists(DsnParser::class) ? (new DsnParser())->parse($connection) : ['url' => $connection]; diff --git a/src/Symfony/Component/Lock/Store/DoctrineDbalPostgreSqlStore.php b/src/Symfony/Component/Lock/Store/DoctrineDbalPostgreSqlStore.php index 0c3660a906d3d..9419b4ef35d5b 100644 --- a/src/Symfony/Component/Lock/Store/DoctrineDbalPostgreSqlStore.php +++ b/src/Symfony/Component/Lock/Store/DoctrineDbalPostgreSqlStore.php @@ -52,7 +52,7 @@ public function __construct($connOrUrl) $this->conn = $connOrUrl; } elseif (\is_string($connOrUrl)) { if (!class_exists(DriverManager::class)) { - throw new InvalidArgumentException(sprintf('Failed to parse the DSN "%s". Try running "composer require doctrine/dbal".', $connOrUrl)); + throw new InvalidArgumentException('Failed to parse DSN. Try running "composer require doctrine/dbal".'); } if (class_exists(DsnParser::class)) { $params = (new DsnParser([ @@ -274,7 +274,7 @@ private function unlockShared(Key $key): void private function filterDsn(string $dsn): string { if (!str_contains($dsn, '://')) { - throw new InvalidArgumentException(sprintf('String "%s" is not a valid DSN for Doctrine DBAL.', $dsn)); + throw new InvalidArgumentException('DSN is invalid for Doctrine DBAL.'); } [$scheme, $rest] = explode(':', $dsn, 2); diff --git a/src/Symfony/Component/Lock/Store/DoctrineDbalStore.php b/src/Symfony/Component/Lock/Store/DoctrineDbalStore.php index 7874f465b8274..0d60b8a3f4f74 100644 --- a/src/Symfony/Component/Lock/Store/DoctrineDbalStore.php +++ b/src/Symfony/Component/Lock/Store/DoctrineDbalStore.php @@ -69,7 +69,7 @@ public function __construct($connOrUrl, array $options = [], float $gcProbabilit $this->conn = $connOrUrl; } elseif (\is_string($connOrUrl)) { if (!class_exists(DriverManager::class)) { - throw new InvalidArgumentException(sprintf('Failed to parse the DSN "%s". Try running "composer require doctrine/dbal".', $connOrUrl)); + throw new InvalidArgumentException('Failed to parse the DSN. Try running "composer require doctrine/dbal".'); } if (class_exists(DsnParser::class)) { $params = (new DsnParser([ diff --git a/src/Symfony/Component/Lock/Store/StoreFactory.php b/src/Symfony/Component/Lock/Store/StoreFactory.php index 847928ef8c113..02ed47f8d70ca 100644 --- a/src/Symfony/Component/Lock/Store/StoreFactory.php +++ b/src/Symfony/Component/Lock/Store/StoreFactory.php @@ -75,7 +75,7 @@ public static function createStore($connection) case str_starts_with($connection, 'rediss:'): case str_starts_with($connection, 'memcached:'): if (!class_exists(AbstractAdapter::class)) { - throw new InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection)); + throw new InvalidArgumentException('Unsupported Redis or Memcached DSN. Try running "composer require symfony/cache".'); } $storeClass = str_starts_with($connection, 'memcached:') ? MemcachedStore::class : RedisStore::class; $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]); diff --git a/src/Symfony/Component/Lock/Store/ZookeeperStore.php b/src/Symfony/Component/Lock/Store/ZookeeperStore.php index d1f3de971b0f8..eef4846e7a216 100644 --- a/src/Symfony/Component/Lock/Store/ZookeeperStore.php +++ b/src/Symfony/Component/Lock/Store/ZookeeperStore.php @@ -37,11 +37,11 @@ public function __construct(\Zookeeper $zookeeper) public static function createConnection(string $dsn): \Zookeeper { if (!str_starts_with($dsn, 'zookeeper:')) { - throw new InvalidArgumentException(sprintf('Unsupported DSN: "%s".', $dsn)); + throw new InvalidArgumentException('Unsupported DSN for Zookeeper.'); } if (false === $params = parse_url($dsn)) { - throw new InvalidArgumentException(sprintf('Invalid Zookeeper DSN: "%s".', $dsn)); + throw new InvalidArgumentException('Invalid Zookeeper DSN.'); } $host = $params['host'] ?? ''; diff --git a/src/Symfony/Component/Mailer/Tests/Transport/DsnTest.php b/src/Symfony/Component/Mailer/Tests/Transport/DsnTest.php index f3c0a0bc7f804..f0c0a8ffe0fed 100644 --- a/src/Symfony/Component/Mailer/Tests/Transport/DsnTest.php +++ b/src/Symfony/Component/Mailer/Tests/Transport/DsnTest.php @@ -92,17 +92,17 @@ public static function invalidDsnProvider(): iterable { yield [ 'some://', - 'The "some://" mailer DSN is invalid.', + 'The mailer DSN is invalid.', ]; yield [ '//sendmail', - 'The "//sendmail" mailer DSN must contain a scheme.', + 'The mailer DSN must contain a scheme.', ]; yield [ 'file:///some/path', - 'The "file:///some/path" mailer DSN must contain a host (use "default" by default).', + 'The mailer DSN must contain a host (use "default" by default).', ]; } } diff --git a/src/Symfony/Component/Mailer/Tests/TransportTest.php b/src/Symfony/Component/Mailer/Tests/TransportTest.php index 3ffd706cfaea0..50e0f7440dffe 100644 --- a/src/Symfony/Component/Mailer/Tests/TransportTest.php +++ b/src/Symfony/Component/Mailer/Tests/TransportTest.php @@ -90,11 +90,11 @@ public function testFromWrongString(string $dsn, string $error) public static function fromWrongStringProvider(): iterable { - yield 'garbage at the end' => ['dummy://a some garbage here', 'The DSN has some garbage at the end: " some garbage here".']; + yield 'garbage at the end' => ['dummy://a some garbage here', 'The mailer DSN has some garbage at the end.']; - yield 'not a valid DSN' => ['something not a dsn', 'The "something" mailer DSN must contain a scheme.']; + yield 'not a valid DSN' => ['something not a dsn', 'The mailer DSN must contain a scheme.']; - yield 'failover not closed' => ['failover(dummy://a', 'The "(dummy://a" mailer DSN must contain a scheme.']; + yield 'failover not closed' => ['failover(dummy://a', 'The mailer DSN must contain a scheme.']; yield 'not a valid keyword' => ['foobar(dummy://a)', 'The "foobar" keyword is not valid (valid ones are "failover", "roundrobin")']; } diff --git a/src/Symfony/Component/Mailer/Transport.php b/src/Symfony/Component/Mailer/Transport.php index c2b813f947771..ab7b67e4669a0 100644 --- a/src/Symfony/Component/Mailer/Transport.php +++ b/src/Symfony/Component/Mailer/Transport.php @@ -112,7 +112,7 @@ public function fromString(string $dsn): TransportInterface { [$transport, $offset] = $this->parseDsn($dsn); if ($offset !== \strlen($dsn)) { - throw new InvalidArgumentException(sprintf('The DSN has some garbage at the end: "%s".', substr($dsn, $offset))); + throw new InvalidArgumentException('The mailer DSN has some garbage at the end.'); } return $transport; diff --git a/src/Symfony/Component/Mailer/Transport/Dsn.php b/src/Symfony/Component/Mailer/Transport/Dsn.php index 04d3540f7b002..cef6041ef4c20 100644 --- a/src/Symfony/Component/Mailer/Transport/Dsn.php +++ b/src/Symfony/Component/Mailer/Transport/Dsn.php @@ -38,15 +38,15 @@ public function __construct(string $scheme, string $host, string $user = null, s public static function fromString(string $dsn): self { if (false === $parsedDsn = parse_url($dsn)) { - throw new InvalidArgumentException(sprintf('The "%s" mailer DSN is invalid.', $dsn)); + throw new InvalidArgumentException('The mailer DSN is invalid.'); } if (!isset($parsedDsn['scheme'])) { - throw new InvalidArgumentException(sprintf('The "%s" mailer DSN must contain a scheme.', $dsn)); + throw new InvalidArgumentException('The mailer DSN must contain a scheme.'); } if (!isset($parsedDsn['host'])) { - throw new InvalidArgumentException(sprintf('The "%s" mailer DSN must contain a host (use "default" by default).', $dsn)); + throw new InvalidArgumentException('The mailer DSN must contain a host (use "default" by default).'); } $user = '' !== ($parsedDsn['user'] ?? '') ? urldecode($parsedDsn['user']) : null; diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/ConnectionTest.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/ConnectionTest.php index 6297435ee1ef3..2abdb5d3b3e67 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/ConnectionTest.php @@ -59,7 +59,7 @@ public function testConfigureWithCredentials() public function testFromInvalidDsn() { $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('The given Amazon SQS DSN "sqs://" is invalid.'); + $this->expectExceptionMessage('The given Amazon SQS DSN is invalid.'); Connection::fromDsn('sqs://'); } diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php index 20aef2cc0b421..3588ab323a5db 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php @@ -104,7 +104,7 @@ public function __destruct() public static function fromDsn(string $dsn, array $options = [], HttpClientInterface $client = null, LoggerInterface $logger = null): self { if (false === $parsedUrl = parse_url($dsn)) { - throw new InvalidArgumentException(sprintf('The given Amazon SQS DSN "%s" is invalid.', $dsn)); + throw new InvalidArgumentException('The given Amazon SQS DSN is invalid.'); } $query = []; diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/ConnectionTest.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/ConnectionTest.php index 1b39dc7d1a445..32abfd58438be 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/ConnectionTest.php @@ -33,7 +33,7 @@ class ConnectionTest extends TestCase public function testItCannotBeConstructedWithAWrongDsn() { $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('The given AMQP DSN "amqp://:" is invalid.'); + $this->expectExceptionMessage('The given AMQP DSN is invalid.'); Connection::fromDsn('amqp://:'); } diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php index 166031b3aea90..0357575e3edfb 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php @@ -180,7 +180,7 @@ public static function fromDsn(string $dsn, array $options = [], AmqpFactory $am if (false === $parsedUrl = parse_url($dsn)) { // this is a valid URI that parse_url cannot handle when you want to pass all parameters as options if (!\in_array($dsn, ['amqp://', 'amqps://'])) { - throw new InvalidArgumentException(sprintf('The given AMQP DSN "%s" is invalid.', $dsn)); + throw new InvalidArgumentException('The given AMQP DSN is invalid.'); } $parsedUrl = []; diff --git a/src/Symfony/Component/Messenger/Bridge/Beanstalkd/Tests/Transport/ConnectionTest.php b/src/Symfony/Component/Messenger/Bridge/Beanstalkd/Tests/Transport/ConnectionTest.php index 4c135cd879a4d..06ef855c83a5c 100644 --- a/src/Symfony/Component/Messenger/Bridge/Beanstalkd/Tests/Transport/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Bridge/Beanstalkd/Tests/Transport/ConnectionTest.php @@ -30,7 +30,7 @@ final class ConnectionTest extends TestCase public function testFromInvalidDsn() { $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('The given Beanstalkd DSN "beanstalkd://" is invalid.'); + $this->expectExceptionMessage('The given Beanstalkd DSN is invalid.'); Connection::fromDsn('beanstalkd://'); } diff --git a/src/Symfony/Component/Messenger/Bridge/Beanstalkd/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Beanstalkd/Transport/Connection.php index a8aaeae34264e..7ce26eec29f87 100644 --- a/src/Symfony/Component/Messenger/Bridge/Beanstalkd/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Beanstalkd/Transport/Connection.php @@ -59,7 +59,7 @@ public function __construct(array $configuration, PheanstalkInterface $client) public static function fromDsn(string $dsn, array $options = []): self { if (false === $components = parse_url($dsn)) { - throw new InvalidArgumentException(sprintf('The given Beanstalkd DSN "%s" is invalid.', $dsn)); + throw new InvalidArgumentException('The given Beanstalkd DSN is invalid.'); } $connectionCredentials = [ diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/DoctrineTransportFactoryTest.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/DoctrineTransportFactoryTest.php index 6e108baa449be..a4ad6d50a15df 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/DoctrineTransportFactoryTest.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/DoctrineTransportFactoryTest.php @@ -98,7 +98,7 @@ public function testCreateTransportNotifyWithPostgreSQLPlatform() public function testCreateTransportMustThrowAnExceptionIfManagerIsNotFound() { $this->expectException(TransportException::class); - $this->expectExceptionMessage('Could not find Doctrine connection from Messenger DSN "doctrine://default".'); + $this->expectExceptionMessage('Could not find Doctrine connection from Messenger DSN.'); $registry = $this->createMock(ConnectionRegistry::class); $registry->expects($this->once()) ->method('getConnection') diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php index df8dafdb2f4b5..b3981e8a63461 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php @@ -87,7 +87,7 @@ public function getConfiguration(): array public static function buildConfiguration(string $dsn, array $options = []): array { if (false === $components = parse_url($dsn)) { - throw new InvalidArgumentException(sprintf('The given Doctrine Messenger DSN "%s" is invalid.', $dsn)); + throw new InvalidArgumentException('The given Doctrine Messenger DSN is invalid.'); } $query = []; diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransportFactory.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransportFactory.php index f634e5548168f..4ddb85882970c 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransportFactory.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransportFactory.php @@ -45,7 +45,7 @@ public function createTransport(string $dsn, array $options, SerializerInterface try { $driverConnection = $this->registry->getConnection($configuration['connection']); } catch (\InvalidArgumentException $e) { - throw new TransportException(sprintf('Could not find Doctrine connection from Messenger DSN "%s".', $dsn), 0, $e); + throw new TransportException('Could not find Doctrine connection from Messenger DSN.', 0, $e); } if ($useNotify && $driverConnection->getDatabasePlatform() instanceof PostgreSQLPlatform) { diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php b/src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php index fb98baf70b610..71ccea4c1752e 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php @@ -26,7 +26,7 @@ class ConnectionTest extends TestCase public function testFromInvalidDsn() { $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('The given Redis DSN "redis://" is invalid.'); + $this->expectExceptionMessage('The given Redis DSN is invalid.'); Connection::fromDsn('redis://'); } diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php index c8050658fc5a1..321b0001ac5f2 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php @@ -162,9 +162,9 @@ public static function fromDsn(string $dsn, array $redisOptions = [], $redis = n $parsedUrl = array_merge(...$parsedUrls); // Regroup all the hosts in an array interpretable by RedisCluster - $parsedUrl['host'] = array_map(function ($parsedUrl, $dsn) { + $parsedUrl['host'] = array_map(function ($parsedUrl) { if (!isset($parsedUrl['host'])) { - throw new InvalidArgumentException(sprintf('Missing host in DSN part "%s", it must be defined when using Redis Cluster.', $dsn)); + throw new InvalidArgumentException('Missing host in DSN, it must be defined when using Redis Cluster.'); } return $parsedUrl['host'].':'.($parsedUrl['port'] ?? 6379); @@ -276,7 +276,7 @@ private static function parseDsn(string $dsn, array &$redisOptions): array } if (false === $parsedUrl = parse_url($url)) { - throw new InvalidArgumentException(sprintf('The given Redis DSN "%s" is invalid.', $dsn)); + throw new InvalidArgumentException('The given Redis DSN is invalid.'); } if (isset($parsedUrl['query'])) { parse_str($parsedUrl['query'], $dsnOptions); diff --git a/src/Symfony/Component/Messenger/Transport/TransportFactory.php b/src/Symfony/Component/Messenger/Transport/TransportFactory.php index 474dd6fe2f006..a6fa16ecc9a8e 100644 --- a/src/Symfony/Component/Messenger/Transport/TransportFactory.php +++ b/src/Symfony/Component/Messenger/Transport/TransportFactory.php @@ -51,7 +51,7 @@ public function createTransport(string $dsn, array $options, SerializerInterface $packageSuggestion = ' Run "composer require symfony/beanstalkd-messenger" to install Beanstalkd transport.'; } - throw new InvalidArgumentException(sprintf('No transport supports the given Messenger DSN "%s".%s.', $dsn, $packageSuggestion)); + throw new InvalidArgumentException('No transport supports the given Messenger DSN.'.$packageSuggestion); } public function supports(string $dsn, array $options): bool diff --git a/src/Symfony/Component/Notifier/Bridge/MicrosoftTeams/MicrosoftTeamsTransportFactory.php b/src/Symfony/Component/Notifier/Bridge/MicrosoftTeams/MicrosoftTeamsTransportFactory.php index 1e4b411e5a23e..39f9361fc5c91 100644 --- a/src/Symfony/Component/Notifier/Bridge/MicrosoftTeams/MicrosoftTeamsTransportFactory.php +++ b/src/Symfony/Component/Notifier/Bridge/MicrosoftTeams/MicrosoftTeamsTransportFactory.php @@ -34,7 +34,7 @@ public function create(Dsn $dsn): TransportInterface $path = $dsn->getPath(); if (null === $path) { - throw new IncompleteDsnException('Path is not set.', $dsn->getOriginalDsn()); + throw new IncompleteDsnException('Path is not set.', 'microsoftteams://'.$dsn->getHost()); } $host = $dsn->getHost(); diff --git a/src/Symfony/Component/Notifier/Bridge/OvhCloud/OvhCloudTransport.php b/src/Symfony/Component/Notifier/Bridge/OvhCloud/OvhCloudTransport.php index 0c07729ed5704..27ef84e992633 100644 --- a/src/Symfony/Component/Notifier/Bridge/OvhCloud/OvhCloudTransport.php +++ b/src/Symfony/Component/Notifier/Bridge/OvhCloud/OvhCloudTransport.php @@ -47,10 +47,10 @@ public function __construct(string $applicationKey, string $applicationSecret, s public function __toString(): string { if (null !== $this->sender) { - return sprintf('ovhcloud://%s?consumer_key=%s&service_name=%s&sender=%s', $this->getEndpoint(), $this->consumerKey, $this->serviceName, $this->sender); + return sprintf('ovhcloud://%s?service_name=%s&sender=%s', $this->getEndpoint(), $this->serviceName, $this->sender); } - return sprintf('ovhcloud://%s?consumer_key=%s&service_name=%s', $this->getEndpoint(), $this->consumerKey, $this->serviceName); + return sprintf('ovhcloud://%s?service_name=%s', $this->getEndpoint(), $this->serviceName); } /** diff --git a/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportFactoryTest.php b/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportFactoryTest.php index 9ea6e40e7decb..89ad537fe2ad6 100644 --- a/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportFactoryTest.php +++ b/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportFactoryTest.php @@ -28,14 +28,29 @@ public function createFactory(): TransportFactoryInterface public static function createProvider(): iterable { yield [ - 'ovhcloud://host.test?consumer_key=consumerKey&service_name=serviceName', + 'ovhcloud://host.test?service_name=serviceName', 'ovhcloud://key:secret@host.test?consumer_key=consumerKey&service_name=serviceName', ]; yield [ - 'ovhcloud://host.test?consumer_key=consumerKey&service_name=serviceName&sender=sender', + 'ovhcloud://host.test?service_name=serviceName&sender=sender', 'ovhcloud://key:secret@host.test?consumer_key=consumerKey&service_name=serviceName&sender=sender', ]; + + yield [ + 'ovhcloud://host.test?service_name=serviceName', + 'ovhcloud://key:secret@host.test?consumer_key=consumerKey&service_name=serviceName&no_stop_clause=0', + ]; + + yield [ + 'ovhcloud://host.test?service_name=serviceName', + 'ovhcloud://key:secret@host.test?consumer_key=consumerKey&service_name=serviceName&no_stop_clause=1', + ]; + + yield [ + 'ovhcloud://host.test?service_name=serviceName', + 'ovhcloud://key:secret@host.test?consumer_key=consumerKey&service_name=serviceName&no_stop_clause=true', + ]; } public static function supportsProvider(): iterable diff --git a/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportTest.php b/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportTest.php index b36cdd0557771..d3b90b43c23d0 100644 --- a/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportTest.php +++ b/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportTest.php @@ -34,8 +34,9 @@ public static function createTransport(HttpClientInterface $client = null, strin public static function toStringProvider(): iterable { - yield ['ovhcloud://eu.api.ovh.com?consumer_key=consumerKey&service_name=serviceName', self::createTransport()]; - yield ['ovhcloud://eu.api.ovh.com?consumer_key=consumerKey&service_name=serviceName&sender=sender', self::createTransport(null, 'sender')]; + yield ['ovhcloud://eu.api.ovh.com?service_name=serviceName', self::createTransport()]; + yield ['ovhcloud://eu.api.ovh.com?service_name=serviceName', self::createTransport(null, null, true)]; + yield ['ovhcloud://eu.api.ovh.com?service_name=serviceName&sender=sender', self::createTransport(null, 'sender')]; } public static function supportedMessagesProvider(): iterable diff --git a/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransportFactory.php b/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransportFactory.php index 490fe1d26e9b7..d7d17a6527caf 100644 --- a/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransportFactory.php +++ b/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransportFactory.php @@ -49,11 +49,11 @@ protected function getSupportedSchemes(): array private function getToken(Dsn $dsn): string { if (null === $dsn->getUser() && null === $dsn->getPassword()) { - throw new IncompleteDsnException('Missing token.', $dsn->getOriginalDsn()); + throw new IncompleteDsnException('Missing token.', 'telegram://'.$dsn->getHost()); } if (null === $dsn->getPassword()) { - throw new IncompleteDsnException('Malformed token.', $dsn->getOriginalDsn()); + throw new IncompleteDsnException('Malformed token.', 'telegram://'.$dsn->getHost()); } return sprintf('%s:%s', $dsn->getUser(), $dsn->getPassword()); diff --git a/src/Symfony/Component/Notifier/Tests/Transport/DsnTest.php b/src/Symfony/Component/Notifier/Tests/Transport/DsnTest.php index 98a898cd50a36..a75f1608d8090 100644 --- a/src/Symfony/Component/Notifier/Tests/Transport/DsnTest.php +++ b/src/Symfony/Component/Notifier/Tests/Transport/DsnTest.php @@ -155,17 +155,17 @@ public static function invalidDsnProvider(): iterable { yield [ 'some://', - 'The "some://" notifier DSN is invalid.', + 'The notifier DSN is invalid.', ]; yield [ '//slack', - 'The "//slack" notifier DSN must contain a scheme.', + 'The notifier DSN must contain a scheme.', ]; yield [ 'file:///some/path', - 'The "file:///some/path" notifier DSN must contain a host (use "default" by default).', + 'The notifier DSN must contain a host (use "default" by default).', ]; } diff --git a/src/Symfony/Component/Notifier/Transport/AbstractTransportFactory.php b/src/Symfony/Component/Notifier/Transport/AbstractTransportFactory.php index d595aa623a723..f983c480e9ee8 100644 --- a/src/Symfony/Component/Notifier/Transport/AbstractTransportFactory.php +++ b/src/Symfony/Component/Notifier/Transport/AbstractTransportFactory.php @@ -46,7 +46,7 @@ protected function getUser(Dsn $dsn): string { $user = $dsn->getUser(); if (null === $user) { - throw new IncompleteDsnException('User is not set.', $dsn->getOriginalDsn()); + throw new IncompleteDsnException('User is not set.', $dsn->getScheme().'://'.$dsn->getHost()); } return $user; diff --git a/src/Symfony/Component/Notifier/Transport/Dsn.php b/src/Symfony/Component/Notifier/Transport/Dsn.php index 16f722356578b..6f4c3577a8c1a 100644 --- a/src/Symfony/Component/Notifier/Transport/Dsn.php +++ b/src/Symfony/Component/Notifier/Transport/Dsn.php @@ -34,16 +34,16 @@ public function __construct(string $dsn) $this->originalDsn = $dsn; if (false === $parsedDsn = parse_url($dsn)) { - throw new InvalidArgumentException(sprintf('The "%s" notifier DSN is invalid.', $dsn)); + throw new InvalidArgumentException('The notifier DSN is invalid.'); } if (!isset($parsedDsn['scheme'])) { - throw new InvalidArgumentException(sprintf('The "%s" notifier DSN must contain a scheme.', $dsn)); + throw new InvalidArgumentException('The notifier DSN must contain a scheme.'); } $this->scheme = $parsedDsn['scheme']; if (!isset($parsedDsn['host'])) { - throw new InvalidArgumentException(sprintf('The "%s" notifier DSN must contain a host (use "default" by default).', $dsn)); + throw new InvalidArgumentException('The notifier DSN must contain a host (use "default" by default).'); } $this->host = $parsedDsn['host']; diff --git a/src/Symfony/Component/Semaphore/Store/StoreFactory.php b/src/Symfony/Component/Semaphore/Store/StoreFactory.php index 4c6304921ff91..f3a02418da680 100644 --- a/src/Symfony/Component/Semaphore/Store/StoreFactory.php +++ b/src/Symfony/Component/Semaphore/Store/StoreFactory.php @@ -48,7 +48,7 @@ public static function createStore($connection): PersistingStoreInterface case 0 === strpos($connection, 'redis://'): case 0 === strpos($connection, 'rediss://'): if (!class_exists(AbstractAdapter::class)) { - throw new InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection)); + throw new InvalidArgumentException('Unsupported Redis DSN. Try running "composer require symfony/cache".'); } $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]); diff --git a/src/Symfony/Component/Translation/Provider/AbstractProviderFactory.php b/src/Symfony/Component/Translation/Provider/AbstractProviderFactory.php index 17442fde873a1..fdfeb8ce38068 100644 --- a/src/Symfony/Component/Translation/Provider/AbstractProviderFactory.php +++ b/src/Symfony/Component/Translation/Provider/AbstractProviderFactory.php @@ -28,7 +28,7 @@ abstract protected function getSupportedSchemes(): array; protected function getUser(Dsn $dsn): string { if (null === $user = $dsn->getUser()) { - throw new IncompleteDsnException('User is not set.', $dsn->getOriginalDsn()); + throw new IncompleteDsnException('User is not set.', $dsn->getScheme().'://'.$dsn->getHost()); } return $user; diff --git a/src/Symfony/Component/Translation/Provider/Dsn.php b/src/Symfony/Component/Translation/Provider/Dsn.php index 820cabfb3a810..792b8dc1dcc8a 100644 --- a/src/Symfony/Component/Translation/Provider/Dsn.php +++ b/src/Symfony/Component/Translation/Provider/Dsn.php @@ -34,16 +34,16 @@ public function __construct(string $dsn) $this->originalDsn = $dsn; if (false === $parsedDsn = parse_url($dsn)) { - throw new InvalidArgumentException(sprintf('The "%s" translation provider DSN is invalid.', $dsn)); + throw new InvalidArgumentException('The translation provider DSN is invalid.'); } if (!isset($parsedDsn['scheme'])) { - throw new InvalidArgumentException(sprintf('The "%s" translation provider DSN must contain a scheme.', $dsn)); + throw new InvalidArgumentException('The translation provider DSN must contain a scheme.'); } $this->scheme = $parsedDsn['scheme']; if (!isset($parsedDsn['host'])) { - throw new InvalidArgumentException(sprintf('The "%s" translation provider DSN must contain a host (use "default" by default).', $dsn)); + throw new InvalidArgumentException('The translation provider DSN must contain a host (use "default" by default).'); } $this->host = $parsedDsn['host']; diff --git a/src/Symfony/Component/Translation/Tests/Provider/DsnTest.php b/src/Symfony/Component/Translation/Tests/Provider/DsnTest.php index 6240e7c4e6e95..54593be96710d 100644 --- a/src/Symfony/Component/Translation/Tests/Provider/DsnTest.php +++ b/src/Symfony/Component/Translation/Tests/Provider/DsnTest.php @@ -155,17 +155,17 @@ public static function invalidDsnProvider(): iterable { yield [ 'some://', - 'The "some://" translation provider DSN is invalid.', + 'The translation provider DSN is invalid.', ]; yield [ '//loco', - 'The "//loco" translation provider DSN must contain a scheme.', + 'The translation provider DSN must contain a scheme.', ]; yield [ 'file:///some/path', - 'The "file:///some/path" translation provider DSN must contain a host (use "default" by default).', + 'The translation provider DSN must contain a host (use "default" by default).', ]; } From 3e0192534081f1bd2f06834cec6b6bf7d9d836b9 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 6 Nov 2023 09:49:13 +0100 Subject: [PATCH 19/33] fix tests --- .../Cache/Tests/Adapter/RedisAdapterSentinelTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php index c05c6f3e7341a..f54460b1f7fdf 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterSentinelTest.php @@ -39,7 +39,7 @@ public static function setUpBeforeClass(): void public function testInvalidDSNHasBothClusterAndSentinel() { $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Cannot use both "redis_cluster" and "redis_sentinel" at the same time:'); + $this->expectExceptionMessage('Cannot use both "redis_cluster" and "redis_sentinel" at the same time.'); $dsn = 'redis:?host[redis1]&host[redis2]&host[redis3]&redis_cluster=1&redis_sentinel=mymaster'; RedisAdapter::createConnection($dsn); } @@ -49,7 +49,7 @@ public function testExceptionMessageWhenFailingToRetrieveMasterInformation() $hosts = getenv('REDIS_SENTINEL_HOSTS'); $dsn = 'redis:?host['.str_replace(' ', ']&host[', $hosts).']'; $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Failed to retrieve master information from sentinel "invalid-masterset-name" and dsn "'.$dsn.'".'); + $this->expectExceptionMessage('Failed to retrieve master information from sentinel "invalid-masterset-name".'); AbstractAdapter::createConnection($dsn, ['redis_sentinel' => 'invalid-masterset-name']); } } From 534c34cb79624b55123f541b8ae30a93406eec1e Mon Sep 17 00:00:00 2001 From: HypeMC Date: Sun, 5 Nov 2023 18:18:30 +0100 Subject: [PATCH 20/33] [Cache][HttpFoundation][Lock] Fix empty username/password for PDO PostgreSQL --- src/Symfony/Component/Cache/Adapter/PdoAdapter.php | 4 ++-- .../Session/Storage/Handler/PdoSessionHandler.php | 8 ++++---- src/Symfony/Component/Lock/Store/PdoStore.php | 6 +++--- src/Symfony/Component/Lock/Store/PostgreSqlStore.php | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/PdoAdapter.php b/src/Symfony/Component/Cache/Adapter/PdoAdapter.php index 34a0c12190700..b339defeb30fd 100644 --- a/src/Symfony/Component/Cache/Adapter/PdoAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PdoAdapter.php @@ -34,8 +34,8 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface private $dataCol = 'item_data'; private $lifetimeCol = 'item_lifetime'; private $timeCol = 'item_time'; - private $username = ''; - private $password = ''; + private $username = null; + private $password = null; private $connectionOptions = []; private $namespace; diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php index cad7e0a7263f4..f9c5d9b59da7f 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php @@ -112,16 +112,16 @@ class PdoSessionHandler extends AbstractSessionHandler /** * Username when lazy-connect. * - * @var string + * @var string|null */ - private $username = ''; + private $username = null; /** * Password when lazy-connect. * - * @var string + * @var string|null */ - private $password = ''; + private $password = null; /** * Connection options when lazy-connect. diff --git a/src/Symfony/Component/Lock/Store/PdoStore.php b/src/Symfony/Component/Lock/Store/PdoStore.php index 79fe680145960..3eeb83b572e9c 100644 --- a/src/Symfony/Component/Lock/Store/PdoStore.php +++ b/src/Symfony/Component/Lock/Store/PdoStore.php @@ -24,7 +24,7 @@ * * Lock metadata are stored in a table. You can use createTable() to initialize * a correctly defined table. - + * * CAUTION: This store relies on all client and server nodes to have * synchronized clocks for lock expiry to occur at the correct time. * To ensure locks don't expire prematurely; the TTLs should be set with enough @@ -40,8 +40,8 @@ class PdoStore implements PersistingStoreInterface private $conn; private $dsn; private $driver; - private $username = ''; - private $password = ''; + private $username = null; + private $password = null; private $connectionOptions = []; private $dbalStore; diff --git a/src/Symfony/Component/Lock/Store/PostgreSqlStore.php b/src/Symfony/Component/Lock/Store/PostgreSqlStore.php index 6c78386da1cff..4332969a82806 100644 --- a/src/Symfony/Component/Lock/Store/PostgreSqlStore.php +++ b/src/Symfony/Component/Lock/Store/PostgreSqlStore.php @@ -29,8 +29,8 @@ class PostgreSqlStore implements BlockingSharedLockStoreInterface, BlockingStore { private $conn; private $dsn; - private $username = ''; - private $password = ''; + private $username = null; + private $password = null; private $connectionOptions = []; private static $storeRegistry = []; From d94a30bb4685d834f52c809fba176e10341b5d4a Mon Sep 17 00:00:00 2001 From: Tomasz Kowalczyk Date: Thu, 2 Nov 2023 17:53:20 +0100 Subject: [PATCH 21/33] [Validator] updated Greek translation --- .../Resources/translations/validators.el.xlf | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf index 768986d537b34..b4a432d87e44c 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf @@ -402,6 +402,30 @@ The value of the netmask should be between {{ min }} and {{ max }}. Η τιμή του netmask πρέπει να είναι ανάμεσα σε {{ min }} και {{ max }}.
+ + The filename is too long. It should have {{ filename_max_length }} character or less.|The filename is too long. It should have {{ filename_max_length }} characters or less. + Το όνομα αρχείου είναι πολύ μεγάλο. Θα πρέπει να έχει έως {{ filename_max_length }} χαρακτήρα.|Το όνομα αρχείου είναι πολύ μεγάλο. Θα πρέπει να έχει έως {{ filename_max_length }} χαρακτήρες. + + + The password strength is too low. Please use a stronger password. + Η ισχύς του κωδικού πρόσβασης είναι πολύ χαμηλή. Χρησιμοποιήστε έναν ισχυρότερο κωδικό πρόσβασης. + + + This value contains characters that are not allowed by the current restriction-level. + Αυτή η τιμή περιέχει χαρακτήρες που δεν επιτρέπονται από το τρέχον επίπεδο περιορισμού. + + + Using invisible characters is not allowed. + Δεν επιτρέπεται η χρήση αόρατων χαρακτήρων. + + + Mixing numbers from different scripts is not allowed. + Δεν επιτρέπεται η μίξη αριθμών από διαφορετικά γραφήματα. + + + Using hidden overlay characters is not allowed. + Δεν επιτρέπεται η χρήση κρυφών χαρακτήρων επικάλυψης. + From a9f0705c1bf8dc3c41fc97262e49424d4d65320d Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 2 Nov 2023 12:02:02 +0100 Subject: [PATCH 22/33] ensure string type with mbstring func overloading enabled --- src/Symfony/Component/HttpFoundation/HeaderUtils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/HeaderUtils.php b/src/Symfony/Component/HttpFoundation/HeaderUtils.php index f91c7e1d97d86..3456edace0dc1 100644 --- a/src/Symfony/Component/HttpFoundation/HeaderUtils.php +++ b/src/Symfony/Component/HttpFoundation/HeaderUtils.php @@ -256,7 +256,7 @@ public static function parseQuery(string $query, bool $ignoreBrackets = false, s private static function groupParts(array $matches, string $separators, bool $first = true): array { $separator = $separators[0]; - $separators = substr($separators, 1); + $separators = substr($separators, 1) ?: ''; $i = 0; if ('' === $separators && !$first) { From fca96ac15e53a9e208215ce7c2ac4971d10ff1cb Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 6 Nov 2023 22:39:41 +0100 Subject: [PATCH 23/33] fix compatibility with Doctrine DBAL 4 --- .../Tests/Transport/ConnectionTest.php | 13 ++++++-- .../Bridge/Doctrine/Transport/Connection.php | 30 ++++++++++++++----- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/ConnectionTest.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/ConnectionTest.php index a85c2fab85736..51f6963a318b3 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/ConnectionTest.php @@ -82,6 +82,9 @@ public function testGetWithNoPendingMessageWillReturnNull() $queryBuilder ->method('getParameterTypes') ->willReturn([]); + $queryBuilder + ->method('getSQL') + ->willReturn('SELECT FOR UPDATE'); $driverConnection->expects($this->once()) ->method('createQueryBuilder') ->willReturn($queryBuilder); @@ -120,7 +123,11 @@ private function getDBALConnectionMock() { $driverConnection = $this->createMock(DBALConnection::class); $platform = $this->createMock(AbstractPlatform::class); - $platform->method('getWriteLockSQL')->willReturn('FOR UPDATE'); + + if (!method_exists(QueryBuilder::class, 'forUpdate')) { + $platform->method('getWriteLockSQL')->willReturn('FOR UPDATE'); + } + $configuration = $this->createMock(\Doctrine\DBAL\Configuration::class); $driverConnection->method('getDatabasePlatform')->willReturn($platform); $driverConnection->method('getConfiguration')->willReturn($configuration); @@ -381,7 +388,9 @@ public function testGeneratedSql(AbstractPlatform $platform, string $expectedSql $driverConnection ->expects($this->once()) ->method('executeQuery') - ->with($expectedSql) + ->with($this->callback(function ($sql) use ($expectedSql) { + return trim($expectedSql) === trim($sql); + })) ->willReturn($result) ; $driverConnection->expects($this->once())->method('commit'); diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php index b3981e8a63461..8b348e708d128 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php @@ -177,7 +177,24 @@ public function get(): ?array // Append pessimistic write lock to FROM clause if db platform supports it $sql = $query->getSQL(); - if (preg_match('/FROM (.+) WHERE/', (string) $sql, $matches)) { + + // Wrap the rownum query in a sub-query to allow writelocks without ORA-02014 error + if ($this->driverConnection->getDatabasePlatform() instanceof OraclePlatform) { + $query = $this->createQueryBuilder('w') + ->where('w.id IN ('.str_replace('SELECT a.* FROM', 'SELECT a.id FROM', $sql).')'); + + if (method_exists(QueryBuilder::class, 'forUpdate')) { + $query->forUpdate(); + } + + $sql = $query->getSQL(); + } elseif (method_exists(QueryBuilder::class, 'forUpdate')) { + $query->forUpdate(); + try { + $sql = $query->getSQL(); + } catch (DBALException $e) { + } + } elseif (preg_match('/FROM (.+) WHERE/', (string) $sql, $matches)) { $fromClause = $matches[1]; $sql = str_replace( sprintf('FROM %s WHERE', $fromClause), @@ -186,16 +203,13 @@ public function get(): ?array ); } - // Wrap the rownum query in a sub-query to allow writelocks without ORA-02014 error - if ($this->driverConnection->getDatabasePlatform() instanceof OraclePlatform) { - $sql = $this->createQueryBuilder('w') - ->where('w.id IN ('.str_replace('SELECT a.* FROM', 'SELECT a.id FROM', $sql).')') - ->getSQL(); + // use SELECT ... FOR UPDATE to lock table + if (!method_exists(QueryBuilder::class, 'forUpdate')) { + $sql .= ' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL(); } - // use SELECT ... FOR UPDATE to lock table $stmt = $this->executeQuery( - $sql.' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL(), + $sql, $query->getParameters(), $query->getParameterTypes() ); From 985434697229c6371368ac96f321022119716264 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 7 Nov 2023 18:20:03 +0100 Subject: [PATCH 24/33] [HttpKernel] Fix PHP deprecation --- .../Component/HttpKernel/DataCollector/LoggerDataCollector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php index 2bbd2a039eab9..7b1896ac2925c 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php @@ -224,7 +224,7 @@ private function getContainerDeprecationLogs(): array private function getContainerCompilerLogs(string $compilerLogsFilepath = null): array { - if (!is_file($compilerLogsFilepath)) { + if (!$compilerLogsFilepath || !is_file($compilerLogsFilepath)) { return []; } From 08a27c28ca5bd657892fbedffd49f6340df028d0 Mon Sep 17 00:00:00 2001 From: Vincent Vermeulen Date: Tue, 7 Nov 2023 23:34:54 +0100 Subject: [PATCH 25/33] [String] Method toByteString conversion using iconv is unreachable --- .../Component/String/AbstractString.php | 5 ++++- .../String/Tests/AbstractAsciiTestCase.php | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/String/AbstractString.php b/src/Symfony/Component/String/AbstractString.php index 13567c7b0f4f3..a0a801e69ab0b 100644 --- a/src/Symfony/Component/String/AbstractString.php +++ b/src/Symfony/Component/String/AbstractString.php @@ -577,8 +577,11 @@ public function toByteString(string $toEncoding = null): ByteString try { try { $b->string = mb_convert_encoding($this->string, $toEncoding, 'UTF-8'); - } catch (InvalidArgumentException $e) { + } catch (InvalidArgumentException|\ValueError $e) { if (!\function_exists('iconv')) { + if ($e instanceof \ValueError) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } throw $e; } diff --git a/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php b/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php index d25fbdee57b6f..5d3127329c459 100644 --- a/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php +++ b/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php @@ -1583,4 +1583,22 @@ public static function provideWidth(): array [17, "\u{007f}\u{007f}f\u{001b}[0moo\u{0001}bar\u{007f}cccïf\u{008e}cy\u{0005}1", false], // f[0moobarcccïfcy1 ]; } + + /** + * @dataProvider provideToByteString + */ + public function testToByteString(string $origin, string $encoding) + { + $instance = static::createFromString($origin)->toByteString($encoding); + $this->assertInstanceOf(ByteString::class, $instance); + } + + public static function provideToByteString(): array + { + return [ + ['žsžsý', 'UTF-8'], + ['žsžsý', 'windows-1250'], + ['žsžsý', 'Windows-1252'], + ]; + } } From 9e8db58d1331e2ac9d737ebf9871e1cab4a5e168 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Wed, 8 Nov 2023 13:49:25 -0500 Subject: [PATCH 26/33] [Config] Prefixing FileExistenceResource::__toString() to avoid conflict with FileResource --- src/Symfony/Component/Config/Resource/FileExistenceResource.php | 2 +- .../Config/Tests/Resource/FileExistenceResourceTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/FileExistenceResource.php b/src/Symfony/Component/Config/Resource/FileExistenceResource.php index 6d79d6d1b48af..1655798eb0943 100644 --- a/src/Symfony/Component/Config/Resource/FileExistenceResource.php +++ b/src/Symfony/Component/Config/Resource/FileExistenceResource.php @@ -38,7 +38,7 @@ public function __construct(string $resource) public function __toString(): string { - return $this->resource; + return 'existence.'.$this->resource; } public function getResource(): string diff --git a/src/Symfony/Component/Config/Tests/Resource/FileExistenceResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileExistenceResourceTest.php index c450ff172c0ad..5a7e5d1d663b3 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileExistenceResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileExistenceResourceTest.php @@ -36,7 +36,7 @@ protected function tearDown(): void public function testToString() { - $this->assertSame($this->file, (string) $this->resource); + $this->assertSame('existence.'.$this->file, (string) $this->resource); } public function testGetResource() From a15eae4081c0af60ba85405f1e10d67352ea4d54 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 9 Nov 2023 10:26:13 +0100 Subject: [PATCH 27/33] wire the secret for Symfony 6.4 compatibility --- .../Security/Factory/LoginThrottlingFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginThrottlingFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginThrottlingFactory.php index 9714fab632acc..de7e3f110929d 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginThrottlingFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginThrottlingFactory.php @@ -89,6 +89,7 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal $container->register($config['limiter'] = 'security.login_throttling.'.$firewallName.'.limiter', DefaultLoginRateLimiter::class) ->addArgument(new Reference('limiter.'.$globalId)) ->addArgument(new Reference('limiter.'.$localId)) + ->addArgument('%kernel.secret%') ; } From 70fd3e7e6ddd1c7bd4ebbdc530a008d624015505 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 9 Nov 2023 10:36:37 +0100 Subject: [PATCH 28/33] do not emit an error if an issue suppression handler was not used --- psalm.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/psalm.xml b/psalm.xml index f34d4dd4281d8..eef4f912449df 100644 --- a/psalm.xml +++ b/psalm.xml @@ -9,6 +9,7 @@ errorBaseline=".github/psalm/psalm.baseline.xml" findUnusedBaselineEntry="false" findUnusedCode="false" + findUnusedIssueHandlerSuppression="false" > From 9da9a145ce57e4585031ad4bee37c497353eec7c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 3 Nov 2023 17:03:49 +0100 Subject: [PATCH 29/33] [TwigBridge] Ensure CodeExtension's filters properly escape their input --- .../Bridge/Twig/Extension/CodeExtension.php | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php index eeea01d84532e..6f50d5a578d07 100644 --- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php @@ -48,8 +48,8 @@ public function __construct($fileLinkFormat, string $projectDir, string $charset public function getFilters() { return [ - new TwigFilter('abbr_class', [$this, 'abbrClass'], ['is_safe' => ['html']]), - new TwigFilter('abbr_method', [$this, 'abbrMethod'], ['is_safe' => ['html']]), + new TwigFilter('abbr_class', [$this, 'abbrClass'], ['is_safe' => ['html'], 'pre_escape' => 'html']), + new TwigFilter('abbr_method', [$this, 'abbrMethod'], ['is_safe' => ['html'], 'pre_escape' => 'html']), new TwigFilter('format_args', [$this, 'formatArgs'], ['is_safe' => ['html']]), new TwigFilter('format_args_as_text', [$this, 'formatArgsAsText']), new TwigFilter('file_excerpt', [$this, 'fileExcerpt'], ['is_safe' => ['html']]), @@ -95,22 +95,23 @@ public function formatArgs($args) $result = []; foreach ($args as $key => $item) { if ('object' === $item[0]) { + $item[1] = htmlspecialchars($item[1], \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset); $parts = explode('\\', $item[1]); $short = array_pop($parts); $formattedValue = sprintf('object(%s)', $item[1], $short); } elseif ('array' === $item[0]) { - $formattedValue = sprintf('array(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); + $formattedValue = sprintf('array(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset)); } elseif ('null' === $item[0]) { $formattedValue = 'null'; } elseif ('boolean' === $item[0]) { - $formattedValue = ''.strtolower(var_export($item[1], true)).''; + $formattedValue = ''.strtolower(htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset)).''; } elseif ('resource' === $item[0]) { $formattedValue = 'resource'; } else { $formattedValue = str_replace("\n", '', htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset)); } - $result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); + $result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", htmlspecialchars($key, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), $formattedValue); } return implode(', ', $result); @@ -178,13 +179,17 @@ public function fileExcerpt($file, $line, $srcContext = 3) public function formatFile($file, $line, $text = null) { $file = trim($file); + $line = (int) $line; if (null === $text) { - $text = $file; - if (null !== $rel = $this->getFileRelative($text)) { - $rel = explode('/', $rel, 2); - $text = sprintf('%s%s', $this->projectDir, $rel[0], '/'.($rel[1] ?? '')); + if (null !== $rel = $this->getFileRelative($file)) { + $rel = explode('/', htmlspecialchars($rel, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), 2); + $text = sprintf('%s%s', htmlspecialchars($this->projectDir, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), $rel[0], '/'.($rel[1] ?? '')); + } else { + $text = htmlspecialchars($file, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset); } + } else { + $text = htmlspecialchars($text, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset); } if (0 < $line) { From ea300f7847842222fe7e2b37cecc1983ff9d3bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Thu, 9 Nov 2023 16:03:53 +0100 Subject: [PATCH 30/33] [TwigBridge] Add integration tests on twig code helpers --- .../Tests/Extension/CodeExtensionTest.php | 140 +++++++++++++++--- 1 file changed, 119 insertions(+), 21 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/CodeExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/CodeExtensionTest.php index 874faeeb99955..fc0891e118810 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/CodeExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/CodeExtensionTest.php @@ -14,6 +14,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Twig\Extension\CodeExtension; use Symfony\Component\HttpKernel\Debug\FileLinkFormatter; +use Twig\Environment; +use Twig\Loader\ArrayLoader; class CodeExtensionTest extends TestCase { @@ -28,38 +30,123 @@ public function testFileRelative() $this->assertEquals('file.txt', $this->getExtension()->getFileRelative(\DIRECTORY_SEPARATOR.'project'.\DIRECTORY_SEPARATOR.'file.txt')); } - /** - * @dataProvider getClassNameProvider - */ - public function testGettingClassAbbreviation($class, $abbr) + public function testClassAbbreviationIntegration() { - $this->assertEquals($this->getExtension()->abbrClass($class), $abbr); + $data = [ + 'fqcn' => 'F\Q\N\Foo', + 'xss' => '