From e973541baf389f796da56c4f025bb94291f72a55 Mon Sep 17 00:00:00 2001 From: MatTheCat Date: Thu, 13 May 2021 20:01:22 +0200 Subject: [PATCH 01/78] =?UTF-8?q?Update=20loader=E2=80=99s=20directory=20w?= =?UTF-8?q?hen=20calling=20ContainerConfigurator::withPath?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Loader/Configurator/ContainerConfigurator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php index 7c4377f7aa117..666f11fe9d59a 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php @@ -78,6 +78,7 @@ final public function withPath(string $path): self { $clone = clone $this; $clone->path = $clone->file = $path; + $clone->loader->setCurrentDir(\dirname($path)); return $clone; } From 1fda3d02841994c6705588a3c9739c38aeaf97d0 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Sun, 30 May 2021 11:06:17 -0500 Subject: [PATCH 02/78] Document null support in NumberToLocalizedStringTransformer --- .../DataTransformer/MoneyToLocalizedStringTransformer.php | 4 ++-- .../DataTransformer/NumberToLocalizedStringTransformer.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php index ca341ac7120a0..18341b06775c1 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php @@ -45,7 +45,7 @@ public function __construct(?int $scale = 2, ?bool $grouping = true, ?int $round /** * Transforms a normalized format into a localized money string. * - * @param int|float $value Normalized number + * @param int|float|null $value Normalized number * * @return string Localized money string * @@ -69,7 +69,7 @@ public function transform($value) * * @param string $value Localized money string * - * @return int|float Normalized number + * @return int|float|null Normalized number * * @throws TransformationFailedException if the given value is not a string * or if the value can not be transformed diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php index 84ad6d18e1344..7cf46d17c3478 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php @@ -98,7 +98,7 @@ public function __construct(int $scale = null, ?bool $grouping = false, ?int $ro /** * Transforms a number type into localized number. * - * @param int|float $value Number value + * @param int|float|null $value Number value * * @return string Localized value * @@ -133,7 +133,7 @@ public function transform($value) * * @param string $value The localized value * - * @return int|float The numeric value + * @return int|float|null The numeric value * * @throws TransformationFailedException if the given value is not a string * or if the value can not be transformed From fbc689363ae348801d62a19e04d99f72a6311fcf Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 31 May 2021 23:41:53 +0200 Subject: [PATCH 03/78] remove service if its class doesn't exist --- .../DependencyInjection/FrameworkExtension.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 645d45a38b4d7..ccaa7fa8c3439 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1450,6 +1450,10 @@ private function registerValidationConfiguration(array $config, ContainerBuilder ->setArgument(2, $config['not_compromised_password']['enabled']) ->setArgument(3, $config['not_compromised_password']['endpoint']) ; + + if (!class_exists(ExpressionLanguage::class)) { + $container->removeDefinition('validator.expression_language'); + } } private function registerValidatorMapping(ContainerBuilder $container, array $config, array &$files) From 2bfe6f25a8ce5bc21a5d5c91f4d79dd0389838c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 1 Jun 2021 22:46:48 +0200 Subject: [PATCH 04/78] [FrameworkBundle] fix KernelBrowser::loginUser with a stateless firewall --- src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php | 10 +++++++++- .../FrameworkBundle/Tests/Functional/SecurityTest.php | 1 + .../Tests/Functional/app/Security/config.yml | 9 +++++++++ .../Tests/Functional/app/Security/routing.yml | 4 ++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index dff1eea251041..cf71cdfc09160 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -122,7 +122,15 @@ public function loginUser($user, string $firewallContext = 'main'): self $token = new TestBrowserToken($user->getRoles(), $user, $firewallContext); $token->setAuthenticated(true); - $session = $this->getContainer()->get('session'); + + $container = $this->getContainer(); + $container->get('security.token_storage')->setToken($token); + + if (!$container->has('session')) { + return $this; + } + + $session = $container->get('session'); $session->set('_security_'.$firewallContext, serialize($token)); $session->save(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SecurityTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SecurityTest.php index be2999ec1c331..fe13549050d6b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SecurityTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SecurityTest.php @@ -38,6 +38,7 @@ public function getUsers() yield ['the-username', ['ROLE_FOO'], null]; yield ['the-username', ['ROLE_FOO'], 'main']; yield ['other-username', ['ROLE_FOO'], 'custom']; + yield ['stateless-username', ['ROLE_FOO'], 'stateless']; yield ['the-username', ['ROLE_FOO'], null]; yield ['no-role-username', [], null]; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/config.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/config.yml index 686d7ad9820a5..4c2bc9ef293b7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/config.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/config.yml @@ -12,6 +12,10 @@ security: memory: users: other-username: { password: the-password, roles: ['ROLE_FOO'] } + stateless: + memory: + users: + stateless-username: { password: the-password, roles: ['ROLE_FOO'] } firewalls: main: @@ -24,3 +28,8 @@ security: form_login: check_path: /custom/login/check provider: custom + stateless: + pattern: ^/stateless + stateless: true + http_basic: ~ + provider: stateless diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/routing.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/routing.yml index e894da532b179..0e8a27a44dd80 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/routing.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/routing.yml @@ -5,3 +5,7 @@ security_profile: security_custom_profile: path: /custom/user_profile defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\SecurityController::profileAction } + +security_stateless_profile: + path: /stateless/user_profile + defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\SecurityController::profileAction } From 64b5b4a95babb77502003c0e998160e8ec1e0a2b Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 2 Jun 2021 12:21:08 +0200 Subject: [PATCH 05/78] Bump Symfony version to 5.3.2 --- 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 a50521454f36f..5cf810d862c64 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -75,12 +75,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - public const VERSION = '5.3.1'; - public const VERSION_ID = 50301; + public const VERSION = '5.3.2-DEV'; + public const VERSION_ID = 50302; public const MAJOR_VERSION = 5; public const MINOR_VERSION = 3; - public const RELEASE_VERSION = 1; - public const EXTRA_VERSION = ''; + public const RELEASE_VERSION = 2; + public const EXTRA_VERSION = 'DEV'; public const END_OF_MAINTENANCE = '01/2022'; public const END_OF_LIFE = '01/2022'; From 7d821f112a1eb826211312cef3f95d37202d0066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Wed, 2 Jun 2021 17:16:21 +0200 Subject: [PATCH 06/78] Move symfony/runtime from require to require-dev in main composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index f244517786900..3c6619b7f2823 100644 --- a/composer.json +++ b/composer.json @@ -53,8 +53,7 @@ "symfony/polyfill-php73": "^1.11", "symfony/polyfill-php80": "^1.15", "symfony/polyfill-php81": "^1.22", - "symfony/polyfill-uuid": "^1.15", - "symfony/runtime": "self.version" + "symfony/polyfill-uuid": "^1.15" }, "replace": { "symfony/asset": "self.version", @@ -144,6 +143,7 @@ "egulias/email-validator": "^2.1.10|^3.1", "symfony/mercure-bundle": "^0.3", "symfony/phpunit-bridge": "^5.2", + "symfony/runtime": "self.version", "symfony/security-acl": "~2.8|~3.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "twig/cssinliner-extra": "^2.12|^3", From 46bdeb8507a0f5cd0bfdd56cee5da1c44fcd8812 Mon Sep 17 00:00:00 2001 From: Matthieu Calie Date: Wed, 2 Jun 2021 11:27:58 +0200 Subject: [PATCH 07/78] [SecurityBundle] Link UserProviderListener to correct firewall dispatcher --- .../DependencyInjection/SecurityExtension.php | 5 +- .../Tests/Functional/AuthenticatorTest.php | 24 +++++++ .../LoginFormAuthenticator.php | 64 +++++++++++++++++++ .../SecurityController.php | 28 ++++++++ .../Functional/app/Authenticator/config.yml | 8 +++ .../multiple_firewall_user_provider.yml | 14 ++++ .../Functional/app/Authenticator/routing.yml | 16 +++++ 7 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/LoginFormAuthenticator.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/SecurityController.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/multiple_firewall_user_provider.yml diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 6f48e5313d045..472b42a8f95a0 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -339,6 +339,8 @@ private function createFirewall(ContainerBuilder $container, string $id, array $ $config->replaceArgument(4, $firewall['stateless']); + $firewallEventDispatcherId = 'security.event_dispatcher.'.$id; + // Provider id (must be configured explicitly per firewall/authenticator if more than one provider is set) $defaultProvider = null; if (isset($firewall['provider'])) { @@ -349,7 +351,7 @@ private function createFirewall(ContainerBuilder $container, string $id, array $ if ($this->authenticatorManagerEnabled) { $container->setDefinition('security.listener.'.$id.'.user_provider', new ChildDefinition('security.listener.user_provider.abstract')) - ->addTag('kernel.event_listener', ['event' => CheckPassportEvent::class, 'priority' => 2048, 'method' => 'checkPassport']) + ->addTag('kernel.event_listener', ['dispatcher' => $firewallEventDispatcherId, 'event' => CheckPassportEvent::class, 'priority' => 2048, 'method' => 'checkPassport']) ->replaceArgument(0, new Reference($defaultProvider)); } } elseif (1 === \count($providerIds)) { @@ -359,7 +361,6 @@ private function createFirewall(ContainerBuilder $container, string $id, array $ $config->replaceArgument(5, $defaultProvider); // Register Firewall-specific event dispatcher - $firewallEventDispatcherId = 'security.event_dispatcher.'.$id; $container->register($firewallEventDispatcherId, EventDispatcher::class); // Register listeners diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php index 5c60294876221..beb12a0b4d60f 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php @@ -63,4 +63,28 @@ public function provideEmails() yield ['jane@example.org', true]; yield ['john@example.org', false]; } + + /** + * @dataProvider provideEmailsWithFirewalls + */ + public function testLoginUsersWithMultipleFirewalls(string $username, string $firewallContext) + { + $client = $this->createClient(['test_case' => 'Authenticator', 'root_config' => 'multiple_firewall_user_provider.yml']); + $client->request('GET', '/main/login/check'); + + $client->request('POST', '/'.$firewallContext.'/login/check', [ + '_username' => $username, + '_password' => 'test', + ]); + $this->assertResponseRedirects('/'.$firewallContext.'/user_profile'); + + $client->request('GET', '/'.$firewallContext.'/user_profile'); + $this->assertEquals('Welcome '.$username.'!', $client->getResponse()->getContent()); + } + + public function provideEmailsWithFirewalls() + { + yield ['jane@example.org', 'main']; + yield ['john@example.org', 'custom']; + } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/LoginFormAuthenticator.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/LoginFormAuthenticator.php new file mode 100644 index 0000000000000..2440b23440f7d --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/LoginFormAuthenticator.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle; + +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Security; +use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator; +use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; +use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; +use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; +use Symfony\Component\Security\Http\Util\TargetPathTrait; + +class LoginFormAuthenticator extends AbstractLoginFormAuthenticator +{ + use TargetPathTrait; + + /** @var UrlGeneratorInterface */ + private $urlGenerator; + + public function __construct(UrlGeneratorInterface $urlGenerator) + { + $this->urlGenerator = $urlGenerator; + } + + public function authenticate(Request $request): PassportInterface + { + $username = $request->request->get('_username', ''); + + $request->getSession()->set(Security::LAST_USERNAME, $username); + + return new Passport( + new UserBadge($username), + new PasswordCredentials($request->request->get('_password', '')), + [] + ); + } + + public function onAuthenticationSuccess(Request $request, TokenInterface $token, $firewallName): ?Response + { + return new RedirectResponse($this->urlGenerator->generate('security_'.$firewallName.'_profile')); + } + + protected function getLoginUrl(Request $request): string + { + return strpos($request->getUri(), 'main') ? + $this->urlGenerator->generate('security_main_login') : + $this->urlGenerator->generate('security_custom_login') + ; + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/SecurityController.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/SecurityController.php new file mode 100644 index 0000000000000..821017fe5ebeb --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/SecurityController.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle; + +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Response; + +class SecurityController extends AbstractController +{ + public function checkAction() + { + return new Response('OK'); + } + + public function profileAction() + { + return new Response('Welcome '.$this->getUser()->getUsername().'!'); + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/config.yml index 45bde5bda3f22..af3e0e9736523 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/config.yml @@ -14,4 +14,12 @@ services: calls: - ['setContainer', ['@Psr\Container\ContainerInterface']] tags: [container.service_subscriber] + Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController: + public: true + calls: + - ['setContainer', ['@Psr\Container\ContainerInterface']] + tags: [container.service_subscriber] Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\ApiAuthenticator: ~ + Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\LoginFormAuthenticator: + public: true + arguments: ['@router'] diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/multiple_firewall_user_provider.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/multiple_firewall_user_provider.yml new file mode 100644 index 0000000000000..2630fd00b475f --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/multiple_firewall_user_provider.yml @@ -0,0 +1,14 @@ +imports: +- { resource: ./config.yml } +- { resource: ./security.yml } + +security: + firewalls: + main: + pattern: ^/main + provider: in_memory + custom_authenticator: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\LoginFormAuthenticator + custom: + pattern: ^/custom + provider: in_memory2 + custom_authenticator: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\LoginFormAuthenticator diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml index 2fd12cf5607a3..35662387dcf78 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml @@ -2,3 +2,19 @@ profile: path: /profile defaults: _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\ProfileController + +security_main_login: + path: /main/login/check + defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::checkAction } + +security_custom_login: + path: /custom/login/check + defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::checkAction } + +security_main_profile: + path: /main/user_profile + defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::profileAction } + +security_custom_profile: + path: /custom/user_profile + defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::profileAction } From c8d3f3ed412b51379126fde3d064cbcffa6a36b2 Mon Sep 17 00:00:00 2001 From: Artem Henvald Date: Thu, 3 Jun 2021 00:27:02 +0300 Subject: [PATCH 08/78] Remove hidden dependency on HttpFoundation for SmsBiurasTransport --- .../Component/Notifier/Bridge/SmsBiuras/SmsBiurasTransport.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/Notifier/Bridge/SmsBiuras/SmsBiurasTransport.php b/src/Symfony/Component/Notifier/Bridge/SmsBiuras/SmsBiurasTransport.php index a223d6dc6189a..ad24d3cfa37b0 100644 --- a/src/Symfony/Component/Notifier/Bridge/SmsBiuras/SmsBiurasTransport.php +++ b/src/Symfony/Component/Notifier/Bridge/SmsBiuras/SmsBiurasTransport.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Notifier\Bridge\SmsBiuras; -use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Notifier\Exception\TransportException; use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException; use Symfony\Component\Notifier\Message\MessageInterface; @@ -90,7 +89,7 @@ protected function doSend(MessageInterface $message): SentMessage ], ]); - if (Response::HTTP_OK !== $response->getStatusCode()) { + if (200 !== $response->getStatusCode()) { throw new TransportException('Unable to send the SMS.', $response); } From 960cb520dfcb26b8409d0e2b0011dfb547852754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4dlich?= Date: Sun, 23 May 2021 17:28:21 +0200 Subject: [PATCH 09/78] [Console] Escape synopsis output --- src/Symfony/Component/Console/Application.php | 2 +- .../Component/Console/Tests/ApplicationTest.php | 17 +++++++++++++++++ .../Console/Tests/Command/CommandTest.php | 3 ++- .../application_rendersynopsis_escapesline.txt | 7 +++++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/Console/Tests/Fixtures/application_rendersynopsis_escapesline.txt diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index e71a16d109035..ed6d00190ee83 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -833,7 +833,7 @@ public function renderThrowable(\Throwable $e, OutputInterface $output): void private function finishRenderThrowableOrException(OutputInterface $output): void { if (null !== $this->runningCommand) { - $output->writeln(sprintf('%s', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET); + $output->writeln(sprintf('%s', OutputFormatter::escape(sprintf($this->runningCommand->getSynopsis(), $this->getName()))), OutputInterface::VERBOSITY_QUIET); $output->writeln('', OutputInterface::VERBOSITY_QUIET); } } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index d293697d422c5..1634c01991b0a 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -940,6 +940,23 @@ public function testRenderExceptionStackTraceContainsRootException() $this->assertStringContainsString('Dummy type "class@anonymous" is invalid.', $tester->getDisplay(true)); } + public function testRenderExceptionEscapesLinesOfSynopsis() + { + $application = new Application(); + $application->setAutoExit(false); + $application + ->register('foo') + ->setCode(function () { + throw new \Exception('some exception'); + }) + ->addArgument('info') + ; + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->assertStringMatchesFormatFile(self::$fixturesPath.'/application_rendersynopsis_escapesline.txt', $tester->getDisplay(true), '->renderException() escapes lines containing formatting of synopsis'); + } + public function testRun() { $application = new Application(); diff --git a/src/Symfony/Component/Console/Tests/Command/CommandTest.php b/src/Symfony/Component/Console/Tests/Command/CommandTest.php index 10a476d192e31..7648b80ff0f08 100644 --- a/src/Symfony/Component/Console/Tests/Command/CommandTest.php +++ b/src/Symfony/Component/Console/Tests/Command/CommandTest.php @@ -192,7 +192,8 @@ public function testGetSynopsis() $command = new \TestCommand(); $command->addOption('foo'); $command->addArgument('bar'); - $this->assertEquals('namespace:name [--foo] [--] []', $command->getSynopsis(), '->getSynopsis() returns the synopsis'); + $command->addArgument('info'); + $this->assertEquals('namespace:name [--foo] [--] [ []]', $command->getSynopsis(), '->getSynopsis() returns the synopsis'); } public function testAddGetUsages() diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_rendersynopsis_escapesline.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_rendersynopsis_escapesline.txt new file mode 100644 index 0000000000000..a781326c621be --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/application_rendersynopsis_escapesline.txt @@ -0,0 +1,7 @@ + +In ApplicationTest.php line %d: + + some exception + + +foo [] From b004f3bf3bb871f88e3bc28f93b52295d6bcb97d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 3 Jun 2021 15:41:38 +0200 Subject: [PATCH 10/78] fix --- src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index cf71cdfc09160..5afe16f7b0cc2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -124,7 +124,7 @@ public function loginUser($user, string $firewallContext = 'main'): self $token->setAuthenticated(true); $container = $this->getContainer(); - $container->get('security.token_storage')->setToken($token); + $container->get('security.untracked_token_storage')->setToken($token); if (!$container->has('session')) { return $this; From 5e609da601422a422a1b736887b71606faee79ea Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 3 Jun 2021 15:58:19 +0200 Subject: [PATCH 11/78] Fix KernelBrowser --- src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index 5afe16f7b0cc2..99f749e5fa7f7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -123,7 +123,7 @@ public function loginUser($user, string $firewallContext = 'main'): self $token = new TestBrowserToken($user->getRoles(), $user, $firewallContext); $token->setAuthenticated(true); - $container = $this->getContainer(); + $container = $this->kernel->getContainer()->get('test.service_container'); $container->get('security.untracked_token_storage')->setToken($token); if (!$container->has('session')) { From 440bd5f1c7ab5c64a8fe3a5f412c9508255b7d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Fri, 4 Jun 2021 00:48:40 +0200 Subject: [PATCH 12/78] [Console] Fix negated options not accessible --- src/Symfony/Component/Console/Input/Input.php | 16 ++++++++++++++-- .../Component/Console/Tests/Input/InputTest.php | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Input/Input.php b/src/Symfony/Component/Console/Input/Input.php index dd7658094678b..3b054c4b6e001 100644 --- a/src/Symfony/Component/Console/Input/Input.php +++ b/src/Symfony/Component/Console/Input/Input.php @@ -146,6 +146,14 @@ public function getOptions() */ public function getOption(string $name) { + if ($this->definition->hasNegation($name)) { + if (null === $value = $this->getOption($this->definition->negationToName($name))) { + return $value; + } + + return !$value; + } + if (!$this->definition->hasOption($name)) { throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); } @@ -158,7 +166,11 @@ public function getOption(string $name) */ public function setOption(string $name, $value) { - if (!$this->definition->hasOption($name)) { + if ($this->definition->hasNegation($name)) { + $this->options[$this->definition->negationToName($name)] = !$value; + + return; + } elseif (!$this->definition->hasOption($name)) { throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); } @@ -170,7 +182,7 @@ public function setOption(string $name, $value) */ public function hasOption(string $name) { - return $this->definition->hasOption($name); + return $this->definition->hasOption($name) || $this->definition->hasNegation($name); } /** diff --git a/src/Symfony/Component/Console/Tests/Input/InputTest.php b/src/Symfony/Component/Console/Tests/Input/InputTest.php index 48c287cd9d3b3..6547822fbbced 100644 --- a/src/Symfony/Component/Console/Tests/Input/InputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/InputTest.php @@ -45,6 +45,20 @@ public function testOptions() $input = new ArrayInput(['--name' => 'foo', '--bar' => null], new InputDefinition([new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default')])); $this->assertNull($input->getOption('bar'), '->getOption() returns null for options explicitly passed without value (or an empty value)'); $this->assertEquals(['name' => 'foo', 'bar' => null], $input->getOptions(), '->getOptions() returns all option values'); + + $input = new ArrayInput(['--name' => null], new InputDefinition([new InputOption('name', null, InputOption::VALUE_NEGATABLE)])); + $this->assertTrue($input->hasOption('name')); + $this->assertTrue($input->hasOption('no-name')); + $this->assertTrue($input->getOption('name')); + $this->assertFalse($input->getOption('no-name')); + + $input = new ArrayInput(['--no-name' => null], new InputDefinition([new InputOption('name', null, InputOption::VALUE_NEGATABLE)])); + $this->assertFalse($input->getOption('name')); + $this->assertTrue($input->getOption('no-name')); + + $input = new ArrayInput([], new InputDefinition([new InputOption('name', null, InputOption::VALUE_NEGATABLE)])); + $this->assertNull($input->getOption('name')); + $this->assertNull($input->getOption('no-name')); } public function testSetInvalidOption() From 74e0b318cf5be59f5f12957e6c101ddb0f977235 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 4 Jun 2021 13:21:50 +0200 Subject: [PATCH 13/78] Fix call to deprecated getUsername() in tests --- .../Bundle/AuthenticatorBundle/SecurityController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/SecurityController.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/SecurityController.php index 821017fe5ebeb..04d165b015e59 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/SecurityController.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/SecurityController.php @@ -23,6 +23,6 @@ public function checkAction() public function profileAction() { - return new Response('Welcome '.$this->getUser()->getUsername().'!'); + return new Response('Welcome '.$this->getUser()->getUserIdentifier().'!'); } } From 21c0829a25410434f08fdb8f8ab40505dcaaa40f Mon Sep 17 00:00:00 2001 From: Oleg Zhulnev Date: Tue, 1 Jun 2021 14:01:19 +0300 Subject: [PATCH 14/78] [Serializer] Do not allow to denormalize string with spaces only to valid a DateTime object --- .../Serializer/Normalizer/DateTimeNormalizer.php | 2 +- .../Tests/Normalizer/DateTimeNormalizerTest.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index 8bdfc977efd5d..f48745031e8b7 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -97,7 +97,7 @@ public function denormalize($data, $type, $format = null, array $context = []) $dateTimeFormat = $context[self::FORMAT_KEY] ?? null; $timezone = $this->getTimezone($context); - if ('' === $data || null === $data) { + if (null === $data || (\is_string($data) && '' === trim($data))) { throw new NotNormalizableValueException('The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.'); } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php index 576d5eb03f105..51fc17d85afea 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php @@ -201,6 +201,7 @@ public function testDenormalize() $this->assertEquals(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeInterface::class)); $this->assertEquals(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeImmutable::class)); $this->assertEquals(new \DateTime('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTime::class)); + $this->assertEquals(new \DateTime('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize(' 2016-01-01T00:00:00+00:00 ', \DateTime::class)); } public function testDenormalizeUsingTimezonePassedInConstructor() @@ -290,6 +291,20 @@ public function testDenormalizeEmptyStringThrowsException() $this->normalizer->denormalize('', \DateTimeInterface::class); } + public function testDenormalizeStringWithSpacesOnlyThrowsAnException() + { + $this->expectException(UnexpectedValueException::class); + $this->expectExceptionMessage('The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.'); + $this->normalizer->denormalize(' ', \DateTimeInterface::class); + } + + public function testDenormalizeDateTimeStringWithSpacesUsingFormatPassedInContextThrowsAnException() + { + $this->expectException(UnexpectedValueException::class); + $this->expectExceptionMessage("Parsing datetime string \" 2016.01.01 \" using format \"Y.m.d|\" resulted in 2 errors: \nat position 0: Unexpected data found.\nat position 12: Trailing data"); + $this->normalizer->denormalize(' 2016.01.01 ', \DateTime::class, null, [DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|']); + } + public function testDenormalizeFormatMismatchThrowsException() { $this->expectException(UnexpectedValueException::class); From b10b6951a64c29aa2e109805ca12f4de9b7ad11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 5 Jun 2021 00:24:11 +0200 Subject: [PATCH 15/78] Fix opcache preload with alias classes --- .../Core/Authorization/TraceableAccessDecisionManager.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php b/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php index 7a9c4d0cfb23a..3b5004edf2fcd 100644 --- a/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php +++ b/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php @@ -107,4 +107,6 @@ public function getDecisionLog(): array } } -class_alias(TraceableAccessDecisionManager::class, DebugAccessDecisionManager::class); +if (!class_exists(DebugAccessDecisionManager::class, false)) { + class_alias(TraceableAccessDecisionManager::class, DebugAccessDecisionManager::class); +} From 3bd24c5e07f764ed820e3f4473cbeca79fdae8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 5 Jun 2021 00:34:10 +0200 Subject: [PATCH 16/78] [Messenger] Fix opcache preload with alias classes --- .../Messenger/Bridge/Amqp/Transport/AmqpFactory.php | 5 ++++- .../Messenger/Bridge/Amqp/Transport/AmqpReceivedStamp.php | 5 ++++- .../Messenger/Bridge/Amqp/Transport/AmqpReceiver.php | 5 ++++- .../Component/Messenger/Bridge/Amqp/Transport/AmqpSender.php | 5 ++++- .../Component/Messenger/Bridge/Amqp/Transport/AmqpStamp.php | 5 ++++- .../Messenger/Bridge/Amqp/Transport/AmqpTransport.php | 5 ++++- .../Messenger/Bridge/Amqp/Transport/AmqpTransportFactory.php | 5 ++++- .../Component/Messenger/Bridge/Amqp/Transport/Connection.php | 5 ++++- .../Messenger/Bridge/Doctrine/Transport/Connection.php | 5 ++++- .../Bridge/Doctrine/Transport/DoctrineReceivedStamp.php | 5 ++++- .../Messenger/Bridge/Doctrine/Transport/DoctrineReceiver.php | 5 ++++- .../Messenger/Bridge/Doctrine/Transport/DoctrineSender.php | 5 ++++- .../Bridge/Doctrine/Transport/DoctrineTransport.php | 5 ++++- .../Bridge/Doctrine/Transport/DoctrineTransportFactory.php | 5 ++++- .../Messenger/Bridge/Redis/Transport/Connection.php | 5 ++++- .../Messenger/Bridge/Redis/Transport/RedisReceivedStamp.php | 5 ++++- .../Messenger/Bridge/Redis/Transport/RedisReceiver.php | 5 ++++- .../Messenger/Bridge/Redis/Transport/RedisSender.php | 5 ++++- .../Messenger/Bridge/Redis/Transport/RedisTransport.php | 5 ++++- .../Bridge/Redis/Transport/RedisTransportFactory.php | 5 ++++- 20 files changed, 80 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpFactory.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpFactory.php index 6ce1bdc4dae62..47d8487c29863 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpFactory.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpFactory.php @@ -33,4 +33,7 @@ public function createExchange(\AMQPChannel $channel): \AMQPExchange return new \AMQPExchange($channel); } } -class_alias(AmqpFactory::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpFactory::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\AmqpExt\AmqpFactory::class, false)) { + class_alias(AmqpFactory::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpFactory::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceivedStamp.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceivedStamp.php index dd4656e809ea7..b661cd8da91c2 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceivedStamp.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceivedStamp.php @@ -37,4 +37,7 @@ public function getQueueName(): string return $this->queueName; } } -class_alias(AmqpReceivedStamp::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceivedStamp::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceivedStamp::class, false)) { + class_alias(AmqpReceivedStamp::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceivedStamp::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceiver.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceiver.php index 009e7be8d55bb..0639e80b35325 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceiver.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpReceiver.php @@ -136,4 +136,7 @@ private function findAmqpStamp(Envelope $envelope): AmqpReceivedStamp return $amqpReceivedStamp; } } -class_alias(AmqpReceiver::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceiver::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceiver::class, false)) { + class_alias(AmqpReceiver::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceiver::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpSender.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpSender.php index a77268bd056d0..2ceb965e1d56f 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpSender.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpSender.php @@ -75,4 +75,7 @@ public function send(Envelope $envelope): Envelope return $envelope; } } -class_alias(AmqpSender::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpSender::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\AmqpExt\AmqpSender::class, false)) { + class_alias(AmqpSender::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpSender::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpStamp.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpStamp.php index 7d013974cc3e9..a2b2254927e7a 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpStamp.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpStamp.php @@ -74,4 +74,7 @@ public static function createWithAttributes(array $attributes, self $previousSta ); } } -class_alias(AmqpStamp::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpStamp::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\AmqpExt\AmqpStamp::class, false)) { + class_alias(AmqpStamp::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpStamp::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpTransport.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpTransport.php index 030046851fbea..f3e7a7ce048a1 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpTransport.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpTransport.php @@ -92,4 +92,7 @@ private function getSender(): AmqpSender return $this->sender = new AmqpSender($this->connection, $this->serializer); } } -class_alias(AmqpTransport::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpTransport::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\AmqpExt\AmqpTransport::class, false)) { + class_alias(AmqpTransport::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpTransport::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpTransportFactory.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpTransportFactory.php index 6743e192f7dcf..420cf7a22c297 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpTransportFactory.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpTransportFactory.php @@ -32,4 +32,7 @@ public function supports(string $dsn, array $options): bool return 0 === strpos($dsn, 'amqp://') || 0 === strpos($dsn, 'amqps://'); } } -class_alias(AmqpTransportFactory::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpTransportFactory::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\AmqpExt\AmqpTransportFactory::class, false)) { + class_alias(AmqpTransportFactory::class, \Symfony\Component\Messenger\Transport\AmqpExt\AmqpTransportFactory::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php index 5b21388915074..4aed8831b57bc 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php @@ -588,4 +588,7 @@ private function getRoutingKeyForMessage(?AmqpStamp $amqpStamp): ?string return (null !== $amqpStamp ? $amqpStamp->getRoutingKey() : null) ?? $this->getDefaultPublishRoutingKey(); } } -class_alias(Connection::class, \Symfony\Component\Messenger\Transport\AmqpExt\Connection::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\AmqpExt\Connection::class, false)) { + class_alias(Connection::class, \Symfony\Component\Messenger\Transport\AmqpExt\Connection::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php index b7c99a23bf52d..c4b398aa43ae9 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php @@ -445,4 +445,7 @@ private function updateSchema(): void } } } -class_alias(Connection::class, \Symfony\Component\Messenger\Transport\Doctrine\Connection::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\Doctrine\Connection::class, false)) { + class_alias(Connection::class, \Symfony\Component\Messenger\Transport\Doctrine\Connection::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineReceivedStamp.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineReceivedStamp.php index 6ec3389ab664e..7f0dee1a99c67 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineReceivedStamp.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineReceivedStamp.php @@ -30,4 +30,7 @@ public function getId(): string return $this->id; } } -class_alias(DoctrineReceivedStamp::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineReceivedStamp::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\Doctrine\DoctrineReceivedStamp::class, false)) { + class_alias(DoctrineReceivedStamp::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineReceivedStamp::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineReceiver.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineReceiver.php index ca00b52a5bc62..de1fd53c7cd4c 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineReceiver.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineReceiver.php @@ -171,4 +171,7 @@ private function createEnvelopeFromData(array $data): Envelope ); } } -class_alias(DoctrineReceiver::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineReceiver::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\Doctrine\DoctrineReceiver::class, false)) { + class_alias(DoctrineReceiver::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineReceiver::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineSender.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineSender.php index f5612f30f0408..490955dd2ae5a 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineSender.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineSender.php @@ -55,4 +55,7 @@ public function send(Envelope $envelope): Envelope return $envelope->with(new TransportMessageIdStamp($id)); } } -class_alias(DoctrineSender::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineSender::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\Doctrine\DoctrineSender::class, false)) { + class_alias(DoctrineSender::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineSender::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransport.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransport.php index 9982d343e305d..97bc6fac3feea 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransport.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransport.php @@ -129,4 +129,7 @@ private function getSender(): DoctrineSender return $this->sender = new DoctrineSender($this->connection, $this->serializer); } } -class_alias(DoctrineTransport::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransport::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransport::class, false)) { + class_alias(DoctrineTransport::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransport::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransportFactory.php b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransportFactory.php index 27759ec3b03a4..0cda9a35ea6af 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransportFactory.php +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/DoctrineTransportFactory.php @@ -62,4 +62,7 @@ public function supports(string $dsn, array $options): bool return 0 === strpos($dsn, 'doctrine://'); } } -class_alias(DoctrineTransportFactory::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransportFactory::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransportFactory::class, false)) { + class_alias(DoctrineTransportFactory::class, \Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransportFactory::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php index 737b24e66f751..0e5bdfb935e40 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php @@ -497,4 +497,7 @@ public function cleanup(): void } } } -class_alias(Connection::class, \Symfony\Component\Messenger\Transport\RedisExt\Connection::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\RedisExt\Connection::class, false)) { + class_alias(Connection::class, \Symfony\Component\Messenger\Transport\RedisExt\Connection::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisReceivedStamp.php b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisReceivedStamp.php index 486aa58dfd139..3469f69461979 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisReceivedStamp.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisReceivedStamp.php @@ -30,4 +30,7 @@ public function getId(): string return $this->id; } } -class_alias(RedisReceivedStamp::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisReceivedStamp::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\RedisExt\RedisReceivedStamp::class, false)) { + class_alias(RedisReceivedStamp::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisReceivedStamp::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisReceiver.php b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisReceiver.php index 0c51d15163da2..89f14c4307bd9 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisReceiver.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisReceiver.php @@ -86,4 +86,7 @@ private function findRedisReceivedStamp(Envelope $envelope): RedisReceivedStamp return $redisReceivedStamp; } } -class_alias(RedisReceiver::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisReceiver::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\RedisExt\RedisReceiver::class, false)) { + class_alias(RedisReceiver::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisReceiver::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisSender.php b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisSender.php index 38b2e4751535b..433cfe924105c 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisSender.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisSender.php @@ -47,4 +47,7 @@ public function send(Envelope $envelope): Envelope return $envelope; } } -class_alias(RedisSender::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisSender::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\RedisExt\RedisSender::class, false)) { + class_alias(RedisSender::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisSender::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisTransport.php b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisTransport.php index d92afdec66184..88daa22c5366f 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisTransport.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisTransport.php @@ -84,4 +84,7 @@ private function getSender(): RedisSender return $this->sender = new RedisSender($this->connection, $this->serializer); } } -class_alias(RedisTransport::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisTransport::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\RedisExt\RedisTransport::class, false)) { + class_alias(RedisTransport::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisTransport::class); +} diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisTransportFactory.php b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisTransportFactory.php index b8a340e84f384..55deeb09e7fa8 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisTransportFactory.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/RedisTransportFactory.php @@ -33,4 +33,7 @@ public function supports(string $dsn, array $options): bool return 0 === strpos($dsn, 'redis://'); } } -class_alias(RedisTransportFactory::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisTransportFactory::class); + +if (!class_exists(\Symfony\Component\Messenger\Transport\RedisExt\RedisTransportFactory::class, false)) { + class_alias(RedisTransportFactory::class, \Symfony\Component\Messenger\Transport\RedisExt\RedisTransportFactory::class); +} From acfeaf66565547a933b4989f467a918f367a06b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 5 Jun 2021 00:37:42 +0200 Subject: [PATCH 17/78] [Security] Fix opcache preload with alias classes --- .../Security/Core/Exception/UserNotFoundException.php | 5 ++++- .../Component/Security/Core/User/InMemoryUserChecker.php | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Exception/UserNotFoundException.php b/src/Symfony/Component/Security/Core/Exception/UserNotFoundException.php index f9c40c3249f8f..685b079ef17e8 100644 --- a/src/Symfony/Component/Security/Core/Exception/UserNotFoundException.php +++ b/src/Symfony/Component/Security/Core/Exception/UserNotFoundException.php @@ -93,4 +93,7 @@ public function __unserialize(array $data): void parent::__unserialize($parentData); } } -class_alias(UserNotFoundException::class, UsernameNotFoundException::class); + +if (!class_exists(UsernameNotFoundException::class, false)) { + class_alias(UserNotFoundException::class, UsernameNotFoundException::class); +} diff --git a/src/Symfony/Component/Security/Core/User/InMemoryUserChecker.php b/src/Symfony/Component/Security/Core/User/InMemoryUserChecker.php index 6f661c76297b0..b35e6303f6f82 100644 --- a/src/Symfony/Component/Security/Core/User/InMemoryUserChecker.php +++ b/src/Symfony/Component/Security/Core/User/InMemoryUserChecker.php @@ -67,4 +67,7 @@ public function checkPostAuth(UserInterface $user) } } } -class_alias(InMemoryUserChecker::class, UserChecker::class); + +if (!class_exists(UserChecker::class, false)) { + class_alias(InMemoryUserChecker::class, UserChecker::class); +} From 0bce1f6de1581eae94fdf1f8f43b22adbc1daccd Mon Sep 17 00:00:00 2001 From: HypeMC Date: Thu, 3 Jun 2021 22:06:42 +0200 Subject: [PATCH 18/78] Add missing security translations --- .../Security/Core/Resources/translations/security.hr.xlf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.hr.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.hr.xlf index e193dcb500032..d46be51682e36 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.hr.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.hr.xlf @@ -70,6 +70,14 @@ Invalid or expired login link. Link za prijavu je isteako ili je neispravan. + + Too many failed login attempts, please try again in %minutes% minute. + Previše neuspjelih pokušaja prijave, molim pokušajte ponovo za %minutes% minutu. + + + Too many failed login attempts, please try again in %minutes% minutes. + Previše neuspjelih pokušaja prijave, molim pokušajte ponovo za %minutes% minutu.|Previše neuspjelih pokušaja prijave, molim pokušajte ponovo za %minutes% minute.|Previše neuspjelih pokušaja prijave, molim pokušajte ponovo za %minutes% minuta. + From 48e76fafc6acd3aa62396c8b979cd9f935706563 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 5 Jun 2021 18:29:25 +0200 Subject: [PATCH 19/78] Fix Serializable deprecations triggered by token mocks --- src/Symfony/Bridge/Twig/Tests/AppVariableTest.php | 2 +- .../Bridge/Twig/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../FrameworkBundle/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Tests/Templating/GlobalVariablesTest.php | 2 +- .../SecurityBundle/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Tests/Functional/EventAliasTest.php | 2 +- .../Tests/SecurityUserValueResolverTest.php | 2 +- .../AuthenticationProviderManagerTest.php | 2 +- .../AuthenticationTrustResolverTest.php | 2 +- .../Provider/AnonymousAuthenticationProviderTest.php | 2 +- .../PreAuthenticatedAuthenticationProviderTest.php | 2 +- .../Provider/RememberMeAuthenticationProviderTest.php | 2 +- .../Provider/SimpleAuthenticationProviderTest.php | 2 +- .../Provider/UserAuthenticationProviderTest.php | 2 +- .../Token/Storage/UsageTrackingTokenStorageTest.php | 2 +- .../Tests/Authorization/AccessDecisionManagerTest.php | 2 +- .../TraceableAccessDecisionManagerTest.php | 2 +- .../Authorization/Voter/AuthenticatedVoterTest.php | 2 +- .../Tests/Authorization/Voter/ExpressionVoterTest.php | 2 +- .../Core/Tests/Authorization/Voter/RoleVoterTest.php | 2 +- .../Tests/Authorization/Voter/TraceableVoterTest.php | 2 +- .../Core/Tests/Authorization/Voter/VoterTest.php | 3 ++- .../Security/Core/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Security/Core/Tests/Role/SwitchUserRoleTest.php | 2 +- .../Component/Security/Core/Tests/SecurityTest.php | 2 +- .../Constraints/UserPasswordValidatorTest.php | 2 +- .../Firewall/GuardAuthenticationListenerTest.php | 2 +- .../Guard/Tests/Fixtures/GuardTokenInterface.php | 11 +++++++++++ .../Security/Guard/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Guard/Tests/GuardAuthenticatorHandlerTest.php | 2 +- .../Provider/GuardAuthenticationProviderTest.php | 2 +- .../DefaultAuthenticationSuccessHandlerTest.php | 2 +- .../SimpleAuthenticationHandlerTest.php | 2 +- .../Firewall/AbstractPreAuthenticatedListenerTest.php | 2 +- .../Http/Tests/Firewall/AccessListenerTest.php | 2 +- .../Firewall/AnonymousAuthenticationListenerTest.php | 2 +- .../Firewall/BasicAuthenticationListenerTest.php | 2 +- .../Http/Tests/Firewall/ExceptionListenerTest.php | 2 +- .../Http/Tests/Firewall/LogoutListenerTest.php | 2 +- .../Http/Tests/Firewall/RememberMeListenerTest.php | 2 +- .../Firewall/SimplePreAuthenticationListenerTest.php | 2 +- ...UsernamePasswordJsonAuthenticationListenerTest.php | 3 ++- .../Security/Http/Tests/Fixtures/TokenInterface.php | 11 +++++++++++ .../Tests/Logout/CookieClearingLogoutHandlerTest.php | 2 +- .../Logout/CsrfTokenClearingLogoutHandlerTest.php | 2 +- .../Http/Tests/Logout/SessionLogoutHandlerTest.php | 2 +- .../RememberMe/AbstractRememberMeServicesTest.php | 2 +- .../PersistentTokenBasedRememberMeServicesTest.php | 2 +- .../RememberMe/TokenBasedRememberMeServicesTest.php | 2 +- .../Session/SessionAuthenticationStrategyTest.php | 2 +- 50 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 src/Symfony/Bridge/Twig/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Component/Security/Core/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Component/Security/Guard/Tests/Fixtures/GuardTokenInterface.php create mode 100644 src/Symfony/Component/Security/Guard/Tests/Fixtures/TokenInterface.php create mode 100644 src/Symfony/Component/Security/Http/Tests/Fixtures/TokenInterface.php diff --git a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php index f5fcbeada6562..58c3cfde4beab 100644 --- a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php +++ b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php @@ -4,12 +4,12 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Twig\AppVariable; +use Symfony\Bridge\Twig\Tests\Fixtures\TokenInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\User\UserInterface; class AppVariableTest extends TestCase diff --git a/src/Symfony/Bridge/Twig/Tests/Fixtures/TokenInterface.php b/src/Symfony/Bridge/Twig/Tests/Fixtures/TokenInterface.php new file mode 100644 index 0000000000000..b22e99e66d22b --- /dev/null +++ b/src/Symfony/Bridge/Twig/Tests/Fixtures/TokenInterface.php @@ -0,0 +1,11 @@ +token = $this->createMock(TokenInterface::class); + $this->token = $this->createMock(StrictTokenInterface::class); } public function getTests() diff --git a/src/Symfony/Component/Security/Core/Tests/Fixtures/TokenInterface.php b/src/Symfony/Component/Security/Core/Tests/Fixtures/TokenInterface.php new file mode 100644 index 0000000000000..32a83deeb6800 --- /dev/null +++ b/src/Symfony/Component/Security/Core/Tests/Fixtures/TokenInterface.php @@ -0,0 +1,11 @@ + @@ -50,7 +51,7 @@ private function createListener(array $options = [], $success = true, $matchChec ; $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticatedToken = $this->createMock(TokenInterface::class); + $authenticatedToken = $this->createMock(StrictTokenInterface::class); if ($success) { $authenticationManager->method('authenticate')->willReturn($authenticatedToken); diff --git a/src/Symfony/Component/Security/Http/Tests/Fixtures/TokenInterface.php b/src/Symfony/Component/Security/Http/Tests/Fixtures/TokenInterface.php new file mode 100644 index 0000000000000..254381cb23203 --- /dev/null +++ b/src/Symfony/Component/Security/Http/Tests/Fixtures/TokenInterface.php @@ -0,0 +1,11 @@ + Date: Sat, 5 Jun 2021 22:21:26 +0200 Subject: [PATCH 20/78] Add return types to JsonSerializable implementations --- .../HttpFoundation/Tests/JsonResponseTest.php | 13 ++++--------- .../Tests/Fixtures/JsonSerializableDummy.php | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php index 664f577b1765c..9cd63da728f84 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -224,9 +224,6 @@ public function testSetContentJsonSerializeError() { $this->expectException(\Exception::class); $this->expectExceptionMessage('This error is expected'); - if (!interface_exists(\JsonSerializable::class, false)) { - $this->markTestSkipped('JsonSerializable is required.'); - } $serializable = new JsonSerializableObject(); @@ -280,12 +277,10 @@ public function testConstructorWithObjectWithoutToStringMethodThrowsAnException( } } -if (interface_exists(\JsonSerializable::class, false)) { - class JsonSerializableObject implements \JsonSerializable +class JsonSerializableObject implements \JsonSerializable +{ + public function jsonSerialize(): array { - public function jsonSerialize() - { - throw new \Exception('This error is expected'); - } + throw new \Exception('This error is expected'); } } diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/JsonSerializableDummy.php b/src/Symfony/Component/Serializer/Tests/Fixtures/JsonSerializableDummy.php index 958200fdc74e7..ed4fd7e5e7b9b 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/JsonSerializableDummy.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/JsonSerializableDummy.php @@ -13,7 +13,7 @@ class JsonSerializableDummy implements \JsonSerializable { - public function jsonSerialize() + public function jsonSerialize(): array { return [ 'foo' => 'a', From e14dd67e85e455d34ea5373ea01835068efe370f Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 00:53:17 +0200 Subject: [PATCH 21/78] [DependencyInjection] Don't pass null to trim() --- .../Component/DependencyInjection/Dumper/PhpDumper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index ea11778a640e9..c38d3eb3d5ffa 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -2147,7 +2147,9 @@ private function getClasses(Definition $definition): array $classes = []; while ($definition instanceof Definition) { - $classes[] = trim($definition->getClass(), '\\'); + if ($class = $definition->getClass()) { + $classes[] = trim($class, '\\'); + } $factory = $definition->getFactory(); if (!\is_array($factory)) { From 7d1435b1197a1db4da6146cccd883307f208f0ed Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 01:18:30 +0200 Subject: [PATCH 22/78] [Messenger] Fix broken mock Signed-off-by: Alexander M. Turek --- .../Tests/Transport/AmazonSqsTransportTest.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsTransportTest.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsTransportTest.php index a5d0fe7473ab6..d2483b8b22a7b 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsTransportTest.php +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsTransportTest.php @@ -177,6 +177,20 @@ private function getTransport(SerializerInterface $serializer = null, Connection private function createHttpException(): HttpException { - return new ServerException($this->createMock(ResponseInterface::class)); + $response = $this->createMock(ResponseInterface::class); + $response->method('getInfo')->willReturnCallback(static function (?string $type = null) { + $info = [ + 'http_code' => 500, + 'url' => 'https://symfony.com', + ]; + + if (null === $type) { + return $info; + } + + return $info[$type] ?? null; + }); + + return new ServerException($response); } } From 83b966c1cf04ac50188204d000677c216a5c9aff Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 10:04:50 +0200 Subject: [PATCH 23/78] [Asset] Don't pass null to strpos() Signed-off-by: Alexander M. Turek --- .../Asset/VersionStrategy/JsonManifestVersionStrategy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php b/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php index e72cdc1f174a6..256bc21963720 100644 --- a/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php +++ b/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php @@ -39,7 +39,7 @@ public function __construct(string $manifestPath, HttpClientInterface $httpClien $this->manifestPath = $manifestPath; $this->httpClient = $httpClient; - if (null === $this->httpClient && 0 === strpos(parse_url($this->manifestPath, \PHP_URL_SCHEME), 'http')) { + if (null === $this->httpClient && ($scheme = parse_url($this->manifestPath, \PHP_URL_SCHEME)) && 0 === strpos($scheme, 'http')) { throw new \LogicException(sprintf('The "%s" class needs an HTTP client to use a remote manifest. Try running "composer require symfony/http-client".', self::class)); } } From 448a017fd12f746cd6d359825e259dfb0d25faec Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 10:17:47 +0200 Subject: [PATCH 24/78] [String] Fix implicit float-to-int casts Signed-off-by: Alexander M. Turek --- src/Symfony/Component/String/AbstractUnicodeString.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/String/AbstractUnicodeString.php b/src/Symfony/Component/String/AbstractUnicodeString.php index ed186cc4452aa..8af75a1069133 100644 --- a/src/Symfony/Component/String/AbstractUnicodeString.php +++ b/src/Symfony/Component/String/AbstractUnicodeString.php @@ -480,22 +480,22 @@ private function pad(int $len, self $pad, int $type): parent switch ($type) { case \STR_PAD_RIGHT: - return $this->append(str_repeat($pad->string, $freeLen / $padLen).($len ? $pad->slice(0, $len) : '')); + return $this->append(str_repeat($pad->string, intdiv($freeLen, $padLen)).($len ? $pad->slice(0, $len) : '')); case \STR_PAD_LEFT: - return $this->prepend(str_repeat($pad->string, $freeLen / $padLen).($len ? $pad->slice(0, $len) : '')); + return $this->prepend(str_repeat($pad->string, intdiv($freeLen, $padLen)).($len ? $pad->slice(0, $len) : '')); case \STR_PAD_BOTH: $freeLen /= 2; $rightLen = ceil($freeLen); $len = $rightLen % $padLen; - $str = $this->append(str_repeat($pad->string, $rightLen / $padLen).($len ? $pad->slice(0, $len) : '')); + $str = $this->append(str_repeat($pad->string, intdiv($rightLen, $padLen)).($len ? $pad->slice(0, $len) : '')); $leftLen = floor($freeLen); $len = $leftLen % $padLen; - return $str->prepend(str_repeat($pad->string, $leftLen / $padLen).($len ? $pad->slice(0, $len) : '')); + return $str->prepend(str_repeat($pad->string, intdiv($leftLen, $padLen)).($len ? $pad->slice(0, $len) : '')); default: throw new InvalidArgumentException('Invalid padding type.'); From 40992f001bb65e8ff759d6702c56c2f418ca44f8 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 6 Jun 2021 10:41:27 +0200 Subject: [PATCH 25/78] cs fix --- src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index c38d3eb3d5ffa..711b631d54590 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -2166,6 +2166,6 @@ private function getClasses(Definition $definition): array $definition = $factory[0]; } - return array_filter($classes); + return $classes; } } From 3c8cf9a3d4f525954692ca49e05d96e4706e10ad Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 10:50:48 +0200 Subject: [PATCH 26/78] [Translation] Don't pass null to strtoupper() Signed-off-by: Alexander M. Turek --- src/Symfony/Component/Translation/Loader/XliffFileLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php index a949e59ce4030..35e2d9c10c181 100644 --- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php @@ -76,7 +76,7 @@ private function extract($resource, MessageCatalogue $catalogue, string $domain) private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain) { $xml = simplexml_import_dom($dom); - $encoding = strtoupper($dom->encoding); + $encoding = $dom->encoding ? strtoupper($dom->encoding) : null; $namespace = 'urn:oasis:names:tc:xliff:document:1.2'; $xml->registerXPathNamespace('xliff', $namespace); From fc7447681cff7e5bcad42d3b349db34626c7910c Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 5 Jun 2021 22:03:01 +0200 Subject: [PATCH 27/78] Fix incompatible implicit float-to-int conversions Signed-off-by: Alexander M. Turek --- .../Component/Console/Helper/ProgressBar.php | 4 ++-- .../Component/Console/Helper/Table.php | 2 +- .../Console/Tests/Helper/ProgressBarTest.php | 2 +- .../Lock/Tests/Store/PdoStoreTest.php | 2 +- .../Command/Descriptor/CliDescriptor.php | 2 +- .../Command/Descriptor/HtmlDescriptor.php | 2 +- .../Component/Yaml/Tests/InlineTest.php | 20 +++++++++---------- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/ProgressBar.php b/src/Symfony/Component/Console/Helper/ProgressBar.php index 5049c7dae0636..1de9b7b3cfe92 100644 --- a/src/Symfony/Component/Console/Helper/ProgressBar.php +++ b/src/Symfony/Component/Console/Helper/ProgressBar.php @@ -193,7 +193,7 @@ public function getProgressPercent(): float public function getBarOffset(): int { - return floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? min(5, $this->barWidth / 15) * $this->writeCount : $this->step) % $this->barWidth); + return floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? (int) (min(5, $this->barWidth / 15) * $this->writeCount) : $this->step) % $this->barWidth); } public function setBarWidth(int $size) @@ -249,7 +249,7 @@ public function setFormat(string $format) /** * Sets the redraw frequency. * - * @param int|float $freq The frequency in steps + * @param int|null $freq The frequency in steps */ public function setRedrawFrequency(?int $freq) { diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php index 329f240827a11..d51aee98908b3 100644 --- a/src/Symfony/Component/Console/Helper/Table.php +++ b/src/Symfony/Component/Console/Helper/Table.php @@ -454,7 +454,7 @@ private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $tit $formattedTitle = sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3).'...'); } - $titleStart = ($markupLength - $titleLength) / 2; + $titleStart = intdiv($markupLength - $titleLength, 2); if (false === mb_detect_encoding($markup, null, true)) { $markup = substr_replace($markup, $formattedTitle, $titleStart, $titleLength); } else { diff --git a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php index 2d32e1c3d512a..9fdaa570d3100 100644 --- a/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php @@ -535,7 +535,7 @@ public function testRedrawFrequencyIsAtLeastOneIfZeroGiven() public function testRedrawFrequencyIsAtLeastOneIfSmallerOneGiven() { $bar = new ProgressBar($output = $this->getOutputStream(), 0, 0); - $bar->setRedrawFrequency(0.9); + $bar->setRedrawFrequency(0); $bar->start(); $bar->advance(); diff --git a/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php index 2d7cf1035ebc2..082f50aa75e63 100644 --- a/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/PdoStoreTest.php @@ -72,7 +72,7 @@ public function testInvalidTtlConstruct() { $this->expectException(InvalidTtlException::class); - return new PdoStore('sqlite:'.self::$dbFile, [], 0.1, 0.1); + return new PdoStore('sqlite:'.self::$dbFile, [], 0.1, 0); } /** diff --git a/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php b/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php index dc77d03ecd80c..7d9ec0e7ee614 100644 --- a/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php +++ b/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php @@ -42,7 +42,7 @@ public function describe(OutputInterface $output, Data $data, array $context, in $io = $output instanceof SymfonyStyle ? $output : new SymfonyStyle(new ArrayInput([]), $output); $this->dumper->setColors($output->isDecorated()); - $rows = [['date', date('r', $context['timestamp'])]]; + $rows = [['date', date('r', (int) $context['timestamp'])]]; $lastIdentifier = $this->lastIdentifier; $this->lastIdentifier = $clientId; diff --git a/src/Symfony/Component/VarDumper/Command/Descriptor/HtmlDescriptor.php b/src/Symfony/Component/VarDumper/Command/Descriptor/HtmlDescriptor.php index 35a203b0000a5..636b61828d140 100644 --- a/src/Symfony/Component/VarDumper/Command/Descriptor/HtmlDescriptor.php +++ b/src/Symfony/Component/VarDumper/Command/Descriptor/HtmlDescriptor.php @@ -94,7 +94,7 @@ public function describe(OutputInterface $output, Data $data, array $context, in private function extractDate(array $context, string $format = 'r'): string { - return date($format, $context['timestamp']); + return date($format, (int) $context['timestamp']); } private function renderTags(array $tags): string diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index b1f0206d547db..b4b8520642628 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -523,7 +523,7 @@ public function getTestsForDump() /** * @dataProvider getTimestampTests */ - public function testParseTimestampAsUnixTimestampByDefault($yaml, $year, $month, $day, $hour, $minute, $second) + public function testParseTimestampAsUnixTimestampByDefault(string $yaml, int $year, int $month, int $day, int $hour, int $minute, int $second) { $this->assertSame(gmmktime($hour, $minute, $second, $month, $day, $year), Inline::parse($yaml)); } @@ -531,37 +531,37 @@ public function testParseTimestampAsUnixTimestampByDefault($yaml, $year, $month, /** * @dataProvider getTimestampTests */ - public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second, $timezone) + public function testParseTimestampAsDateTimeObject(string $yaml, int $year, int $month, int $day, int $hour, int $minute, int $second, int $microsecond, string $timezone) { $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); $expected->setDate($year, $month, $day); - $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + $expected->setTime($hour, $minute, $second, $microsecond); $date = Inline::parse($yaml, Yaml::PARSE_DATETIME); $this->assertEquals($expected, $date); $this->assertSame($timezone, $date->format('O')); } - public function getTimestampTests() + public function getTimestampTests(): array { return [ - 'canonical' => ['2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1, '+0000'], - 'ISO-8601' => ['2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1, '-0500'], - 'spaced' => ['2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1, '-0500'], - 'date' => ['2001-12-15', 2001, 12, 15, 0, 0, 0, '+0000'], + 'canonical' => ['2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43, 100000, '+0000'], + 'ISO-8601' => ['2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43, 100000, '-0500'], + 'spaced' => ['2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43, 100000, '-0500'], + 'date' => ['2001-12-15', 2001, 12, 15, 0, 0, 0, 0, '+0000'], ]; } /** * @dataProvider getTimestampTests */ - public function testParseNestedTimestampListAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second) + public function testParseNestedTimestampListAsDateTimeObject(string $yaml, int $year, int $month, int $day, int $hour, int $minute, int $second, int $microsecond) { $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); $expected->setDate($year, $month, $day); - $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + $expected->setTime($hour, $minute, $second, $microsecond); $expectedNested = ['nested' => [$expected]]; $yamlNested = "{nested: [$yaml]}"; From 5af6edae62dbbd5885c62059c2b864e54e97af47 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 14:37:28 +0200 Subject: [PATCH 28/78] [FrameworkBundle][WebProfilerBundle] Don't pass null to string parameters Signed-off-by: Alexander M. Turek --- .../FrameworkBundle/Console/Descriptor/XmlDescriptor.php | 4 ++-- .../FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php | 6 ++++-- .../EventListener/WebDebugToolbarListener.php | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php index b11674a31b113..e0ea8233f16ea 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php @@ -285,7 +285,7 @@ private function getContainerDefinitionDocument(Definition $definition, string $ $descriptionXML->appendChild($dom->createCDATASection($classDescription)); } - $serviceXML->setAttribute('class', $definition->getClass()); + $serviceXML->setAttribute('class', $definition->getClass() ?? ''); if ($factory = $definition->getFactory()) { $serviceXML->appendChild($factoryXML = $dom->createElement('factory')); @@ -311,7 +311,7 @@ private function getContainerDefinitionDocument(Definition $definition, string $ $serviceXML->setAttribute('abstract', $definition->isAbstract() ? 'true' : 'false'); $serviceXML->setAttribute('autowired', $definition->isAutowired() ? 'true' : 'false'); $serviceXML->setAttribute('autoconfigured', $definition->isAutoconfigured() ? 'true' : 'false'); - $serviceXML->setAttribute('file', $definition->getFile()); + $serviceXML->setAttribute('file', $definition->getFile() ?? ''); $calls = $definition->getMethodCalls(); if (\count($calls) > 0) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php index b2a84ed536863..6eb02fa11a8d9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php @@ -76,8 +76,10 @@ public function __wakeup() public function __destruct() { - $fs = new Filesystem(); - $fs->remove($this->cacheDir); + if ($this->cacheDir) { + $fs = new Filesystem(); + $fs->remove($this->cacheDir); + } } protected function configureRoutes(RouteCollectionBuilder $routes) diff --git a/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php b/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php index 7f41db3052f40..a681f5d2427a6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php +++ b/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php @@ -103,7 +103,7 @@ public function onKernelResponse(FilterResponseEvent $event) || $response->isRedirection() || ($response->headers->has('Content-Type') && false === strpos($response->headers->get('Content-Type'), 'html')) || 'html' !== $request->getRequestFormat() - || false !== stripos($response->headers->get('Content-Disposition'), 'attachment;') + || false !== stripos($response->headers->get('Content-Disposition', ''), 'attachment;') ) { return; } From 8fbf3bb3c7903be23afa0482e0b46f387390aaa3 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 6 Jun 2021 14:53:30 +0200 Subject: [PATCH 29/78] [Security] Fix SerializableUser fixture Signed-off-by: Alexander M. Turek --- .../Authentication/Token/AbstractTokenTest.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php index b1e7993de70ae..fccc7768ffb28 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php @@ -322,12 +322,22 @@ public function getSalt() public function serialize(): string { - return serialize($this->name); + return serialize($this->__serialize()); } public function unserialize($serialized): void { - $this->name = unserialize($serialized); + $this->__unserialize(unserialize($serialized)); + } + + public function __serialize(): array + { + return ['name' => $this->name]; + } + + public function __unserialize(array $data): void + { + ['name' => $this->name] = $data; } } From dca28a219cde260f35ba09eb0fd7cd98a04bc118 Mon Sep 17 00:00:00 2001 From: matason Date: Sun, 6 Jun 2021 17:32:26 +0100 Subject: [PATCH 30/78] [PasswordHasher] Prevent PHP fatal error when using auto algorithm --- .../PasswordHasher/Hasher/PasswordHasherFactory.php | 8 ++++++-- .../Tests/Hasher/PasswordHasherFactoryTest.php | 11 +++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactory.php b/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactory.php index 62c5e37e85a81..a2f24224744aa 100644 --- a/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactory.php +++ b/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactory.php @@ -116,9 +116,13 @@ private function getHasherConfigFromAlgorithm(array $config): array if ('auto' === $config['algorithm']) { // "plaintext" is not listed as any leaked hashes could then be used to authenticate directly if (SodiumPasswordHasher::isSupported()) { - $algorithms = ['native', 'sodium', 'pbkdf2', $config['hash_algorithm']]; + $algorithms = ['native', 'sodium', 'pbkdf2']; } else { - $algorithms = ['native', 'pbkdf2', $config['hash_algorithm']]; + $algorithms = ['native', 'pbkdf2']; + } + + if ($config['hash_algorithm'] ?? '') { + $algorithms[] = $config['hash_algorithm']; } $hasherChain = []; diff --git a/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php b/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php index bebd95b1958df..6012ff80c8c39 100644 --- a/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php +++ b/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php @@ -18,6 +18,7 @@ use Symfony\Component\PasswordHasher\Hasher\PasswordHasherAwareInterface; use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory; use Symfony\Component\PasswordHasher\Hasher\SodiumPasswordHasher; +use Symfony\Component\PasswordHasher\PasswordHasherInterface; use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder; use Symfony\Component\Security\Core\User\InMemoryUser; use Symfony\Component\Security\Core\User\UserInterface; @@ -85,6 +86,16 @@ public function testGetHasherConfiguredForConcreteClassWithClassName() $this->assertEquals($expectedHasher->hash('foo', ''), $hasher->hash('foo', '')); } + public function testGetHasherConfiguredWithAuto() + { + $factory = new PasswordHasherFactory([ + 'auto' => ['algorithm' => 'auto'], + ]); + + $hasher = $factory->getPasswordHasher('auto'); + $this->assertInstanceOf(PasswordHasherInterface::class, $hasher); + } + public function testGetNamedHasherForHasherAware() { $factory = new PasswordHasherFactory([ From a245efb6045aaf9368ef5522d2791572ecf24e33 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 6 Jun 2021 16:23:08 +0200 Subject: [PATCH 31/78] [travis] fix travis hopefuly --- .travis.yml | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1b9678a7b6388..d7752d038ac29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: php -dist: xenial +dist: bionic git: depth: 2 @@ -11,6 +11,9 @@ addons: - language-pack-fr-base - zookeeperd - libzookeeper-mt-dev + - librabbitmq-dev + - libsodium-dev + - libtidy-dev env: global: @@ -36,15 +39,6 @@ cache: - ~/php-ext before_install: - - | - # Enable Sury ppa - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6B05F25D762E3157 - sudo add-apt-repository -y ppa:ondrej/php - sudo rm /etc/apt/sources.list.d/google-chrome.list - sudo rm /etc/apt/sources.list.d/mongodb-3.4.list - sudo apt update - sudo apt install -y librabbitmq-dev libsodium-dev - - | # General configuration set -e @@ -123,8 +117,13 @@ before_install: - | # php.ini configuration + ( + for PHP in $TRAVIS_PHP_VERSION $php_extra; do + phpenv global $PHP 2>/dev/null || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & + done + wait + ) for PHP in $TRAVIS_PHP_VERSION $php_extra; do - phpenv global $PHP 2>/dev/null || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/16.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini echo date.timezone = Europe/Paris >> $INI echo memory_limit = -1 >> $INI @@ -132,34 +131,30 @@ before_install: echo session.gc_probability = 0 >> $INI echo opcache.enable_cli = 1 >> $INI echo apc.enable_cli = 1 >> $INI - if [[ $PHP != 8.* ]]; then - echo extension = memcached.so >> $INI - fi done find ~/.phpenv -name xdebug.ini -delete + composer self-update + composer self-update --2 + - | # Install extra PHP extensions for PHP in $TRAVIS_PHP_VERSION $php_extra; do export PHP=$PHP phpenv global $PHP - composer self-update - composer self-update --2 INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini if ! php --ri sodium > /dev/null; then tfold ext.libsodium tpecl libsodium sodium.so $INI fi - if [[ $PHP = 8.* ]]; then - tfold ext.memcached tpecl memcached-3.1.5 memcached.so $INI - else + if [[ $PHP != 8.* ]]; then tfold ext.zookeeper tpecl zookeeper-0.7.2 zookeeper.so $INI - tfold ext.amqp tpecl amqp-1.10.2 amqp.so $INI fi - - tfold ext.mongodb tpecl mongodb-1.9.0 mongodb.so $INI + tfold ext.memcached tpecl memcached-3.1.5 memcached.so $INI + tfold ext.amqp tpecl amqp-1.11.0beta amqp.so $INI tfold ext.apcu tpecl apcu-5.1.19 apcu.so $INI tfold ext.igbinary tpecl igbinary-3.1.6 igbinary.so $INI tfold ext.redis tpecl redis-5.2.3 redis.so $INI "no" + tfold ext.mongodb tpecl mongodb-1.9.1 mongodb.so $INI done install: From e7552ab7b3af52b3cf751b4d0f00807d5bc9237b Mon Sep 17 00:00:00 2001 From: Dragos Protung Date: Mon, 7 Jun 2021 12:06:32 +0200 Subject: [PATCH 32/78] [Serializer] Fix not null return check by "getCollectionKeyTypes" --- .../Serializer/Normalizer/AbstractObjectNormalizer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 9ab8c684c9cce..874f910655da2 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -470,7 +470,7 @@ private function validateAndDenormalize(string $currentClass, string $attribute, $builtinType = Type::BUILTIN_TYPE_OBJECT; $class = $collectionValueType->getClassName().'[]'; - if (null !== $collectionKeyType = $type->getCollectionKeyTypes()) { + if (\count($collectionKeyType = $type->getCollectionKeyTypes()) > 0) { [$context['key_type']] = $collectionKeyType; } } elseif ($type->isCollection() && \count($collectionValueType = $type->getCollectionValueTypes()) > 0 && Type::BUILTIN_TYPE_ARRAY === $collectionValueType[0]->getBuiltinType()) { From 7341e29f2f87c8932baea93895e5ded4c482bf49 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 11:04:09 +0200 Subject: [PATCH 33/78] Fix tests (bis) --- src/Symfony/Component/HttpClient/composer.json | 1 + .../Tests/File/MimeType/MimeTypeTest.php | 3 ++- .../Mime/Tests/FileBinaryMimeTypeGuesserTest.php | 5 +++++ .../HttpClient/Test/Fixtures/web/index.php | 5 +++-- .../HttpClient/Test/HttpClientTestCase.php | 14 +++++++++----- .../Contracts/HttpClient/Test/TestHttpServer.php | 5 +++-- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index a6209060a5548..6c45b6dee3032 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -33,6 +33,7 @@ "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", "symfony/dependency-injection": "^4.3|^5.0", + "symfony/http-client-contracts": "^1.1.11|~2.1.4|~2.2.1|~2.3.2|^2.4.1", "symfony/http-kernel": "^4.4.13", "symfony/process": "^4.2|^5.0" }, diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php b/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php index bbc74e74a6975..42d5c436cdc84 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php @@ -65,7 +65,8 @@ public function testGuessFileWithUnknownExtension() public function testGuessWithDuplicatedFileType() { - $this->assertSame('application/vnd.openxmlformats-officedocument.wordprocessingml.document', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.docx')); + $type = MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.docx'); + $this->assertTrue(\in_array($type, ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'], true)); } public function testGuessWithIncorrectPath() diff --git a/src/Symfony/Component/Mime/Tests/FileBinaryMimeTypeGuesserTest.php b/src/Symfony/Component/Mime/Tests/FileBinaryMimeTypeGuesserTest.php index 0742732895e52..5d225038d4336 100644 --- a/src/Symfony/Component/Mime/Tests/FileBinaryMimeTypeGuesserTest.php +++ b/src/Symfony/Component/Mime/Tests/FileBinaryMimeTypeGuesserTest.php @@ -20,4 +20,9 @@ protected function getGuesser(): MimeTypeGuesserInterface { return new FileBinaryMimeTypeGuesser(); } + + public function testGuessWithDuplicatedFileType() + { + $this->markTestSkipped('Result varies depending on the OS'); + } } diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index 30a7049758d0d..a5cf236a35cfd 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -30,6 +30,7 @@ } $json = json_encode($vars, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); +$localhost = gethostbyname('localhost'); switch ($vars['REQUEST_URI']) { default: @@ -41,7 +42,7 @@ case '/': case '/?a=a&b=b': - case 'http://127.0.0.1:8057/': + case "http://$localhost:8057/": case 'http://localhost:8057/': ob_start('ob_gzhandler'); break; @@ -74,7 +75,7 @@ case '/301': if ('Basic Zm9vOmJhcg==' === $vars['HTTP_AUTHORIZATION']) { - header('Location: http://127.0.0.1:8057/302', true, 301); + header("Location: http://$localhost:8057/302", true, 301); } break; diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index f3e75c9337c2c..af19e387f8a75 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -335,6 +335,7 @@ public function test304() public function testRedirects() { $client = $this->getHttpClient(__FUNCTION__); + $localhost = gethostbyname('localhost'); $response = $client->request('POST', 'http://localhost:8057/301', [ 'auth_basic' => 'foo:bar', 'body' => function () { @@ -352,7 +353,7 @@ public function testRedirects() $expected = [ 'HTTP/1.1 301 Moved Permanently', - 'Location: http://127.0.0.1:8057/302', + "Location: http://$localhost:8057/302", 'Content-Type: application/json', 'HTTP/1.1 302 Found', 'Location: http://localhost:8057/', @@ -425,6 +426,7 @@ public function testRedirect307() public function testMaxRedirects() { $client = $this->getHttpClient(__FUNCTION__); + $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://localhost:8057/301', [ 'max_redirects' => 1, 'auth_basic' => 'foo:bar', @@ -442,7 +444,7 @@ public function testMaxRedirects() $expected = [ 'HTTP/1.1 301 Moved Permanently', - 'Location: http://127.0.0.1:8057/302', + "Location: http://$localhost:8057/302", 'Content-Type: application/json', 'HTTP/1.1 302 Found', 'Location: http://localhost:8057/', @@ -691,8 +693,9 @@ public function testOnProgressError() public function testResolve() { $client = $this->getHttpClient(__FUNCTION__); + $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://symfony.com:8057/', [ - 'resolve' => ['symfony.com' => '127.0.0.1'], + 'resolve' => ['symfony.com' => $localhost], ]); $this->assertSame(200, $response->getStatusCode()); @@ -706,15 +709,16 @@ public function testResolve() public function testIdnResolve() { $client = $this->getHttpClient(__FUNCTION__); + $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://0-------------------------------------------------------------0.com:8057/', [ - 'resolve' => ['0-------------------------------------------------------------0.com' => '127.0.0.1'], + 'resolve' => ['0-------------------------------------------------------------0.com' => $localhost], ]); $this->assertSame(200, $response->getStatusCode()); $response = $client->request('GET', 'http://Bücher.example:8057/', [ - 'resolve' => ['xn--bcher-kva.example' => '127.0.0.1'], + 'resolve' => ['xn--bcher-kva.example' => $localhost], ]); $this->assertSame(200, $response->getStatusCode()); diff --git a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php index 06a11444e35e4..a521a96683a2e 100644 --- a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php +++ b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php @@ -31,15 +31,16 @@ public static function start(int $port = 8057) }); } + $localhost = gethostbyname('localhost'); $finder = new PhpExecutableFinder(); - $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', '127.0.0.1:'.$port])); + $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', "$localhost:$port"])); $process->setWorkingDirectory(__DIR__.'/Fixtures/web'); $process->start(); self::$process[$port] = $process; do { usleep(50000); - } while (!@fopen('http://127.0.0.1:'.$port, 'r')); + } while (!@fopen("http://$localhost:$port", 'r')); return $process; } From a71fb4b8f2fc78670cc1af8bd4f7f286ad470262 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 15:37:24 +0200 Subject: [PATCH 34/78] fix tests (ter) --- .github/workflows/tests.yml | 18 +++++++++--------- .../HttpClient/Tests/CurlHttpClientTest.php | 11 +++++++---- src/Symfony/Component/HttpClient/composer.json | 3 +-- .../HttpClient/Test/HttpClientTestCase.php | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3f5e8ef78fbc7..1e5bffaca5171 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - php: ['7.1', '7.4'] + php: ['7.1', '8.0'] services: ldap: @@ -106,14 +106,14 @@ jobs: LDAP_HOST: localhost LDAP_PORT: 3389 - - name: Run HTTP push tests - if: matrix.php == '7.4' - run: | - [ -d .phpunit ] && mv .phpunit .phpunit.bak - wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/vulcain_0.1.3_Linux_x86_64.tar.gz -O - | tar xz && mv vulcain /usr/local/bin - docker run --rm -e COMPOSER_ROOT_VERSION -v $(pwd):/app -v $(which composer):/usr/local/bin/composer -v /usr/local/bin/vulcain:/usr/local/bin/vulcain -w /app php:7.4-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push - sudo rm -rf .phpunit - [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit + #- name: Run HTTP push tests + # if: matrix.php == '8.0' + # run: | + # [ -d .phpunit ] && mv .phpunit .phpunit.bak + # wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/vulcain_0.1.3_Linux_x86_64.tar.gz -O - | tar xz && mv vulcain /usr/local/bin + # docker run --rm -e COMPOSER_ROOT_VERSION -v $(pwd):/app -v $(which composer):/usr/local/bin/composer -v $(which vulcain):/usr/local/bin/vulcain -w /app php:8.0-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push + # sudo rm -rf .phpunit + # [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit nightly: name: PHPUnit on PHP nightly diff --git a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php index 269705a3f4b9b..8875f60628a0d 100644 --- a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php @@ -38,7 +38,8 @@ protected function getHttpClient(string $testCase): HttpClientInterface public function testBindToPort() { $client = $this->getHttpClient(__FUNCTION__); - $response = $client->request('GET', 'http://localhost:8057', ['bindto' => '127.0.0.1:9876']); + $localhost = gethostbyname('localhost'); + $response = $client->request('GET', "http://$localhost:8057", ['bindto' => "$localhost:9876"]); $response->getStatusCode(); $r = new \ReflectionProperty($response, 'handle'); @@ -46,7 +47,7 @@ public function testBindToPort() $curlInfo = curl_getinfo($r->getValue($response)); - self::assertSame('127.0.0.1', $curlInfo['local_ip']); + self::assertSame($localhost, $curlInfo['local_ip']); self::assertSame(9876, $curlInfo['local_port']); } @@ -152,13 +153,15 @@ private function getVulcainClient(): CurlHttpClient return $client; } - if (['application/json'] !== $client->request('GET', 'http://127.0.0.1:8057/json')->getHeaders()['content-type']) { + $localhost = gethostbyname('localhost'); + + if (['application/json'] !== $client->request('GET', "http://$localhost:8057/json")->getHeaders()['content-type']) { $this->markTestSkipped('symfony/http-client-contracts >= 2.0.1 required'); } $process = new Process(['vulcain'], null, [ 'DEBUG' => 1, - 'UPSTREAM' => 'http://127.0.0.1:8057', + 'UPSTREAM' => "http://$localhost:8057", 'ADDR' => ':3000', 'KEY_FILE' => __DIR__.'/Fixtures/tls/server.key', 'CERT_FILE' => __DIR__.'/Fixtures/tls/server.crt', diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index 6c45b6dee3032..0e4af20f44da8 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -23,7 +23,7 @@ "require": { "php": ">=7.1.3", "psr/log": "^1.0", - "symfony/http-client-contracts": "^1.1.10|^2", + "symfony/http-client-contracts": "^1.1.11|~2.1.4|~2.2.1|~2.3.2|^2.4.1", "symfony/polyfill-php73": "^1.11", "symfony/service-contracts": "^1.0|^2" }, @@ -33,7 +33,6 @@ "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", "symfony/dependency-injection": "^4.3|^5.0", - "symfony/http-client-contracts": "^1.1.11|~2.1.4|~2.2.1|~2.3.2|^2.4.1", "symfony/http-kernel": "^4.4.13", "symfony/process": "^4.2|^5.0" }, diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index af19e387f8a75..77329af8c8ced 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -860,7 +860,7 @@ public function testProxy() $body = $response->toArray(); $this->assertSame('localhost:8057', $body['HTTP_HOST']); - $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.0\.1):8057/$#', $body['REQUEST_URI']); + $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.\d+\.1):8057/$#', $body['REQUEST_URI']); $response = $client->request('GET', 'http://localhost:8057/', [ 'proxy' => 'http://foo:b%3Dar@localhost:8057', From 65e96dd13f65ce13ab485dc758d1e3779f66de3c Mon Sep 17 00:00:00 2001 From: Kien Nguyen Date: Mon, 7 Jun 2021 22:03:43 +0700 Subject: [PATCH 35/78] Add missing translations for Swedish --- .../Security/Core/Resources/translations/security.sv.xlf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.sv.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.sv.xlf index a2bbf44e3ea0d..6d7b248499bb3 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.sv.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.sv.xlf @@ -70,6 +70,14 @@ Invalid or expired login link. Ogiltig eller utgången inloggningslänk. + + Too many failed login attempts, please try again in %minutes% minute. + För många misslyckade inloggningsförsök, försök igen om %minutes% minut. + + + Too many failed login attempts, please try again in %minutes% minutes. + För många misslyckade inloggningsförsök, försök igen om %minutes% minuter. + From a1f376b276b7276611c59b81ed3e2b82899773ca Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 17:05:04 +0200 Subject: [PATCH 36/78] bump ext-mongodb --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d7752d038ac29..311b10c7c82de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -154,7 +154,7 @@ before_install: tfold ext.apcu tpecl apcu-5.1.19 apcu.so $INI tfold ext.igbinary tpecl igbinary-3.1.6 igbinary.so $INI tfold ext.redis tpecl redis-5.2.3 redis.so $INI "no" - tfold ext.mongodb tpecl mongodb-1.9.1 mongodb.so $INI + tfold ext.mongodb tpecl mongodb-1.10.0alpha1 mongodb.so $INI done install: From d3249baa06230558fc2e5b690b71b18955d88c7b Mon Sep 17 00:00:00 2001 From: Kien Nguyen Date: Mon, 7 Jun 2021 21:45:36 +0700 Subject: [PATCH 37/78] Add missing translations for Thai --- .../Security/Core/Resources/translations/security.th.xlf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf index 2b2f1e068ba76..658fcbf99eae4 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.th.xlf @@ -70,6 +70,14 @@ Invalid or expired login link. ลิงค์เข้าสู่ระบบไม่ถูกต้องหรือหมดอายุไปแล้ว + + Too many failed login attempts, please try again in %minutes% minute. + มีความพยายามเข้าสู่ระบบล้มเหลวมากเกินไป โปรดลองอีกครั้งใน %minutes% นาที + + + Too many failed login attempts, please try again in %minutes% minutes. + มีความพยายามเข้าสู่ระบบล้มเหลวมากเกินไป โปรดลองอีกครั้งใน %minutes% นาที + From e705a66a7f9363e5cc106c9d171a44ffac661b63 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 17:35:37 +0200 Subject: [PATCH 38/78] fix tests (quater) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 311b10c7c82de..044f209268474 100644 --- a/.travis.yml +++ b/.travis.yml @@ -119,7 +119,7 @@ before_install: # php.ini configuration ( for PHP in $TRAVIS_PHP_VERSION $php_extra; do - phpenv global $PHP 2>/dev/null || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & + (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & done wait ) From a70b537fbc5331616434b43fef5341e315499fe7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Jun 2021 20:50:09 +0200 Subject: [PATCH 39/78] fix tests (quinter) --- .travis.yml | 1 + .../HttpClient/Tests/CurlHttpClientTest.php | 11 ++++------- src/Symfony/Component/HttpClient/composer.json | 2 +- .../HttpClient/Test/Fixtures/web/index.php | 5 ++--- .../HttpClient/Test/HttpClientTestCase.php | 16 ++++++---------- .../Contracts/HttpClient/Test/TestHttpServer.php | 5 ++--- 6 files changed, 16 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index 044f209268474..738f4fc2b3a73 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ before_install: # General configuration set -e stty cols 120 + sudo sed -i 's/127\.0\.1\.1 localhost/127.0.0.1 localhost/' /etc/hosts cp .github/composer-config.json "$(composer config home)/config.json" git config --global user.email "" git config --global user.name "Symfony" diff --git a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php index 8875f60628a0d..269705a3f4b9b 100644 --- a/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php @@ -38,8 +38,7 @@ protected function getHttpClient(string $testCase): HttpClientInterface public function testBindToPort() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); - $response = $client->request('GET', "http://$localhost:8057", ['bindto' => "$localhost:9876"]); + $response = $client->request('GET', 'http://localhost:8057', ['bindto' => '127.0.0.1:9876']); $response->getStatusCode(); $r = new \ReflectionProperty($response, 'handle'); @@ -47,7 +46,7 @@ public function testBindToPort() $curlInfo = curl_getinfo($r->getValue($response)); - self::assertSame($localhost, $curlInfo['local_ip']); + self::assertSame('127.0.0.1', $curlInfo['local_ip']); self::assertSame(9876, $curlInfo['local_port']); } @@ -153,15 +152,13 @@ private function getVulcainClient(): CurlHttpClient return $client; } - $localhost = gethostbyname('localhost'); - - if (['application/json'] !== $client->request('GET', "http://$localhost:8057/json")->getHeaders()['content-type']) { + if (['application/json'] !== $client->request('GET', 'http://127.0.0.1:8057/json')->getHeaders()['content-type']) { $this->markTestSkipped('symfony/http-client-contracts >= 2.0.1 required'); } $process = new Process(['vulcain'], null, [ 'DEBUG' => 1, - 'UPSTREAM' => "http://$localhost:8057", + 'UPSTREAM' => 'http://127.0.0.1:8057', 'ADDR' => ':3000', 'KEY_FILE' => __DIR__.'/Fixtures/tls/server.key', 'CERT_FILE' => __DIR__.'/Fixtures/tls/server.crt', diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index 0e4af20f44da8..a6209060a5548 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -23,7 +23,7 @@ "require": { "php": ">=7.1.3", "psr/log": "^1.0", - "symfony/http-client-contracts": "^1.1.11|~2.1.4|~2.2.1|~2.3.2|^2.4.1", + "symfony/http-client-contracts": "^1.1.10|^2", "symfony/polyfill-php73": "^1.11", "symfony/service-contracts": "^1.0|^2" }, diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index a5cf236a35cfd..30a7049758d0d 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -30,7 +30,6 @@ } $json = json_encode($vars, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); -$localhost = gethostbyname('localhost'); switch ($vars['REQUEST_URI']) { default: @@ -42,7 +41,7 @@ case '/': case '/?a=a&b=b': - case "http://$localhost:8057/": + case 'http://127.0.0.1:8057/': case 'http://localhost:8057/': ob_start('ob_gzhandler'); break; @@ -75,7 +74,7 @@ case '/301': if ('Basic Zm9vOmJhcg==' === $vars['HTTP_AUTHORIZATION']) { - header("Location: http://$localhost:8057/302", true, 301); + header('Location: http://127.0.0.1:8057/302', true, 301); } break; diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index 77329af8c8ced..f3e75c9337c2c 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -335,7 +335,6 @@ public function test304() public function testRedirects() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); $response = $client->request('POST', 'http://localhost:8057/301', [ 'auth_basic' => 'foo:bar', 'body' => function () { @@ -353,7 +352,7 @@ public function testRedirects() $expected = [ 'HTTP/1.1 301 Moved Permanently', - "Location: http://$localhost:8057/302", + 'Location: http://127.0.0.1:8057/302', 'Content-Type: application/json', 'HTTP/1.1 302 Found', 'Location: http://localhost:8057/', @@ -426,7 +425,6 @@ public function testRedirect307() public function testMaxRedirects() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://localhost:8057/301', [ 'max_redirects' => 1, 'auth_basic' => 'foo:bar', @@ -444,7 +442,7 @@ public function testMaxRedirects() $expected = [ 'HTTP/1.1 301 Moved Permanently', - "Location: http://$localhost:8057/302", + 'Location: http://127.0.0.1:8057/302', 'Content-Type: application/json', 'HTTP/1.1 302 Found', 'Location: http://localhost:8057/', @@ -693,9 +691,8 @@ public function testOnProgressError() public function testResolve() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://symfony.com:8057/', [ - 'resolve' => ['symfony.com' => $localhost], + 'resolve' => ['symfony.com' => '127.0.0.1'], ]); $this->assertSame(200, $response->getStatusCode()); @@ -709,16 +706,15 @@ public function testResolve() public function testIdnResolve() { $client = $this->getHttpClient(__FUNCTION__); - $localhost = gethostbyname('localhost'); $response = $client->request('GET', 'http://0-------------------------------------------------------------0.com:8057/', [ - 'resolve' => ['0-------------------------------------------------------------0.com' => $localhost], + 'resolve' => ['0-------------------------------------------------------------0.com' => '127.0.0.1'], ]); $this->assertSame(200, $response->getStatusCode()); $response = $client->request('GET', 'http://Bücher.example:8057/', [ - 'resolve' => ['xn--bcher-kva.example' => $localhost], + 'resolve' => ['xn--bcher-kva.example' => '127.0.0.1'], ]); $this->assertSame(200, $response->getStatusCode()); @@ -860,7 +856,7 @@ public function testProxy() $body = $response->toArray(); $this->assertSame('localhost:8057', $body['HTTP_HOST']); - $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.\d+\.1):8057/$#', $body['REQUEST_URI']); + $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.0\.1):8057/$#', $body['REQUEST_URI']); $response = $client->request('GET', 'http://localhost:8057/', [ 'proxy' => 'http://foo:b%3Dar@localhost:8057', diff --git a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php index a521a96683a2e..06a11444e35e4 100644 --- a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php +++ b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php @@ -31,16 +31,15 @@ public static function start(int $port = 8057) }); } - $localhost = gethostbyname('localhost'); $finder = new PhpExecutableFinder(); - $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', "$localhost:$port"])); + $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', '127.0.0.1:'.$port])); $process->setWorkingDirectory(__DIR__.'/Fixtures/web'); $process->start(); self::$process[$port] = $process; do { usleep(50000); - } while (!@fopen("http://$localhost:$port", 'r')); + } while (!@fopen('http://127.0.0.1:'.$port, 'r')); return $process; } From 32cac1c6f2e541c89b3bebe16d25b3309dc152e6 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Jun 2021 21:46:40 +0200 Subject: [PATCH 40/78] Remove duplicate catch block --- .../Tests/Functional/CachePoolsTest.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php index e6f6bbb3158d8..fc5d64f4d2fed 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolsTest.php @@ -39,11 +39,6 @@ public function testRedisCachePools() throw $e; } $this->markTestSkipped($e->getMessage()); - } catch (\PHPUnit\Framework\Error\Warning $e) { - if (0 !== strpos($e->getMessage(), 'unable to connect to')) { - throw $e; - } - $this->markTestSkipped($e->getMessage()); } catch (InvalidArgumentException $e) { if (0 !== strpos($e->getMessage(), 'Redis connection ')) { throw $e; @@ -67,11 +62,6 @@ public function testRedisCustomCachePools() throw $e; } $this->markTestSkipped($e->getMessage()); - } catch (\PHPUnit\Framework\Error\Warning $e) { - if (0 !== strpos($e->getMessage(), 'unable to connect to')) { - throw $e; - } - $this->markTestSkipped($e->getMessage()); } } From a5be1968278dc956dd9e9d8775fc34bdc97202bf Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 8 Jun 2021 09:24:10 +0200 Subject: [PATCH 41/78] [DependencyInjection] Fix testServiceSubscriber for PHP 8.1 --- .../Tests/Dumper/PhpDumperTest.php | 6 +- .../php/services_subscriber_php81.php | 111 ++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index f088bcf3c36f0..b46fbf937b910 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -950,7 +950,11 @@ public function process(ContainerBuilder $container) $dumper = new PhpDumper($container); - $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_subscriber.php', $dumper->dump()); + if (80100 <= \PHP_VERSION_ID) { + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_subscriber_php81.php', $dumper->dump()); + } else { + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_subscriber.php', $dumper->dump()); + } } public function testPrivateWithIgnoreOnInvalidReference() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php new file mode 100644 index 0000000000000..e897fa53a8e31 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php @@ -0,0 +1,111 @@ +getService = \Closure::fromCallable([$this, 'getService']); + $this->services = $this->privates = []; + $this->methodMap = [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'getTestServiceSubscriberService', + 'foo_service' => 'getFooServiceService', + 'late_alias' => 'getLateAliasService', + ]; + $this->aliases = [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1' => 'late_alias', + ]; + } + + public function compile(): void + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled(): bool + { + return true; + } + + public function getRemovedIds(): array + { + return [ + '.service_locator.Txga9_U' => true, + '.service_locator.Txga9_U.foo_service' => true, + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true, + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1' => true, + 'late_alias' => true, + ]; + } + + /** + * Gets the public 'Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber + */ + protected function getTestServiceSubscriberService() + { + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber(); + } + + /** + * Gets the public 'foo_service' shared autowired service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber + */ + protected function getFooServiceService() + { + return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber((new \Symfony\Component\DependencyInjection\Argument\ServiceLocator($this->getService, [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => ['privates', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', 'getCustomDefinitionService', false], + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false], + 'bar' => ['services', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', 'getTestServiceSubscriberService', false], + 'baz' => ['privates', 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', 'getCustomDefinitionService', false], + 'late_alias' => ['services', 'late_alias', 'getLateAliasService', false], + ], [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', + 'bar' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', + 'baz' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', + 'late_alias' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestDefinition1', + ]))->withContext('foo_service', $this)); + } + + /** + * Gets the public 'late_alias' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1 + */ + protected function getLateAliasService() + { + return $this->services['late_alias'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1(); + } + + /** + * Gets the private 'Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition + */ + protected function getCustomDefinitionService() + { + return $this->privates['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition(); + } +} From 622fa2dd6a79e943f80c89868b5ba89bbda53396 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 8 Jun 2021 10:38:51 +0200 Subject: [PATCH 42/78] sync logic to determine the default value --- .../Tests/DependencyInjection/ConfigurationTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index b056ed498e5ad..8273beafdcfb9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -17,6 +17,7 @@ use Symfony\Bundle\FullStack; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\Lock\Store\SemaphoreStore; use Symfony\Component\Mailer\Mailer; @@ -496,7 +497,7 @@ protected static function getBundleDefaultConfig() 'directory' => '%kernel.cache_dir%/pools', 'default_redis_provider' => 'redis://localhost', 'default_memcached_provider' => 'memcached://localhost', - 'default_pdo_provider' => class_exists(Connection::class) ? 'database_connection' : null, + 'default_pdo_provider' => ContainerBuilder::willBeAvailable('doctrine/dbal', Connection::class, ['symfony/framework-bundle']) ? 'database_connection' : null, 'prefix_seed' => '_%kernel.project_dir%.%kernel.container_class%', ], 'workflows' => [ From 117cb8f085d7736a61cfd6cc43e64842056e3d8e Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Tue, 8 Jun 2021 13:19:15 +0200 Subject: [PATCH 43/78] [DependencyInjection] Fix CSV file mime type guess test for PHP 8.1 --- src/Symfony/Component/Mime/Tests/MimeTypesTest.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Mime/Tests/MimeTypesTest.php b/src/Symfony/Component/Mime/Tests/MimeTypesTest.php index 9b16ff6807046..50d99ae5159a7 100644 --- a/src/Symfony/Component/Mime/Tests/MimeTypesTest.php +++ b/src/Symfony/Component/Mime/Tests/MimeTypesTest.php @@ -75,7 +75,12 @@ public function testCustomMimeTypes() } /** - * PHP 8 detects .csv files as "application/csv" while PHP 7 returns "text/plain". + * PHP 8 detects .csv files as "application/csv" (or "text/csv", depending + * on your system) while PHP 7 returns "text/plain". + * + * "text/csv" is described by RFC 7111. + * + * @see https://datatracker.ietf.org/doc/html/rfc7111 * * @requires PHP 8 */ @@ -84,7 +89,7 @@ public function testCsvExtension() $mt = new MimeTypes(); $mime = $mt->guessMimeType(__DIR__.'/Fixtures/mimetypes/abc.csv'); - $this->assertSame('application/csv', $mime); + $this->assertContains($mime, ['application/csv', 'text/csv']); $this->assertSame(['csv'], $mt->getExtensions($mime)); } } From fe51b80903546f7cc1bd0c6997ca7f08d2fe2a34 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 8 Jun 2021 11:28:08 +0200 Subject: [PATCH 44/78] Optimize travis file a bit --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 738f4fc2b3a73..d0dd9bb830613 100644 --- a/.travis.yml +++ b/.travis.yml @@ -120,7 +120,7 @@ before_install: # php.ini configuration ( for PHP in $TRAVIS_PHP_VERSION $php_extra; do - (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & + ([[ $PHP != 7.4 ]] && phpenv global $PHP 2>/dev/null) || (cd / && wget https://storage.googleapis.com/travis-ci-language-archives/php/binaries/ubuntu/18.04/x86_64/php-$PHP.tar.bz2 -O - | tar -xj) & done wait ) From e91c0b8e489a7f952cab199909f961f6b134de32 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 8 Jun 2021 15:57:16 +0200 Subject: [PATCH 45/78] fix tests --- .../Component/DependencyInjection/ContainerBuilder.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 15a93896a8075..45df70183dda0 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1486,6 +1486,11 @@ final public static function willBeAvailable(string $package, string $class, arr // the package is installed but in dev-mode only, check if this applies to one of the parent packages too $rootPackage = InstalledVersions::getRootPackage()['name'] ?? ''; + + if ('symfony/symfony' === $rootPackage) { + return true; + } + foreach ($parentPackages as $parentPackage) { if ($rootPackage === $parentPackage || (InstalledVersions::isInstalled($parentPackage) && !InstalledVersions::isInstalled($parentPackage, false))) { return true; From aa0e166dc583bfc104b659f3c1bb79de1519461c Mon Sep 17 00:00:00 2001 From: Hugo Monteiro Date: Sat, 5 Jun 2021 16:05:48 +0100 Subject: [PATCH 46/78] [Messenger] fix BC for FrameworkBundle 4.4 with a non-existence alias being used --- .../Messenger/DependencyInjection/MessengerPass.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php index 1a64dac475b02..959f053cc8d77 100644 --- a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php +++ b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php @@ -260,7 +260,11 @@ private function registerReceivers(ContainerBuilder $container, array $busIds) $commandDefinition = $container->getDefinition('console.command.messenger_failed_messages_retry'); $globalReceiverName = $commandDefinition->getArgument(0); if (null !== $globalReceiverName) { - $failureTransportsMap[$commandDefinition->getArgument(0)] = new Reference('messenger.failure_transports.default'); + if ($container->hasAlias('messenger.failure_transports.default')) { + $failureTransportsMap[$globalReceiverName] = new Reference('messenger.failure_transports.default'); + } else { + $failureTransportsMap[$globalReceiverName] = new Reference('messenger.transport.'.$globalReceiverName); + } } } From 18fe0dd89b46fd87dab0801c5ac765af3b093476 Mon Sep 17 00:00:00 2001 From: Maarten Nusteling Date: Mon, 7 Jun 2021 23:48:42 +0200 Subject: [PATCH 47/78] [DependencyInjection] Removed unsetting of environment property in loaders --- .../Loader/XmlFileLoader.php | 16 ++++---- .../Loader/YamlFileLoader.php | 16 ++++---- .../Tests/Fixtures/xml/services29.xml | 31 ++++++++++++++++ .../Tests/Fixtures/xml/services30.xml | 24 ++++++++++++ .../Tests/Fixtures/yaml/services29.yml | 17 +++++++++ .../Tests/Fixtures/yaml/services30.yml | 14 +++++++ .../Tests/Loader/XmlFileLoaderTest.php | 37 +++++++++++++++++++ .../Tests/Loader/YamlFileLoaderTest.php | 37 +++++++++++++++++++ 8 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services29.xml create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services30.xml create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services29.yml create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services30.yml diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 887b4f9d16bd8..75b24dceba22a 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -51,19 +51,19 @@ public function load($resource, string $type = null) $this->container->fileExists($path); - $env = $this->env; - $this->env = null; - try { - $this->loadXml($xml, $path); - } finally { - $this->env = $env; - } + $this->loadXml($xml, $path); if ($this->env) { $xpath = new \DOMXPath($xml); $xpath->registerNamespace('container', self::NS); foreach ($xpath->query(sprintf('//container:when[@env="%s"]', $this->env)) ?: [] as $root) { - $this->loadXml($xml, $path, $root); + $env = $this->env; + $this->env = null; + try { + $this->loadXml($xml, $path, $root); + } finally { + $this->env = $env; + } } } } diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index 31d511196dbff..8f3924dc4fb3d 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -130,13 +130,7 @@ public function load($resource, string $type = null) return; } - $env = $this->env; - $this->env = null; - try { - $this->loadContent($content, $path); - } finally { - $this->env = $env; - } + $this->loadContent($content, $path); // per-env configuration if ($this->env && isset($content['when@'.$this->env])) { @@ -144,7 +138,13 @@ public function load($resource, string $type = null) throw new InvalidArgumentException(sprintf('The "when@%s" key should contain an array in "%s". Check your YAML syntax.', $this->env, $path)); } - $this->loadContent($content['when@'.$this->env], $path); + $env = $this->env; + $this->env = null; + try { + $this->loadContent($content['when@'.$env], $path); + } finally { + $this->env = $env; + } } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services29.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services29.xml new file mode 100644 index 0000000000000..48e6d20f0ce29 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services29.xml @@ -0,0 +1,31 @@ + + + + + + + + + default value + + + + + value when on dev + + + + + + value when on test + + + + + + value when on prod + + + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services30.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services30.xml new file mode 100644 index 0000000000000..9a945a478a707 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services30.xml @@ -0,0 +1,24 @@ + + + + default value + + + + + value when on dev + + + + + + value when on test + + + + + + value when on prod + + + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services29.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services29.yml new file mode 100644 index 0000000000000..0b6ede650eb56 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services29.yml @@ -0,0 +1,17 @@ +imports: + - { resource: services30.yml } + +parameters: + root_parameter: 'default value' + +when@dev: + parameters: + root_parameter: 'value when on dev' + +when@test: + parameters: + root_parameter: 'value when on test' + +when@prod: + parameters: + root_parameter: 'value when on prod' diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services30.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services30.yml new file mode 100644 index 0000000000000..a9109b05ffccc --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services30.yml @@ -0,0 +1,14 @@ +parameters: + imported_parameter: 'default value' + +when@dev: + parameters: + imported_parameter: 'value when on dev' + +when@test: + parameters: + imported_parameter: 'value when on test' + +when@prod: + parameters: + imported_parameter: 'value when on prod' diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index a419422a6b2e8..c20b2311b8337 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -231,6 +231,43 @@ public function testLoadImports() } } + public function testLoadWithEnvironment() + { + $container = new ContainerBuilder(); + + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'), 'dev'); + $loader->load('services29.xml'); + + self::assertSame([ + 'imported_parameter' => 'value when on dev', + 'root_parameter' => 'value when on dev', + ], $container->getParameterBag()->all()); + + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'), 'test'); + $loader->load('services29.xml'); + + self::assertSame([ + 'imported_parameter' => 'value when on test', + 'root_parameter' => 'value when on test', + ], $container->getParameterBag()->all()); + + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'), 'prod'); + $loader->load('services29.xml'); + + self::assertSame([ + 'imported_parameter' => 'value when on prod', + 'root_parameter' => 'value when on prod', + ], $container->getParameterBag()->all()); + + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'), 'other'); + $loader->load('services29.xml'); + + self::assertSame([ + 'imported_parameter' => 'default value', + 'root_parameter' => 'default value', + ], $container->getParameterBag()->all()); + } + public function testLoadAnonymousServices() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index 8fa6f14f59628..0ab8c39993c23 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -172,6 +172,43 @@ public function testLoadImports() } } + public function testLoadWithEnvironment() + { + $container = new ContainerBuilder(); + + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'), 'dev'); + $loader->load('services29.yml'); + + self::assertSame([ + 'imported_parameter' => 'value when on dev', + 'root_parameter' => 'value when on dev', + ], $container->getParameterBag()->all()); + + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'), 'test'); + $loader->load('services29.yml'); + + self::assertSame([ + 'imported_parameter' => 'value when on test', + 'root_parameter' => 'value when on test', + ], $container->getParameterBag()->all()); + + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'), 'prod'); + $loader->load('services29.yml'); + + self::assertSame([ + 'imported_parameter' => 'value when on prod', + 'root_parameter' => 'value when on prod', + ], $container->getParameterBag()->all()); + + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'), 'other'); + $loader->load('services29.yml'); + + self::assertSame([ + 'imported_parameter' => 'default value', + 'root_parameter' => 'default value', + ], $container->getParameterBag()->all()); + } + public function testLoadServices() { $container = new ContainerBuilder(); From e9afce33341e1576c6726e9c0f5115d5cf86b260 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 8 Jun 2021 18:37:25 +0200 Subject: [PATCH 48/78] [HttpClient] Revert bindto workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … for unaffected PHP versions Signed-off-by: Alexander M. Turek --- src/Symfony/Component/HttpClient/NativeHttpClient.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpClient/NativeHttpClient.php b/src/Symfony/Component/HttpClient/NativeHttpClient.php index 18bf8f569bbbf..381202de2320f 100644 --- a/src/Symfony/Component/HttpClient/NativeHttpClient.php +++ b/src/Symfony/Component/HttpClient/NativeHttpClient.php @@ -193,6 +193,11 @@ public function request(string $method, string $url, array $options = []): Respo $options['timeout'] = min($options['max_duration'], $options['timeout']); } + $bindto = $options['bindto']; + if (!$bindto && (70322 === \PHP_VERSION_ID || 70410 === \PHP_VERSION_ID)) { + $bindto = '0:0'; + } + $context = [ 'http' => [ 'protocol_version' => min($options['http_version'] ?: '1.1', '1.1'), @@ -221,7 +226,7 @@ public function request(string $method, string $url, array $options = []): Respo 'disable_compression' => true, ], static function ($v) { return null !== $v; }), 'socket' => [ - 'bindto' => $options['bindto'] ?: '0:0', + 'bindto' => $bindto, 'tcp_nodelay' => true, ], ]; From 56359cb999764c2e8f98c507dd309156db7b72d4 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 8 Jun 2021 19:35:06 +0200 Subject: [PATCH 49/78] [VarExporter] Fix test on PHP 8.1 Signed-off-by: Alexander M. Turek --- src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php b/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php index ab225a6f55135..744e576c0a0c9 100644 --- a/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php +++ b/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php @@ -55,7 +55,10 @@ public function testInstantiate() "\0".__NAMESPACE__."\Foo\0priv" => 234, ]; - $this->assertSame($expected, (array) Instantiator::instantiate(Bar::class, ['priv' => 123], [Foo::class => ['priv' => 234]])); + $actual = (array) Instantiator::instantiate(Bar::class, ['priv' => 123], [Foo::class => ['priv' => 234]]); + ksort($actual); + + $this->assertSame($expected, $actual); $e = Instantiator::instantiate('Exception', ['foo' => 123, 'trace' => [234]]); From 46e18aff9b09bdc7ab91994fe4e6bcb7ab3f029c Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 8 Jun 2021 23:07:02 +0200 Subject: [PATCH 50/78] [Config] Backport type declarations Signed-off-by: Alexander M. Turek --- .../Component/Config/Definition/ArrayNode.php | 25 ++------ .../Builder/ArrayNodeDefinition.php | 2 +- .../Config/Definition/Builder/ExprBuilder.php | 6 +- .../Builder/NumericNodeDefinition.php | 4 +- .../Definition/Dumper/XmlReferenceDumper.php | 2 +- .../Component/Config/Definition/EnumNode.php | 3 + .../Config/Definition/NumericNode.php | 4 ++ .../Config/Definition/PrototypedArrayNode.php | 26 +------- .../Config/Tests/ConfigCacheTest.php | 6 +- .../Config/Tests/Definition/ArrayNodeTest.php | 26 ++++---- .../Config/Tests/Definition/BaseNodeTest.php | 4 +- .../Tests/Definition/BooleanNodeTest.php | 10 ++- .../Builder/ArrayNodeDefinitionTest.php | 19 +++--- .../Definition/Builder/ExprBuilderTest.php | 31 +++++----- .../Dumper/YamlReferenceDumperTest.php | 6 +- .../Config/Tests/Definition/FloatNodeTest.php | 8 ++- .../Tests/Definition/IntegerNodeTest.php | 10 ++- .../Tests/Definition/NormalizationTest.php | 16 ++--- .../Definition/PrototypedArrayNodeTest.php | 8 +-- .../Tests/Definition/ScalarNodeTest.php | 8 +-- .../Config/Tests/FileLocatorTest.php | 4 +- .../Tests/Fixtures/Builder/NodeBuilder.php | 6 +- .../Fixtures/Configuration/CustomNode.php | 8 +-- .../Config/Tests/Loader/FileLoaderTest.php | 14 +---- .../Tests/Resource/DirectoryResourceTest.php | 2 +- .../Resource/ReflectionClassResourceTest.php | 62 +++++++++---------- .../Config/Tests/Resource/ResourceStub.php | 2 +- .../Config/Tests/Util/XmlUtilsTest.php | 6 +- 28 files changed, 144 insertions(+), 184 deletions(-) diff --git a/src/Symfony/Component/Config/Definition/ArrayNode.php b/src/Symfony/Component/Config/Definition/ArrayNode.php index 96f38dcc9250d..c3c837a4129ea 100644 --- a/src/Symfony/Component/Config/Definition/ArrayNode.php +++ b/src/Symfony/Component/Config/Definition/ArrayNode.php @@ -203,11 +203,7 @@ public function addChild(NodeInterface $node) } /** - * Finalizes the value of this node. - * - * @param mixed $value - * - * @return mixed The finalised value + * {@inheritdoc} * * @throws UnsetKeyException * @throws InvalidConfigurationException if the node doesn't have enough children @@ -249,11 +245,7 @@ protected function finalizeValue($value) } /** - * Validates the type of the value. - * - * @param mixed $value - * - * @throws InvalidTypeException + * {@inheritdoc} */ protected function validateType($value) { @@ -269,11 +261,7 @@ protected function validateType($value) } /** - * Normalizes the value. - * - * @param mixed $value The value to normalize - * - * @return mixed The normalized value + * {@inheritdoc} * * @throws InvalidConfigurationException */ @@ -355,12 +343,7 @@ protected function remapXml($value) } /** - * Merges values together. - * - * @param mixed $leftSide The left side to merge - * @param mixed $rightSide The right side to merge - * - * @return mixed The merged values + * {@inheritdoc} * * @throws InvalidConfigurationException * @throws \RuntimeException diff --git a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php index bec08b0db653b..61348387be2d3 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php @@ -280,7 +280,7 @@ public function canBeEnabled() ->treatNullLike(['enabled' => true]) ->beforeNormalization() ->ifArray() - ->then(function ($v) { + ->then(function (array $v) { $v['enabled'] = $v['enabled'] ?? true; return $v; diff --git a/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php b/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php index 5db229dccab7f..0cf47c162c938 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php +++ b/src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php @@ -37,7 +37,7 @@ public function __construct(NodeDefinition $node) */ public function always(\Closure $then = null) { - $this->ifPart = function ($v) { return true; }; + $this->ifPart = function () { return true; }; if (null !== $then) { $this->thenPart = $then; @@ -168,7 +168,7 @@ public function then(\Closure $closure) */ public function thenEmptyArray() { - $this->thenPart = function ($v) { return []; }; + $this->thenPart = function () { return []; }; return $this; } @@ -200,7 +200,7 @@ public function thenInvalid($message) */ public function thenUnset() { - $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key.'); }; + $this->thenPart = function () { throw new UnsetKeyException('Unsetting key.'); }; return $this; } diff --git a/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php index 390b1136567e6..c4bff1756fb0d 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php @@ -26,7 +26,7 @@ abstract class NumericNodeDefinition extends ScalarNodeDefinition /** * Ensures that the value is smaller than the given reference. * - * @param mixed $max + * @param int|float $max * * @return $this * @@ -45,7 +45,7 @@ public function max($max) /** * Ensures that the value is bigger than the given reference. * - * @param mixed $min + * @param int|float $min * * @return $this * diff --git a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php index 29e4076f97ae8..a6b6240c77a54 100644 --- a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php +++ b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php @@ -49,7 +49,7 @@ private function writeNode(NodeInterface $node, int $depth = 0, bool $root = fal // xml remapping if ($node->getParent()) { - $remapping = array_filter($node->getParent()->getXmlRemappings(), function ($mapping) use ($rootName) { + $remapping = array_filter($node->getParent()->getXmlRemappings(), function (array $mapping) use ($rootName) { return $rootName === $mapping[1]; }); diff --git a/src/Symfony/Component/Config/Definition/EnumNode.php b/src/Symfony/Component/Config/Definition/EnumNode.php index 23fc508a78fa9..822e6b57f1642 100644 --- a/src/Symfony/Component/Config/Definition/EnumNode.php +++ b/src/Symfony/Component/Config/Definition/EnumNode.php @@ -38,6 +38,9 @@ public function getValues() return $this->values; } + /** + * {@inheritdoc} + */ protected function finalizeValue($value) { $value = parent::finalizeValue($value); diff --git a/src/Symfony/Component/Config/Definition/NumericNode.php b/src/Symfony/Component/Config/Definition/NumericNode.php index 19c96e8af764c..50d137c2d71fb 100644 --- a/src/Symfony/Component/Config/Definition/NumericNode.php +++ b/src/Symfony/Component/Config/Definition/NumericNode.php @@ -23,6 +23,10 @@ class NumericNode extends ScalarNode protected $min; protected $max; + /** + * @param int|float|null $min + * @param int|float|null $max + */ public function __construct(?string $name, NodeInterface $parent = null, $min = null, $max = null, string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR) { parent::__construct($name, $parent, $pathSeparator); diff --git a/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php b/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php index 72d3578be7a09..03822236772f8 100644 --- a/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php +++ b/src/Symfony/Component/Config/Definition/PrototypedArrayNode.php @@ -173,14 +173,7 @@ public function addChild(NodeInterface $node) } /** - * Finalizes the value of this node. - * - * @param mixed $value - * - * @return mixed The finalized value - * - * @throws UnsetKeyException - * @throws InvalidConfigurationException if the node doesn't have enough children + * {@inheritdoc} */ protected function finalizeValue($value) { @@ -208,13 +201,8 @@ protected function finalizeValue($value) } /** - * Normalizes the value. - * - * @param mixed $value The value to normalize - * - * @return mixed The normalized value + * {@inheritdoc} * - * @throws InvalidConfigurationException * @throws DuplicateKeyException */ protected function normalizeValue($value) @@ -282,15 +270,7 @@ protected function normalizeValue($value) } /** - * Merges values together. - * - * @param mixed $leftSide The left side to merge - * @param mixed $rightSide The right side to merge - * - * @return mixed The merged values - * - * @throws InvalidConfigurationException - * @throws \RuntimeException + * {@inheritdoc} */ protected function mergeValues($leftSide, $rightSide) { diff --git a/src/Symfony/Component/Config/Tests/ConfigCacheTest.php b/src/Symfony/Component/Config/Tests/ConfigCacheTest.php index cfb2403a82a6c..ff72302a46406 100644 --- a/src/Symfony/Component/Config/Tests/ConfigCacheTest.php +++ b/src/Symfony/Component/Config/Tests/ConfigCacheTest.php @@ -38,7 +38,7 @@ protected function tearDown(): void /** * @dataProvider debugModes */ - public function testCacheIsNotValidIfNothingHasBeenCached($debug) + public function testCacheIsNotValidIfNothingHasBeenCached(bool $debug) { unlink($this->cacheFile); // remove tempnam() side effect $cache = new ConfigCache($this->cacheFile, $debug); @@ -60,7 +60,7 @@ public function testIsAlwaysFreshInProduction() /** * @dataProvider debugModes */ - public function testIsFreshWhenNoResourceProvided($debug) + public function testIsFreshWhenNoResourceProvided(bool $debug) { $cache = new ConfigCache($this->cacheFile, $debug); $cache->write('', []); @@ -89,7 +89,7 @@ public function testStaleResourceInDebug() $this->assertFalse($cache->isFresh()); } - public function debugModes() + public function debugModes(): array { return [ [true], diff --git a/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php index 54a966f1779f7..95f8480316b44 100644 --- a/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php @@ -55,7 +55,7 @@ public function testNormalizeWithoutProposals() $node->normalize(['beta' => 'foo']); } - public function ignoreAndRemoveMatrixProvider() + public function ignoreAndRemoveMatrixProvider(): array { $unrecognizedOptionException = new InvalidConfigurationException('Unrecognized option "foo" under "root"'); @@ -68,9 +68,11 @@ public function ignoreAndRemoveMatrixProvider() } /** + * @param array|\Exception $expected + * * @dataProvider ignoreAndRemoveMatrixProvider */ - public function testIgnoreAndRemoveBehaviors($ignore, $remove, $expected, $message = '') + public function testIgnoreAndRemoveBehaviors(bool $ignore, bool $remove, $expected, string $message = '') { if ($expected instanceof \Exception) { $this->expectException(\get_class($expected)); @@ -85,7 +87,7 @@ public function testIgnoreAndRemoveBehaviors($ignore, $remove, $expected, $messa /** * @dataProvider getPreNormalizationTests */ - public function testPreNormalize($denormalized, $normalized) + public function testPreNormalize(array $denormalized, array $normalized) { $node = new ArrayNode('foo'); @@ -95,7 +97,7 @@ public function testPreNormalize($denormalized, $normalized) $this->assertSame($normalized, $r->invoke($node, $denormalized)); } - public function getPreNormalizationTests() + public function getPreNormalizationTests(): array { return [ [ @@ -120,7 +122,7 @@ public function getPreNormalizationTests() /** * @dataProvider getZeroNamedNodeExamplesData */ - public function testNodeNameCanBeZero($denormalized, $normalized) + public function testNodeNameCanBeZero(array $denormalized, array $normalized) { $zeroNode = new ArrayNode(0); $zeroNode->addChild(new ScalarNode('name')); @@ -137,7 +139,7 @@ public function testNodeNameCanBeZero($denormalized, $normalized) $this->assertSame($normalized, $r->invoke($rootNode, $denormalized)); } - public function getZeroNamedNodeExamplesData() + public function getZeroNamedNodeExamplesData(): array { return [ [ @@ -168,7 +170,7 @@ public function getZeroNamedNodeExamplesData() /** * @dataProvider getPreNormalizedNormalizedOrderedData */ - public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized) + public function testChildrenOrderIsMaintainedOnNormalizeValue(array $prenormalized, array $normalized) { $scalar1 = new ScalarNode('1'); $scalar2 = new ScalarNode('2'); @@ -184,7 +186,7 @@ public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $n $this->assertSame($normalized, $r->invoke($node, $prenormalized)); } - public function getPreNormalizedNormalizedOrderedData() + public function getPreNormalizedNormalizedOrderedData(): array { return [ [ @@ -260,7 +262,7 @@ public function testSetDeprecated() /** * @dataProvider getDataWithIncludedExtraKeys */ - public function testMergeWithoutIgnoringExtraKeys($prenormalizeds, $merged) + public function testMergeWithoutIgnoringExtraKeys(array $prenormalizeds) { $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('merge() expects a normalized config array.'); @@ -278,7 +280,7 @@ public function testMergeWithoutIgnoringExtraKeys($prenormalizeds, $merged) /** * @dataProvider getDataWithIncludedExtraKeys */ - public function testMergeWithIgnoringAndRemovingExtraKeys($prenormalizeds, $merged) + public function testMergeWithIgnoringAndRemovingExtraKeys(array $prenormalizeds) { $this->expectException(\RuntimeException::class); $this->expectExceptionMessage('merge() expects a normalized config array.'); @@ -296,7 +298,7 @@ public function testMergeWithIgnoringAndRemovingExtraKeys($prenormalizeds, $merg /** * @dataProvider getDataWithIncludedExtraKeys */ - public function testMergeWithIgnoringExtraKeys($prenormalizeds, $merged) + public function testMergeWithIgnoringExtraKeys(array $prenormalizeds, array $merged) { $node = new ArrayNode('root'); $node->addChild(new ScalarNode('foo')); @@ -309,7 +311,7 @@ public function testMergeWithIgnoringExtraKeys($prenormalizeds, $merged) $this->assertEquals($merged, $r->invoke($node, ...$prenormalizeds)); } - public function getDataWithIncludedExtraKeys() + public function getDataWithIncludedExtraKeys(): array { return [ [ diff --git a/src/Symfony/Component/Config/Tests/Definition/BaseNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/BaseNodeTest.php index ea2ed639ff383..afe3cdf691a90 100644 --- a/src/Symfony/Component/Config/Tests/Definition/BaseNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/BaseNodeTest.php @@ -20,7 +20,7 @@ class BaseNodeTest extends TestCase /** * @dataProvider providePath */ - public function testGetPathForChildNode($expected, array $params) + public function testGetPathForChildNode(string $expected, array $params) { $constructorArgs = []; $constructorArgs[] = $params[0]; @@ -41,7 +41,7 @@ public function testGetPathForChildNode($expected, array $params) $this->assertSame($expected, $node->getPath()); } - public function providePath() + public function providePath(): array { return [ 'name only' => ['root', ['root']], diff --git a/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php index 3a05e3efd8159..bec3b5996dd08 100644 --- a/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php @@ -20,7 +20,7 @@ class BooleanNodeTest extends TestCase /** * @dataProvider getValidValues */ - public function testNormalize($value) + public function testNormalize(bool $value) { $node = new BooleanNode('test'); $this->assertSame($value, $node->normalize($value)); @@ -28,10 +28,8 @@ public function testNormalize($value) /** * @dataProvider getValidValues - * - * @param bool $value */ - public function testValidNonEmptyValues($value) + public function testValidNonEmptyValues(bool $value) { $node = new BooleanNode('test'); $node->setAllowEmptyValue(false); @@ -39,7 +37,7 @@ public function testValidNonEmptyValues($value) $this->assertSame($value, $node->finalize($value)); } - public function getValidValues() + public function getValidValues(): array { return [ [false], @@ -57,7 +55,7 @@ public function testNormalizeThrowsExceptionOnInvalidValues($value) $node->normalize($value); } - public function getInvalidValues() + public function getInvalidValues(): array { return [ [null], diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php index 0e489ac910973..0f111826d35f6 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php @@ -42,7 +42,7 @@ public function testAppendingSomeNode() /** * @dataProvider providePrototypeNodeSpecificCalls */ - public function testPrototypeNodeSpecificOption($method, $args) + public function testPrototypeNodeSpecificOption(string $method, array $args) { $this->expectException(InvalidDefinitionException::class); $node = new ArrayNodeDefinition('root'); @@ -52,7 +52,7 @@ public function testPrototypeNodeSpecificOption($method, $args) $node->getNode(); } - public function providePrototypeNodeSpecificCalls() + public function providePrototypeNodeSpecificCalls(): array { return [ ['defaultValue', [[]]], @@ -98,9 +98,11 @@ public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren() } /** + * @param int|array|string|null $args + * * @dataProvider providePrototypedArrayNodeDefaults */ - public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults) + public function testPrototypedArrayNodeDefault($args, bool $shouldThrowWhenUsingAttrAsKey, bool $shouldThrowWhenNotUsingAttrAsKey, array $defaults) { $node = new ArrayNodeDefinition('root'); $node @@ -132,7 +134,7 @@ public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrA } } - public function providePrototypedArrayNodeDefaults() + public function providePrototypedArrayNodeDefaults(): array { return [ [null, true, false, [[]]], @@ -173,7 +175,7 @@ public function testEnabledNodeDefaults() /** * @dataProvider getEnableableNodeFixtures */ - public function testTrueEnableEnabledNode($expected, $config, $message) + public function testTrueEnableEnabledNode(array $expected, array $config, string $message) { $processor = new Processor(); $node = new ArrayNodeDefinition('root'); @@ -293,7 +295,7 @@ public function testPrototypeEnum() $this->assertEquals($node->prototype('enum'), $node->enumPrototype()); } - public function getEnableableNodeFixtures() + public function getEnableableNodeFixtures(): array { return [ [['enabled' => true, 'foo' => 'bar'], [true], 'true enables an enableable node'], @@ -432,7 +434,10 @@ protected function assertNode(string $expectedName, string $expectedType, NodeDe $this->assertSame($expectedName, $this->getField($actualNode, 'name')); } - protected function getField($object, $field) + /** + * @param object $object + */ + protected function getField($object, string $field) { $reflection = new \ReflectionProperty($object, $field); $reflection->setAccessible(true); diff --git a/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php b/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php index c634f0887714c..74ae972e54aab 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Builder\ExprBuilder; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; @@ -36,13 +37,13 @@ public function testIfTrueExpression() $this->assertFinalizedValueIs('new_value', $test, ['key' => true]); $test = $this->getTestBuilder() - ->ifTrue(function ($v) { return true; }) + ->ifTrue(function () { return true; }) ->then($this->returnClosure('new_value')) ->end(); $this->assertFinalizedValueIs('new_value', $test); $test = $this->getTestBuilder() - ->ifTrue(function ($v) { return false; }) + ->ifTrue(function () { return false; }) ->then($this->returnClosure('new_value')) ->end(); $this->assertFinalizedValueIs('value', $test); @@ -150,7 +151,7 @@ public function testThenEmptyArrayExpression() /** * @dataProvider castToArrayValues */ - public function testCastToArrayExpression($configValue, $expectedValue) + public function testCastToArrayExpression($configValue, array $expectedValue) { $test = $this->getTestBuilder() ->castToArray() @@ -158,7 +159,7 @@ public function testCastToArrayExpression($configValue, $expectedValue) $this->assertFinalizedValueIs($expectedValue, $test, ['key' => $configValue]); } - public function castToArrayValues() + public function castToArrayValues(): iterable { yield ['value', ['value']]; yield [-3.14, [-3.14]]; @@ -219,20 +220,19 @@ protected function getTestBuilder(): ExprBuilder /** * Close the validation process and finalize with the given config. * - * @param TreeBuilder $testBuilder The tree builder to finalize - * @param array $config The config you want to use for the finalization, if nothing provided - * a simple ['key'=>'value'] will be used + * @param array|null $config The config you want to use for the finalization, if nothing provided + * a simple ['key'=>'value'] will be used * * @return array The finalized config values */ - protected function finalizeTestBuilder($testBuilder, $config = null): array + protected function finalizeTestBuilder(NodeDefinition $nodeDefinition, ?array $config = null): array { - return $testBuilder + return $nodeDefinition ->end() ->end() ->end() ->buildTree() - ->finalize(null === $config ? ['key' => 'value'] : $config) + ->finalize($config ?? ['key' => 'value']) ; } @@ -243,7 +243,7 @@ protected function finalizeTestBuilder($testBuilder, $config = null): array */ protected function returnClosure($val): \Closure { - return function ($v) use ($val) { + return function () use ($val) { return $val; }; } @@ -251,12 +251,11 @@ protected function returnClosure($val): \Closure /** * Assert that the given test builder, will return the given value. * - * @param mixed $value The value to test - * @param TreeBuilder $treeBuilder The tree builder to finalize - * @param mixed $config The config values that new to be finalized + * @param mixed $value The value to test + * @param mixed $config The config values that new to be finalized */ - protected function assertFinalizedValueIs($value, $treeBuilder, $config = null) + protected function assertFinalizedValueIs($value, NodeDefinition $nodeDefinition, $config = null) { - $this->assertEquals(['key' => $value], $this->finalizeTestBuilder($treeBuilder, $config)); + $this->assertEquals(['key' => $value], $this->finalizeTestBuilder($nodeDefinition, $config)); } } diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php index 146917aaa7084..f1871d49725c8 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php @@ -26,7 +26,7 @@ public function testDumper() $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration)); } - public function provideDumpAtPath() + public function provideDumpAtPath(): array { return [ 'Regular node' => ['scalar_true', <<assertSame(trim($expected), trim($dumper->dumpAtPath($configuration, $path))); } - private function getConfigurationAsString() + private function getConfigurationAsString(): string { return <<<'EOL' acme_root: diff --git a/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php index 68ed8a752120a..d675f47046f90 100644 --- a/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php @@ -19,6 +19,8 @@ class FloatNodeTest extends TestCase { /** * @dataProvider getValidValues + * + * @param int|float $value */ public function testNormalize($value) { @@ -29,7 +31,7 @@ public function testNormalize($value) /** * @dataProvider getValidValues * - * @param int $value + * @param int|float $value */ public function testValidNonEmptyValues($value) { @@ -39,7 +41,7 @@ public function testValidNonEmptyValues($value) $this->assertSame($value, $node->finalize($value)); } - public function getValidValues() + public function getValidValues(): array { return [ [1798.0], @@ -63,7 +65,7 @@ public function testNormalizeThrowsExceptionOnInvalidValues($value) $node->normalize($value); } - public function getInvalidValues() + public function getInvalidValues(): array { return [ [null], diff --git a/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php index c4dd57b8f45f4..7c843b38f3716 100644 --- a/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php @@ -20,7 +20,7 @@ class IntegerNodeTest extends TestCase /** * @dataProvider getValidValues */ - public function testNormalize($value) + public function testNormalize(int $value) { $node = new IntegerNode('test'); $this->assertSame($value, $node->normalize($value)); @@ -28,10 +28,8 @@ public function testNormalize($value) /** * @dataProvider getValidValues - * - * @param int $value */ - public function testValidNonEmptyValues($value) + public function testValidNonEmptyValues(int $value) { $node = new IntegerNode('test'); $node->setAllowEmptyValue(false); @@ -39,7 +37,7 @@ public function testValidNonEmptyValues($value) $this->assertSame($value, $node->finalize($value)); } - public function getValidValues() + public function getValidValues(): array { return [ [1798], @@ -58,7 +56,7 @@ public function testNormalizeThrowsExceptionOnInvalidValues($value) $node->normalize($value); } - public function getInvalidValues() + public function getInvalidValues(): array { return [ [null], diff --git a/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php b/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php index 3fecac2e3e7e2..0b497707e4604 100644 --- a/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/NormalizationTest.php @@ -51,7 +51,7 @@ public function testNormalizeEncoders($denormalized) $this->assertNormalized($tree, $denormalized, $normalized); } - public function getEncoderTests() + public function getEncoderTests(): array { $configs = []; @@ -120,7 +120,7 @@ public function testAnonymousKeysArray($denormalized) $this->assertNormalized($tree, $denormalized, $normalized); } - public function getAnonymousKeysTests() + public function getAnonymousKeysTests(): array { $configs = []; @@ -151,7 +151,7 @@ public function testNumericKeysAsAttributes($denormalized) $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, $normalized); } - public function getNumericKeysTests() + public function getNumericKeysTests(): array { $configs = []; @@ -233,10 +233,9 @@ public static function assertNormalized(NodeInterface $tree, $denormalized, $nor self::assertSame($normalized, $tree->normalize($denormalized)); } - private function getNumericKeysTestTree() + private function getNumericKeysTestTree(): NodeInterface { - $tb = new TreeBuilder('root', 'array'); - $tree = $tb + return (new TreeBuilder('root', 'array')) ->getRootNode() ->children() ->node('thing', 'array') @@ -247,9 +246,6 @@ private function getNumericKeysTestTree() ->end() ->end() ->end() - ->buildTree() - ; - - return $tree; + ->buildTree(); } } diff --git a/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php index 58d2408a71c90..b02d6ce6df2d4 100644 --- a/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php @@ -264,7 +264,7 @@ protected function getPrototypeNodeWithDefaultChildren() * * @dataProvider getDataForKeyRemovedLeftValueOnly */ - public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $expected) + public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, array $expected) { $node = new PrototypedArrayNode('root'); $node->setKeyAttribute('id', true); @@ -280,7 +280,7 @@ public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $this->assertEquals($expected, $normalized); } - public function getDataForKeyRemovedLeftValueOnly() + public function getDataForKeyRemovedLeftValueOnly(): array { $scalarValue = new ScalarNode('value'); @@ -342,7 +342,7 @@ public function getDataForKeyRemovedLeftValueOnly() /** * @dataProvider getPrototypedArrayNodeDataToMerge */ - public function testPrototypedArrayNodeMerge($left, $right, $expected) + public function testPrototypedArrayNodeMerge(array $left, array $right, array $expected) { $node = new PrototypedArrayNode('options'); $node->setNormalizeKeys(false); @@ -354,7 +354,7 @@ public function testPrototypedArrayNodeMerge($left, $right, $expected) self::assertSame($result, $expected); } - public function getPrototypedArrayNodeDataToMerge() + public function getPrototypedArrayNodeDataToMerge(): array { return [ // data to merged is a plain array diff --git a/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php index 0eb66963ebe58..0ddd1104faaa0 100644 --- a/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php @@ -28,7 +28,7 @@ public function testNormalize($value) $this->assertSame($value, $node->normalize($value)); } - public function getValidValues() + public function getValidValues(): array { return [ [false], @@ -84,7 +84,7 @@ public function testNormalizeThrowsExceptionOnInvalidValues($value) $node->normalize($value); } - public function getInvalidValues() + public function getInvalidValues(): array { return [ [[]], @@ -127,7 +127,7 @@ public function testValidNonEmptyValues($value) $this->assertSame($value, $node->finalize($value)); } - public function getValidNonEmptyValues() + public function getValidNonEmptyValues(): array { return [ [false], @@ -153,7 +153,7 @@ public function testNotAllowedEmptyValuesThrowException($value) $node->finalize($value); } - public function getEmptyValues() + public function getEmptyValues(): array { return [ [null], diff --git a/src/Symfony/Component/Config/Tests/FileLocatorTest.php b/src/Symfony/Component/Config/Tests/FileLocatorTest.php index 44ef5ac9e3ebe..b8419d9a1ad01 100644 --- a/src/Symfony/Component/Config/Tests/FileLocatorTest.php +++ b/src/Symfony/Component/Config/Tests/FileLocatorTest.php @@ -20,7 +20,7 @@ class FileLocatorTest extends TestCase /** * @dataProvider getIsAbsolutePathTests */ - public function testIsAbsolutePath($path) + public function testIsAbsolutePath(string $path) { $loader = new FileLocator([]); $r = new \ReflectionObject($loader); @@ -30,7 +30,7 @@ public function testIsAbsolutePath($path) $this->assertTrue($m->invoke($loader, $path), '->isAbsolutePath() returns true for an absolute path'); } - public function getIsAbsolutePathTests() + public function getIsAbsolutePathTests(): array { return [ ['/foo.xml'], diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php b/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php index 26323e9805d64..5a0a8fe6f3375 100644 --- a/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php +++ b/src/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php @@ -12,10 +12,11 @@ namespace Symfony\Component\Config\Tests\Fixtures\Builder; use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder; +use Symfony\Component\Config\Definition\Builder\NodeDefinition; class NodeBuilder extends BaseNodeBuilder { - public function barNode($name) + public function barNode($name): NodeDefinition { return $this->node($name, 'bar'); } @@ -23,9 +24,8 @@ public function barNode($name) protected function getNodeClass($type): string { switch ($type) { - case 'variable': - return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition'; case 'bar': + case 'variable': return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition'; default: return parent::getNodeClass($type); diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/CustomNode.php b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/CustomNode.php index 1270eb6a68323..f6c53ceeeb88f 100644 --- a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/CustomNode.php +++ b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/CustomNode.php @@ -7,22 +7,22 @@ class CustomNode implements NodeInterface { - public function getName() + public function getName(): string { return 'custom_node'; } - public function getPath() + public function getPath(): string { return 'custom'; } - public function isRequired() + public function isRequired(): bool { return false; } - public function hasDefaultValue() + public function hasDefaultValue(): bool { return true; } diff --git a/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php b/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php index 023bbe0f31ea6..9c74f6d60a379 100644 --- a/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php +++ b/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php @@ -165,22 +165,12 @@ public function supports($resource, $type = null): bool return $this->supports; } - public function addLoading($resource) + public function addLoading(string $resource): void { self::$loading[$resource] = true; } - public function removeLoading($resource) - { - unset(self::$loading[$resource]); - } - - public function clearLoading() - { - self::$loading = []; - } - - public function setSupports($supports) + public function setSupports(bool $supports): void { $this->supports = $supports; } diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index 3de58f4be0a01..a114f214ab1ad 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -35,7 +35,7 @@ protected function tearDown(): void $this->removeDirectory($this->directory); } - protected function removeDirectory($directory) + protected function removeDirectory(string $directory): void { $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::CHILD_FIRST); foreach ($iterator as $path) { diff --git a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php index af0c2cd2c905e..64cfbf129a990 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php @@ -64,7 +64,7 @@ public function testIsFreshForDeletedResources() /** * @dataProvider provideHashedSignature */ - public function testHashedSignature($changeExpected, $changedLine, $changedCode, $setContext = null) + public function testHashedSignature(bool $changeExpected, int $changedLine, ?string $changedCode, ?\Closure $setContext = null) { if ($setContext) { $setContext(); @@ -117,43 +117,43 @@ public function testHashedSignature($changeExpected, $changedLine, $changedCode, } } - public function provideHashedSignature() + public function provideHashedSignature(): iterable { - yield [0, 0, "// line change\n\n"]; - yield [1, 0, '/** class docblock */']; - yield [1, 1, 'abstract class %s']; - yield [1, 1, 'final class %s']; - yield [1, 1, 'class %s extends Exception']; - yield [1, 1, 'class %s implements '.DummyInterface::class]; - yield [1, 3, 'const FOO = 456;']; - yield [1, 3, 'const BAR = 123;']; - yield [1, 4, '/** pub docblock */']; - yield [1, 5, 'protected $pub = [];']; - yield [1, 5, 'public $pub = [123];']; - yield [1, 6, '/** prot docblock */']; - yield [1, 7, 'private $prot;']; - yield [0, 8, '/** priv docblock */']; - yield [0, 9, 'private $priv = 123;']; - yield [1, 10, '/** pub docblock */']; - yield [1, 11, 'public function pub(...$arg) {}']; - yield [1, 11, 'public function pub($arg = null): Foo {}']; - yield [0, 11, "public function pub(\$arg = null) {\nreturn 123;\n}"]; - yield [1, 12, '/** prot docblock */']; - yield [1, 13, 'protected function prot($a = [123]) {}']; - yield [0, 14, '/** priv docblock */']; - yield [0, 15, '']; + yield [false, 0, "// line change\n\n"]; + yield [true, 0, '/** class docblock */']; + yield [true, 1, 'abstract class %s']; + yield [true, 1, 'final class %s']; + yield [true, 1, 'class %s extends Exception']; + yield [true, 1, 'class %s implements '.DummyInterface::class]; + yield [true, 3, 'const FOO = 456;']; + yield [true, 3, 'const BAR = 123;']; + yield [true, 4, '/** pub docblock */']; + yield [true, 5, 'protected $pub = [];']; + yield [true, 5, 'public $pub = [123];']; + yield [true, 6, '/** prot docblock */']; + yield [true, 7, 'private $prot;']; + yield [false, 8, '/** priv docblock */']; + yield [false, 9, 'private $priv = 123;']; + yield [true, 10, '/** pub docblock */']; + yield [true, 11, 'public function pub(...$arg) {}']; + yield [true, 11, 'public function pub($arg = null): Foo {}']; + yield [false, 11, "public function pub(\$arg = null) {\nreturn 123;\n}"]; + yield [true, 12, '/** prot docblock */']; + yield [true, 13, 'protected function prot($a = [123]) {}']; + yield [false, 14, '/** priv docblock */']; + yield [false, 15, '']; if (\PHP_VERSION_ID >= 70400) { // PHP7.4 typed properties without default value are // undefined, make sure this doesn't throw an error - yield [1, 5, 'public array $pub;']; - yield [0, 7, 'protected int $prot;']; - yield [0, 9, 'private string $priv;']; + yield [true, 5, 'public array $pub;']; + yield [false, 7, 'protected int $prot;']; + yield [false, 9, 'private string $priv;']; } - yield [1, 17, 'public function ccc($bar = 187) {}']; - yield [1, 17, 'public function ccc($bar = ANOTHER_ONE_THAT_WILL_NEVER_BE_DEFINED_CCCCCCCCC) {}']; - yield [1, 17, null, static function () { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }]; + yield [true, 17, 'public function ccc($bar = 187) {}']; + yield [true, 17, 'public function ccc($bar = ANOTHER_ONE_THAT_WILL_NEVER_BE_DEFINED_CCCCCCCCC) {}']; + yield [true, 17, null, static function () { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }]; } public function testEventSubscriber() diff --git a/src/Symfony/Component/Config/Tests/Resource/ResourceStub.php b/src/Symfony/Component/Config/Tests/Resource/ResourceStub.php index 959b00290ed6d..4073566d19f2a 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ResourceStub.php +++ b/src/Symfony/Component/Config/Tests/Resource/ResourceStub.php @@ -17,7 +17,7 @@ class ResourceStub implements SelfCheckingResourceInterface { private $fresh = true; - public function setFresh($isFresh) + public function setFresh(bool $isFresh): void { $this->fresh = $isFresh; } diff --git a/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php b/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php index 481603763aa25..a7a8ae980d597 100644 --- a/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php +++ b/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php @@ -116,7 +116,7 @@ public function testLoadFileWithInternalErrorsEnabled() /** * @dataProvider getDataForConvertDomToArray */ - public function testConvertDomToArray($expected, $xml, $root = false, $checkPrefix = true) + public function testConvertDomToArray($expected, string $xml, bool $root = false, bool $checkPrefix = true) { $dom = new \DOMDocument(); $dom->loadXML($root ? $xml : ''.$xml.''); @@ -124,7 +124,7 @@ public function testConvertDomToArray($expected, $xml, $root = false, $checkPref $this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix)); } - public function getDataForConvertDomToArray() + public function getDataForConvertDomToArray(): array { return [ [null, ''], @@ -155,7 +155,7 @@ public function testPhpize($expected, $value) $this->assertSame($expected, XmlUtils::phpize($value)); } - public function getDataForPhpize() + public function getDataForPhpize(): array { return [ ['', ''], From 181d5480c6e4efcd8e297222949438c26d77cc7c Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Wed, 9 Jun 2021 12:32:05 +0200 Subject: [PATCH 51/78] [Validator] Fix tests by making constraint options dumps order consistent --- src/Symfony/Component/Validator/Command/DebugCommand.php | 2 ++ .../Component/Validator/Tests/Command/DebugCommandTest.php | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/Command/DebugCommand.php b/src/Symfony/Component/Validator/Command/DebugCommand.php index 0f0912ea46e89..04f2f4af25acf 100644 --- a/src/Symfony/Component/Validator/Command/DebugCommand.php +++ b/src/Symfony/Component/Validator/Command/DebugCommand.php @@ -165,6 +165,8 @@ private function getConstraintOptions(Constraint $constraint): array $options[$propertyName] = $constraint->$propertyName; } + ksort($options); + return $options; } diff --git a/src/Symfony/Component/Validator/Tests/Command/DebugCommandTest.php b/src/Symfony/Component/Validator/Tests/Command/DebugCommandTest.php index 0f2b7b17f6c53..f6d1691662e3f 100644 --- a/src/Symfony/Component/Validator/Tests/Command/DebugCommandTest.php +++ b/src/Symfony/Component/Validator/Tests/Command/DebugCommandTest.php @@ -72,8 +72,8 @@ public function testOutputWithClassArgument() | Property | Name | Groups | Options | +---------------+--------------------------------------------------+---------+------------------------------------------------------------+ | firstArgument | Symfony\Component\Validator\Constraints\NotBlank | Default | [ | -| | | | "message" => "This value should not be blank.", | | | | | "allowNull" => false, | +| | | | "message" => "This value should not be blank.", | | | | | "normalizer" => null, | | | | | "payload" => null | | | | | ] | @@ -133,8 +133,8 @@ public function testOutputWithPathArgument() | Property | Name | Groups | Options | +---------------+--------------------------------------------------+---------+------------------------------------------------------------+ | firstArgument | Symfony\Component\Validator\Constraints\NotBlank | Default | [ | -| | | | "message" => "This value should not be blank.", | | | | | "allowNull" => false, | +| | | | "message" => "This value should not be blank.", | | | | | "normalizer" => null, | | | | | "payload" => null | | | | | ] | @@ -153,8 +153,8 @@ public function testOutputWithPathArgument() | Property | Name | Groups | Options | +---------------+--------------------------------------------------+---------+------------------------------------------------------------+ | firstArgument | Symfony\Component\Validator\Constraints\NotBlank | Default | [ | -| | | | "message" => "This value should not be blank.", | | | | | "allowNull" => false, | +| | | | "message" => "This value should not be blank.", | | | | | "normalizer" => null, | | | | | "payload" => null | | | | | ] | From 1d24bce18fd3db62dfb6583d0a83ff0538e933ee Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 8 Jun 2021 19:11:04 +0200 Subject: [PATCH 52/78] [HttpFoundation] Handle tentative return types Signed-off-by: Alexander M. Turek --- .../Storage/Handler/MigratingSessionHandler.php | 8 ++++++++ .../Session/Storage/Handler/NullSessionHandler.php | 4 ++++ .../Session/Storage/Handler/PdoSessionHandler.php | 5 +++++ .../Handler/MigratingSessionHandlerTest.php | 5 ++--- .../Storage/Handler/PdoSessionHandlerTest.php | 14 ++++++++++++-- .../Storage/Handler/StrictSessionHandlerTest.php | 4 ++-- .../Storage/Proxy/SessionHandlerProxyTest.php | 8 ++++++-- 7 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MigratingSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MigratingSessionHandler.php index c6b16d11c8544..c3e7ef6e60a30 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MigratingSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MigratingSessionHandler.php @@ -41,6 +41,7 @@ public function __construct(\SessionHandlerInterface $currentHandler, \SessionHa /** * @return bool */ + #[\ReturnTypeWillChange] public function close() { $result = $this->currentHandler->close(); @@ -52,6 +53,7 @@ public function close() /** * @return bool */ + #[\ReturnTypeWillChange] public function destroy($sessionId) { $result = $this->currentHandler->destroy($sessionId); @@ -63,6 +65,7 @@ public function destroy($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function gc($maxlifetime) { $result = $this->currentHandler->gc($maxlifetime); @@ -74,6 +77,7 @@ public function gc($maxlifetime) /** * @return bool */ + #[\ReturnTypeWillChange] public function open($savePath, $sessionName) { $result = $this->currentHandler->open($savePath, $sessionName); @@ -85,6 +89,7 @@ public function open($savePath, $sessionName) /** * @return string */ + #[\ReturnTypeWillChange] public function read($sessionId) { // No reading from new handler until switch-over @@ -94,6 +99,7 @@ public function read($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function write($sessionId, $sessionData) { $result = $this->currentHandler->write($sessionId, $sessionData); @@ -105,6 +111,7 @@ public function write($sessionId, $sessionData) /** * @return bool */ + #[\ReturnTypeWillChange] public function validateId($sessionId) { // No reading from new handler until switch-over @@ -114,6 +121,7 @@ public function validateId($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function updateTimestamp($sessionId, $sessionData) { $result = $this->currentHandler->updateTimestamp($sessionId, $sessionData); diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php index 0634e46dd53f4..c34c25edbb38b 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php @@ -21,6 +21,7 @@ class NullSessionHandler extends AbstractSessionHandler /** * @return bool */ + #[\ReturnTypeWillChange] public function close() { return true; @@ -29,6 +30,7 @@ public function close() /** * @return bool */ + #[\ReturnTypeWillChange] public function validateId($sessionId) { return true; @@ -45,6 +47,7 @@ protected function doRead($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function updateTimestamp($sessionId, $data) { return true; @@ -69,6 +72,7 @@ protected function doDestroy($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function gc($maxlifetime) { return true; diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php index db741877602dc..d3c5651d41300 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php @@ -262,6 +262,7 @@ public function isSessionExpired() /** * @return bool */ + #[\ReturnTypeWillChange] public function open($savePath, $sessionName) { $this->sessionExpired = false; @@ -276,6 +277,7 @@ public function open($savePath, $sessionName) /** * @return string */ + #[\ReturnTypeWillChange] public function read($sessionId) { try { @@ -290,6 +292,7 @@ public function read($sessionId) /** * @return bool */ + #[\ReturnTypeWillChange] public function gc($maxlifetime) { // We delay gc() to close() so that it is executed outside the transactional and blocking read-write process. @@ -369,6 +372,7 @@ protected function doWrite($sessionId, $data) /** * @return bool */ + #[\ReturnTypeWillChange] public function updateTimestamp($sessionId, $data) { $expiry = time() + (int) ini_get('session.gc_maxlifetime'); @@ -393,6 +397,7 @@ public function updateTimestamp($sessionId, $data) /** * @return bool */ + #[\ReturnTypeWillChange] public function close() { $this->commit(); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MigratingSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MigratingSessionHandlerTest.php index 01615e6b1f2eb..f56f753af6c85 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MigratingSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MigratingSessionHandlerTest.php @@ -75,15 +75,14 @@ public function testGc() $this->currentHandler->expects($this->once()) ->method('gc') ->with($maxlifetime) - ->willReturn(true); + ->willReturn(1); $this->writeOnlyHandler->expects($this->once()) ->method('gc') ->with($maxlifetime) ->willReturn(false); - $result = $this->dualHandler->gc($maxlifetime); - $this->assertTrue($result); + $this->assertSame(1, $this->dualHandler->gc($maxlifetime)); } public function testOpen() diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php index c73118091636b..79ab73c1a4d1f 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php @@ -371,6 +371,10 @@ public function __construct(string $driverName = null, int $errorMode = null) $this->errorMode = null !== $errorMode ?: \PDO::ERRMODE_EXCEPTION; } + /** + * @return mixed + */ + #[\ReturnTypeWillChange] public function getAttribute($attribute) { if (\PDO::ATTR_ERRMODE === $attribute) { @@ -384,6 +388,10 @@ public function getAttribute($attribute) return parent::getAttribute($attribute); } + /** + * @return false|\PDOStatement + */ + #[\ReturnTypeWillChange] public function prepare($statement, $driverOptions = []) { return \is_callable($this->prepareResult) @@ -391,11 +399,13 @@ public function prepare($statement, $driverOptions = []) : $this->prepareResult; } - public function beginTransaction() + public function beginTransaction(): bool { + return true; } - public function rollBack() + public function rollBack(): bool { + return true; } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php index 353b1a02ec993..4f91016ac5cd8 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php @@ -181,9 +181,9 @@ public function testGc() { $handler = $this->createMock(\SessionHandlerInterface::class); $handler->expects($this->once())->method('gc') - ->with(123)->willReturn(true); + ->with(123)->willReturn(1); $proxy = new StrictSessionHandler($handler); - $this->assertTrue($proxy->gc(123)); + $this->assertSame(1, $proxy->gc(123)); } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php index 27bf3e27a6de9..1422eccfbc049 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php @@ -93,7 +93,9 @@ public function testCloseFalse() public function testRead() { $this->mock->expects($this->once()) - ->method('read'); + ->method('read') + ->willReturn('foo') + ; $this->proxy->read('id'); } @@ -117,7 +119,9 @@ public function testDestroy() public function testGc() { $this->mock->expects($this->once()) - ->method('gc'); + ->method('gc') + ->willReturn(1) + ; $this->proxy->gc(86400); } From 37e602dd28316482e860b52c4280575b6815e6c0 Mon Sep 17 00:00:00 2001 From: Olivier Dolbeau Date: Mon, 7 Jun 2021 17:25:08 +0200 Subject: [PATCH 53/78] Remove TLS related options when not using TLS --- .../Amqp/Tests/Transport/ConnectionTest.php | 21 +++++++++++++++++++ .../Bridge/Amqp/Transport/Connection.php | 4 ++++ 2 files changed, 25 insertions(+) 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 d1c43898a6270..93444dec1bf35 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/ConnectionTest.php @@ -748,6 +748,27 @@ public function testItCanPublishAndWaitForConfirmation() $connection = Connection::fromDsn('amqp://localhost?confirm_timeout=0.5', [], $factory); $connection->publish('body'); } + + public function testItCanBeConstructedWithTLSOptionsAndNonTLSDsn() + { + $this->assertEquals( + new Connection([ + 'host' => 'localhost', + 'port' => 5672, + 'vhost' => '/', + ], [ + 'name' => self::DEFAULT_EXCHANGE_NAME, + ], [ + self::DEFAULT_EXCHANGE_NAME => [], + ]), + Connection::fromDsn('amqp://', [ + 'cacert' => 'foobar', + 'cert' => 'foobar', + 'key' => 'foobar', + 'verify' => false, + ]) + ); + } } class TestAmqpFactory extends AmqpFactory diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php index 4aed8831b57bc..94a573c0ccc95 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php @@ -219,6 +219,10 @@ public static function fromDsn(string $dsn, array $options = [], AmqpFactory $am return $queueOptions; }, $queuesOptions); + if (!$useAmqps) { + unset($amqpOptions['cacert'], $amqpOptions['cert'], $amqpOptions['key'], $amqpOptions['verify']); + } + if ($useAmqps && !self::hasCaCertConfigured($amqpOptions)) { throw new InvalidArgumentException('No CA certificate has been provided. Set "amqp.cacert" in your php.ini or pass the "cacert" parameter in the DSN to use SSL. Alternatively, you can use amqp:// to use without SSL.'); } From d1579a2922bb2ad608673697c3a41a23eeeaec8a Mon Sep 17 00:00:00 2001 From: bch36 <31776675+bch36@users.noreply.github.com> Date: Tue, 8 Jun 2021 11:05:01 -0500 Subject: [PATCH 54/78] [Process] Fix incorrect parameter type --- src/Symfony/Component/Process/Pipes/WindowsPipes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Process/Pipes/WindowsPipes.php b/src/Symfony/Component/Process/Pipes/WindowsPipes.php index b2c3f4f4f3732..3a1ef405f6814 100644 --- a/src/Symfony/Component/Process/Pipes/WindowsPipes.php +++ b/src/Symfony/Component/Process/Pipes/WindowsPipes.php @@ -71,7 +71,7 @@ public function __construct($input, bool $haveReadSupport) } $this->lockHandles[$pipe] = $h; - if (!fclose(fopen($file, 'w')) || !$h = fopen($file, 'r')) { + if (!($h = fopen($file, 'w')) || !fclose($h) || !$h = fopen($file, 'r')) { flock($this->lockHandles[$pipe], \LOCK_UN); fclose($this->lockHandles[$pipe]); unset($this->lockHandles[$pipe]); From 7ad82474223e5951db3f9844b07a2afe8d16a9cd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 9 Jun 2021 17:56:09 +0200 Subject: [PATCH 55/78] [Config] fix tracking attributes in ReflectionClassResource --- .../Resource/ReflectionClassResource.php | 33 +++++++++++++++++++ .../Resource/ReflectionClassResourceTest.php | 11 +++++++ 2 files changed, 44 insertions(+) diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index 2b58bd663258d..a0aeb354c74ff 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -119,6 +119,15 @@ private function computeHash(): string private function generateSignature(\ReflectionClass $class): iterable { + if (\PHP_VERSION_ID >= 80000) { + $attributes = []; + foreach ($class->getAttributes() as $a) { + $attributes[] = [$a->getName(), $a->getArguments()]; + } + yield print_r($attributes, true); + $attributes = []; + } + yield $class->getDocComment(); yield (int) $class->isFinal(); yield (int) $class->isAbstract(); @@ -135,6 +144,14 @@ private function generateSignature(\ReflectionClass $class): iterable $defaults = $class->getDefaultProperties(); foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED) as $p) { + if (\PHP_VERSION_ID >= 80000) { + foreach ($p->getAttributes() as $a) { + $attributes[] = [$a->getName(), $a->getArguments()]; + } + yield print_r($attributes, true); + $attributes = []; + } + yield $p->getDocComment(); yield $p->isDefault() ? '' : ''; yield $p->isPublic() ? 'public' : 'protected'; @@ -145,9 +162,25 @@ private function generateSignature(\ReflectionClass $class): iterable } foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) { + if (\PHP_VERSION_ID >= 80000) { + foreach ($m->getAttributes() as $a) { + $attributes[] = [$a->getName(), $a->getArguments()]; + } + yield print_r($attributes, true); + $attributes = []; + } + $defaults = []; $parametersWithUndefinedConstants = []; foreach ($m->getParameters() as $p) { + if (\PHP_VERSION_ID >= 80000) { + foreach ($p->getAttributes() as $a) { + $attributes[] = [$a->getName(), $a->getArguments()]; + } + yield print_r($attributes, true); + $attributes = []; + } + if (!$p->isDefaultValueAvailable()) { $defaults[$p->name] = null; diff --git a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php index 64cfbf129a990..4f61c5bbd7c61 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php @@ -121,6 +121,11 @@ public function provideHashedSignature(): iterable { yield [false, 0, "// line change\n\n"]; yield [true, 0, '/** class docblock */']; + + if (\PHP_VERSION_ID >= 80000) { + yield [true, 0, '#[Foo]']; + } + yield [true, 1, 'abstract class %s']; yield [true, 1, 'final class %s']; yield [true, 1, 'class %s extends Exception']; @@ -140,6 +145,12 @@ public function provideHashedSignature(): iterable yield [false, 11, "public function pub(\$arg = null) {\nreturn 123;\n}"]; yield [true, 12, '/** prot docblock */']; yield [true, 13, 'protected function prot($a = [123]) {}']; + + if (\PHP_VERSION_ID >= 80000) { + yield [true, 13, '#[Foo] protected function prot($a = []) {}']; + yield [true, 13, 'protected function prot(#[Foo] $a = []) {}']; + } + yield [false, 14, '/** priv docblock */']; yield [false, 15, '']; From 29621cd83b7f19d4aefc53f37becb67dab0f39b1 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 10 Jun 2021 20:05:39 +0200 Subject: [PATCH 56/78] [Serializer] Fix call to expectExceptionMessage() Signed-off-by: Alexander M. Turek --- .../Component/Serializer/Tests/Normalizer/UidNormalizerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/UidNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/UidNormalizerTest.php index e2e68832a92bf..fc2f55bbee2e1 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/UidNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/UidNormalizerTest.php @@ -162,7 +162,7 @@ public function testNormalizeWithNormalizationFormatPassedInConstructor() public function testNormalizeWithNormalizationFormatNotValid() { $this->expectException(LogicException::class); - $this->expectDeprecationMessage('The "ccc" format is not valid.'); + $this->expectExceptionMessage('The "ccc" format is not valid.'); $this->normalizer->normalize(new Ulid(), null, [ 'uid_normalization_format' => 'ccc', From 0aa0fcbbbcf049950ca3418c59e81cb0c7a1544b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= Date: Tue, 8 Jun 2021 09:06:09 +0200 Subject: [PATCH 57/78] [Notifier] Escape `.` char for Telegram transport --- .../Bridge/Telegram/TelegramTransport.php | 3 +- .../Telegram/Tests/TelegramTransportTest.php | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransport.php b/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransport.php index a31a394c518b7..bd9966d1cb27c 100644 --- a/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransport.php +++ b/src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransport.php @@ -79,8 +79,9 @@ protected function doSend(MessageInterface $message): SentMessage $options['text'] = $message->getSubject(); - if (!isset($options['parse_mode'])) { + if (!isset($options['parse_mode']) || TelegramOptions::PARSE_MODE_MARKDOWN_V2 === $options['parse_mode']) { $options['parse_mode'] = TelegramOptions::PARSE_MODE_MARKDOWN_V2; + $options['text'] = str_replace('.', '\.', $message->getSubject()); } $response = $this->client->request('POST', $endpoint, [ diff --git a/src/Symfony/Component/Notifier/Bridge/Telegram/Tests/TelegramTransportTest.php b/src/Symfony/Component/Notifier/Bridge/Telegram/Tests/TelegramTransportTest.php index 869ec7e1abde3..25bc56a905c3e 100644 --- a/src/Symfony/Component/Notifier/Bridge/Telegram/Tests/TelegramTransportTest.php +++ b/src/Symfony/Component/Notifier/Bridge/Telegram/Tests/TelegramTransportTest.php @@ -185,4 +185,56 @@ public function testSendWithChannelOverride() $this->assertEquals(1, $sentMessage->getMessageId()); $this->assertEquals('telegram://api.telegram.org?channel=defaultChannel', $sentMessage->getTransport()); } + + public function testSendWithMarkdownShouldEscapeDots() + { + $response = $this->createMock(ResponseInterface::class); + $response->expects($this->exactly(2)) + ->method('getStatusCode') + ->willReturn(200); + + $content = <<expects($this->once()) + ->method('getContent') + ->willReturn($content) + ; + + $expectedBody = [ + 'chat_id' => 'testChannel', + 'text' => 'I contain a \.', + 'parse_mode' => 'MarkdownV2', + ]; + + $client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface { + $this->assertSame($expectedBody, json_decode($options['body'], true)); + + return $response; + }); + + $transport = $this->createTransport($client, 'testChannel'); + + $transport->send(new ChatMessage('I contain a .')); + } } From 38dae138fd32837fdab18ed77f34112f6410782b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 Jun 2021 18:31:26 +0200 Subject: [PATCH 58/78] [HttpClient] throw exception when AsyncDecoratorTrait gets an already consumed response --- .../HttpClient/Response/AsyncResponse.php | 17 ++++++++-- .../Tests/AsyncDecoratorTraitTest.php | 31 +++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/AsyncResponse.php b/src/Symfony/Component/HttpClient/Response/AsyncResponse.php index 481d760a596dc..1e64959df8e0b 100644 --- a/src/Symfony/Component/HttpClient/Response/AsyncResponse.php +++ b/src/Symfony/Component/HttpClient/Response/AsyncResponse.php @@ -31,12 +31,15 @@ final class AsyncResponse implements ResponseInterface, StreamableInterface { use CommonResponseTrait; + private const FIRST_CHUNK_YIELDED = 1; + private const LAST_CHUNK_YIELDED = 2; + private $client; private $response; private $info = ['canceled' => false]; private $passthru; private $stream; - private $lastYielded = false; + private $yieldedState; /** * @param ?callable(ChunkInterface, AsyncContext): ?\Iterator $passthru @@ -272,6 +275,14 @@ public static function stream(iterable $responses, float $timeout = null, string continue; } + if (null !== $chunk->getError()) { + // no-op + } elseif ($chunk->isFirst()) { + $r->yieldedState = self::FIRST_CHUNK_YIELDED; + } elseif (self::FIRST_CHUNK_YIELDED !== $r->yieldedState && null === $chunk->getInformationalStatus()) { + throw new \LogicException(sprintf('Instance of "%s" is already consumed and cannot be managed by "%s". A decorated client should not call any of the response\'s methods in its "request()" method.', get_debug_type($response), $class ?? static::class)); + } + foreach (self::passthru($r->client, $r, $chunk, $asyncMap) as $chunk) { yield $r => $chunk; } @@ -282,9 +293,9 @@ public static function stream(iterable $responses, float $timeout = null, string } if (null === $chunk->getError() && $chunk->isLast()) { - $r->lastYielded = true; + $r->yieldedState = self::LAST_CHUNK_YIELDED; } - if (null === $chunk->getError() && !$r->lastYielded && $r->response === $response && null !== $r->client) { + if (null === $chunk->getError() && self::LAST_CHUNK_YIELDED !== $r->yieldedState && $r->response === $response && null !== $r->client) { throw new \LogicException('A chunk passthru must yield an "isLast()" chunk before ending a stream.'); } diff --git a/src/Symfony/Component/HttpClient/Tests/AsyncDecoratorTraitTest.php b/src/Symfony/Component/HttpClient/Tests/AsyncDecoratorTraitTest.php index 499cc1ef30e00..6ebadc7155101 100644 --- a/src/Symfony/Component/HttpClient/Tests/AsyncDecoratorTraitTest.php +++ b/src/Symfony/Component/HttpClient/Tests/AsyncDecoratorTraitTest.php @@ -19,10 +19,11 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; class AsyncDecoratorTraitTest extends NativeHttpClientTest { - protected function getHttpClient(string $testCase, \Closure $chunkFilter = null): HttpClientInterface + protected function getHttpClient(string $testCase, \Closure $chunkFilter = null, HttpClientInterface $decoratedClient = null): HttpClientInterface { if ('testHandleIsRemovedOnException' === $testCase) { $this->markTestSkipped("AsyncDecoratorTrait doesn't cache handles"); @@ -30,7 +31,7 @@ protected function getHttpClient(string $testCase, \Closure $chunkFilter = null) $chunkFilter = $chunkFilter ?? static function (ChunkInterface $chunk, AsyncContext $context) { yield $chunk; }; - return new class(parent::getHttpClient($testCase), $chunkFilter) implements HttpClientInterface { + return new class($decoratedClient ?? parent::getHttpClient($testCase), $chunkFilter) implements HttpClientInterface { use AsyncDecoratorTrait; private $chunkFilter; @@ -303,4 +304,30 @@ public function testMultipleYieldInInitializer() $this->assertSame(404, $response->getStatusCode()); $this->assertStringContainsString('injectedFoo', $response->getContent(false)); } + + public function testConsumingDecoratedClient() + { + $client = $this->getHttpClient(__FUNCTION__, null, new class(parent::getHttpClient(__FUNCTION__)) implements HttpClientInterface { + use AsyncDecoratorTrait; + + public function request(string $method, string $url, array $options = []): ResponseInterface + { + $response = $this->client->request($method, $url, $options); + $response->getStatusCode(); // should be avoided and breaks compatibility with AsyncDecoratorTrait + + return $response; + } + + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + return $this->client->stream($responses, $timeout); + } + }); + + $response = $client->request('GET', 'http://localhost:8057/'); + + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Instance of "Symfony\Component\HttpClient\Response\NativeResponse" is already consumed and cannot be managed by "Symfony\Component\HttpClient\Response\AsyncResponse". A decorated client should not call any of the response\'s methods in its "request()" method.'); + $response->getStatusCode(); + } } From 25fb2f727851a56c99b99abf92451e835b7ae11c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 11 Jun 2021 14:33:25 +0200 Subject: [PATCH 59/78] [Runtime] fix overriding --env|-e with single-command apps --- src/Symfony/Component/Runtime/SymfonyRuntime.php | 1 + src/Symfony/Component/Runtime/Tests/phpt/command.php | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Runtime/SymfonyRuntime.php b/src/Symfony/Component/Runtime/SymfonyRuntime.php index 461f38e7767ee..9df2f5ca4b7b3 100644 --- a/src/Symfony/Component/Runtime/SymfonyRuntime.php +++ b/src/Symfony/Component/Runtime/SymfonyRuntime.php @@ -131,6 +131,7 @@ public function getRunner(?object $application): RunnerInterface } $console->setDefaultCommand($application->getName(), true); + $console->getDefinition()->addOptions($application->getDefinition()->getOptions()); return $this->getRunner($console); } diff --git a/src/Symfony/Component/Runtime/Tests/phpt/command.php b/src/Symfony/Component/Runtime/Tests/phpt/command.php index 42d66c1c98462..f8ba65133e7db 100644 --- a/src/Symfony/Component/Runtime/Tests/phpt/command.php +++ b/src/Symfony/Component/Runtime/Tests/phpt/command.php @@ -2,14 +2,15 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; require __DIR__.'/autoload.php'; return function (Command $command, InputInterface $input, OutputInterface $output, array $context) { - $command->setCode(function () use ($output, $context) { - $output->write('OK Command '.$context['SOME_VAR']); - }); + $command->addOption('hello', 'e', InputOption::VALUE_REQUIRED, 'How should I greet?', 'OK'); - return $command; + return $command->setCode(function () use ($input, $output, $context) { + $output->write($input->getOption('hello').' Command '.$context['SOME_VAR']); + }); }; From 9cf7fbc8b1c0ba7798ecf2cdf73b481799de7275 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 11 Jun 2021 14:38:10 +0200 Subject: [PATCH 60/78] [Uid] Realign inspect commands labels --- .../Uid/Command/InspectUlidCommand.php | 8 +- .../Uid/Command/InspectUuidCommand.php | 8 +- .../Tests/Command/InspectUlidCommandTest.php | 18 +- .../Tests/Command/InspectUuidCommandTest.php | 168 +++++++++--------- 4 files changed, 101 insertions(+), 101 deletions(-) diff --git a/src/Symfony/Component/Uid/Command/InspectUlidCommand.php b/src/Symfony/Component/Uid/Command/InspectUlidCommand.php index e95652a7985ff..f0943e599f8ca 100644 --- a/src/Symfony/Component/Uid/Command/InspectUlidCommand.php +++ b/src/Symfony/Component/Uid/Command/InspectUlidCommand.php @@ -62,11 +62,11 @@ protected function execute(InputInterface $input, OutputInterface $output) } $io->table(['Label', 'Value'], [ - ['Canonical (Base 32)', (string) $ulid], - ['Base 58', $ulid->toBase58()], - ['RFC 4122', $ulid->toRfc4122()], + ['toBase32 (canonical)', (string) $ulid], + ['toBase58', $ulid->toBase58()], + ['toRfc4122', $ulid->toRfc4122()], new TableSeparator(), - ['Timestamp', ($ulid->getDateTime())->format('Y-m-d H:i:s.v')], + ['Time', ($ulid->getDateTime())->format('Y-m-d H:i:s.v \U\T\C')], ]); return 0; diff --git a/src/Symfony/Component/Uid/Command/InspectUuidCommand.php b/src/Symfony/Component/Uid/Command/InspectUuidCommand.php index 4b10b7a8f5983..a41a198648257 100644 --- a/src/Symfony/Component/Uid/Command/InspectUuidCommand.php +++ b/src/Symfony/Component/Uid/Command/InspectUuidCommand.php @@ -72,14 +72,14 @@ protected function execute(InputInterface $input, OutputInterface $output) $rows = [ ['Version', $version], - ['Canonical (RFC 4122)', (string) $uuid], - ['Base 58', $uuid->toBase58()], - ['Base 32', $uuid->toBase32()], + ['toRfc4122 (canonical)', (string) $uuid], + ['toBase58', $uuid->toBase58()], + ['toBase32', $uuid->toBase32()], ]; if ($uuid instanceof UuidV1 || $uuid instanceof UuidV6) { $rows[] = new TableSeparator(); - $rows[] = ['Timestamp', $uuid->getDateTime()->format('Y-m-d H:i:s.u')]; + $rows[] = ['Time', $uuid->getDateTime()->format('Y-m-d H:i:s.u \U\T\C')]; } $io->table(['Label', 'Value'], $rows); diff --git a/src/Symfony/Component/Uid/Tests/Command/InspectUlidCommandTest.php b/src/Symfony/Component/Uid/Tests/Command/InspectUlidCommandTest.php index 7bd48bc9ab931..dc77eb0976e3f 100644 --- a/src/Symfony/Component/Uid/Tests/Command/InspectUlidCommandTest.php +++ b/src/Symfony/Component/Uid/Tests/Command/InspectUlidCommandTest.php @@ -31,15 +31,15 @@ public function test() ] as $ulid) { $this->assertSame(0, $commandTester->execute(['ulid' => $ulid])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => '00000000-0000-0000-0000-000000000000'])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => '461cc9b9-2397-0dba-91e9-33af4c63f7ec'])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => '461cc9b9-2397-2dba-91e9-33af4c63f7ec'])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => '461cc9b9-2397-7dba-91e9-33af4c63f7ec'])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => '461cc9b9-2397-cdba-91e9-33af4c63f7ec'])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => '4c8e3a2a-5993-11eb-a861-2bf05af69e52'])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => 'd108a1a0-957e-3c77-b110-d3f912374439'])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => '705c6eab-a535-4f49-bd51-436d0e81206a'])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => '4ec6c3ad-de94-5f75-b5f0-ad56661a30c4'])); $this->assertSame(<<assertSame(0, $commandTester->execute(['uuid' => '1eb59937-b0a7-6288-a861-db3dc2d8d4db'])); $this->assertSame(<< Date: Fri, 11 Jun 2021 15:06:13 +0200 Subject: [PATCH 61/78] Remove Debug component from patch-types.php --- .github/patch-types.php | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/patch-types.php b/.github/patch-types.php index 04335da560504..30fc4c1573c92 100644 --- a/.github/patch-types.php +++ b/.github/patch-types.php @@ -19,7 +19,6 @@ case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/BadFileName.php'): case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php'): case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/ParseError.php'): - case false !== strpos($file, '/src/Symfony/Component/Debug/Tests/Fixtures/'): case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Compiler/OptionalServiceClass.php'): case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php'): case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/MultipleArgumentsOptionalScalarNotReallyOptional.php'): From 8d3bea5fbb6bcdfa263b9ec7e047cf1758a183eb Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 11 Jun 2021 15:02:47 +0200 Subject: [PATCH 62/78] [PasswordHasher] Fix missing PasswordHasherAwareInterface allowed type in signatures --- .../Hasher/PasswordHasherFactoryInterface.php | 3 +-- .../Hasher/UserPasswordHasher.php | 6 +++--- .../Hasher/UserPasswordHasherInterface.php | 6 +++--- .../Tests/Hasher/PasswordHasherFactoryTest.php | 18 +++++++----------- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactoryInterface.php b/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactoryInterface.php index 0646f9f1843e5..fed2a77cf0ce1 100644 --- a/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactoryInterface.php +++ b/src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactoryInterface.php @@ -13,7 +13,6 @@ use Symfony\Component\PasswordHasher\PasswordHasherInterface; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; -use Symfony\Component\Security\Core\User\UserInterface; /** * PasswordHasherFactoryInterface to support different password hashers for different user accounts. @@ -26,7 +25,7 @@ interface PasswordHasherFactoryInterface /** * Returns the password hasher to use for the given user. * - * @param PasswordAuthenticatedUserInterface|UserInterface|string $user A PasswordAuthenticatedUserInterface/UserInterface instance or a class name + * @param PasswordHasherAwareInterface|PasswordAuthenticatedUserInterface|string $user * * @throws \RuntimeException When no password hasher could be found for the user */ diff --git a/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasher.php b/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasher.php index f26164d7e51af..5d36f86db1002 100644 --- a/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasher.php +++ b/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasher.php @@ -32,7 +32,7 @@ public function __construct(PasswordHasherFactoryInterface $hasherFactory) } /** - * @param PasswordAuthenticatedUserInterface $user + * @param PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user */ public function hashPassword($user, string $plainPassword): string { @@ -54,7 +54,7 @@ public function hashPassword($user, string $plainPassword): string } /** - * @param PasswordAuthenticatedUserInterface $user + * @param PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user */ public function isPasswordValid($user, string $plainPassword): bool { @@ -80,7 +80,7 @@ public function isPasswordValid($user, string $plainPassword): bool } /** - * @param PasswordAuthenticatedUserInterface $user + * @param PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user */ public function needsRehash($user): bool { diff --git a/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasherInterface.php b/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasherInterface.php index cf29220740542..b78309df4e400 100644 --- a/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasherInterface.php +++ b/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasherInterface.php @@ -18,9 +18,9 @@ * * @author Ariel Ferrandini * - * @method string hashPassword(PasswordAuthenticatedUserInterface $user, string $plainPassword) Hashes the plain password for the given user. - * @method bool isPasswordValid(PasswordAuthenticatedUserInterface $user, string $plainPassword) Checks if the plaintext password matches the user's password. - * @method bool needsRehash(PasswordAuthenticatedUserInterface $user) Checks if an encoded password would benefit from rehashing. + * @method string hashPassword(PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user, string $plainPassword) Hashes the plain password for the given user. + * @method bool isPasswordValid(PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user, string $plainPassword) Checks if the plaintext password matches the user's password. + * @method bool needsRehash(PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user) Checks if an encoded password would benefit from rehashing. */ interface UserPasswordHasherInterface { diff --git a/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php b/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php index 6012ff80c8c39..1f8fcb3e79531 100644 --- a/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php +++ b/src/Symfony/Component/PasswordHasher/Tests/Hasher/PasswordHasherFactoryTest.php @@ -21,18 +21,18 @@ use Symfony\Component\PasswordHasher\PasswordHasherInterface; use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder; use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; class PasswordHasherFactoryTest extends TestCase { public function testGetHasherWithMessageDigestHasher() { - $factory = new PasswordHasherFactory([UserInterface::class => [ + $factory = new PasswordHasherFactory([PasswordAuthenticatedUserInterface::class => [ 'class' => MessageDigestPasswordHasher::class, 'arguments' => ['sha512', true, 5], ]]); - $hasher = $factory->getPasswordHasher($this->createMock(UserInterface::class)); + $hasher = $factory->getPasswordHasher($this->createMock(PasswordAuthenticatedUserInterface::class)); $expectedHasher = new MessageDigestPasswordHasher('sha512', true, 5); $this->assertEquals($expectedHasher->hash('foo', 'moo'), $hasher->hash('foo', 'moo')); @@ -41,14 +41,10 @@ public function testGetHasherWithMessageDigestHasher() public function testGetHasherWithService() { $factory = new PasswordHasherFactory([ - UserInterface::class => new MessageDigestPasswordHasher('sha1'), + PasswordAuthenticatedUserInterface::class => new MessageDigestPasswordHasher('sha1'), ]); - $hasher = $factory->getPasswordHasher($this->createMock(UserInterface::class)); - $expectedHasher = new MessageDigestPasswordHasher('sha1'); - $this->assertEquals($expectedHasher->hash('foo', ''), $hasher->hash('foo', '')); - - $hasher = $factory->getPasswordHasher(new InMemoryUser('user', 'pass')); + $hasher = $factory->getPasswordHasher($this->createMock(PasswordAuthenticatedUserInterface::class)); $expectedHasher = new MessageDigestPasswordHasher('sha1'); $this->assertEquals($expectedHasher->hash('foo', ''), $hasher->hash('foo', '')); } @@ -56,7 +52,7 @@ public function testGetHasherWithService() public function testGetHasherWithClassName() { $factory = new PasswordHasherFactory([ - UserInterface::class => new MessageDigestPasswordHasher('sha1'), + PasswordAuthenticatedUserInterface::class => new MessageDigestPasswordHasher('sha1'), ]); $hasher = $factory->getPasswordHasher(SomeChildUser::class); @@ -208,7 +204,7 @@ public function testLegacyEncoderClass() } } -class SomeUser implements UserInterface +class SomeUser implements PasswordAuthenticatedUserInterface { public function getRoles(): array { From e777d54663addadd760dbaea5ee77d0959556f75 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 11 Jun 2021 15:29:40 +0200 Subject: [PATCH 63/78] [Console] fix managing signals when commands are lazy loaded --- src/Symfony/Component/Console/Application.php | 4 ++++ src/Symfony/Component/Console/Tests/ApplicationTest.php | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 426b3c4d6fa0c..9cdcef88cd042 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -287,6 +287,10 @@ public function doRun(InputInterface $input, OutputInterface $output) $command = $this->find($alternative); } + if ($command instanceof LazyCommand) { + $command = $command->getCommand(); + } + $this->runningCommand = $command; $exitCode = $this->doRunCommand($command, $input, $output); $this->runningCommand = null; diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index b3958226b600c..361e174cdec36 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -15,6 +15,7 @@ use Symfony\Component\Console\Application; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\HelpCommand; +use Symfony\Component\Console\Command\LazyCommand; use Symfony\Component\Console\Command\SignalableCommandInterface; use Symfony\Component\Console\CommandLoader\FactoryCommandLoader; use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass; @@ -1672,7 +1673,7 @@ public function testRunLazyCommandService() $container = new ContainerBuilder(); $container->addCompilerPass(new AddConsoleCommandPass()); $container - ->register('lazy-command', LazyCommand::class) + ->register('lazy-command', LazyTestCommand::class) ->addTag('console.command', ['command' => 'lazy:command']) ->addTag('console.command', ['command' => 'lazy:alias']) ->addTag('console.command', ['command' => 'lazy:alias2']); @@ -1847,7 +1848,7 @@ public function testSignal() $application->setAutoExit(false); $application->setDispatcher($dispatcher); $application->setSignalsToDispatchEvent(\SIGALRM); - $application->add($command); + $application->add(new LazyCommand('signal', [], '', false, function () use ($command) { return $command; }, true)); $this->assertFalse($command->signaled); $this->assertFalse($dispatcherCalled); @@ -1902,7 +1903,7 @@ public function __construct() } } -class LazyCommand extends Command +class LazyTestCommand extends Command { public function execute(InputInterface $input, OutputInterface $output): int { From 596ba7866e9e0f3c6ed38dba0f6b3288db1362c0 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 11 Jun 2021 16:36:11 +0200 Subject: [PATCH 64/78] [PasswordHasher] Remove PasswordHasherAwareInterface from UserPasswordHasherInterface API --- .../Component/PasswordHasher/Hasher/UserPasswordHasher.php | 6 +++--- .../PasswordHasher/Hasher/UserPasswordHasherInterface.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasher.php b/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasher.php index 5d36f86db1002..f26164d7e51af 100644 --- a/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasher.php +++ b/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasher.php @@ -32,7 +32,7 @@ public function __construct(PasswordHasherFactoryInterface $hasherFactory) } /** - * @param PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user + * @param PasswordAuthenticatedUserInterface $user */ public function hashPassword($user, string $plainPassword): string { @@ -54,7 +54,7 @@ public function hashPassword($user, string $plainPassword): string } /** - * @param PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user + * @param PasswordAuthenticatedUserInterface $user */ public function isPasswordValid($user, string $plainPassword): bool { @@ -80,7 +80,7 @@ public function isPasswordValid($user, string $plainPassword): bool } /** - * @param PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user + * @param PasswordAuthenticatedUserInterface $user */ public function needsRehash($user): bool { diff --git a/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasherInterface.php b/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasherInterface.php index b78309df4e400..cf29220740542 100644 --- a/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasherInterface.php +++ b/src/Symfony/Component/PasswordHasher/Hasher/UserPasswordHasherInterface.php @@ -18,9 +18,9 @@ * * @author Ariel Ferrandini * - * @method string hashPassword(PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user, string $plainPassword) Hashes the plain password for the given user. - * @method bool isPasswordValid(PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user, string $plainPassword) Checks if the plaintext password matches the user's password. - * @method bool needsRehash(PasswordAuthenticatedUserInterface|PasswordHasherAwareInterface $user) Checks if an encoded password would benefit from rehashing. + * @method string hashPassword(PasswordAuthenticatedUserInterface $user, string $plainPassword) Hashes the plain password for the given user. + * @method bool isPasswordValid(PasswordAuthenticatedUserInterface $user, string $plainPassword) Checks if the plaintext password matches the user's password. + * @method bool needsRehash(PasswordAuthenticatedUserInterface $user) Checks if an encoded password would benefit from rehashing. */ interface UserPasswordHasherInterface { From d8adf5101a294a8d86ccee0ca2f7aecf1f17a3e3 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 11 Jun 2021 13:26:34 +0200 Subject: [PATCH 65/78] [HttpClient] fix compat with cURL <= 7.37 --- src/Symfony/Component/HttpClient/CurlHttpClient.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 48ecf773d4cfd..9025c27fb5fda 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -311,7 +311,7 @@ public function request(string $method, string $url, array $options = []): Respo } foreach ($curlopts as $opt => $value) { - if (null !== $value && !curl_setopt($ch, $opt, $value) && \CURLOPT_CERTINFO !== $opt) { + if (null !== $value && !curl_setopt($ch, $opt, $value) && \CURLOPT_CERTINFO !== $opt && (!\defined('CURLOPT_HEADEROPT') || \CURLOPT_HEADEROPT !== $opt)) { $constantName = $this->findConstantName($opt); throw new TransportException(sprintf('Curl option "%s" is not supported.', $constantName ?? $opt)); } @@ -574,7 +574,6 @@ private function validateExtraCurlOptions(array $options): void \CURLOPT_HEADER, \CURLOPT_CONNECTTIMEOUT, \CURLOPT_CONNECTTIMEOUT_MS, - \CURLOPT_HEADEROPT, \CURLOPT_HTTP_VERSION, \CURLOPT_PORT, \CURLOPT_DNS_USE_GLOBAL_CACHE, @@ -588,6 +587,10 @@ private function validateExtraCurlOptions(array $options): void $curloptsToCheck[] = \CURLOPT_HTTP09_ALLOWED; } + if (\defined('CURLOPT_HEADEROPT')) { + $curloptsToCheck[] = \CURLOPT_HEADEROPT; + } + $methodOpts = [ \CURLOPT_POST, \CURLOPT_PUT, From 6ccc344b4345439c96445635186cd1ec1c2f948a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 11 Jun 2021 13:18:06 +0200 Subject: [PATCH 66/78] [DependencyInjection] fix parsing classes for attributes --- .../RegisterAutoconfigureAttributesPass.php | 2 +- .../DependencyInjection/Loader/FileLoader.php | 2 +- .../RegisterAutoconfigureAttributesPassTest.php | 13 +++++++++++++ .../Tests/Loader/FileLoaderTest.php | 4 ++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RegisterAutoconfigureAttributesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/RegisterAutoconfigureAttributesPass.php index 7dd6d2aed5bad..08befc4dda12f 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RegisterAutoconfigureAttributesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RegisterAutoconfigureAttributesPass.php @@ -36,7 +36,7 @@ public function process(ContainerBuilder $container) } foreach ($container->getDefinitions() as $id => $definition) { - if ($this->accept($definition) && null !== $class = $container->getReflectionClass($definition->getClass())) { + if ($this->accept($definition) && $class = $container->getReflectionClass($definition->getClass(), false)) { $this->processClass($container, $class); } } diff --git a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php index 51b547eaf67b2..54688910b245d 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php @@ -105,7 +105,7 @@ public function registerClasses(Definition $prototype, string $namespace, string $serializedPrototype = serialize($prototype); foreach ($classes as $class => $errorMessage) { - if ($autoconfigureAttributes && $this->env) { + if (null === $errorMessage && $autoconfigureAttributes && $this->env) { $r = $this->container->getReflectionClass($class); $attribute = null; foreach ($r->getAttributes(When::class) as $attribute) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php index 274cde655ed15..111c41ac8a114 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php @@ -19,6 +19,7 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureAttributed; use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfiguredInterface; +use Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists; /** * @requires PHP 8 @@ -78,4 +79,16 @@ public function testAutoconfiguredTag() ; $this->assertEquals([AutoconfiguredInterface::class => $expected], $container->getAutoconfiguredInstanceof()); } + + public function testMissingParent() + { + $container = new ContainerBuilder(); + + $definition = $container->register(ParentNotExists::class, ParentNotExists::class) + ->setAutoconfigured(true); + + (new RegisterAutoconfigureAttributesPass())->process($container); + + $this->addToAssertionCount(1); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php index 6c1ed41204ccf..6c2743e860344 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php @@ -202,10 +202,10 @@ public function testMissingParentClass() { $container = new ContainerBuilder(); $container->setParameter('bad_classes_dir', 'BadClasses'); - $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'), 'test'); $loader->registerClasses( - (new Definition())->setPublic(false), + (new Definition())->setAutoconfigured(true), 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\\', 'Prototype/%bad_classes_dir%/*' ); From c4357ea78070091b2278e1c70ce53257ab035923 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 12 Jun 2021 11:39:52 +0200 Subject: [PATCH 67/78] [Console] Fix using #[AsCommand] without DI --- src/Symfony/Component/Console/Command/Command.php | 13 ++++++++++++- .../Component/Console/Tests/Command/CommandTest.php | 7 +++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index e35ae51ebfa28..71bf5d7c30957 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -101,7 +101,18 @@ public function __construct(string $name = null) { $this->definition = new InputDefinition(); - if (null !== $name || null !== $name = static::getDefaultName()) { + if (null === $name && null !== $name = static::getDefaultName()) { + $aliases = explode('|', $name); + + if ('' === $name = array_shift($aliases)) { + $this->setHidden(true); + $name = array_shift($aliases); + } + + $this->setAliases($aliases); + } + + if (null !== $name) { $this->setName($name); } diff --git a/src/Symfony/Component/Console/Tests/Command/CommandTest.php b/src/Symfony/Component/Console/Tests/Command/CommandTest.php index 68c0366210374..839beac3f0145 100644 --- a/src/Symfony/Component/Console/Tests/Command/CommandTest.php +++ b/src/Symfony/Component/Console/Tests/Command/CommandTest.php @@ -414,6 +414,13 @@ public function testCommandAttribute() { $this->assertSame('|foo|f', Php8Command::getDefaultName()); $this->assertSame('desc', Php8Command::getDefaultDescription()); + + $command = new Php8Command(); + + $this->assertSame('foo', $command->getName()); + $this->assertSame('desc', $command->getDescription()); + $this->assertTrue($command->isHidden()); + $this->assertSame(['f'], $command->getAliases()); } } From 8a2bd4df1d39315ceb0614203f706cf0cb2b4590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tinjo=20Sch=C3=B6ni?= <32767367+tscni@users.noreply.github.com> Date: Mon, 14 Jun 2021 16:11:03 +0200 Subject: [PATCH 68/78] [Security] Fix deprecation notice on TokenInterface::getUser() stringable return AuthenticatorManager raises a deprecation notice about the missing implementation of UserInterface::getUserIdentifier() when TokenInterface::getUser() returns a string. This fixes that issue. --- .../Security/Http/Authentication/AuthenticatorManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php b/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php index 800605d60af48..7774db12884c9 100644 --- a/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php +++ b/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php @@ -230,7 +230,8 @@ private function executeAuthenticator(AuthenticatorInterface $authenticator, Req private function handleAuthenticationSuccess(TokenInterface $authenticatedToken, PassportInterface $passport, Request $request, AuthenticatorInterface $authenticator): ?Response { // @deprecated since 5.3 - if (!method_exists($authenticatedToken->getUser(), 'getUserIdentifier')) { + $user = $authenticatedToken->getUser(); + if ($user instanceof UserInterface && !method_exists($user, 'getUserIdentifier')) { trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier(): string" in user class "%s" is deprecated. This method will replace "getUsername()" in Symfony 6.0.', get_debug_type($authenticatedToken->getUser())); } From 8df2ea12d356af736a416efc939b339f7f02e428 Mon Sep 17 00:00:00 2001 From: George Yiannoulopoulos <47791082+simplegr@users.noreply.github.com> Date: Tue, 15 Jun 2021 11:42:13 +0300 Subject: [PATCH 69/78] Fix some typos in Greek language --- .../Resources/translations/validators.el.xlf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf index c8882d2ae6667..3dded07760de0 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf @@ -68,7 +68,7 @@ The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. - Ο τύπος mime του αρχείου δεν είναι έγκυρος ({{ type }}). Οι έγκρυοι τύποι mime είναι {{ types }}. + Ο τύπος mime του αρχείου δεν είναι έγκυρος ({{ type }}). Οι έγκυροι τύποι mime είναι {{ types }}. This value should be {{ limit }} or less. @@ -144,7 +144,7 @@ This value is not a valid locale. - Αυτή η τιμή δεν αντιστοιχεί σε έκγυρο κωδικό τοποθεσίας. + Αυτή η τιμή δεν αντιστοιχεί σε έγκυρο κωδικό τοποθεσίας. This value is not a valid country. @@ -224,7 +224,7 @@ This is not a valid International Bank Account Number (IBAN). - Αυτό δεν αντιστοιχεί σε έκγυρο διεθνή αριθμό τραπεζικού λογαριασμού (IBAN). + Αυτό δεν αντιστοιχεί σε έγκυρο διεθνή αριθμό τραπεζικού λογαριασμού (IBAN). This value is not a valid ISBN-10. @@ -312,7 +312,7 @@ This is not a valid Business Identifier Code (BIC). - Αυτός δεν έιναι ένας έγκυρος κωδικός BIC. + Αυτός δεν είναι ένας έγκυρος κωδικός BIC. Error @@ -356,11 +356,11 @@ This value is not a valid timezone. - Αυτή η τιμή θα δέν είναι έγκυρη ζώνη ώρας. + Αυτή η τιμή θα δεν είναι έγκυρη ζώνη ώρας. This password has been leaked in a data breach, it must not be used. Please use another password. - Αυτός ο κωδικός πρόσβασης έχει διερρεύσει σε παραβίαση δεδομένων. Παρακαλούμε να χρησιμοποιήσετε έναν άλλο κωδικό. + Αυτός ο κωδικός πρόσβασης έχει διαρρεύσει σε παραβίαση δεδομένων. Παρακαλούμε να χρησιμοποιήσετε έναν άλλο κωδικό. This value should be between {{ min }} and {{ max }}. @@ -368,7 +368,7 @@ This value is not a valid hostname. - Αυτή η τιμή δέν είναι έγκυρο όνομα υποδοχής. + Αυτή η τιμή δεν είναι έγκυρο όνομα υποδοχής. The number of elements in this collection should be a multiple of {{ compared_value }}. @@ -376,7 +376,7 @@ This value should satisfy at least one of the following constraints: - Αυτή η τιμή θα πρέπει να ικανοποιεί τουλάχιστον έναν απο τους παρακάτω περιορισμούς: + Αυτή η τιμή θα πρέπει να ικανοποιεί τουλάχιστον έναν από τους παρακάτω περιορισμούς: Each element of this collection should satisfy its own set of constraints. @@ -384,7 +384,7 @@ This value is not a valid International Securities Identification Number (ISIN). - Αυτή η τιμή δέν είναι έγυρο International Securities Identification Number (ISIN). + Αυτή η τιμή δεν είναι έγκυρο International Securities Identification Number (ISIN). From 4568876d0cbf7921f8317193c66d6a6d16d29ea8 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 14 Jun 2021 19:02:44 +0200 Subject: [PATCH 70/78] [Security] Restore extension point in MessageDigestPasswordEncoder Signed-off-by: Alexander M. Turek --- .../Encoder/MessageDigestPasswordEncoder.php | 53 ++++++++++++++++++- .../MyMessageDigestPasswordEncoder.php | 34 ++++++++++++ .../MessageDigestPasswordEncoderTest.php | 10 ++++ 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/Security/Core/Tests/Encoder/Fixtures/MyMessageDigestPasswordEncoder.php diff --git a/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php index 8ea18c0541cfa..2942c632787df 100644 --- a/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Security\Core\Encoder; use Symfony\Component\PasswordHasher\Hasher\MessageDigestPasswordHasher; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use "%s" instead.', MessageDigestPasswordEncoder::class, MessageDigestPasswordHasher::class); @@ -24,7 +25,10 @@ */ class MessageDigestPasswordEncoder extends BasePasswordEncoder { - use LegacyEncoderTrait; + private $algorithm; + private $encodeHashAsBase64; + private $iterations = 1; + private $encodedLength = -1; /** * @param string $algorithm The digest algorithm to use @@ -33,6 +37,51 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder */ public function __construct(string $algorithm = 'sha512', bool $encodeHashAsBase64 = true, int $iterations = 5000) { - $this->hasher = new MessageDigestPasswordHasher($algorithm, $encodeHashAsBase64, $iterations); + $this->algorithm = $algorithm; + $this->encodeHashAsBase64 = $encodeHashAsBase64; + + try { + $this->encodedLength = \strlen($this->encodePassword('', 'salt')); + } catch (\LogicException $e) { + // ignore algorithm not supported + } + + $this->iterations = $iterations; + } + + /** + * {@inheritdoc} + */ + public function encodePassword(string $raw, ?string $salt) + { + if ($this->isPasswordTooLong($raw)) { + throw new BadCredentialsException('Invalid password.'); + } + + if (!\in_array($this->algorithm, hash_algos(), true)) { + throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm)); + } + + $salted = $this->mergePasswordAndSalt($raw, $salt); + $digest = hash($this->algorithm, $salted, true); + + // "stretch" hash + for ($i = 1; $i < $this->iterations; ++$i) { + $digest = hash($this->algorithm, $digest.$salted, true); + } + + return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest); + } + + /** + * {@inheritdoc} + */ + public function isPasswordValid(string $encoded, string $raw, ?string $salt) + { + if (\strlen($encoded) !== $this->encodedLength || false !== strpos($encoded, '$')) { + return false; + } + + return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); } } diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/Fixtures/MyMessageDigestPasswordEncoder.php b/src/Symfony/Component/Security/Core/Tests/Encoder/Fixtures/MyMessageDigestPasswordEncoder.php new file mode 100644 index 0000000000000..110541d51084c --- /dev/null +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/Fixtures/MyMessageDigestPasswordEncoder.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\Tests\Encoder\Fixtures; + +use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; + +final class MyMessageDigestPasswordEncoder extends MessageDigestPasswordEncoder +{ + public function __construct() + { + parent::__construct('sha512', true, 1); + } + + protected function mergePasswordAndSalt(string $password, ?string $salt): string + { + return json_encode(['password' => $password, 'salt' => $salt]); + } + + protected function demergePasswordAndSalt(string $mergedPasswordSalt): array + { + ['password' => $password, 'salt' => $salt] = json_decode($mergedPasswordSalt, true); + + return [$password, $salt]; + } +} diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php index a354b0dbf25a8..a9753957860fa 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php @@ -14,6 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; use Symfony\Component\Security\Core\Exception\BadCredentialsException; +use Symfony\Component\Security\Core\Tests\Encoder\Fixtures\MyMessageDigestPasswordEncoder; /** * @group legacy @@ -60,4 +61,13 @@ public function testCheckPasswordLength() $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt')); } + + public function testCustomEncoder() + { + $encoder = new MyMessageDigestPasswordEncoder(); + $encodedPassword = $encoder->encodePassword('p4ssw0rd', 's417'); + + $this->assertSame(base64_encode(hash('sha512', '{"password":"p4ssw0rd","salt":"s417"}', true)), $encodedPassword); + $this->assertTrue($encoder->isPasswordValid($encodedPassword, 'p4ssw0rd', 's417')); + } } From 0748b5247e004f9991b3ceb38b7a1edf1a4e2d3b Mon Sep 17 00:00:00 2001 From: Serhii Smirnov Date: Wed, 16 Jun 2021 00:11:27 +0300 Subject: [PATCH 71/78] bug #41715: [FrameworkBundle] Partial backport of PR#41530 https://github.com/symfony/symfony/issues/41715 https://github.com/symfony/symfony/pull/41530 --- .../Bundle/FrameworkBundle/KernelBrowser.php | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index 99f749e5fa7f7..638c71785ea01 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -49,7 +49,9 @@ public function __construct(KernelInterface $kernel, array $server = [], History */ public function getContainer() { - return $this->kernel->getContainer(); + $container = $this->kernel->getContainer(); + + return $container->has('test.service_container') ? $container->get('test.service_container') : $container; } /** @@ -69,11 +71,11 @@ public function getKernel() */ public function getProfile() { - if (null === $this->response || !$this->kernel->getContainer()->has('profiler')) { + if (null === $this->response || !$this->getContainer()->has('profiler')) { return false; } - return $this->kernel->getContainer()->get('profiler')->loadProfileFromResponse($this->response); + return $this->getContainer()->get('profiler')->loadProfileFromResponse($this->response); } /** @@ -83,7 +85,7 @@ public function getProfile() */ public function enableProfiler() { - if ($this->kernel->getContainer()->has('profiler')) { + if ($this->getContainer()->has('profiler')) { $this->profiler = true; } } @@ -123,7 +125,7 @@ public function loginUser($user, string $firewallContext = 'main'): self $token = new TestBrowserToken($user->getRoles(), $user, $firewallContext); $token->setAuthenticated(true); - $container = $this->kernel->getContainer()->get('test.service_container'); + $container = $this->getContainer()->get('test.service_container'); $container->get('security.untracked_token_storage')->setToken($token); if (!$container->has('session')) { @@ -161,7 +163,7 @@ protected function doRequest($request) $this->profiler = false; $this->kernel->boot(); - $this->kernel->getContainer()->get('profiler')->enable(); + $this->getContainer()->get('profiler')->enable(); } return parent::doRequest($request); @@ -220,7 +222,11 @@ protected function getScript($request) $profilerCode = ''; if ($this->profiler) { - $profilerCode = '$kernel->getContainer()->get(\'profiler\')->enable();'; + $profilerCode = <<<'EOF' +$container = $kernel->getContainer(); +$container = $container->has('test.service_container') ? $container->get('test.service_container') : $container; +$container->get('profiler')->enable(); +EOF; } $code = << Date: Wed, 16 Jun 2021 10:34:59 +0200 Subject: [PATCH 72/78] Minor typo in PHPDoc comment --- src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php index bf3ce67908eff..f4c4efd2fd93d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php @@ -91,7 +91,7 @@ protected static function bootKernel(array $options = []) /** * Provides a dedicated test container with access to both public and private - * services. The container will not include private services that has been + * services. The container will not include private services that have been * inlined or removed. Private services will be removed when they are not * used by other services. * From 3084764ad82f29dbb025df19978b9cbc3ab34728 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Thu, 3 Jun 2021 16:11:19 +0200 Subject: [PATCH 73/78] Only trigger for the correct firewall in ContextListener::onKernelResponse() --- .../Tests/Functional/AuthenticatorTest.php | 13 +++++++++++++ .../app/Authenticator/multiple_firewalls.yml | 17 +++++++++++++++++ .../Functional/app/Authenticator/routing.yml | 8 ++++++++ src/Symfony/Bundle/SecurityBundle/composer.json | 2 +- .../Security/Http/Firewall/ContextListener.php | 4 ++-- .../Http/Tests/Firewall/ContextListenerTest.php | 6 +++--- 6 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/multiple_firewalls.yml diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php index beb12a0b4d60f..69f64693c85b7 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php @@ -87,4 +87,17 @@ public function provideEmailsWithFirewalls() yield ['jane@example.org', 'main']; yield ['john@example.org', 'custom']; } + + public function testMultipleFirewalls() + { + $client = $this->createClient(['test_case' => 'Authenticator', 'root_config' => 'multiple_firewalls.yml']); + + $client->request('POST', '/firewall1/login', [ + '_username' => 'jane@example.org', + '_password' => 'test', + ]); + + $client->request('GET', '/firewall2/profile'); + $this->assertResponseRedirects('http://localhost/login'); + } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/multiple_firewalls.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/multiple_firewalls.yml new file mode 100644 index 0000000000000..655a8d83d4d5f --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/multiple_firewalls.yml @@ -0,0 +1,17 @@ +imports: +- { resource: ./config.yml } +- { resource: ./security.yml } + +security: + enable_authenticator_manager: true + firewalls: + firewall1: + pattern: /firewall1 + provider: in_memory + form_login: + check_path: /firewall1/login + firewall2: + pattern: /firewall2 + provider: in_memory2 + form_login: + check_path: /firewall2/login diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml index 35662387dcf78..4796a3f6bc00c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml @@ -18,3 +18,11 @@ security_main_profile: security_custom_profile: path: /custom/user_profile defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::profileAction } + +firewall1_login: + path: /firewall1/login + +firewall2_profile: + path: /firewall2/profile + defaults: + _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\ProfileController diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 1ebe4c7a8686c..5e3d13d072a5b 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -29,7 +29,7 @@ "symfony/security-core": "^5.3", "symfony/security-csrf": "^4.4|^5.0", "symfony/security-guard": "^5.3", - "symfony/security-http": "^5.3" + "symfony/security-http": "^5.3.2" }, "require-dev": { "doctrine/annotations": "^1.10.4", diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php index 9416777b81ae3..098a2225c33f7 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php @@ -95,7 +95,7 @@ public function authenticate(RequestEvent $event) $request = $event->getRequest(); $session = $request->hasPreviousSession() && $request->hasSession() ? $request->getSession() : null; - $request->attributes->set('_security_firewall_run', true); + $request->attributes->set('_security_firewall_run', $this->sessionKey); if (null !== $session) { $usageIndexValue = $session instanceof Session ? $usageIndexReference = &$session->getUsageIndex() : 0; @@ -169,7 +169,7 @@ public function onKernelResponse(ResponseEvent $event) $request = $event->getRequest(); - if (!$request->hasSession() || !$request->attributes->get('_security_firewall_run', false)) { + if (!$request->hasSession() || $request->attributes->get('_security_firewall_run') !== $this->sessionKey) { return; } diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php index f995d215cabf1..bf9b028dcb638 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php @@ -106,7 +106,7 @@ public function testOnKernelResponseWithoutSession() $tokenStorage = new TokenStorage(); $tokenStorage->setToken(new UsernamePasswordToken('test1', 'pass1', 'phpunit')); $request = new Request(); - $request->attributes->set('_security_firewall_run', true); + $request->attributes->set('_security_firewall_run', '_security_session'); $session = new Session(new MockArraySessionStorage()); $request->setSession($session); @@ -212,7 +212,7 @@ public function testOnKernelResponseListenerRemovesItself() $listener = new ContextListener($tokenStorage, [], 'key123', null, $dispatcher); $request = new Request(); - $request->attributes->set('_security_firewall_run', true); + $request->attributes->set('_security_firewall_run', '_security_key123'); $request->setSession($session); $event = new ResponseEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST, new Response()); @@ -370,7 +370,7 @@ protected function runSessionOnKernelResponse($newToken, $original = null) { $session = new Session(new MockArraySessionStorage()); $request = new Request(); - $request->attributes->set('_security_firewall_run', true); + $request->attributes->set('_security_firewall_run', '_security_session'); $request->setSession($session); $requestStack = new RequestStack(); $requestStack->push($request); From 7ad1c44cf4a55ee716f60ed6c291731d851b30bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Tue, 15 Jun 2021 16:01:15 +0200 Subject: [PATCH 74/78] Fix RequestContext not updated --- .../Middleware/RouterContextMiddleware.php | 42 +++++++++++++------ .../RouterContextMiddlewareTest.php | 35 +++++++++------- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/Symfony/Component/Messenger/Middleware/RouterContextMiddleware.php b/src/Symfony/Component/Messenger/Middleware/RouterContextMiddleware.php index 35a381870b858..62bd1d7e5b8d2 100644 --- a/src/Symfony/Component/Messenger/Middleware/RouterContextMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/RouterContextMiddleware.php @@ -14,7 +14,6 @@ use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\Stamp\ConsumedByWorkerStamp; use Symfony\Component\Messenger\Stamp\RouterContextStamp; -use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\RequestContextAwareInterface; /** @@ -49,24 +48,41 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope return $stack->next()->handle($envelope, $stack); } - $currentContext = $this->router->getContext(); + $context = $this->router->getContext(); + $currentBaseUrl = $context->getBaseUrl(); + $currentMethod = $context->getMethod(); + $currentHost = $context->getHost(); + $currentScheme = $context->getScheme(); + $currentHttpPort = $context->getHttpPort(); + $currentHttpsPort = $context->getHttpsPort(); + $currentPathInfo = $context->getPathInfo(); + $currentQueryString = $context->getQueryString(); /* @var RouterContextStamp $contextStamp */ - $this->router->setContext(new RequestContext( - $contextStamp->getBaseUrl(), - $contextStamp->getMethod(), - $contextStamp->getHost(), - $contextStamp->getScheme(), - $contextStamp->getHttpPort(), - $contextStamp->getHttpsPort(), - $contextStamp->getPathInfo(), - $contextStamp->getQueryString() - )); + $context + ->setBaseUrl($contextStamp->getBaseUrl()) + ->setMethod($contextStamp->getMethod()) + ->setHost($contextStamp->getHost()) + ->setScheme($contextStamp->getScheme()) + ->setHttpPort($contextStamp->getHttpPort()) + ->setHttpsPort($contextStamp->getHttpsPort()) + ->setPathInfo($contextStamp->getPathInfo()) + ->setQueryString($contextStamp->getQueryString()) + ; try { return $stack->next()->handle($envelope, $stack); } finally { - $this->router->setContext($currentContext); + $context + ->setBaseUrl($currentBaseUrl) + ->setMethod($currentMethod) + ->setHost($currentHost) + ->setScheme($currentScheme) + ->setHttpPort($currentHttpPort) + ->setHttpsPort($currentHttpsPort) + ->setPathInfo($currentPathInfo) + ->setQueryString($currentQueryString) + ; } } } diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/RouterContextMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/RouterContextMiddlewareTest.php index a183cd03fb6ab..bddf56f65f40e 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/RouterContextMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/RouterContextMiddlewareTest.php @@ -3,7 +3,10 @@ namespace Symfony\Component\Messenger\Tests\Middleware; use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Middleware\MiddlewareInterface; use Symfony\Component\Messenger\Middleware\RouterContextMiddleware; +use Symfony\Component\Messenger\Middleware\StackInterface; +use Symfony\Component\Messenger\Middleware\StackMiddleware; use Symfony\Component\Messenger\Stamp\ConsumedByWorkerStamp; use Symfony\Component\Messenger\Stamp\RouterContextStamp; use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase; @@ -34,30 +37,32 @@ public function testMiddlewareStoreContext() public function testMiddlewareRestoreContext() { $router = $this->createMock(RequestContextAwareInterface::class); - $originalContext = new RequestContext(); + $context = new RequestContext('', 'POST', 'github.com'); $router ->expects($this->once()) ->method('getContext') - ->willReturn($originalContext); - - $router - ->expects($this->exactly(2)) - ->method('setContext') - ->withConsecutive( - [$this->callback(function ($context) { - $this->assertSame('symfony.com', $context->getHost()); - - return true; - })], - [$originalContext] - ); + ->willReturn($context); $middleware = new RouterContextMiddleware($router); $envelope = new Envelope(new \stdClass(), [ new ConsumedByWorkerStamp(), new RouterContextStamp('', 'GET', 'symfony.com', 'https', 80, 443, '/', ''), ]); - $middleware->handle($envelope, $this->getStackMock()); + + $nextMiddleware = $this->createMock(MiddlewareInterface::class); + $nextMiddleware + ->expects($this->once()) + ->method('handle') + ->willReturnCallback(function (Envelope $envelope, StackInterface $stack) use ($context): Envelope { + $this->assertSame('symfony.com', $context->getHost()); + + return $envelope; + }) + ; + + $middleware->handle($envelope, new StackMiddleware($nextMiddleware)); + + $this->assertSame('github.com', $context->getHost()); } } From 7e547fdd3cef07bbbe8d9db5b19310c82fa04a29 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 14 Jun 2021 09:59:25 +0200 Subject: [PATCH 75/78] [Uid] fix performance and prevent collisions with the real clock_seq --- .../Component/Uid/Factory/UuidFactory.php | 5 +---- src/Symfony/Component/Uid/NilUuid.php | 2 +- .../Uid/Tests/Factory/UuidFactoryTest.php | 7 +++--- src/Symfony/Component/Uid/Ulid.php | 13 ++++++++++- src/Symfony/Component/Uid/Uuid.php | 20 ++++++++--------- src/Symfony/Component/Uid/UuidV1.php | 22 ++++++++++++++++--- src/Symfony/Component/Uid/UuidV6.php | 15 +++++-------- 7 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/Symfony/Component/Uid/Factory/UuidFactory.php b/src/Symfony/Component/Uid/Factory/UuidFactory.php index ddcb0501d1b9b..312142837fa1d 100644 --- a/src/Symfony/Component/Uid/Factory/UuidFactory.php +++ b/src/Symfony/Component/Uid/Factory/UuidFactory.php @@ -74,10 +74,7 @@ public function timeBased($node = null): TimeBasedUuidFactory { $node ?? $node = $this->timeBasedNode; - if (null === $node) { - $class = $this->timeBasedClass; - $node = $this->timeBasedNode = new $class(); - } elseif (!$node instanceof Uuid) { + if (null !== $node && !$node instanceof Uuid) { $node = Uuid::fromString($node); } diff --git a/src/Symfony/Component/Uid/NilUuid.php b/src/Symfony/Component/Uid/NilUuid.php index f514c18e3b7c2..9d9746bb0599c 100644 --- a/src/Symfony/Component/Uid/NilUuid.php +++ b/src/Symfony/Component/Uid/NilUuid.php @@ -20,6 +20,6 @@ class NilUuid extends Uuid public function __construct() { - $this->uid = '00000000-0000-0000-0000-000000000000'; + $this->uid = parent::NIL; } } diff --git a/src/Symfony/Component/Uid/Tests/Factory/UuidFactoryTest.php b/src/Symfony/Component/Uid/Tests/Factory/UuidFactoryTest.php index e808f3809828a..b78b66f29f090 100644 --- a/src/Symfony/Component/Uid/Tests/Factory/UuidFactoryTest.php +++ b/src/Symfony/Component/Uid/Tests/Factory/UuidFactoryTest.php @@ -65,9 +65,10 @@ public function testCreateTimed() $this->assertSame('c10ab929ae84', $uuid1->getNode()); // Test default node override - $uuid2 = $uuidFactory->timeBased('7c1ede70-3586-48ed-a984-23c8018d9174')->create(); - $this->assertInstanceOf(UuidV6::class, $uuid2); - $this->assertSame('23c8018d9174', $uuid2->getNode()); + $uuid2Factory = $uuidFactory->timeBased('7c1ede70-3586-48ed-a984-23c8018d9174'); + $this->assertSame('1eb5a7ae-17e1-62d0-a984-23c8018d9174', (string) $uuid2Factory->create(new \DateTime('@1611076938.057800'))); + $this->assertSame('23c8018d9174', substr($uuid2Factory->create(), 24)); + $this->assertNotSame('a984', substr($uuid2Factory->create(), 19, 4)); // Test version override $uuid3 = (new UuidFactory(6, 1))->timeBased()->create(); diff --git a/src/Symfony/Component/Uid/Ulid.php b/src/Symfony/Component/Uid/Ulid.php index 69a782d438e90..d74ff6fb2aa6f 100644 --- a/src/Symfony/Component/Uid/Ulid.php +++ b/src/Symfony/Component/Uid/Ulid.php @@ -20,6 +20,8 @@ */ class Ulid extends AbstractUid { + private const NIL = '00000000000000000000000000'; + private static $time = ''; private static $rand = []; @@ -31,6 +33,12 @@ public function __construct(string $ulid = null) return; } + if (self::NIL === $ulid) { + $this->uid = $ulid; + + return; + } + if (!self::isValid($ulid)) { throw new \InvalidArgumentException(sprintf('Invalid ULID: "%s".', $ulid)); } @@ -77,7 +85,10 @@ public static function fromString(string $ulid): parent base_convert(substr($ulid, 27, 5), 16, 32) ); - return new static(strtr($ulid, 'abcdefghijklmnopqrstuv', 'ABCDEFGHJKMNPQRSTVWXYZ')); + $u = new static(self::NIL); + $u->uid = strtr($ulid, 'abcdefghijklmnopqrstuv', 'ABCDEFGHJKMNPQRSTVWXYZ'); + + return $u; } public function toBinary(): string diff --git a/src/Symfony/Component/Uid/Uuid.php b/src/Symfony/Component/Uid/Uuid.php index b4820d8c8a49f..dc666d28e31ab 100644 --- a/src/Symfony/Component/Uid/Uuid.php +++ b/src/Symfony/Component/Uid/Uuid.php @@ -24,16 +24,17 @@ class Uuid extends AbstractUid public const NAMESPACE_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8'; protected const TYPE = 0; + protected const NIL = '00000000-0000-0000-0000-000000000000'; public function __construct(string $uuid) { - $type = uuid_is_valid($uuid) ? uuid_type($uuid) : false; + $type = preg_match('{^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$}Di', $uuid) ? (int) $uuid[14] : false; - if (false === $type || \UUID_TYPE_INVALID === $type || (static::TYPE ?: $type) !== $type) { + if (false === $type || (static::TYPE ?: $type) !== $type) { throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid)); } - $this->uid = strtr($uuid, 'ABCDEF', 'abcdef'); + $this->uid = strtolower($uuid); } /** @@ -60,17 +61,16 @@ public static function fromString(string $uuid): parent return new static($uuid); } - if (!uuid_is_valid($uuid)) { - throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid)); + if (self::NIL === $uuid) { + return new NilUuid(); } - switch (uuid_type($uuid)) { + switch ($uuid[14]) { case UuidV1::TYPE: return new UuidV1($uuid); case UuidV3::TYPE: return new UuidV3($uuid); case UuidV4::TYPE: return new UuidV4($uuid); case UuidV5::TYPE: return new UuidV5($uuid); case UuidV6::TYPE: return new UuidV6($uuid); - case NilUuid::TYPE: return new NilUuid(); } return new self($uuid); @@ -109,11 +109,11 @@ final public static function v6(): UuidV6 public static function isValid(string $uuid): bool { - if (__CLASS__ === static::class) { - return uuid_is_valid($uuid); + if (!preg_match('{^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$}Di', $uuid)) { + return false; } - return uuid_is_valid($uuid) && static::TYPE === uuid_type($uuid); + return __CLASS__ === static::class || static::TYPE === (int) $uuid[14]; } public function toBinary(): string diff --git a/src/Symfony/Component/Uid/UuidV1.php b/src/Symfony/Component/Uid/UuidV1.php index 7621de5212146..bc8c03203bd3c 100644 --- a/src/Symfony/Component/Uid/UuidV1.php +++ b/src/Symfony/Component/Uid/UuidV1.php @@ -20,6 +20,8 @@ class UuidV1 extends Uuid { protected const TYPE = 1; + private static $clockSeq; + public function __construct(string $uuid = null) { if (null === $uuid) { @@ -41,11 +43,25 @@ public function getNode(): string public static function generate(\DateTimeInterface $time = null, Uuid $node = null): string { - $uuid = uuid_create(static::TYPE); + $uuid = !$time || !$node ? uuid_create(static::TYPE) : parent::NIL; + + if ($time) { + if ($node) { + // use clock_seq from the node + $seq = substr($node->uid, 19, 4); + } else { + // generate a static random clock_seq to prevent any collisions with the real one + $seq = substr($uuid, 19, 4); + + while (null === self::$clockSeq || $seq === self::$clockSeq) { + self::$clockSeq = sprintf('%04x', random_int(0, 0x3fff) | 0x8000); + } + + $seq = self::$clockSeq; + } - if (null !== $time) { $time = BinaryUtil::dateTimeToHex($time); - $uuid = substr($time, 8).'-'.substr($time, 4, 4).'-1'.substr($time, 1, 3).substr($uuid, 18); + $uuid = substr($time, 8).'-'.substr($time, 4, 4).'-1'.substr($time, 1, 3).'-'.$seq.substr($uuid, 23); } if ($node) { diff --git a/src/Symfony/Component/Uid/UuidV6.php b/src/Symfony/Component/Uid/UuidV6.php index cf231e20f2d11..a9a284bef254f 100644 --- a/src/Symfony/Component/Uid/UuidV6.php +++ b/src/Symfony/Component/Uid/UuidV6.php @@ -22,7 +22,7 @@ class UuidV6 extends Uuid { protected const TYPE = 6; - private static $seed; + private static $node; public function __construct(string $uuid = null) { @@ -55,15 +55,12 @@ public static function generate(\DateTimeInterface $time = null, Uuid $node = nu // uuid_create() returns a stable "node" that can leak the MAC of the host, but // UUIDv6 prefers a truly random number here, let's XOR both to preserve the entropy - if (null === self::$seed) { - self::$seed = [random_int(0, 0xffffff), random_int(0, 0xffffff)]; + if (null === self::$node) { + $seed = [random_int(0, 0xffffff), random_int(0, 0xffffff)]; + $node = unpack('N2', hex2bin('00'.substr($uuidV1, 24, 6)).hex2bin('00'.substr($uuidV1, 30))); + self::$node = sprintf('%06x%06x', ($seed[0] ^ $node[1]) | 0x010000, $seed[1] ^ $node[2]); } - $node = unpack('N2', hex2bin('00'.substr($uuidV1, 24, 6)).hex2bin('00'.substr($uuidV1, 30))); - - return $uuid.sprintf('%06x%06x', - (self::$seed[0] ^ $node[1]) | 0x010000, - self::$seed[1] ^ $node[2] - ); + return $uuid.self::$node; } } From 769a05bdc546bfd56d28ebd3123a9b338446f1f0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 17 Jun 2021 15:29:25 +0200 Subject: [PATCH 76/78] [FrameworkBundle] fix leftover --- src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index 638c71785ea01..cc989080ba9ae 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -125,7 +125,7 @@ public function loginUser($user, string $firewallContext = 'main'): self $token = new TestBrowserToken($user->getRoles(), $user, $firewallContext); $token->setAuthenticated(true); - $container = $this->getContainer()->get('test.service_container'); + $container = $this->getContainer(); $container->get('security.untracked_token_storage')->setToken($token); if (!$container->has('session')) { From 414813e895cfe45c8e1b2a92349ae2815eda9d26 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 17 Jun 2021 16:18:11 +0200 Subject: [PATCH 77/78] Update CHANGELOG for 5.3.2 --- CHANGELOG-5.3.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CHANGELOG-5.3.md b/CHANGELOG-5.3.md index 3f2c56d63ac9b..25c4691a7fbd8 100644 --- a/CHANGELOG-5.3.md +++ b/CHANGELOG-5.3.md @@ -7,6 +7,41 @@ in 5.3 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/v5.3.0...v5.3.1 +* 5.3.2 (2021-06-17) + + * security #cve-2021-32693 [SecurityHttp] Fix "Authentication granted with multiple firewalls" (wouterj) + * bug #41693 [Uid] fix performance and prevent collisions with the real clock_seq (nicolas-grekas) + * bug #41700 [Security] Fix deprecation notice on TokenInterface::getUser() stringable return (tscni) + * bug #41703 [Security] Restore extension point in MessageDigestPasswordEncoder (derrabus) + * bug #41716 [Messenger] Fix RequestContext not updated (jderusse) + * bug #41616 [Messenger] Remove TLS related options when not using TLS (odolbeau) + * bug #41719 [FrameworkBundle] fix Could not find service "test.service_container" (smilesrg) + * bug #41686 [Console] Fix using #[AsCommand] without DI (nicolas-grekas) + * bug #41673 [DependencyInjection] fix parsing classes for attributes (nicolas-grekas) + * bug #41675 [Runtime] fix overriding --env|-e with single-command apps (nicolas-grekas) + * bug #41674 [HttpClient] fix compat with cURL <= 7.37 (nicolas-grekas) + * bug #41680 [Console] fix managing signals when commands are lazy loaded (nicolas-grekas) + * bug #41678 [PasswordHasher] Fix missing PasswordHasherAwareInterface allowed type (chalasr) + * bug #41656 [HttpClient] throw exception when AsyncDecoratorTrait gets an already consumed response (nicolas-grekas) + * bug #41600 [Notifier] Escape `.` char for Telegram transport (Clément) + * bug #41644 [Config] fix tracking attributes in ReflectionClassResource (nicolas-grekas) + * bug #41621 [Process] Fix incorrect parameter type (bch36) + * bug #41624 [HttpClient] Revert bindto workaround for unaffected PHP versions (derrabus) + * bug #41597 [DependencyInjection] fix `when@{env}` inside imported files (nusje2000) + * bug #41553 [Messenger] fix BC for FrameworkBundle 4.4 with a non-existence alias being used (monteiro) + * bug #41582 Fix not null get collection key types (dragosprotung) + * bug #41572 [PasswordHasher] Prevent PHP fatal error when using auto algorithm (matason) + * bug #41549 [Security] Fix opcache preload with alias classes (jderusse) + * bug #41491 [Serializer] Do not allow to denormalize string with spaces only to valid a DateTime object (sidz) + * bug #41535 [Console] Fix negated options not accessible (jderusse) + * bug #41472 [Validator] remove service if its class doesn't exist (xabbuh) + * bug #41218 [DependencyInjection] Update loader’s directory when calling ContainerConfigurator::withPath (MatTheCat) + * bug #41505 [FrameworkBundle] fix KernelBrowser::loginUser with a stateless firewall (dunglas) + * bug #41509 [SecurityBundle] Link UserProviderListener to correct firewall dispatcher (Matth--) + * bug #41386 [Console] Escape synopsis output (jschaedl) + * bug #41523 [Notifier] [Bridge] Remove hidden dependency on HttpFoundation for SmsBiurasTransport (fre5h) + * bug #41512 Relax requirement on symfony/runtime (lyrixx) + * 5.3.1 (2021-06-02) * bug #41463 [Serializer][Validator] Fix not null return from "getCollectionValueTypes" (jderusse) From 1e7649fb30a218b405d716c9a334cadb6b8b8e93 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 17 Jun 2021 16:18:27 +0200 Subject: [PATCH 78/78] Update VERSION for 5.3.2 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 5cf810d862c64..1793992a9f451 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -75,12 +75,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - public const VERSION = '5.3.2-DEV'; + public const VERSION = '5.3.2'; public const VERSION_ID = 50302; public const MAJOR_VERSION = 5; public const MINOR_VERSION = 3; public const RELEASE_VERSION = 2; - public const EXTRA_VERSION = 'DEV'; + public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '01/2022'; public const END_OF_LIFE = '01/2022';