From ce92c879c19ed1c53aac885c42929c65baedaf00 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 25 Nov 2022 11:41:13 +0100 Subject: [PATCH 01/16] Bump Symfony version to 6.2.0 --- 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 52a61b868d73c..3661c216a2c4b 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 array $freshCache = []; - public const VERSION = '6.2.0-RC1'; + public const VERSION = '6.2.0-DEV'; public const VERSION_ID = 60200; public const MAJOR_VERSION = 6; public const MINOR_VERSION = 2; public const RELEASE_VERSION = 0; - public const EXTRA_VERSION = 'RC1'; + public const EXTRA_VERSION = 'DEV'; public const END_OF_MAINTENANCE = '07/2023'; public const END_OF_LIFE = '07/2023'; From 60edb5d7796c06a91bd5eb6d41b33617e7049021 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 25 Nov 2022 12:02:30 +0100 Subject: [PATCH 02/16] skip a test if the signal to be sent is not available --- src/Symfony/Component/Console/Tests/ApplicationTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index fdb9b3f335d8a..aa4901be66300 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -1945,6 +1945,10 @@ public function testSignalSubscriber() */ public function testSetSignalsToDispatchEvent() { + if (!\defined('SIGUSR1')) { + $this->markTestSkipped('SIGUSR1 not available'); + } + $command = new BaseSignableCommand(); $subscriber = new SignalEventSubscriber(); From 2ada813500bb58f3be2cd6842c5d73704e1c3ded Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 25 Nov 2022 15:09:27 +0100 Subject: [PATCH 03/16] skip tests if the signal to be sent is not available --- src/Symfony/Component/Console/Tests/ApplicationTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index aa4901be66300..9f85975ad8dd0 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -1981,6 +1981,10 @@ public function testSignalableCommandInterfaceWithoutSignals() public function testSignalableCommandHandlerCalledAfterEventListener() { + if (!\defined('SIGUSR1')) { + $this->markTestSkipped('SIGUSR1 not available'); + } + $command = new SignableCommand(); $subscriber = new SignalEventSubscriber(); From 275d2cd5a344d70b7990833034ce692fa92c3c9a Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 25 Nov 2022 15:23:13 +0100 Subject: [PATCH 04/16] do not wire the MercureTransportFactory if the MercureBundle is not enabled --- .../FrameworkBundle/DependencyInjection/FrameworkExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 77d8a9d27e9a7..a20f2a3ddb4d5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -2587,7 +2587,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ } } - if (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', MercureTransportFactory::class, $parentPackages, true) && ContainerBuilder::willBeAvailable('symfony/mercure-bundle', MercureBundle::class, $parentPackages, true)) { + if (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', MercureTransportFactory::class, $parentPackages, true) && ContainerBuilder::willBeAvailable('symfony/mercure-bundle', MercureBundle::class, $parentPackages, true) && \in_array(MercureBundle::class, $container->getParameter('kernel.bundles'), true)) { $container->getDefinition($classToServices[MercureTransportFactory::class]) ->replaceArgument('$registry', new Reference(HubRegistry::class)); } elseif (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', MercureTransportFactory::class, $parentPackages, true)) { From 03fc7e1cb09160c508c055cb398a5b63ad0f5193 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 25 Nov 2022 10:12:29 +0100 Subject: [PATCH 05/16] [Clock] Implement PSR-20 --- composer.json | 2 ++ src/Symfony/Component/Clock/ClockInterface.php | 6 +++--- src/Symfony/Component/Clock/composer.json | 6 +++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index eda77e963e5ef..782d739047416 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "php-http/async-client-implementation": "*", "php-http/client-implementation": "*", "psr/cache-implementation": "2.0|3.0", + "psr/clock-implementation": "1.0", "psr/container-implementation": "1.1|2.0", "psr/event-dispatcher-implementation": "1.0", "psr/http-client-implementation": "1.0", @@ -40,6 +41,7 @@ "doctrine/persistence": "^2|^3", "twig/twig": "^2.13|^3.0.4", "psr/cache": "^2.0|^3.0", + "psr/clock": "^1.0", "psr/container": "^1.1|^2.0", "psr/event-dispatcher": "^1.0", "psr/link": "^1.1|^2.0", diff --git a/src/Symfony/Component/Clock/ClockInterface.php b/src/Symfony/Component/Clock/ClockInterface.php index af502a14ed6eb..435775a8f05d3 100644 --- a/src/Symfony/Component/Clock/ClockInterface.php +++ b/src/Symfony/Component/Clock/ClockInterface.php @@ -11,13 +11,13 @@ namespace Symfony\Component\Clock; +use Psr\Clock\ClockInterface as PsrClockInterface; + /** * @author Nicolas Grekas */ -interface ClockInterface +interface ClockInterface extends PsrClockInterface { - public function now(): \DateTimeImmutable; - public function sleep(float|int $seconds): void; public function withTimeZone(\DateTimeZone|string $timezone): static; diff --git a/src/Symfony/Component/Clock/composer.json b/src/Symfony/Component/Clock/composer.json index 897d57f4b307a..2ff68a82227fb 100644 --- a/src/Symfony/Component/Clock/composer.json +++ b/src/Symfony/Component/Clock/composer.json @@ -15,8 +15,12 @@ "homepage": "https://symfony.com/contributors" } ], + "provide": { + "psr/clock-implementation": "1.0" + }, "require": { - "php": ">=8.1" + "php": ">=8.1", + "psr/clock": "^1.0" }, "autoload": { "psr-4": { "Symfony\\Component\\Clock\\": "" }, From da327c74a50e8fb43479df79ba479e2f4e7636ce Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 25 Nov 2022 16:40:49 +0100 Subject: [PATCH 06/16] parse unquoted digits in tag values as integers --- src/Symfony/Component/Yaml/Inline.php | 3 +-- .../Component/Yaml/Tests/DumperTest.php | 9 +-------- .../Fixtures/YtsSpecificationExamples.yml | 2 +- .../Component/Yaml/Tests/InlineTest.php | 19 +++++++++++++++++++ .../Component/Yaml/Tests/ParserTest.php | 12 ++++-------- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index d8994cb34cc21..f93f59676d9a4 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -86,7 +86,7 @@ public static function parse(string $value = null, int $flags = 0, array &$refer ++$i; break; default: - $result = self::parseScalar($value, $flags, null, $i, null === $tag, $references); + $result = self::parseScalar($value, $flags, null, $i, true, $references); } // some comments are allowed at the end @@ -657,7 +657,6 @@ private static function evaluateScalar(string $scalar, int $flags, array &$refer } return octdec($value); - // Optimize for returning strings. case \in_array($scalar[0], ['+', '-', '.'], true) || is_numeric($scalar[0]): if (Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar)) { $scalar = str_replace('_', '', $scalar); diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index 59a47a8130f31..4b9c74c2609de 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -492,8 +492,6 @@ public function testDumpingTaggedValueSequenceWithInlinedTagValues() YAML; $this->assertSame($expected, $yaml); - // @todo Fix the parser, preserve numbers. - $data[2] = new TaggedValue('number', '5'); $this->assertSameData($data, $this->parser->parse($expected, Yaml::PARSE_CUSTOM_TAGS)); } @@ -522,8 +520,6 @@ public function testDumpingTaggedValueMapRespectsInlineLevel() YAML; $this->assertSame($expected, $yaml); - // @todo Fix the parser, preserve numbers. - $data['count'] = new TaggedValue('number', '5'); $this->assertSameData($data, $this->parser->parse($expected, Yaml::PARSE_CUSTOM_TAGS)); } @@ -577,9 +573,6 @@ public function testDumpingNotInlinedNullTaggedValue() YAML; $this->assertSame($expected, $this->dumper->dump($data, 2)); - - // @todo Fix the parser, don't stringify null. - $data['foo'] = new TaggedValue('bar', 'null'); $this->assertSameData($data, $this->parser->parse($expected, Yaml::PARSE_CUSTOM_TAGS | Yaml::PARSE_CONSTANT)); } @@ -696,7 +689,7 @@ public function testDumpMultiLineStringAsScalarBlock() nested_inlined_multi_line_string: { inlined_multi_line: "foo\nbar\r\nempty line:\n\nbaz" } YAML -); + ); $this->assertSame($expected, $yml); $this->assertSame($data, $this->parser->parse($yml)); } diff --git a/src/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml b/src/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml index b5f41a2b1eccc..2acc4998e207e 100644 --- a/src/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml +++ b/src/Symfony/Component/Yaml/Tests/Fixtures/YtsSpecificationExamples.yml @@ -913,7 +913,7 @@ yaml: | no int: ! 12 string: !!str 12 php: | - [ 'integer' => 12, 'no int' => '12', 'string' => '12' ] + [ 'integer' => 12, 'no int' => 12, 'string' => '12' ] --- test: Private types todo: true diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index 5d338a41faa62..f71509d28f35c 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -743,6 +743,24 @@ public function testTagWithEmptyValueInMapping() $this->assertSame('', $value['foo']->getValue()); } + public function testTagWithQuotedInteger() + { + $value = Inline::parse('!number "5"', Yaml::PARSE_CUSTOM_TAGS); + + $this->assertInstanceOf(TaggedValue::class, $value); + $this->assertSame('number', $value->getTag()); + $this->assertSame('5', $value->getValue()); + } + + public function testTagWithUnquotedInteger() + { + $value = Inline::parse('!number 5', Yaml::PARSE_CUSTOM_TAGS); + + $this->assertInstanceOf(TaggedValue::class, $value); + $this->assertSame('number', $value->getTag()); + $this->assertSame(5, $value->getValue()); + } + public function testUnfinishedInlineMap() { $this->expectException(ParseException::class); @@ -769,6 +787,7 @@ public function getTestsForOctalNumbers() /** * @group legacy + * * @dataProvider getTestsForOctalNumbersYaml11Notation */ public function testParseOctalNumbersYaml11Notation(int $expected, string $yaml, string $replacement) diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 228c2f2ee9c69..0941075b10b57 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -54,8 +54,7 @@ public function testTaggedValueTopLevelNumber() { $yml = '!number 5'; $data = $this->parser->parse($yml, Yaml::PARSE_CUSTOM_TAGS); - // @todo Preserve the number, don't turn into string. - $expected = new TaggedValue('number', '5'); + $expected = new TaggedValue('number', 5); $this->assertSameData($expected, $data); } @@ -63,9 +62,8 @@ public function testTaggedValueTopLevelNull() { $yml = '!tag null'; $data = $this->parser->parse($yml, Yaml::PARSE_CUSTOM_TAGS); - // @todo Preserve literal null, don't turn into string. - $expected = new TaggedValue('tag', 'null'); - $this->assertSameData($expected, $data); + + $this->assertSameData(new TaggedValue('tag', null), $data); } public function testTaggedValueTopLevelString() @@ -1555,8 +1553,6 @@ public function testParseDateAsMappingValue() } /** - * @param $lineNumber - * @param $yaml * @dataProvider parserThrowsExceptionWithCorrectLineNumberProvider */ public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml) @@ -2310,7 +2306,7 @@ public function taggedValuesProvider() public function testNonSpecificTagSupport() { - $this->assertSame('12', $this->parser->parse('! 12')); + $this->assertSame(12, $this->parser->parse('! 12')); } public function testCustomTagsDisabled() From 8a503039390f8d1be0215a09aa2906771d1e7433 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 20 Nov 2022 20:08:10 +0100 Subject: [PATCH 07/16] Run tests with doctrine/collections 2 --- composer.json | 2 +- src/Symfony/Bridge/Doctrine/composer.json | 2 +- src/Symfony/Component/Form/composer.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index ffe1e31ef4341..600df1683b5a1 100644 --- a/composer.json +++ b/composer.json @@ -126,7 +126,7 @@ "cache/integration-tests": "dev-master", "doctrine/annotations": "^1.13.1", "doctrine/cache": "^1.11|^2.0", - "doctrine/collections": "~1.0", + "doctrine/collections": "^1.0|^2.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "^2.13.1|^3.0", "doctrine/orm": "^2.7.4", diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index d1445b164c5e5..3c10df7d6b2bf 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -44,7 +44,7 @@ "symfony/translation": "^4.4|^5.0|^6.0", "symfony/var-dumper": "^4.4|^5.0|^6.0", "doctrine/annotations": "^1.10.4", - "doctrine/collections": "~1.0", + "doctrine/collections": "^1.0|^2.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "^2.13.1|^3.0", "doctrine/orm": "^2.7.4", diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index ff9e6b9af6aa7..e6be770b8b277 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -29,7 +29,7 @@ "symfony/service-contracts": "^1.1|^2|^3" }, "require-dev": { - "doctrine/collections": "~1.0", + "doctrine/collections": "^1.0|^2.0", "symfony/validator": "^4.4.17|^5.1.9|^6.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", "symfony/expression-language": "^4.4|^5.0|^6.0", From 30a67eaa577a386635f3ed6f95c1d98bd15d727f Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 26 Nov 2022 12:39:45 +0100 Subject: [PATCH 08/16] Fix too eager deprecations for PhpAstExtractor --- .../DependencyInjection/FrameworkExtension.php | 5 ++--- .../Bundle/FrameworkBundle/Resources/config/translation.php | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index bb06a5597629c..c3a97888851a0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1306,9 +1306,8 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder $container->removeDefinition('translation.locale_switcher'); } - if (ContainerBuilder::willBeAvailable('nikic/php-parser', Parser::class, ['symfony/translation']) - && ContainerBuilder::willBeAvailable('symfony/translation', PhpAstExtractor::class, ['symfony/framework-bundle']) - ) { + // don't use ContainerBuilder::willBeAvailable() as these are not needed in production + if (interface_exists(Parser::class) && class_exists(PhpAstExtractor::class)) { $container->removeDefinition('translation.extractor.php'); } else { $container->removeDefinition('translation.extractor.php_ast'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.php index 265fb6da336a0..280e03f355cd4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.php @@ -153,6 +153,7 @@ ->tag('translation.dumper', ['alias' => 'res']) ->set('translation.extractor.php', PhpExtractor::class) + ->deprecate('symfony/framework-bundle', '6.2', 'The "%service_id%" service is deprecated, use "translation.extractor.php_ast" instead.') ->tag('translation.extractor', ['alias' => 'php']) ->set('translation.extractor.php_ast', PhpAstExtractor::class) From 924bce122cfb2be7e6bb0b8e42d3145c4ae6ac73 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 26 Nov 2022 12:41:04 +0100 Subject: [PATCH 09/16] Remove redundant version information from deprecation --- .../Bundle/FrameworkBundle/Resources/config/workflow.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.php index 4b8875da73424..85d786537f031 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.php @@ -41,9 +41,9 @@ ->abstract() ->set('.workflow.registry', Registry::class) ->alias(Registry::class, '.workflow.registry') - ->deprecate('symfony/workflow', '6.2', 'The "%alias_id%" alias is deprecated since Symfony 6.2 and will be removed in Symfony 7.0. Inject the workflow directly.') + ->deprecate('symfony/workflow', '6.2', 'The "%alias_id%" alias is deprecated, inject the workflow directly.') ->alias('workflow.registry', '.workflow.registry') - ->deprecate('symfony/workflow', '6.2', 'The "%alias_id%" service is deprecated since Symfony 6.2 and will be removed in Symfony 7.0. Inject the workflow directly.') + ->deprecate('symfony/workflow', '6.2', 'The "%alias_id%" alias is deprecated, inject the workflow directly.') ->set('workflow.security.expression_language', ExpressionLanguage::class) ; }; From df539e2d45b9d88f6a7432df644a0547e7f662ae Mon Sep 17 00:00:00 2001 From: MatTheCat Date: Sat, 26 Nov 2022 16:31:49 +0100 Subject: [PATCH 10/16] [SecurityBundle] Fix `logout.csrf_token_generator` default value --- .../DependencyInjection/MainConfiguration.php | 2 +- .../MainConfigurationTest.php | 2 +- .../Tests/Functional/LogoutTest.php | 13 ++++++++++ .../app/Logout/config_csrf_enabled.yml | 25 +++++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Logout/config_csrf_enabled.yml diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index 670d9263f45f4..25778ea851dd7 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -222,7 +222,7 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto if (isset($v['csrf_token_generator'])) { $v['enable_csrf'] = true; } elseif ($v['enable_csrf']) { - $v['csrf_token_generator'] = 'security.csrf.token_generator'; + $v['csrf_token_generator'] = 'security.csrf.token_manager'; } return $v; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php index c64a7b49ba56d..20bc11269fa6f 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php @@ -122,7 +122,7 @@ public function testLogoutCsrf() $assertions = [ 'custom_token_generator' => [true, 'a_token_generator'], - 'default_token_generator' => [true, 'security.csrf.token_generator'], + 'default_token_generator' => [true, 'security.csrf.token_manager'], 'disabled_csrf' => [false, null], 'empty' => [false, null], ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php index 5da52d9602a49..72ed1be80d077 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php @@ -69,6 +69,19 @@ public function testCookieClearingOnLogout() $this->assertNull($cookieJar->get('flavor')); } + public function testEnabledCsrf() + { + $client = $this->createClient(['test_case' => 'Logout', 'root_config' => 'config_csrf_enabled.yml']); + + $cookieJar = $client->getCookieJar(); + $cookieJar->set(new Cookie('flavor', 'chocolate', strtotime('+1 day'), null, 'somedomain')); + + $client->request('POST', '/login', ['_username' => 'johannes', '_password' => 'test']); + $client->request('GET', '/logout'); + + $this->assertResponseStatusCodeSame(Response::HTTP_FORBIDDEN); + } + private function callInRequestContext(KernelBrowser $client, callable $callable): void { /** @var EventDispatcherInterface $eventDispatcher */ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Logout/config_csrf_enabled.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Logout/config_csrf_enabled.yml new file mode 100644 index 0000000000000..9d05c34a5d11c --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Logout/config_csrf_enabled.yml @@ -0,0 +1,25 @@ +imports: +- { resource: ./../config/framework.yml } + +security: + password_hashers: + Symfony\Component\Security\Core\User\InMemoryUser: plaintext + + providers: + in_memory: + memory: + users: + johannes: { password: test, roles: [ROLE_USER] } + + firewalls: + default: + form_login: + check_path: login + remember_me: true + require_previous_session: false + logout: + enable_csrf: true + + access_control: + - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: .*, roles: IS_AUTHENTICATED_FULLY } From 913783562ffdb0736ff2e889bed6868ff20c9cce Mon Sep 17 00:00:00 2001 From: Antoine Lamirault Date: Sat, 26 Nov 2022 17:54:11 +0100 Subject: [PATCH 11/16] [Mime] Rename SMimeEncryptorTest to SMimeEncrypterTest --- .../Crypto/{SMimeEncryptorTest.php => SMimeEncrypterTest.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/Symfony/Component/Mime/Tests/Crypto/{SMimeEncryptorTest.php => SMimeEncrypterTest.php} (98%) diff --git a/src/Symfony/Component/Mime/Tests/Crypto/SMimeEncryptorTest.php b/src/Symfony/Component/Mime/Tests/Crypto/SMimeEncrypterTest.php similarity index 98% rename from src/Symfony/Component/Mime/Tests/Crypto/SMimeEncryptorTest.php rename to src/Symfony/Component/Mime/Tests/Crypto/SMimeEncrypterTest.php index 92df05e391c7e..75f3f3c4eb866 100644 --- a/src/Symfony/Component/Mime/Tests/Crypto/SMimeEncryptorTest.php +++ b/src/Symfony/Component/Mime/Tests/Crypto/SMimeEncrypterTest.php @@ -19,7 +19,7 @@ /** * @requires extension openssl */ -class SMimeEncryptorTest extends SMimeTestCase +class SMimeEncrypterTest extends SMimeTestCase { public function testEncryptMessage() { From 648ed20e03eeacffa7b63ec01e2a8bf51ab527e1 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 26 Nov 2022 22:45:21 +0100 Subject: [PATCH 12/16] Autowire the PSR ClockInterface --- .../FrameworkBundle/DependencyInjection/FrameworkExtension.php | 2 ++ .../Bundle/FrameworkBundle/Resources/config/services.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index c3a97888851a0..93d5de007ef9b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -20,6 +20,7 @@ use PhpParser\Parser; use PHPStan\PhpDocParser\Parser\PhpDocParser; use Psr\Cache\CacheItemPoolInterface; +use Psr\Clock\ClockInterface as PsrClockInterface; use Psr\Container\ContainerInterface as PsrContainerInterface; use Psr\Http\Client\ClientInterface; use Psr\Log\LoggerAwareInterface; @@ -277,6 +278,7 @@ public function load(array $configs, ContainerBuilder $container) if (!ContainerBuilder::willBeAvailable('symfony/clock', ClockInterface::class, ['symfony/framework-bundle'])) { $container->removeDefinition('clock'); $container->removeAlias(ClockInterface::class); + $container->removeAlias(PsrClockInterface::class); } $container->registerAliasForArgument('parameter_bag', PsrContainerInterface::class); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php index 40b6a5ac6c445..9facc09c783f8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php @@ -11,6 +11,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; +use Psr\Clock\ClockInterface as PsrClockInterface; use Psr\EventDispatcher\EventDispatcherInterface as PsrEventDispatcherInterface; use Symfony\Bundle\FrameworkBundle\CacheWarmer\ConfigBuilderCacheWarmer; use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache; @@ -230,6 +231,7 @@ class_exists(WorkflowEvents::class) ? WorkflowEvents::ALIASES : [] ->set('clock', NativeClock::class) ->alias(ClockInterface::class, 'clock') + ->alias(PsrClockInterface::class, 'clock') // register as abstract and excluded, aka not-autowirable types ->set(LoaderInterface::class)->abstract()->tag('container.excluded') From dc22f2ac16972b6bd7e77b5061fbb7d538d2b6ce Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Mon, 28 Nov 2022 14:41:56 +0100 Subject: [PATCH 13/16] [VarDumper] Fix typo in deprecation message --- src/Symfony/Component/VarDumper/VarDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/VarDumper.php b/src/Symfony/Component/VarDumper/VarDumper.php index e9fdae59b970e..840bfd6496817 100644 --- a/src/Symfony/Component/VarDumper/VarDumper.php +++ b/src/Symfony/Component/VarDumper/VarDumper.php @@ -49,7 +49,7 @@ public static function dump(mixed $var) public static function setHandler(callable $callable = null): ?callable { if (1 > \func_num_args()) { - trigger_deprecation('symfony/va-dumper', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + trigger_deprecation('symfony/var-dumper', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); } $prevHandler = self::$handler; From 8bb752265a279ab97e9fb29466257a36b80dd441 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Nov 2022 17:13:54 +0100 Subject: [PATCH 14/16] [Mailer] Fix body renderer check --- .../Mailer/EventListener/MessageListener.php | 6 ----- .../Tests/Transport/AbstractTransportTest.php | 23 +++++++++++++++++++ .../Mailer/Transport/AbstractTransport.php | 7 ++++++ src/Symfony/Component/Mailer/composer.json | 3 ++- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Mailer/EventListener/MessageListener.php b/src/Symfony/Component/Mailer/EventListener/MessageListener.php index 6e1fc93112030..951b5a4d81aba 100644 --- a/src/Symfony/Component/Mailer/EventListener/MessageListener.php +++ b/src/Symfony/Component/Mailer/EventListener/MessageListener.php @@ -11,11 +11,9 @@ namespace Symfony\Component\Mailer\EventListener; -use Symfony\Bridge\Twig\Mime\TemplatedEmail; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Mailer\Event\MessageEvent; use Symfony\Component\Mailer\Exception\InvalidArgumentException; -use Symfony\Component\Mailer\Exception\LogicException; use Symfony\Component\Mailer\Exception\RuntimeException; use Symfony\Component\Mime\BodyRendererInterface; use Symfony\Component\Mime\Header\Headers; @@ -121,10 +119,6 @@ private function setHeaders(Message $message): void private function renderMessage(Message $message): void { if (!$this->renderer) { - if ($message instanceof TemplatedEmail && ($message->getTextTemplate() || $message->getHtmlTemplate())) { - throw new LogicException(sprintf('You must configure a "%s" when a "%s" instance has a text or HTML template set.', BodyRendererInterface::class, get_debug_type($message))); - } - return; } diff --git a/src/Symfony/Component/Mailer/Tests/Transport/AbstractTransportTest.php b/src/Symfony/Component/Mailer/Tests/Transport/AbstractTransportTest.php index 12e5d526760ff..42c23fcd735e2 100644 --- a/src/Symfony/Component/Mailer/Tests/Transport/AbstractTransportTest.php +++ b/src/Symfony/Component/Mailer/Tests/Transport/AbstractTransportTest.php @@ -12,11 +12,17 @@ namespace Symfony\Component\Mailer\Tests\Transport; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Twig\Mime\BodyRenderer; +use Symfony\Bridge\Twig\Mime\TemplatedEmail; +use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\EventListener\MessageListener; use Symfony\Component\Mailer\Exception\LogicException; use Symfony\Component\Mailer\Transport\NullTransport; use Symfony\Component\Mime\Address; use Symfony\Component\Mime\RawMessage; +use Twig\Environment; +use Twig\Loader\ArrayLoader; /** * @group time-sensitive @@ -55,4 +61,21 @@ public function testSendingRawMessages() $transport = new NullTransport(); $transport->send(new RawMessage('Some raw email message')); } + + public function testNotRenderedTemplatedEmail() + { + $this->expectException(LogicException::class); + + $transport = new NullTransport(new EventDispatcher()); + $transport->send((new TemplatedEmail())->htmlTemplate('Some template')); + } + + public function testRenderedTemplatedEmail() + { + $transport = new NullTransport($dispatcher = new EventDispatcher()); + $dispatcher->addSubscriber(new MessageListener(null, new BodyRenderer(new Environment(new ArrayLoader(['tpl' => 'Some message']))))); + + $sentMessage = $transport->send((new TemplatedEmail())->to('me@example.com')->from('me@example.com')->htmlTemplate('tpl')); + $this->assertMatchesRegularExpression('/Some message/', $sentMessage->getMessage()->toString()); + } } diff --git a/src/Symfony/Component/Mailer/Transport/AbstractTransport.php b/src/Symfony/Component/Mailer/Transport/AbstractTransport.php index d66db3b753c07..e7fd082c79b07 100644 --- a/src/Symfony/Component/Mailer/Transport/AbstractTransport.php +++ b/src/Symfony/Component/Mailer/Transport/AbstractTransport.php @@ -14,12 +14,15 @@ use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; +use Symfony\Bridge\Twig\Mime\TemplatedEmail; use Symfony\Component\Mailer\Envelope; use Symfony\Component\Mailer\Event\FailedMessageEvent; use Symfony\Component\Mailer\Event\MessageEvent; use Symfony\Component\Mailer\Event\SentMessageEvent; +use Symfony\Component\Mailer\Exception\LogicException; use Symfony\Component\Mailer\SentMessage; use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\BodyRendererInterface; use Symfony\Component\Mime\RawMessage; /** @@ -73,6 +76,10 @@ public function send(RawMessage $message, Envelope $envelope = null): ?SentMessa $envelope = $event->getEnvelope(); $message = $event->getMessage(); + if ($message instanceof TemplatedEmail && ($message->getTextTemplate() || $message->getHtmlTemplate())) { + throw new LogicException(sprintf('You must configure a "%s" when a "%s" instance has a text or HTML template set.', BodyRendererInterface::class, get_debug_type($message))); + } + $sentMessage = new SentMessage($message, $envelope); try { diff --git a/src/Symfony/Component/Mailer/composer.json b/src/Symfony/Component/Mailer/composer.json index 85465f21306bc..a79d3af133a2f 100644 --- a/src/Symfony/Component/Mailer/composer.json +++ b/src/Symfony/Component/Mailer/composer.json @@ -27,7 +27,8 @@ "require-dev": { "symfony/console": "^5.4|^6.0", "symfony/http-client-contracts": "^1.1|^2|^3", - "symfony/messenger": "^6.2" + "symfony/messenger": "^6.2", + "symfony/twig-bridge": "^6.2" }, "conflict": { "symfony/http-kernel": "<5.4", From 6d178c15e0ccfd94757d7a3aee07d510746553a0 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Nov 2022 19:27:13 +0100 Subject: [PATCH 15/16] Update CHANGELOG for 6.2.0-RC2 --- CHANGELOG-6.2.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG-6.2.md b/CHANGELOG-6.2.md index 0870e46a6ab8f..14f9052059e73 100644 --- a/CHANGELOG-6.2.md +++ b/CHANGELOG-6.2.md @@ -7,6 +7,15 @@ in 6.2 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/v6.2.0...v6.2.1 +* 6.2.0-RC2 (2022-11-28) + + * bug #48366 [Mailer] Fix body renderer check (fabpot) + * bug #48347 [Clock] Autowire PSR interface (wouterj) + * bug #48341 [SecurityBundle] Fix `logout.csrf_token_generator` default value (MatTheCat) + * bug #48333 [Yaml] parse unquoted digits in tag values as integers (xabbuh) + * bug #48330 [FrameworkBundle] do not wire the MercureTransportFactory if the MercureBundle is not enabled (xabbuh) + * bug #48320 [Clock] Implement PSR-20 (nicolas-grekas) + * 6.2.0-RC1 (2022-11-25) * bug #48312 [VarExporter] Improve partial-initialization API for ghost objects (nicolas-grekas) From ca8452a5239c6da49f24a87e7c1831fa28f21929 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Nov 2022 19:27:25 +0100 Subject: [PATCH 16/16] Update VERSION for 6.2.0-RC2 --- 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 3661c216a2c4b..1603af6aa1ec8 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 array $freshCache = []; - public const VERSION = '6.2.0-DEV'; + public const VERSION = '6.2.0-RC2'; public const VERSION_ID = 60200; public const MAJOR_VERSION = 6; public const MINOR_VERSION = 2; public const RELEASE_VERSION = 0; - public const EXTRA_VERSION = 'DEV'; + public const EXTRA_VERSION = 'RC2'; public const END_OF_MAINTENANCE = '07/2023'; public const END_OF_LIFE = '07/2023';