From 79fe888072387189e6da105e54a50a9ef8402d70 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 27 Mar 2020 17:16:43 +0100 Subject: [PATCH 01/89] [HttpKernel][LoggerDataCollector] Prevent keys collisions in the sanitized logs processing --- .../HttpKernel/DataCollector/LoggerDataCollector.php | 2 +- .../Tests/DataCollector/LoggerDataCollectorTest.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php index 99a9cf23e8398..9c05daa36fe96 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php @@ -172,7 +172,7 @@ private function sanitizeLogs($logs) continue; } - $message = $log['message']; + $message = '_'.$log['message']; $exception = $log['context']['exception']; if ($exception instanceof SilencedErrorContext) { diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php index 8b7fbe2a19ea6..b46357ed5585e 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php @@ -132,13 +132,15 @@ public function getCollectTestData() [ ['message' => 'foo3', 'context' => ['exception' => new \ErrorException('warning', 0, E_USER_WARNING)], 'priority' => 100, 'priorityName' => 'DEBUG'], ['message' => 'foo3', 'context' => ['exception' => new SilencedErrorContext(E_USER_WARNING, __FILE__, __LINE__)], 'priority' => 100, 'priorityName' => 'DEBUG'], + ['message' => '0', 'context' => ['exception' => new SilencedErrorContext(E_USER_WARNING, __FILE__, __LINE__)], 'priority' => 100, 'priorityName' => 'DEBUG'], ], [ ['message' => 'foo3', 'context' => ['exception' => ['warning', E_USER_WARNING]], 'priority' => 100, 'priorityName' => 'DEBUG'], ['message' => 'foo3', 'context' => ['exception' => [E_USER_WARNING]], 'priority' => 100, 'priorityName' => 'DEBUG', 'errorCount' => 1, 'scream' => true], + ['message' => '0', 'context' => ['exception' => [E_USER_WARNING]], 'priority' => 100, 'priorityName' => 'DEBUG', 'errorCount' => 1, 'scream' => true], ], 0, - 1, + 2, ]; } } From edcfd600aaba75734838f631ecd5cc60df7b6ac2 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Fri, 27 Mar 2020 20:28:29 +0100 Subject: [PATCH 02/89] [Validator] Fixed calling getters before resolving groups --- .../Validator/Context/ExecutionContext.php | 9 ++++-- .../EntityWithGroupedConstraintOnMethods.php | 27 ++++++++++++++++ .../Validator/RecursiveValidatorTest.php | 24 ++++++++++++++ .../Validator/Validator/LazyProperty.php | 32 +++++++++++++++++++ .../RecursiveContextualValidator.php | 14 +++++++- 5 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Component/Validator/Tests/Fixtures/EntityWithGroupedConstraintOnMethods.php create mode 100644 src/Symfony/Component/Validator/Validator/LazyProperty.php diff --git a/src/Symfony/Component/Validator/Context/ExecutionContext.php b/src/Symfony/Component/Validator/Context/ExecutionContext.php index 7ca9caa80fefb..44427c8489cca 100644 --- a/src/Symfony/Component/Validator/Context/ExecutionContext.php +++ b/src/Symfony/Component/Validator/Context/ExecutionContext.php @@ -20,6 +20,7 @@ use Symfony\Component\Validator\Mapping\MetadataInterface; use Symfony\Component\Validator\Mapping\PropertyMetadataInterface; use Symfony\Component\Validator\Util\PropertyPath; +use Symfony\Component\Validator\Validator\LazyProperty; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Validator\Violation\ConstraintViolationBuilder; @@ -187,7 +188,7 @@ public function addViolation($message, array $parameters = []) $parameters, $this->root, $this->propertyPath, - $this->value, + $this->getValue(), null, null, $this->constraint @@ -206,7 +207,7 @@ public function buildViolation($message, array $parameters = []) $parameters, $this->root, $this->propertyPath, - $this->value, + $this->getValue(), $this->translator, $this->translationDomain ); @@ -241,6 +242,10 @@ public function getRoot() */ public function getValue() { + if ($this->value instanceof LazyProperty) { + return $this->value->getPropertyValue(); + } + return $this->value; } diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/EntityWithGroupedConstraintOnMethods.php b/src/Symfony/Component/Validator/Tests/Fixtures/EntityWithGroupedConstraintOnMethods.php new file mode 100644 index 0000000000000..89cae29f050c7 --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Fixtures/EntityWithGroupedConstraintOnMethods.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Tests\Fixtures; + +class EntityWithGroupedConstraintOnMethods +{ + public $bar; + + public function isValidInFoo() + { + return false; + } + + public function getBar() + { + throw new \Exception('Should not be called'); + } +} diff --git a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php index 8109b6b9bfd4d..31871c3f9a1ed 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php @@ -14,14 +14,19 @@ use Symfony\Component\Translation\IdentityTranslator; use Symfony\Component\Validator\Constraints\All; use Symfony\Component\Validator\Constraints\Collection; +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\Constraints\IsTrue; use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; +use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\ConstraintValidatorFactory; use Symfony\Component\Validator\Context\ExecutionContextFactory; +use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; use Symfony\Component\Validator\Tests\Constraints\Fixtures\ChildA; use Symfony\Component\Validator\Tests\Constraints\Fixtures\ChildB; use Symfony\Component\Validator\Tests\Fixtures\Entity; +use Symfony\Component\Validator\Tests\Fixtures\EntityWithGroupedConstraintOnMethods; use Symfony\Component\Validator\Validator\RecursiveValidator; class RecursiveValidatorTest extends AbstractTest @@ -117,6 +122,25 @@ public function testCollectionConstraintValidateAllGroupsForNestedConstraints() $this->assertInstanceOf(NotBlank::class, $violations->get(1)->getConstraint()); } + public function testGroupedMethodConstraintValidateInSequence() + { + $metadata = new ClassMetadata(EntityWithGroupedConstraintOnMethods::class); + $metadata->addPropertyConstraint('bar', new NotNull(['groups' => 'Foo'])); + $metadata->addGetterMethodConstraint('validInFoo', 'isValidInFoo', new IsTrue(['groups' => 'Foo'])); + $metadata->addGetterMethodConstraint('bar', 'getBar', new NotNull(['groups' => 'Bar'])); + + $this->metadataFactory->addMetadata($metadata); + + $entity = new EntityWithGroupedConstraintOnMethods(); + $groups = new GroupSequence(['EntityWithGroupedConstraintOnMethods', 'Foo', 'Bar']); + + $violations = $this->validator->validate($entity, null, $groups); + + $this->assertCount(2, $violations); + $this->assertInstanceOf(NotNull::class, $violations->get(0)->getConstraint()); + $this->assertInstanceOf(IsTrue::class, $violations->get(1)->getConstraint()); + } + public function testAllConstraintValidateAllGroupsForNestedConstraints() { $this->metadata->addPropertyConstraint('data', new All(['constraints' => [ diff --git a/src/Symfony/Component/Validator/Validator/LazyProperty.php b/src/Symfony/Component/Validator/Validator/LazyProperty.php new file mode 100644 index 0000000000000..a0799963c150f --- /dev/null +++ b/src/Symfony/Component/Validator/Validator/LazyProperty.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Validator; + +/** + * A wrapper for a callable initializing a property from a getter. + * + * @internal + */ +class LazyProperty +{ + private $propertyValueCallback; + + public function __construct(\Closure $propertyValueCallback) + { + $this->propertyValueCallback = $propertyValueCallback; + } + + public function getPropertyValue() + { + return \call_user_func($this->propertyValueCallback); + } +} diff --git a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php index dc139c36d4254..dd96247b4cf85 100644 --- a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php +++ b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php @@ -26,6 +26,7 @@ use Symfony\Component\Validator\Mapping\ClassMetadataInterface; use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; use Symfony\Component\Validator\Mapping\GenericMetadata; +use Symfony\Component\Validator\Mapping\GetterMetadata; use Symfony\Component\Validator\Mapping\MetadataInterface; use Symfony\Component\Validator\Mapping\PropertyMetadataInterface; use Symfony\Component\Validator\Mapping\TraversalStrategy; @@ -534,7 +535,13 @@ private function validateClassNode($object, $cacheKey, ClassMetadataInterface $m throw new UnsupportedMetadataException(sprintf('The property metadata instances should implement "Symfony\Component\Validator\Mapping\PropertyMetadataInterface", got: "%s".', \is_object($propertyMetadata) ? \get_class($propertyMetadata) : \gettype($propertyMetadata))); } - $propertyValue = $propertyMetadata->getPropertyValue($object); + if ($propertyMetadata instanceof GetterMetadata) { + $propertyValue = new LazyProperty(static function () use ($propertyMetadata, $object) { + return $propertyMetadata->getPropertyValue($object); + }); + } else { + $propertyValue = $propertyMetadata->getPropertyValue($object); + } $this->validateGenericNode( $propertyValue, @@ -798,6 +805,11 @@ private function validateInGroup($value, $cacheKey, MetadataInterface $metadata, $validator = $this->validatorFactory->getInstance($constraint); $validator->initialize($context); + + if ($value instanceof LazyProperty) { + $value = $value->getPropertyValue(); + } + $validator->validate($value, $constraint); } } From be6612060c82b45d039c0679249739b6c68a83d2 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Fri, 27 Mar 2020 20:34:28 +0100 Subject: [PATCH 03/89] Add installation and minimal example to README --- src/Symfony/Component/Routing/README.md | 40 ++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/README.md b/src/Symfony/Component/Routing/README.md index a16d9d7fcbbbb..03b258ec8203b 100644 --- a/src/Symfony/Component/Routing/README.md +++ b/src/Symfony/Component/Routing/README.md @@ -3,10 +3,48 @@ Routing Component The Routing component maps an HTTP request to a set of configuration variables. +Getting Started +--------------- + +``` +$ composer require symfony/routing +``` + +```php +use App\Controller\BlogController; +use Symfony\Component\Routing\Generator\UrlGenerator; +use Symfony\Component\Routing\Matcher\UrlMatcher; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; + +$route = new Route('/blog/{slug}', ['_controller' => BlogController::class]); +$routes = new RouteCollection(); +$routes->add('blog_show', $route); + +$context = new RequestContext(); + +// Routing can match routes with incoming requests +$matcher = new UrlMatcher($routes, $context); +$parameters = $matcher->match('/blog/lorem-ipsum'); +// $parameters = [ +// '_controller' => 'App\Controller\BlogController', +// 'slug' => 'lorem-ipsum', +// '_route' => 'blog_show' +// ] + +// Routing can also generate URLs for a given route +$generator = new UrlGenerator($routes, $context); +$url = $generator->generate('blog_show', [ + 'slug' => 'my-blog-post', +]); +// $url = '/blog/my-blog-post' +``` + Resources --------- - * [Documentation](https://symfony.com/doc/current/components/routing.html) + * [Documentation](https://symfony.com/doc/current/routing.html) * [Contributing](https://symfony.com/doc/current/contributing/index.html) * [Report issues](https://github.com/symfony/symfony/issues) and [send Pull Requests](https://github.com/symfony/symfony/pulls) From a164e22f7752994e05e7a9998f420be65b668674 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Mar 2020 17:04:12 +0200 Subject: [PATCH 04/89] bumped Symfony version to 4.4.8 --- 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 89198bd7cffcc..c583aa66d7650 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '4.4.7'; - const VERSION_ID = 40407; + const VERSION = '4.4.8-DEV'; + const VERSION_ID = 40408; const MAJOR_VERSION = 4; const MINOR_VERSION = 4; - const RELEASE_VERSION = 7; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 8; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2022'; const END_OF_LIFE = '11/2023'; From 1b7ec67b73c319fc62ab57f9bec46be8a0374e37 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 31 Mar 2020 08:34:20 +0200 Subject: [PATCH 05/89] forward multiple attributes voting flag --- .../Core/Authorization/TraceableAccessDecisionManager.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php b/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php index 7690b3e2264bc..7a9c4d0cfb23a 100644 --- a/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php +++ b/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php @@ -47,8 +47,10 @@ public function __construct(AccessDecisionManagerInterface $manager) /** * {@inheritdoc} + * + * @param bool $allowMultipleAttributes Whether to allow passing multiple values to the $attributes array */ - public function decide(TokenInterface $token, array $attributes, $object = null): bool + public function decide(TokenInterface $token, array $attributes, $object = null/*, bool $allowMultipleAttributes = false*/): bool { $currentDecisionLog = [ 'attributes' => $attributes, @@ -58,7 +60,7 @@ public function decide(TokenInterface $token, array $attributes, $object = null) $this->currentLog[] = &$currentDecisionLog; - $result = $this->manager->decide($token, $attributes, $object); + $result = $this->manager->decide($token, $attributes, $object, 3 < \func_num_args() && func_get_arg(3)); $currentDecisionLog['result'] = $result; From c329ca7e014ab2583f1a69531f99d243e7125038 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Mon, 30 Mar 2020 14:56:31 +0200 Subject: [PATCH 06/89] Fix the reporting of deprecations in twig:lint - ensure that the message is rendered when the line detection fails and we end up with 0 as line number (the implementation also deals with -1 which is sometimes used by Twig for errors when it does not know the line, even though this should not happen for compile-time errors). - fix the detection of the line number when the number is at the end of the sentence, which happens for the deprecation of filters for instance. --- .../Bridge/Twig/Command/LintCommand.php | 10 +++++- .../Twig/Tests/Command/LintCommandTest.php | 36 ++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Command/LintCommand.php b/src/Symfony/Bridge/Twig/Command/LintCommand.php index fa12718818815..16f960e9f74c0 100644 --- a/src/Symfony/Bridge/Twig/Command/LintCommand.php +++ b/src/Symfony/Bridge/Twig/Command/LintCommand.php @@ -110,7 +110,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $prevErrorHandler = set_error_handler(static function ($level, $message, $file, $line) use (&$prevErrorHandler) { if (E_USER_DEPRECATED === $level) { $templateLine = 0; - if (preg_match('/ at line (\d+) /', $message, $matches)) { + if (preg_match('/ at line (\d+)[ .]/', $message, $matches)) { $templateLine = $matches[1]; } @@ -236,6 +236,14 @@ private function renderException(OutputInterface $output, string $template, Erro $output->text(sprintf(' ERROR (line %s)', $line)); } + // If the line is not known (this might happen for deprecations if we fail at detecting the line for instance), + // we render the message without context, to ensure the message is displayed. + if ($line <= 0) { + $output->text(sprintf(' >> %s ', $exception->getRawMessage())); + + return; + } + foreach ($this->getContext($template, $line) as $lineNumber => $code) { $output->text(sprintf( '%s %-6s %s', diff --git a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php index 46c0883722a20..8970bb497764e 100644 --- a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php @@ -18,6 +18,7 @@ use Symfony\Component\Console\Tester\CommandTester; use Twig\Environment; use Twig\Loader\FilesystemLoader; +use Twig\TwigFilter; class LintCommandTest extends TestCase { @@ -66,6 +67,34 @@ public function testLintFileCompileTimeException() $this->assertRegExp('/ERROR in \S+ \(line /', trim($tester->getDisplay())); } + /** + * When deprecations are not reported by the command, the testsuite reporter will catch them so we need to mark the test as legacy. + * + * @group legacy + */ + public function testLintFileWithNotReportedDeprecation() + { + $tester = $this->createCommandTester(); + $filename = $this->createFile('{{ foo|deprecated_filter }}'); + + $ret = $tester->execute(['filename' => [$filename]], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]); + + $this->assertEquals(0, $ret, 'Returns 0 in case of success'); + $this->assertStringContainsString('OK in', trim($tester->getDisplay())); + } + + public function testLintFileWithReportedDeprecation() + { + $tester = $this->createCommandTester(); + $filename = $this->createFile('{{ foo|deprecated_filter }}'); + + $ret = $tester->execute(['filename' => [$filename], '--show-deprecations' => true], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]); + + $this->assertEquals(1, $ret, 'Returns 1 in case of error'); + $this->assertRegExp('/ERROR in \S+ \(line 1\)/', trim($tester->getDisplay())); + $this->assertStringContainsString('Filter "deprecated_filter" is deprecated', trim($tester->getDisplay())); + } + /** * @group tty */ @@ -80,7 +109,12 @@ public function testLintDefaultPaths() private function createCommandTester(): CommandTester { - $command = new LintCommand(new Environment(new FilesystemLoader(\dirname(__DIR__).'/Fixtures/templates/'))); + $environment = new Environment(new FilesystemLoader(\dirname(__DIR__).'/Fixtures/templates/')); + $environment->addFilter(new TwigFilter('deprecated_filter', function ($v) { + return $v; + }, ['deprecated' => true])); + + $command = new LintCommand($environment); $application = new Application(); $application->add($command); From bbc08d7a9e74a10458c46ae4fb7824cd67e03100 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 1 Apr 2020 07:33:51 +0200 Subject: [PATCH 07/89] Fix wrong namespaces --- .../Fixtures/CustomPathBundle/src/CustomPathBundle.php | 2 +- .../DependencyInjection/Fixtures/TestBundle/TestBundle.php | 2 +- .../PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/CustomPathBundle/src/CustomPathBundle.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/CustomPathBundle/src/CustomPathBundle.php index 166b606a459e2..a4049b8690522 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/CustomPathBundle/src/CustomPathBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/CustomPathBundle/src/CustomPathBundle.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Bundle\FrameworkBundle\Tests; +namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\CustomPathBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php index 2f090b2de8d53..c58b25066bf4a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/TestBundle/TestBundle.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Bundle\FrameworkBundle\Tests; +namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\TestBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php index f4f9e9dc77e29..4c19a86b43767 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\PropertyInfo\Tests\PhpDocExtractor; +namespace Symfony\Component\PropertyInfo\Tests\Extractor; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; From 801f2d344e70242eb5ba5cf8918088c14d401b08 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 1 Apr 2020 08:23:29 +0200 Subject: [PATCH 08/89] Fix wrong namespaces --- .../Tests/Transport/Receiver/SingleMessageReceiverTest.php | 2 +- .../Messenger/Tests/Transport/Sync/SyncTransportFactoryTest.php | 2 +- .../Messenger/Tests/Transport/Sync/SyncTransportTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Receiver/SingleMessageReceiverTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Receiver/SingleMessageReceiverTest.php index e8f5ef4ce1720..bfebfc5aa3f02 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Receiver/SingleMessageReceiverTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Receiver/SingleMessageReceiverTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Messenger\Tests\Transport\Sender; +namespace Symfony\Component\Messenger\Tests\Transport\Receiver; use PHPUnit\Framework\TestCase; use Symfony\Component\Messenger\Envelope; diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Sync/SyncTransportFactoryTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Sync/SyncTransportFactoryTest.php index 021c7ae9706a4..63aa43fb7ca0f 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Sync/SyncTransportFactoryTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Sync/SyncTransportFactoryTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Messenger\Tests\Transport\AmqpExt; +namespace Symfony\Component\Messenger\Tests\Transport\Sync; use PHPUnit\Framework\TestCase; use Symfony\Component\Messenger\MessageBusInterface; diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Sync/SyncTransportTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Sync/SyncTransportTest.php index 13549e27582a1..8ea4eb2e00522 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Sync/SyncTransportTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Sync/SyncTransportTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\Messenger\Tests\Transport\AmqpExt; +namespace Symfony\Component\Messenger\Tests\Transport\Sync; use PHPUnit\Framework\TestCase; use Symfony\Component\Messenger\Envelope; From 42311d5c29a47c17ca2bf7620f5dfc39e8482186 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Wed, 1 Apr 2020 11:15:47 +0200 Subject: [PATCH 09/89] [Security][Http][SwitchUserListener] Ignore all non existent username protection errors --- .../Component/Security/Http/Firewall/SwitchUserListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php index 21bd1bc1cdb0b..a6718a7232824 100644 --- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php @@ -168,7 +168,7 @@ private function attemptSwitchUser(Request $request, string $username): ?TokenIn try { $this->provider->loadUserByUsername($nonExistentUsername); - } catch (AuthenticationException $e) { + } catch (\Exception $e) { } } catch (AuthenticationException $e) { $this->provider->loadUserByUsername($currentUsername); From b4df2b9dff8510772de418e70688b84ce1445b1c Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Wed, 1 Apr 2020 19:12:29 +0200 Subject: [PATCH 10/89] [PropertyInfo][ReflectionExtractor] Check the array mutator prefixes last when the property is singular --- .../PropertyInfo/Extractor/ReflectionExtractor.php | 10 +++++++++- .../Tests/Extractor/ReflectionExtractorTest.php | 4 ++++ .../Component/PropertyInfo/Tests/Fixtures/Dummy.php | 8 ++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index dcb06ee192249..3306946a9b337 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -61,6 +61,9 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp */ private $arrayMutatorPrefixes; + private $arrayMutatorPrefixesFirst; + private $arrayMutatorPrefixesLast; + /** * @param string[]|null $mutatorPrefixes * @param string[]|null $accessorPrefixes @@ -72,6 +75,9 @@ public function __construct(array $mutatorPrefixes = null, array $accessorPrefix $this->mutatorPrefixes = null !== $mutatorPrefixes ? $mutatorPrefixes : self::$defaultMutatorPrefixes; $this->accessorPrefixes = null !== $accessorPrefixes ? $accessorPrefixes : self::$defaultAccessorPrefixes; $this->arrayMutatorPrefixes = null !== $arrayMutatorPrefixes ? $arrayMutatorPrefixes : self::$defaultArrayMutatorPrefixes; + + $this->arrayMutatorPrefixesFirst = array_merge($this->arrayMutatorPrefixes, array_diff($this->mutatorPrefixes, $this->arrayMutatorPrefixes)); + $this->arrayMutatorPrefixesLast = array_reverse($this->arrayMutatorPrefixesFirst); } /** @@ -330,7 +336,9 @@ private function getMutatorMethod($class, $property) $ucProperty = ucfirst($property); $ucSingulars = (array) Inflector::singularize($ucProperty); - foreach ($this->mutatorPrefixes as $prefix) { + $mutatorPrefixes = \in_array($ucProperty, $ucSingulars, true) ? $this->arrayMutatorPrefixesLast : $this->arrayMutatorPrefixesFirst; + + foreach ($mutatorPrefixes as $prefix) { $names = [$ucProperty]; if (\in_array($prefix, $this->arrayMutatorPrefixes)) { $names = array_merge($names, $ucSingulars); diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 5a5c0c7b62c6a..36fc9d55e37f8 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -61,6 +61,7 @@ public function testGetProperties() 'realParent', 'xTotals', 'YT', + 'date', 'c', 'd', 'e', @@ -96,6 +97,7 @@ public function testGetPropertiesWithCustomPrefixes() 'foo4', 'foo5', 'files', + 'date', 'c', 'd', 'e', @@ -156,6 +158,8 @@ public function typesProvider() ['staticSetter', null], ['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy')]], ['realParent', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy')]], + ['date', [new Type(Type::BUILTIN_TYPE_OBJECT, false, \DateTime::class)]], + ['dates', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, \DateTime::class))]], ]; } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php index 663fef84c7760..4a7b7c0951d46 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php @@ -190,4 +190,12 @@ public function getXTotals() public function getYT() { } + + public function setDate(\DateTime $date) + { + } + + public function addDate(\DateTime $date) + { + } } From 7f33f1fa3a0c0fab863b4e6b67e2de9a68384cf8 Mon Sep 17 00:00:00 2001 From: ampaze Date: Thu, 2 Apr 2020 13:53:10 +0200 Subject: [PATCH 11/89] Support for Content Security Policy style-src-elem and script-src-elem in WebProfiler If a `style-src-elem` or `script-src-elem` Content Security Policy exist, the WebProfiler Styles or Scripts will be rejected as the nonce is missing. --- .../WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php b/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php index a38e7c686fd0a..e62895fe6d2b2 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php @@ -128,7 +128,7 @@ private function updateCspHeaders(Response $response, array $nonces = []) $headers = $this->getCspHeaders($response); foreach ($headers as $header => $directives) { - foreach (['script-src' => 'csp_script_nonce', 'style-src' => 'csp_style_nonce'] as $type => $tokenName) { + foreach (['script-src' => 'csp_script_nonce', 'script-src-elem' => 'csp_script_nonce', 'style-src' => 'csp_style_nonce', 'style-src-elem' => 'csp_style_nonce'] as $type => $tokenName) { if ($this->authorizesInline($directives, $type)) { continue; } From 923c24f4383387778439c3e5d9112b7160721d27 Mon Sep 17 00:00:00 2001 From: rosier Date: Mon, 30 Mar 2020 19:57:25 +0200 Subject: [PATCH 12/89] No need to reconnect the bags to the session Bug https://bugs.php.net/70013 was fixed before the release of PHP v7.0 --- .../HttpFoundation/Session/Storage/NativeSessionStorage.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index 5165b5d0d882f..d6ce2a79def98 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -223,10 +223,6 @@ public function regenerate($destroy = false, $lifetime = null) $isRegenerated = session_regenerate_id($destroy); - // The reference to $_SESSION in session bags is lost in PHP7 and we need to re-create it. - // @see https://bugs.php.net/70013 - $this->loadSession(); - if (null !== $this->emulateSameSite) { $originalCookie = SessionUtils::popSessionCookie(session_name(), session_id()); if (null !== $originalCookie) { From 19a8905d321530de1301df19de092dfa7a10dbf0 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 3 Apr 2020 16:53:29 +0200 Subject: [PATCH 13/89] [4.4][MonologBridge] Fix $level type --- .../Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php | 5 ++++- src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php b/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php index b8b0f7b9e99cb..99ba3bbc3d94a 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php @@ -49,7 +49,10 @@ class ElasticsearchLogstashHandler extends AbstractHandler private $client; private $responses; - public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $index = 'monolog', HttpClientInterface $client = null, int $level = Logger::DEBUG, bool $bubble = true) + /** + * @param string|int $level The minimum logging level at which this handler will be triggered + */ + public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $index = 'monolog', HttpClientInterface $client = null, $level = Logger::DEBUG, bool $bubble = true) { if (!interface_exists(HttpClientInterface::class)) { throw new \LogicException(sprintf('The "%s" handler needs an HTTP client. Try running "composer require symfony/http-client".', __CLASS__)); diff --git a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php index 28582d31725a3..e5a26ccd221e2 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php @@ -25,7 +25,10 @@ class ServerLogHandler extends AbstractHandler private $context; private $socket; - public function __construct(string $host, int $level = Logger::DEBUG, bool $bubble = true, array $context = []) + /** + * @param string|int $level The minimum logging level at which this handler will be triggered + */ + public function __construct(string $host, $level = Logger::DEBUG, bool $bubble = true, array $context = []) { parent::__construct($level, $bubble); From 8d96dbd08b5c44c0d3eea57d60541fc25b747dff Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Fri, 3 Apr 2020 15:39:47 +0200 Subject: [PATCH 14/89] Track session usage when setting the token --- .../GuardedBundle/AppCustomAuthenticator.php | 2 +- .../AuthenticationController.php | 38 +++++++++++++++++++ .../Tests/Functional/GuardedTest.php | 10 +++++ .../Tests/Functional/app/Guarded/config.yml | 11 ++++++ .../Tests/Functional/app/Guarded/routing.yml | 9 +++++ .../Token/Storage/TokenStorage.php | 5 +++ .../Storage/UsageTrackingTokenStorage.php | 5 +++ .../Tests/Firewall/ContextListenerTest.php | 8 +++- .../Component/Security/Http/composer.json | 2 +- 9 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AuthenticationController.php diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AppCustomAuthenticator.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AppCustomAuthenticator.php index fef2732759fa1..22d378835e4c0 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AppCustomAuthenticator.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AppCustomAuthenticator.php @@ -23,7 +23,7 @@ class AppCustomAuthenticator extends AbstractGuardAuthenticator { public function supports(Request $request) { - return true; + return '/manual_login' !== $request->getPathInfo() && '/profile' !== $request->getPathInfo(); } public function getCredentials(Request $request) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AuthenticationController.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AuthenticationController.php new file mode 100644 index 0000000000000..9833d05513833 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AuthenticationController.php @@ -0,0 +1,38 @@ + + * + * 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\GuardedBundle; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Security\Core\User\User; +use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; +use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; + +class AuthenticationController +{ + public function manualLoginAction(GuardAuthenticatorHandler $guardAuthenticatorHandler, Request $request) + { + $guardAuthenticatorHandler->authenticateWithToken(new PostAuthenticationGuardToken(new User('Jane', 'test', ['ROLE_USER']), 'secure', ['ROLE_USER']), $request, 'secure'); + + return new Response('Logged in.'); + } + + public function profileAction(UserInterface $user = null) + { + if (null === $user) { + return new Response('Not logged in.'); + } + + return new Response('Username: '.$user->getUsername()); + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/GuardedTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/GuardedTest.php index bb0969c36a2fd..83cd4118d76e4 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/GuardedTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/GuardedTest.php @@ -21,4 +21,14 @@ public function testGuarded() $this->assertSame(418, $client->getResponse()->getStatusCode()); } + + public function testManualLogin() + { + $client = $this->createClient(['debug' => true, 'test_case' => 'Guarded', 'root_config' => 'config.yml']); + + $client->request('GET', '/manual_login'); + $client->request('GET', '/profile'); + + $this->assertSame('Username: Jane', $client->getResponse()->getContent()); + } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml index 2d1f779a530ec..7f87c307d28b5 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml @@ -10,8 +10,19 @@ framework: services: logger: { class: Psr\Log\NullLogger } Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AppCustomAuthenticator: ~ + Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AuthenticationController: + tags: [controller.service_arguments] security: + encoders: + Symfony\Component\Security\Core\User\User: plaintext + + providers: + in_memory: + memory: + users: + Jane: { password: test, roles: [ROLE_USER] } + firewalls: secure: pattern: ^/ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/routing.yml index 4d11154375219..146aa811a143d 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/routing.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/routing.yml @@ -3,3 +3,12 @@ main: defaults: _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction path: /app +profile: + path: /profile + defaults: + _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AuthenticationController::profileAction + +manual_login: + path: /manual_login + defaults: + _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AuthenticationController::manualLoginAction diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php index bf491797aa25d..dd8a5ae00420a 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php @@ -49,6 +49,11 @@ public function setToken(TokenInterface $token = null) @trigger_error(sprintf('Not implementing the "%s::getRoleNames()" method in "%s" is deprecated since Symfony 4.3.', TokenInterface::class, \get_class($token)), E_USER_DEPRECATED); } + if ($token) { + // ensure any initializer is called + $this->getToken(); + } + $this->initializer = null; $this->token = $token; } diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/UsageTrackingTokenStorage.php b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/UsageTrackingTokenStorage.php index 3ce8913aa4fbb..b90d5ab28b635 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/UsageTrackingTokenStorage.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/UsageTrackingTokenStorage.php @@ -52,6 +52,11 @@ public function getToken(): ?TokenInterface public function setToken(TokenInterface $token = null): void { $this->storage->setToken($token); + + if ($token && $this->enableUsageTracking) { + // increments the internal session usage index + $this->sessionLocator->get('session')->getMetadataBag(); + } } public function enableUsageTracking(): void diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php index 82a5f917d98ee..7e89c0b1b36fb 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php @@ -411,9 +411,9 @@ protected function runSessionOnKernelResponse($newToken, $original = null) private function handleEventWithPreviousSession($userProviders, UserInterface $user = null, RememberMeServicesInterface $rememberMeServices = null) { - $user = $user ?: new User('foo', 'bar'); + $tokenUser = $user ?: new User('foo', 'bar'); $session = new Session(new MockArraySessionStorage()); - $session->set('_security_context_key', serialize(new UsernamePasswordToken($user, '', 'context_key', ['ROLE_USER']))); + $session->set('_security_context_key', serialize(new UsernamePasswordToken($tokenUser, '', 'context_key', ['ROLE_USER']))); $request = new Request(); $request->setSession($session); @@ -442,6 +442,10 @@ private function handleEventWithPreviousSession($userProviders, UserInterface $u $listener(new RequestEvent($this->getMockBuilder(HttpKernelInterface::class)->getMock(), $request, HttpKernelInterface::MASTER_REQUEST)); if (null !== $usageIndex) { + if (null !== $user) { + ++$usageIndex; + } + $this->assertSame($usageIndex, $session->getUsageIndex()); $tokenStorage->getToken(); $this->assertSame(1 + $usageIndex, $session->getUsageIndex()); diff --git a/src/Symfony/Component/Security/Http/composer.json b/src/Symfony/Component/Security/Http/composer.json index 699ffcf7032b3..6b23f5cc8e311 100644 --- a/src/Symfony/Component/Security/Http/composer.json +++ b/src/Symfony/Component/Security/Http/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": "^7.1.3", - "symfony/security-core": "^4.4.7", + "symfony/security-core": "^4.4.8", "symfony/http-foundation": "^3.4.40|^4.4.7|^5.0.7", "symfony/http-kernel": "^4.4", "symfony/property-access": "^3.4|^4.0|^5.0" From d43ef4ec920ec570b395cb29de942c03deeced61 Mon Sep 17 00:00:00 2001 From: Serhiy Lunak Date: Sat, 28 Mar 2020 15:25:34 +0000 Subject: [PATCH 15/89] [Validator] Add missing Ukrainian and Russian translations --- .../Resources/translations/validators.ru.xlf | 12 ++++++++++++ .../Resources/translations/validators.uk.xlf | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf index 80911a9902910..3c03fd8525cca 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.ru.xlf @@ -370,6 +370,18 @@ This value is not a valid hostname. Значение не является корректным именем хоста. + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Количество элементов в этой коллекции должно быть кратным {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Значение должно удовлетворять как минимум одному из следующих ограничений: + + + Each element of this collection should satisfy its own set of constraints. + Каждый элемент этой коллекции должен удовлетворять своему собственному набору ограничений. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.uk.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.uk.xlf index cba61915544a3..688e11fbe929c 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.uk.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.uk.xlf @@ -366,6 +366,22 @@ This value should be between {{ min }} and {{ max }}. Значення має бути між {{ min }} та {{ max }}. + + This value is not a valid hostname. + Значення не є дійсним іменем хоста. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Кількість елементів у цій колекції повинна бути кратною {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Значення повинно задовольняти хоча б одному з наступних обмежень: + + + Each element of this collection should satisfy its own set of constraints. + Кожен елемент цієї колекції повинен задовольняти власному набору обмежень. + From 1fafff7c10b11d6079c10d65b85272c586a20a4f Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Fri, 3 Apr 2020 12:40:07 +0200 Subject: [PATCH 16/89] [Serializer] Fix unitialized properties (from PHP 7.4.2) when serializing context for the cache key --- .../Normalizer/AbstractObjectNormalizer.php | 1 + .../AbstractObjectNormalizerTest.php | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 56dc3c590ede3..1eba26343dd1a 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -400,6 +400,7 @@ protected function createChildContext(array $parentContext, $attribute/*, string */ private function getCacheKey($format, array $context) { + unset($context[self::OBJECT_TO_POPULATE]); unset($context['cache_key']); // avoid artificially different keys try { return md5($format.serialize([ diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php index d5d7cace362e4..d269da27e810d 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -163,6 +163,14 @@ public function testDenormalizeStringCollectionDecodedFromXmlWithTwoChildren() $this->assertEquals('bar', $stringCollection->children[1]); } + public function testDenormalizeNotSerializableObjectToPopulate() + { + $normalizer = new AbstractObjectNormalizerDummy(); + $normalizedData = $normalizer->denormalize(['foo' => 'foo'], Dummy::class, null, [AbstractObjectNormalizer::OBJECT_TO_POPULATE => new NotSerializable()]); + + $this->assertSame('foo', $normalizedData->foo); + } + private function getDenormalizerForStringCollection() { $extractor = $this->getMockBuilder(PhpDocExtractor::class)->getMock(); @@ -379,3 +387,15 @@ public function setSerializer(SerializerInterface $serializer) $this->serializer = $serializer; } } + +class NotSerializable +{ + public function __sleep() + { + if (class_exists(\Error::class)) { + throw new \Error('not serializable'); + } + + throw new \Exception('not serializable'); + } +} From 8a56c506e348bfb1aba42cdd713fae9dedfc2855 Mon Sep 17 00:00:00 2001 From: Christian Weiske Date: Tue, 31 Mar 2020 11:41:21 +0200 Subject: [PATCH 17/89] Allow URL-encoded special characters in basic auth part of URLs Resolves: https://github.com/symfony/symfony/issues/36285 --- src/Symfony/Component/Validator/Constraints/UrlValidator.php | 2 +- .../Validator/Tests/Constraints/UrlValidatorTest.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/UrlValidator.php b/src/Symfony/Component/Validator/Constraints/UrlValidator.php index d934162eeefc3..97a05450754ea 100644 --- a/src/Symfony/Component/Validator/Constraints/UrlValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UrlValidator.php @@ -23,7 +23,7 @@ class UrlValidator extends ConstraintValidator { const PATTERN = '~^ (%s):// # protocol - (([\_\.\pL\pN-]+:)?([\_\.\pL\pN-]+)@)? # basic auth + (((?:[\_\.\pL\pN-]|%%[0-9A-Fa-f]{2})+:)?((?:[\_\.\pL\pN-]|%%[0-9A-Fa-f]{2})+)@)? # basic auth ( ([\pL\pN\pS\-\_\.])+(\.?([\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name | # or diff --git a/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php index 0357172680c61..6bcc5c54c5928 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php @@ -122,6 +122,8 @@ public function getValidUrls() ['http://user.name:pass.word@symfony.com'], ['http://user-name@symfony.com'], ['http://user_name@symfony.com'], + ['http://u%24er:password@symfony.com'], + ['http://user:pa%24%24word@symfony.com'], ['http://symfony.com?'], ['http://symfony.com?query=1'], ['http://symfony.com/?query=1'], @@ -168,6 +170,8 @@ public function getInvalidUrls() ['http://:password@@symfony.com'], ['http://username:passwordsymfony.com'], ['http://usern@me:password@symfony.com'], + ['http://nota%hex:password@symfony.com'], + ['http://username:nota%hex@symfony.com'], ['http://example.com/exploit.html?'], ['http://example.com/exploit.html?hel lo'], ['http://example.com/exploit.html?not_a%hex'], From 3e943435c98f71c828759f06fb42a6a6b692f003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 4 Apr 2020 09:51:57 +0200 Subject: [PATCH 18/89] [Serializer] Remove unused variable --- .../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 1eba26343dd1a..c1fc4ad82f93a 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -304,7 +304,7 @@ private function validateAndDenormalize($currentClass, $attribute, $data, $forma */ protected function denormalizeParameter(\ReflectionClass $class, \ReflectionParameter $parameter, $parameterName, $parameterData, array $context, $format = null) { - if (null === $this->propertyTypeExtractor || null === $types = $this->propertyTypeExtractor->getTypes($class->getName(), $parameterName)) { + if (null === $this->propertyTypeExtractor || null === $this->propertyTypeExtractor->getTypes($class->getName(), $parameterName)) { return parent::denormalizeParameter($class, $parameter, $parameterName, $parameterData, $context, $format); } From d5c54c2fa7141c6caaf0d4d4bb870663ee6b45ee Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 4 Apr 2020 13:58:35 +0200 Subject: [PATCH 19/89] [HttpKernel][FrameworkBundle] fix compat with Debug component --- src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php | 4 ++++ .../HttpKernel/EventListener/DebugHandlersListener.php | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index b505daf131c36..0dc2860229bdf 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -35,6 +35,7 @@ use Symfony\Component\Cache\DependencyInjection\CachePoolPrunerPass; use Symfony\Component\Config\Resource\ClassExistenceResource; use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass; +use Symfony\Component\Debug\ErrorHandler as LegacyErrorHandler; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\Compiler\RegisterReverseContainerPass; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -89,6 +90,9 @@ class FrameworkBundle extends Bundle public function boot() { ErrorHandler::register(null, false)->throwAt($this->container->getParameter('debug.error_handler.throw_at'), true); + if (class_exists(LegacyErrorHandler::class, false)) { + LegacyErrorHandler::register(null, false)->throwAt($this->container->getParameter('debug.error_handler.throw_at'), true); + } if ($this->container->getParameter('kernel.http_method_override')) { Request::enableHttpMethodParameterOverride(); diff --git a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php index dcb54ea891c4a..0e672a299dd41 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php @@ -15,6 +15,7 @@ use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleEvent; use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Debug\ErrorHandler as LegacyErrorHandler; use Symfony\Component\Debug\Exception\FatalThrowableError; use Symfony\Component\ErrorHandler\ErrorHandler; use Symfony\Component\EventDispatcher\Event; @@ -79,7 +80,7 @@ public function configure(Event $event = null) restore_exception_handler(); if ($this->logger || null !== $this->throwAt) { - if ($handler instanceof ErrorHandler) { + if ($handler instanceof ErrorHandler || $handler instanceof LegacyErrorHandler) { if ($this->logger) { $handler->setDefaultLogger($this->logger, $this->levels); if (\is_array($this->levels)) { @@ -138,7 +139,7 @@ public function configure(Event $event = null) } } if ($this->exceptionHandler) { - if ($handler instanceof ErrorHandler) { + if ($handler instanceof ErrorHandler || $handler instanceof LegacyErrorHandler) { $handler->setExceptionHandler($this->exceptionHandler); } $this->exceptionHandler = null; From 3e824de3855660264f1348f7502a3a9f148732cf Mon Sep 17 00:00:00 2001 From: Guite Date: Sun, 9 Feb 2020 17:51:23 +0100 Subject: [PATCH 20/89] [HttpFoundation] Fixed session migration with custom cookie lifetime --- .../Session/Storage/NativeSessionStorage.php | 8 +++++--- .../Session/Storage/NativeSessionStorageTest.php | 13 +++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index 7502897a4456b..66343cd31e4d6 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -152,7 +152,7 @@ public function start() // ok to try and start the session if (!session_start()) { - throw new \RuntimeException('Failed to start the session'); + throw new \RuntimeException('Failed to start the session.'); } if (null !== $this->emulateSameSite) { @@ -213,8 +213,10 @@ public function regenerate($destroy = false, $lifetime = null) return false; } - if (null !== $lifetime) { + if (null !== $lifetime && $lifetime != ini_get('session.cookie_lifetime')) { + $this->save(); ini_set('session.cookie_lifetime', $lifetime); + $this->start(); } if ($destroy) { @@ -314,7 +316,7 @@ public function registerBag(SessionBagInterface $bag) public function getBag($name) { if (!isset($this->bags[$name])) { - throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name)); + throw new \InvalidArgumentException(sprintf('The SessionBagInterface "%s" is not registered.', $name)); } if (!$this->started && $this->saveHandler->isActive()) { diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php index d2cf324525443..7cfcd223e0323 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php @@ -123,6 +123,19 @@ public function testRegenerateDestroy() $this->assertEquals(11, $storage->getBag('attributes')->get('legs')); } + public function testRegenerateWithCustomLifetime() + { + $storage = $this->getStorage(); + $storage->start(); + $id = $storage->getId(); + $lifetime = 999999; + $storage->getBag('attributes')->set('legs', 11); + $storage->regenerate(false, $lifetime); + $this->assertNotEquals($id, $storage->getId()); + $this->assertEquals(11, $storage->getBag('attributes')->get('legs')); + $this->assertEquals($lifetime, ini_get('session.cookie_lifetime')); + } + public function testSessionGlobalIsUpToDateAfterIdRegeneration() { $storage = $this->getStorage(); From 3c8bf2d29d5fa19d2ef9eaffec77cde358c525ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Masforn=C3=A9?= Date: Wed, 1 Apr 2020 23:52:46 +0200 Subject: [PATCH 21/89] [PropertyAccess] Improve message of unitialized property in php 7.4 --- src/Symfony/Component/PropertyAccess/PropertyAccessor.php | 2 +- .../Component/PropertyAccess/Tests/PropertyAccessorTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 66b38eaf3caef..d1b3625fb1d66 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -505,7 +505,7 @@ private function readProperty($zval, $property) if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ([\w\\\]+)::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) { $r = new \ReflectionProperty($matches[1], $matches[2]); - throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%3$s". You should either initialize it or make it nullable using "?%3$s" instead.', $r->getDeclaringClass()->getName(), $r->getName(), $r->getType()->getName()), 0, $e); + throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%2$s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getType()->getName()), 0, $e); } throw $e; diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index 62a95d68e9304..6ccf674113b86 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -126,7 +126,7 @@ public function testGetValueThrowsExceptionIfIndexNotFoundAndIndexExceptionsEnab public function testGetValueThrowsExceptionIfUninitializedProperty() { $this->expectException('Symfony\Component\PropertyAccess\Exception\AccessException'); - $this->expectExceptionMessage('The property "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedProperty::$uninitialized" is not readable because it is typed "string". You should either initialize it or make it nullable using "?string" instead.'); + $this->expectExceptionMessage('The property "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedProperty::$uninitialized" is not readable because it is typed "string". You should initialize it or declare a default value instead.'); $this->propertyAccessor->getValue(new UninitializedProperty(), 'uninitialized'); } From 112b5de3cf35b651c137cce684bd52cff2b49152 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 6 Apr 2020 10:30:32 +0200 Subject: [PATCH 22/89] remove assertions that can never be reached --- .../Tests/Debug/OptionsResolverIntrospectorTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php b/src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php index 8d6e9f63f6370..5fdb9e2657f3b 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php @@ -44,7 +44,7 @@ public function testGetDefaultThrowsOnNoConfiguredValue() $resolver->setDefined($option = 'foo'); $debug = new OptionsResolverIntrospector($resolver); - $this->assertSame('bar', $debug->getDefault($option)); + $debug->getDefault($option); } public function testGetDefaultThrowsOnNotDefinedOption() @@ -54,7 +54,7 @@ public function testGetDefaultThrowsOnNotDefinedOption() $resolver = new OptionsResolver(); $debug = new OptionsResolverIntrospector($resolver); - $this->assertSame('bar', $debug->getDefault('foo')); + $debug->getDefault('foo'); } public function testGetLazyClosures() @@ -75,7 +75,7 @@ public function testGetLazyClosuresThrowsOnNoConfiguredValue() $resolver->setDefined($option = 'foo'); $debug = new OptionsResolverIntrospector($resolver); - $this->assertSame('bar', $debug->getLazyClosures($option)); + $debug->getLazyClosures($option); } public function testGetLazyClosuresThrowsOnNotDefinedOption() @@ -85,7 +85,7 @@ public function testGetLazyClosuresThrowsOnNotDefinedOption() $resolver = new OptionsResolver(); $debug = new OptionsResolverIntrospector($resolver); - $this->assertSame('bar', $debug->getLazyClosures('foo')); + $debug->getLazyClosures('foo'); } public function testGetAllowedTypes() From a20110c6b602b6f2217ab0961069342572523012 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 6 Apr 2020 11:49:16 +0200 Subject: [PATCH 23/89] [WebProfilerBundle] fix test --- .../Tests/Csp/ContentSecurityPolicyHandlerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php index acccc7cbfb6d2..349db2aaf75b4 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php @@ -41,7 +41,7 @@ public function testOnKernelResponse($nonce, $expectedNonce, Request $request, R $this->assertFalse($response->headers->has('X-SymfonyProfiler-Style-Nonce')); foreach ($expectedCsp as $header => $value) { - $this->assertSame($value, $response->headers->get($header)); + $this->assertSame($value, $response->headers->get($header), $header); } } @@ -131,7 +131,7 @@ public function provideRequestAndResponsesForOnKernelResponse() ['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce], $this->createRequest(), $this->createResponse(['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'']), - ['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; style-src \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; style-src \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null], + ['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src-elem \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src-elem \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null], ], [ $nonce, From 995ef18f957628202923d7873c583cfe835cc45d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 6 Apr 2020 12:01:14 +0200 Subject: [PATCH 24/89] [PropertyAccess] fix tests --- src/Symfony/Component/PropertyAccess/PropertyAccessor.php | 4 ++-- .../Component/PropertyAccess/Tests/PropertyAccessorTest.php | 2 +- src/Symfony/Component/Yaml/Inline.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index d1b3625fb1d66..6f715d620418c 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -472,7 +472,7 @@ private function readProperty($zval, $property) } catch (\TypeError $e) { // handle uninitialized properties in PHP >= 7 if (preg_match((sprintf('/^Return value of %s::%s\(\) must be of the type (\w+), null returned$/', preg_quote(\get_class($object)), $access[self::ACCESS_NAME])), $e->getMessage(), $matches)) { - throw new AccessException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Have you forgotten to initialize a property or to make the return type nullable using "?%3$s" instead?', \get_class($object), $access[self::ACCESS_NAME], $matches[1]), 0, $e); + throw new AccessException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', \get_class($object), $access[self::ACCESS_NAME], $matches[1]), 0, $e); } throw $e; @@ -505,7 +505,7 @@ private function readProperty($zval, $property) if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ([\w\\\]+)::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) { $r = new \ReflectionProperty($matches[1], $matches[2]); - throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%2$s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getType()->getName()), 0, $e); + throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getName(), $r->getType()->getName()), 0, $e); } throw $e; diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index 6ccf674113b86..d8331e76ad811 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -137,7 +137,7 @@ public function testGetValueThrowsExceptionIfUninitializedProperty() public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetter() { $this->expectException('Symfony\Component\PropertyAccess\Exception\AccessException'); - $this->expectExceptionMessage('The method "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedPrivateProperty::getUninitialized()" returned "null", but expected type "array". Have you forgotten to initialize a property or to make the return type nullable using "?array" instead?'); + $this->expectExceptionMessage('The method "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedPrivateProperty::getUninitialized()" returned "null", but expected type "array". Did you forget to initialize a property or to make the return type nullable using "?array"?'); $this->propertyAccessor->getValue(new UninitializedPrivateProperty(), 'uninitialized'); } diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index 7198d077980c2..4c7d37428e474 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -720,7 +720,7 @@ private static function evaluateScalar($scalar, $flags, $references = []) throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } if (self::$exceptionOnInvalidType) { - throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } return null; @@ -738,7 +738,7 @@ private static function evaluateScalar($scalar, $flags, $references = []) throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } if (self::$exceptionOnInvalidType) { - throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); } return null; From aebe8ae1632b363752808f80c3e72a76326769ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Tue, 7 Apr 2020 11:39:41 +0200 Subject: [PATCH 25/89] [Workflow] Use a strict comparison when retrieving raw markin in MarkingStore --- .../MarkingStore/SingleStateMarkingStore.php | 2 +- .../MarkingStore/SingleStateMarkingStoreTest.php | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Workflow/MarkingStore/SingleStateMarkingStore.php b/src/Symfony/Component/Workflow/MarkingStore/SingleStateMarkingStore.php index daccc65b41606..cd102f4ce67a2 100644 --- a/src/Symfony/Component/Workflow/MarkingStore/SingleStateMarkingStore.php +++ b/src/Symfony/Component/Workflow/MarkingStore/SingleStateMarkingStore.php @@ -44,7 +44,7 @@ public function getMarking($subject) { $placeName = $this->propertyAccessor->getValue($subject, $this->property); - if (!$placeName) { + if (null === $placeName) { return new Marking(); } diff --git a/src/Symfony/Component/Workflow/Tests/MarkingStore/SingleStateMarkingStoreTest.php b/src/Symfony/Component/Workflow/Tests/MarkingStore/SingleStateMarkingStoreTest.php index 2e00714d2762a..0db37986cfc70 100644 --- a/src/Symfony/Component/Workflow/Tests/MarkingStore/SingleStateMarkingStoreTest.php +++ b/src/Symfony/Component/Workflow/Tests/MarkingStore/SingleStateMarkingStoreTest.php @@ -30,4 +30,17 @@ public function testGetSetMarking() $this->assertEquals($marking, $marking2); } + + public function testAlmostEmptyPlaceName() + { + $subject = new \stdClass(); + $subject->myMarks = 0; + + $markingStore = new SingleStateMarkingStore('myMarks'); + + $marking = $markingStore->getMarking($subject); + + $this->assertInstanceOf(Marking::class, $marking); + $this->assertCount(1, $marking->getPlaces()); + } } From a00a2f111532a5edc4726f2d540514d9007dc7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Tue, 7 Apr 2020 11:51:42 +0200 Subject: [PATCH 26/89] [Workflow] Use a strict comparison when retrieving raw marking in MarkingStore --- .../Workflow/MarkingStore/MethodMarkingStore.php | 2 +- .../Tests/MarkingStore/MethodMarkingStoreTest.php | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php b/src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php index 8c219f502bc3d..feb012913cf1a 100644 --- a/src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php +++ b/src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php @@ -56,7 +56,7 @@ public function getMarking($subject): Marking $marking = $subject->{$method}(); - if (!$marking) { + if (null === $marking) { return new Marking(); } diff --git a/src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php b/src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php index 7393faa825752..155f285a4a976 100644 --- a/src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php +++ b/src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php @@ -53,6 +53,18 @@ public function testGetSetMarkingWithSingleState() $this->assertEquals($marking, $marking2); } + public function testGetSetMarkingWithSingleStateAndAlmostEmptyPlaceName() + { + $subject = new Subject(0); + + $markingStore = new MethodMarkingStore(true); + + $marking = $markingStore->getMarking($subject); + + $this->assertInstanceOf(Marking::class, $marking); + $this->assertCount(1, $marking->getPlaces()); + } + public function testGetMarkingWithValueObject() { $subject = new Subject($this->createValueObject('first_place')); From a07578dba3004f0923fc91b03563163c771e0708 Mon Sep 17 00:00:00 2001 From: Antonio Pauletich Date: Tue, 7 Apr 2020 13:57:54 +0200 Subject: [PATCH 27/89] [HttpClient] Fix scoped client without query option configuration --- .../DependencyInjection/Configuration.php | 2 +- .../http_client_scoped_without_query_option.php | 11 +++++++++++ .../http_client_scoped_without_query_option.xml | 16 ++++++++++++++++ .../http_client_scoped_without_query_option.yml | 5 +++++ .../FrameworkExtensionTest.php | 8 ++++++++ 5 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/http_client_scoped_without_query_option.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/http_client_scoped_without_query_option.xml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/http_client_scoped_without_query_option.yml diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 105695c963d91..13c63ff9988d5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -1482,7 +1482,7 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode) ->thenInvalid('Either "scope" or "base_uri" should be defined.') ->end() ->validate() - ->ifTrue(function ($v) { return isset($v['query']) && !isset($v['base_uri']); }) + ->ifTrue(function ($v) { return !empty($v['query']) && !isset($v['base_uri']); }) ->thenInvalid('"query" applies to "base_uri" but no base URI is defined.') ->end() ->children() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/http_client_scoped_without_query_option.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/http_client_scoped_without_query_option.php new file mode 100644 index 0000000000000..0d3dc88472f84 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/http_client_scoped_without_query_option.php @@ -0,0 +1,11 @@ +loadFromExtension('framework', [ + 'http_client' => [ + 'scoped_clients' => [ + 'foo' => [ + 'scope' => '.*', + ], + ], + ], +]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/http_client_scoped_without_query_option.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/http_client_scoped_without_query_option.xml new file mode 100644 index 0000000000000..43043aeda2a01 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/http_client_scoped_without_query_option.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/http_client_scoped_without_query_option.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/http_client_scoped_without_query_option.yml new file mode 100644 index 0000000000000..ecfc9d41fd4c3 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/http_client_scoped_without_query_option.yml @@ -0,0 +1,5 @@ +framework: + http_client: + scoped_clients: + foo: + scope: '.*' diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index edcdb7aae487f..9a8fc0776f0af 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -1547,6 +1547,14 @@ public function testHttpClientDefaultOptions() $this->assertSame(ScopingHttpClient::class, $container->getDefinition('foo')->getClass()); } + public function testScopedHttpClientWithoutQueryOption() + { + $container = $this->createContainerFromFile('http_client_scoped_without_query_option'); + + $this->assertTrue($container->hasDefinition('foo'), 'should have the "foo" service.'); + $this->assertSame(ScopingHttpClient::class, $container->getDefinition('foo')->getClass()); + } + public function testHttpClientOverrideDefaultOptions() { $container = $this->createContainerFromFile('http_client_override_default_options'); From b98abde65a65b1ba4dbab6ec187bb48ebd0a94cb Mon Sep 17 00:00:00 2001 From: Michel Bardelmeijer Date: Tue, 7 Apr 2020 21:12:26 +0200 Subject: [PATCH 28/89] Supress error from fread when reading a unix pipe --- src/Symfony/Component/Process/Pipes/UnixPipes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Process/Pipes/UnixPipes.php b/src/Symfony/Component/Process/Pipes/UnixPipes.php index 603d726b47fc9..70fdd29574ec7 100644 --- a/src/Symfony/Component/Process/Pipes/UnixPipes.php +++ b/src/Symfony/Component/Process/Pipes/UnixPipes.php @@ -118,7 +118,7 @@ public function readAndWrite(bool $blocking, bool $close = false): array $read[$type = array_search($pipe, $this->pipes, true)] = ''; do { - $data = fread($pipe, self::CHUNK_SIZE); + $data = @fread($pipe, self::CHUNK_SIZE); $read[$type] .= $data; } while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1]))); From 117ee34698e9bf2383d57aee6304b2c1fc7fab28 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Mon, 6 Apr 2020 21:16:17 +0200 Subject: [PATCH 29/89] [Validator] Fixed default group for nested composite constraints --- .../Validator/Constraints/Composite.php | 3 ++- .../Tests/Constraints/CollectionTest.php | 12 +++++++++ .../Constraints/CollectionValidatorTest.php | 23 ++++++++++++++++ .../Tests/Constraints/CompositeTest.php | 26 ++++++++++++++++++- 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/Composite.php b/src/Symfony/Component/Validator/Constraints/Composite.php index bd7030ee27a44..b14276c3bbf1a 100644 --- a/src/Symfony/Component/Validator/Constraints/Composite.php +++ b/src/Symfony/Component/Validator/Constraints/Composite.php @@ -88,7 +88,8 @@ public function __construct($options = null) } } - $this->groups = array_keys($mergedGroups); + // prevent empty composite constraint to have empty groups + $this->groups = array_keys($mergedGroups) ?: [self::DEFAULT_GROUP]; $this->$compositeOption = $nestedConstraints; return; diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php index fef129cfa7494..254154dae7244 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php @@ -100,4 +100,16 @@ public function testAcceptRequiredConstraintAsOneElementArray() $this->assertEquals($collection1, $collection2); } + + public function testConstraintHasDefaultGroupWithOptionalValues() + { + $constraint = new Collection([ + 'foo' => new Required(), + 'bar' => new Optional(), + ]); + + $this->assertEquals(['Default'], $constraint->groups); + $this->assertEquals(['Default'], $constraint->fields['foo']->groups); + $this->assertEquals(['Default'], $constraint->fields['bar']->groups); + } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php index e0ccdba754b0b..11913eb2307ac 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php @@ -143,6 +143,29 @@ public function testExtraFieldsDisallowed() ->assertRaised(); } + public function testExtraFieldsDisallowedWithOptionalValues() + { + $constraint = new Optional(); + + $data = $this->prepareTestData([ + 'baz' => 6, + ]); + + $this->validator->validate($data, new Collection([ + 'fields' => [ + 'foo' => $constraint, + ], + 'extraFieldsMessage' => 'myMessage', + ])); + + $this->buildViolation('myMessage') + ->setParameter('{{ field }}', '"baz"') + ->atPath('property.path[baz]') + ->setInvalidValue(6) + ->setCode(Collection::NO_SUCH_FIELD_ERROR) + ->assertRaised(); + } + // bug fix public function testNullNotConsideredExtraField() { diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CompositeTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CompositeTest.php index 2d42807821bb3..287fd6d6681cb 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/CompositeTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/CompositeTest.php @@ -19,7 +19,7 @@ class ConcreteComposite extends Composite { - public $constraints; + public $constraints = []; protected function getCompositeOption() { @@ -37,6 +37,30 @@ public function getDefaultOption() */ class CompositeTest extends TestCase { + public function testConstraintHasDefaultGroup() + { + $constraint = new ConcreteComposite([ + new NotNull(), + new NotBlank(), + ]); + + $this->assertEquals(['Default'], $constraint->groups); + $this->assertEquals(['Default'], $constraint->constraints[0]->groups); + $this->assertEquals(['Default'], $constraint->constraints[1]->groups); + } + + public function testNestedCompositeConstraintHasDefaultGroup() + { + $constraint = new ConcreteComposite([ + new ConcreteComposite(), + new ConcreteComposite(), + ]); + + $this->assertEquals(['Default'], $constraint->groups); + $this->assertEquals(['Default'], $constraint->constraints[0]->groups); + $this->assertEquals(['Default'], $constraint->constraints[1]->groups); + } + public function testMergeNestedGroupsIfNoExplicitParentGroup() { $constraint = new ConcreteComposite([ From bf17165fb1293aa3e10aacacb569423d86cdbd42 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 8 Apr 2020 16:17:20 +0200 Subject: [PATCH 30/89] [DI] fix detecting short service syntax in yaml --- .../DependencyInjection/Loader/YamlFileLoader.php | 2 +- .../Tests/Fixtures/yaml/services_short_syntax.yml | 6 ++++++ .../Tests/Loader/YamlFileLoaderTest.php | 11 +++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_short_syntax.yml diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index a31959e456552..986ccf0b81f9e 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -299,7 +299,7 @@ private function parseDefaults(array &$content, string $file): array private function isUsingShortSyntax(array $service): bool { foreach ($service as $key => $value) { - if (\is_string($key) && ('' === $key || '$' !== $key[0])) { + if (\is_string($key) && ('' === $key || ('$' !== $key[0] && false === strpos($key, '\\')))) { return false; } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_short_syntax.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_short_syntax.yml new file mode 100644 index 0000000000000..16ddb6bdf241a --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_short_syntax.yml @@ -0,0 +1,6 @@ +services: + foo_bar: [1, 2] + + bar_foo: + $a: 'a' + App\Foo: 'foo' diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index f40fc22cc3452..eb6d01a19749a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -205,6 +205,17 @@ public function testLoadServices() $this->assertEquals(['decorated', 'decorated.pif-pouf', 5, ContainerInterface::IGNORE_ON_INVALID_REFERENCE], $services['decorator_service_with_name_and_priority_and_on_invalid']->getDecoratedService()); } + public function testLoadShortSyntax() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_short_syntax.yml'); + $services = $container->getDefinitions(); + + $this->assertSame([1, 2], $services['foo_bar']->getArguments()); + $this->assertSame(['$a' => 'a', 'App\Foo' => 'foo'], $services['bar_foo']->getArguments()); + } + public function testDeprecatedAliases() { $container = new ContainerBuilder(); From a6a4442cd98ef980d9979dc9f6b7ee6478439787 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 8 Apr 2020 22:51:14 +0200 Subject: [PATCH 31/89] [DI] add missing property declarations in InlineServiceConfigurator --- .../Loader/Configurator/AliasConfigurator.php | 1 + .../Loader/Configurator/InlineServiceConfigurator.php | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/AliasConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/AliasConfigurator.php index cb00f58c049d4..8ac635758bb74 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/AliasConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/AliasConfigurator.php @@ -20,6 +20,7 @@ class AliasConfigurator extends AbstractServiceConfigurator { const FACTORY = 'alias'; + use Traits\DeprecateTrait; use Traits\PublicTrait; public function __construct(ServicesConfigurator $parent, Alias $alias) diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/InlineServiceConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/InlineServiceConfigurator.php index 362b374e55970..ea5db9778bad8 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/InlineServiceConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/InlineServiceConfigurator.php @@ -29,6 +29,10 @@ class InlineServiceConfigurator extends AbstractConfigurator use Traits\ParentTrait; use Traits\TagTrait; + private $id = '[inline]'; + private $allowParent = true; + private $path = null; + public function __construct(Definition $definition) { $this->definition = $definition; From 67f336b808ff5869cffbdf56333ced6cd54589ac Mon Sep 17 00:00:00 2001 From: Ivan Grigoriev Date: Tue, 4 Feb 2020 19:53:14 +0300 Subject: [PATCH 32/89] do not merge constraints within interfaces --- .../Factory/LazyLoadingMetadataFactory.php | 29 +++++++------------ .../Tests/Fixtures/AbstractPropertyGetter.php | 13 +++++++++ .../Tests/Fixtures/ChildGetterInterface.php | 7 +++++ .../Tests/Fixtures/PropertyGetter.php | 12 ++++++++ .../Fixtures/PropertyGetterInterface.php | 8 +++++ .../LazyLoadingMetadataFactoryTest.php | 25 +++++++++++++++- 6 files changed, 74 insertions(+), 20 deletions(-) create mode 100644 src/Symfony/Component/Validator/Tests/Fixtures/AbstractPropertyGetter.php create mode 100644 src/Symfony/Component/Validator/Tests/Fixtures/ChildGetterInterface.php create mode 100644 src/Symfony/Component/Validator/Tests/Fixtures/PropertyGetter.php create mode 100644 src/Symfony/Component/Validator/Tests/Fixtures/PropertyGetterInterface.php diff --git a/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php b/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php index 6bd16c1c7dcae..b17ff691fba48 100644 --- a/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php +++ b/src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php @@ -117,34 +117,25 @@ public function getMetadataFor($value) private function mergeConstraints(ClassMetadata $metadata) { + if ($metadata->getReflectionClass()->isInterface()) { + return; + } + // Include constraints from the parent class if ($parent = $metadata->getReflectionClass()->getParentClass()) { $metadata->mergeConstraints($this->getMetadataFor($parent->name)); } - $interfaces = $metadata->getReflectionClass()->getInterfaces(); - - $interfaces = array_filter($interfaces, function ($interface) use ($parent, $interfaces) { - $interfaceName = $interface->getName(); - - if ($parent && $parent->implementsInterface($interfaceName)) { - return false; - } - - foreach ($interfaces as $i) { - if ($i !== $interface && $i->implementsInterface($interfaceName)) { - return false; - } - } - - return true; - }); - // Include constraints from all directly implemented interfaces - foreach ($interfaces as $interface) { + foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) { if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) { continue; } + + if ($parent && \in_array($interface->getName(), $parent->getInterfaceNames(), true)) { + continue; + } + $metadata->mergeConstraints($this->getMetadataFor($interface->name)); } } diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/AbstractPropertyGetter.php b/src/Symfony/Component/Validator/Tests/Fixtures/AbstractPropertyGetter.php new file mode 100644 index 0000000000000..3df0b9469ddf4 --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Fixtures/AbstractPropertyGetter.php @@ -0,0 +1,13 @@ +property; + } +} diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/ChildGetterInterface.php b/src/Symfony/Component/Validator/Tests/Fixtures/ChildGetterInterface.php new file mode 100644 index 0000000000000..65c144bbeadb9 --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Fixtures/ChildGetterInterface.php @@ -0,0 +1,7 @@ + [ 'Default', 'EntityParentInterface', - 'EntityInterfaceB', 'Entity', ]]), ]; @@ -186,6 +188,15 @@ public function testGroupsFromParent() $this->assertContains('EntityStaticCar', $groups); $this->assertContains('EntityStaticVehicle', $groups); } + + public function testMultipathInterfaceConstraint() + { + $factory = new LazyLoadingMetadataFactory(new PropertyGetterInterfaceConstraintLoader()); + $metadata = $factory->getMetadataFor(PropertyGetter::class); + $constraints = $metadata->getPropertyMetadata('property'); + + $this->assertCount(1, $constraints); + } } class TestLoader implements LoaderInterface @@ -195,3 +206,15 @@ public function loadClassMetadata(ClassMetadata $metadata) $metadata->addConstraint(new ConstraintA()); } } + +class PropertyGetterInterfaceConstraintLoader implements LoaderInterface +{ + public function loadClassMetadata(ClassMetadata $metadata) + { + if (PropertyGetterInterface::class === $metadata->getClassName()) { + $metadata->addGetterConstraint('property', new NotBlank()); + } + + return true; + } +} From c9bf0c8683fd72a56d5b990692cf5e1d6987cf67 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 9 Apr 2020 10:29:41 -0400 Subject: [PATCH 33/89] Allowing empty secrets to be set --- .../FrameworkBundle/Command/SecretsSetCommand.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsSetCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsSetCommand.php index 5cca8d7011fac..91e0031299c3b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/SecretsSetCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/SecretsSetCommand.php @@ -96,6 +96,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int $value = strtr(substr(base64_encode(random_bytes($random)), 0, $random), '+/', '-_'); } elseif (!$file = $input->getArgument('file')) { $value = $io->askHidden('Please type the secret value'); + + if (null === $value) { + $io->warning('No value provided: using empty string'); + $value = ''; + } } elseif ('-' === $file) { $value = file_get_contents('php://stdin'); } elseif (is_file($file) && is_readable($file)) { @@ -106,12 +111,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int throw new \InvalidArgumentException(sprintf('File is not readable: "%s".', $file)); } - if (null === $value) { - $io->warning('No value provided, aborting.'); - - return 1; - } - if ($vault->generateKeys()) { $io->success($vault->getLastMessage()); From 7ccbef62f6153255bed2f127d888637634d377a1 Mon Sep 17 00:00:00 2001 From: oesteve Date: Fri, 10 Apr 2020 20:51:00 +0200 Subject: [PATCH 34/89] Force ping after transport Exception --- .../Transport/Smtp/SmtpTransportTest.php | 44 +++++++++++++++++++ .../Mailer/Transport/Smtp/SmtpTransport.php | 5 +-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php b/src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php index 7ec8313612049..2c8d91e9e4402 100644 --- a/src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php +++ b/src/Symfony/Component/Mailer/Tests/Transport/Smtp/SmtpTransportTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\Exception\TransportException; use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport; use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream; use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; @@ -43,6 +44,29 @@ public function testSendDoesNotPingBelowThreshold(): void $this->assertNotContains("NOOP\r\n", $stream->getCommands()); } + public function testSendPingAfterTransportException(): void + { + $stream = new DummyStream(); + $envelope = new Envelope(new Address('sender@example.org'), [new Address('recipient@example.org')]); + + $transport = new SmtpTransport($stream); + $transport->send(new RawMessage('Message 1'), $envelope); + $stream->close(); + $catch = false; + + try { + $transport->send(new RawMessage('Message 2'), $envelope); + } catch (TransportException $exception) { + $catch = true; + } + $this->assertTrue($catch); + $this->assertTrue($stream->isClosed()); + + $transport->send(new RawMessage('Message 3'), $envelope); + + $this->assertFalse($stream->isClosed()); + } + public function testSendDoesPingAboveThreshold(): void { $stream = new DummyStream(); @@ -76,13 +100,23 @@ class DummyStream extends AbstractStream */ private $commands; + /** + * @var bool + */ + private $closed = true; + public function initialize(): void { + $this->closed = false; $this->nextResponse = '220 localhost'; } public function write(string $bytes, $debug = true): void { + if ($this->closed) { + throw new TransportException('Unable to write bytes on the wire.'); + } + $this->commands[] = $bytes; if (0 === strpos($bytes, 'DATA')) { @@ -120,4 +154,14 @@ protected function getReadConnectionDescription(): string { return 'null'; } + + public function close(): void + { + $this->closed = true; + } + + public function isClosed(): bool + { + return $this->closed; + } } diff --git a/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php b/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php index 091b5e2bc5a60..26f2057f941ae 100644 --- a/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php +++ b/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php @@ -206,12 +206,11 @@ protected function doSend(SentMessage $message): void $this->stream->flush(); $this->executeCommand("\r\n.\r\n", [250]); $message->appendDebug($this->stream->getDebug()); + $this->lastMessageTime = microtime(true); } catch (TransportExceptionInterface $e) { $e->appendDebug($this->stream->getDebug()); - + $this->lastMessageTime = 0; throw $e; - } finally { - $this->lastMessageTime = microtime(true); } } From 728cd66a1317c159fb2c0722af548f9d2d8173d3 Mon Sep 17 00:00:00 2001 From: Artem Lopata Date: Fri, 10 Apr 2020 13:43:00 +0200 Subject: [PATCH 35/89] RepeatedType should always have inner types mapped --- .../Form/Extension/Core/Type/RepeatedType.php | 7 ++-- .../Extension/Core/Type/RepeatedTypeTest.php | 36 +++++++++++++++++++ .../Form/Tests/Fixtures/NotMappedType.php | 23 ++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/Form/Tests/Fixtures/NotMappedType.php diff --git a/src/Symfony/Component/Form/Extension/Core/Type/RepeatedType.php b/src/Symfony/Component/Form/Extension/Core/Type/RepeatedType.php index ffb7520a582b6..6ed403523cb77 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/RepeatedType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/RepeatedType.php @@ -31,13 +31,16 @@ public function buildForm(FormBuilderInterface $builder, array $options) $options['options']['error_bubbling'] = $options['error_bubbling']; } + // children fields must always be mapped + $defaultOptions = ['mapped' => true]; + $builder ->addViewTransformer(new ValueToDuplicatesTransformer([ $options['first_name'], $options['second_name'], ])) - ->add($options['first_name'], $options['type'], array_merge($options['options'], $options['first_options'])) - ->add($options['second_name'], $options['type'], array_merge($options['options'], $options['second_options'])) + ->add($options['first_name'], $options['type'], array_merge($options['options'], $options['first_options'], $defaultOptions)) + ->add($options['second_name'], $options['type'], array_merge($options['options'], $options['second_options'], $defaultOptions)) ; } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php index 8b4666d6fa5f0..3d5544c05d25a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; use Symfony\Component\Form\Form; +use Symfony\Component\Form\Tests\Fixtures\NotMappedType; class RepeatedTypeTest extends BaseTypeTest { @@ -78,6 +79,41 @@ public function testSetRequired() $this->assertFalse($form['second']->isRequired()); } + public function testMappedOverridesDefault() + { + $form = $this->factory->create(NotMappedType::class); + $this->assertFalse($form->getConfig()->getMapped()); + + $form = $this->factory->create(static::TESTED_TYPE, null, [ + 'type' => NotMappedType::class, + ]); + + $this->assertTrue($form['first']->getConfig()->getMapped()); + $this->assertTrue($form['second']->getConfig()->getMapped()); + } + + /** + * @dataProvider notMappedConfigurationKeys + */ + public function testNotMappedInnerIsOverridden($configurationKey) + { + $form = $this->factory->create(static::TESTED_TYPE, null, [ + 'type' => TextTypeTest::TESTED_TYPE, + $configurationKey => ['mapped' => false], + ]); + + $this->assertTrue($form['first']->getConfig()->getMapped()); + $this->assertTrue($form['second']->getConfig()->getMapped()); + } + + public function notMappedConfigurationKeys() + { + return [ + ['first_options'], + ['second_options'], + ]; + } + public function testSetInvalidOptions() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); diff --git a/src/Symfony/Component/Form/Tests/Fixtures/NotMappedType.php b/src/Symfony/Component/Form/Tests/Fixtures/NotMappedType.php new file mode 100644 index 0000000000000..14c340b8917af --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Fixtures/NotMappedType.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Fixtures; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class NotMappedType extends AbstractType +{ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefault('mapped', false); + } +} From 015d8d7e869b015e08080396d75ec9d177df6bdc Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 10 Apr 2020 22:02:31 +0200 Subject: [PATCH 36/89] =?UTF-8?q?[DI]=20=C2=B5fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Component/DependencyInjection/Loader/YamlFileLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index 5a011c04ddaaf..ca52ff36c0db6 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -355,7 +355,7 @@ private function parseDefinition($id, $service, $file, array $defaults) if (isset($service['alias'])) { $this->container->setAlias($id, $alias = new Alias($service['alias'])); - if (\array_key_exists('public', $service)) { + if (isset($service['public'])) { $alias->setPublic($service['public']); } elseif (isset($defaults['public'])) { $alias->setPublic($defaults['public']); From b2c9a6ea910b2a01d278e737bc4711c0486ae74e Mon Sep 17 00:00:00 2001 From: Mike Milano Date: Thu, 9 Apr 2020 08:07:46 -0700 Subject: [PATCH 37/89] [Twig][Mime] Removed extra quotes in missing package exception message --- src/Symfony/Bridge/Twig/Mime/NotificationEmail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/Mime/NotificationEmail.php b/src/Symfony/Bridge/Twig/Mime/NotificationEmail.php index 6d9bffcfcc47e..e6b28c4db43d2 100644 --- a/src/Symfony/Bridge/Twig/Mime/NotificationEmail.php +++ b/src/Symfony/Bridge/Twig/Mime/NotificationEmail.php @@ -51,7 +51,7 @@ public function __construct(Headers $headers = null, AbstractPart $body = null) } if ($missingPackages) { - throw new \LogicException(sprintf('You cannot use "%s" if the "%s" Twig extension%s not available; try running "composer require "%s"".', static::class, implode('" and "', $missingPackages), \count($missingPackages) > 1 ? 's are' : ' is', implode(' ', array_keys($missingPackages)))); + throw new \LogicException(sprintf('You cannot use "%s" if the "%s" Twig extension%s not available; try running "%s".', static::class, implode('" and "', $missingPackages), \count($missingPackages) > 1 ? 's are' : ' is', 'composer require '.implode(' ', array_keys($missingPackages)))); } parent::__construct($headers, $body); From 8920f183fbb6489f622d94f5637e82bb36fc12fa Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 10 Apr 2020 22:35:26 +0200 Subject: [PATCH 38/89] [appveyor] bump cache --- phpunit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit b/phpunit index c89d2e400b602..fbce26d8edcca 100755 --- a/phpunit +++ b/phpunit @@ -1,7 +1,7 @@ #!/usr/bin/env php Date: Sat, 11 Apr 2020 11:49:39 +0200 Subject: [PATCH 39/89] [HttpClient] fix HTTP/2 support on non-SSL connections - CurlHttpClient only --- src/Symfony/Component/HttpClient/CurlHttpClient.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index ddc7f9d9f351c..2fcba7902ebef 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -141,12 +141,12 @@ public function request(string $method, string $url, array $options = []): Respo CURLOPT_CERTINFO => $options['capture_peer_cert_chain'], ]; - if (1.0 === (float) $options['http_version']) { + if (\defined('CURL_VERSION_HTTP2') && (CURL_VERSION_HTTP2 & self::$curlVersion['features']) && ('https:' === $scheme || 2.0 === (float) $options['http_version'])) { + $curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0; + } elseif (1.0 === (float) $options['http_version']) { $curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0; - } elseif (1.1 === (float) $options['http_version'] || 'https:' !== $scheme) { + } elseif (1.1 === (float) $options['http_version']) { $curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1; - } elseif (\defined('CURL_VERSION_HTTP2') && CURL_VERSION_HTTP2 & self::$curlVersion['features']) { - $curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0; } if (isset($options['auth_ntlm'])) { From f6410cbab2797af4fa56a7281442f279a3dd48ae Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 11 Apr 2020 21:55:18 +0200 Subject: [PATCH 40/89] [travis] fix CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a5246b3eafb58..d6830ea27bb3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -269,7 +269,7 @@ install: export PHP=$1 if [[ !$deps && $PHP = 7.2 ]]; then - tfold src/Symfony/Component/HttpClient.h2push "$COMPOSER_UP symfony/contracts && docker run -it --rm -v $(pwd):/app -v $(phpenv which composer):/usr/local/bin/composer -v /usr/local/bin/vulcain:/usr/local/bin/vulcain -w /app php:7.3-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push" + tfold src/Symfony/Component/HttpClient.h2push "$COMPOSER_UP symfony/contracts && ./phpunit install && docker run -it --rm -v $(pwd):/app -v $(phpenv which composer):/usr/local/bin/composer -v /usr/local/bin/vulcain:/usr/local/bin/vulcain -w /app php:7.3-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push" fi if [[ $PHP != 7.4* && $PHP != $TRAVIS_PHP_VERSION && $TRAVIS_PULL_REQUEST != false ]]; then From e479e51f7c0de69d646813e52fefb40590c132dc Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Sat, 11 Apr 2020 20:54:18 +0200 Subject: [PATCH 41/89] [Form] Removed legacy check in `ValidationListener` --- .../Extension/Validator/EventListener/ValidationListener.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php b/src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php index 80c94dc66e4d0..e6cd81a4245f5 100644 --- a/src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php +++ b/src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php @@ -55,8 +55,7 @@ public function validateForm(FormEvent $event) foreach ($this->validator->validate($form) as $violation) { // Allow the "invalid" constraint to be put onto // non-synchronized forms - // ConstraintViolation::getConstraint() must not expect to provide a constraint as long as Symfony\Component\Validator\ExecutionContext exists (before 3.0) - $allowNonSynchronized = (null === $violation->getConstraint() || $violation->getConstraint() instanceof Form) && Form::NOT_SYNCHRONIZED_ERROR === $violation->getCode(); + $allowNonSynchronized = $violation->getConstraint() instanceof Form && Form::NOT_SYNCHRONIZED_ERROR === $violation->getCode(); $this->violationMapper->mapViolation($violation, $form, $allowNonSynchronized); } From 8302eedd26883da5105e64029db3e3c2c64914cf Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 11 Apr 2020 22:32:17 +0200 Subject: [PATCH 42/89] [travis] fix CI (bis) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d6830ea27bb3f..859e0ccc5473c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -269,6 +269,7 @@ install: export PHP=$1 if [[ !$deps && $PHP = 7.2 ]]; then + phpenv global $PHP tfold src/Symfony/Component/HttpClient.h2push "$COMPOSER_UP symfony/contracts && ./phpunit install && docker run -it --rm -v $(pwd):/app -v $(phpenv which composer):/usr/local/bin/composer -v /usr/local/bin/vulcain:/usr/local/bin/vulcain -w /app php:7.3-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push" fi From 5182253aa267a719533c42292b91607d4f6c3574 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 12 Apr 2020 00:02:39 +0200 Subject: [PATCH 43/89] [travis][appveyor] don't cache .phpunit --- .appveyor.yml | 1 - .travis.yml | 1 - phpunit | 2 -- 3 files changed, 4 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 188dfe78a2493..85892655405f5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,7 +4,6 @@ clone_folder: c:\projects\symfony cache: - composer.phar - - .phpunit -> phpunit init: - SET PATH=c:\php;%PATH% diff --git a/.travis.yml b/.travis.yml index 4251d2fa0247c..cb35dc95f5e97 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,6 @@ matrix: cache: directories: - - .phpunit - php-$MIN_PHP - ~/php-ext diff --git a/phpunit b/phpunit index fbce26d8edcca..abce96135b50d 100755 --- a/phpunit +++ b/phpunit @@ -1,8 +1,6 @@ #!/usr/bin/env php Date: Sun, 12 Apr 2020 11:28:02 +0200 Subject: [PATCH 44/89] silence E_NOTICE triggered since PHP 7.4 --- src/Symfony/Component/HttpKernel/Log/Logger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Log/Logger.php b/src/Symfony/Component/HttpKernel/Log/Logger.php index f490293a62e03..e05d8c32ec797 100644 --- a/src/Symfony/Component/HttpKernel/Log/Logger.php +++ b/src/Symfony/Component/HttpKernel/Log/Logger.php @@ -77,7 +77,7 @@ public function log($level, $message, array $context = []) } $formatter = $this->formatter; - fwrite($this->handle, $formatter($level, $message, $context)); + @fwrite($this->handle, $formatter($level, $message, $context)); } /** From 966989a2b9fc4a9a301f964d2164f28e8fb15913 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 12 Apr 2020 11:36:17 +0200 Subject: [PATCH 45/89] Revert "[travis][appveyor] don't cache .phpunit" This reverts commit 5182253aa267a719533c42292b91607d4f6c3574. --- .appveyor.yml | 1 + .travis.yml | 1 + phpunit | 2 ++ 3 files changed, 4 insertions(+) diff --git a/.appveyor.yml b/.appveyor.yml index 85892655405f5..188dfe78a2493 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,6 +4,7 @@ clone_folder: c:\projects\symfony cache: - composer.phar + - .phpunit -> phpunit init: - SET PATH=c:\php;%PATH% diff --git a/.travis.yml b/.travis.yml index cb35dc95f5e97..4251d2fa0247c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ matrix: cache: directories: + - .phpunit - php-$MIN_PHP - ~/php-ext diff --git a/phpunit b/phpunit index abce96135b50d..fbce26d8edcca 100755 --- a/phpunit +++ b/phpunit @@ -1,6 +1,8 @@ #!/usr/bin/env php Date: Sun, 12 Apr 2020 11:46:54 +0200 Subject: [PATCH 46/89] [travis] fix CI (ter) --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 00b49c27aace0..99e6310eb2b7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -271,8 +271,10 @@ install: if [[ !$deps && $PHP = 7.2 ]]; then phpenv global $PHP tfold 'composer update' $COMPOSER_UP - tfold 'phpunit install' ./phpunit install - tfold src/Symfony/Component/HttpClient.h2push "docker run -it --rm -v $(pwd):/app -v /usr/local/bin/vulcain:/usr/local/bin/vulcain -w /app php:7.3-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push" + [ -d .phpunit ] && mv .phpunit .phpunit.bak + tfold src/Symfony/Component/HttpClient.h2push "docker run -it --rm -v $(pwd):/app -v $(phpenv which composer):/usr/local/bin/composer -v /usr/local/bin/vulcain:/usr/local/bin/vulcain -w /app php:7.3-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push" + sudo rm .phpunit -rf + [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit fi if [[ $PHP != 7.4* && $PHP != $TRAVIS_PHP_VERSION && $TRAVIS_PULL_REQUEST != false ]]; then @@ -281,12 +283,10 @@ install: fi phpenv global $PHP ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer config platform.ext-mongodb 1.6.0; composer require --dev --no-update mongodb/mongodb ~1.5.0) - if [[ $deps || $PHP != 7.2 ]]; then tfold 'composer update' $COMPOSER_UP - tfold 'phpunit install' ./phpunit install fi - + tfold 'phpunit install' ./phpunit install if [[ $deps = high ]]; then echo "$COMPONENTS" | parallel --gnu "tfold {} 'cd {} && $COMPOSER_UP && $PHPUNIT_X$LEGACY'" || X=1 (cd src/Symfony/Component/HttpFoundation; mv composer.bak composer.json) From a21c1127dc18553a729da0aa925fa24186a57488 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 12 Apr 2020 11:58:27 +0200 Subject: [PATCH 47/89] =?UTF-8?q?[Routing]=20=C2=B5tweaks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php | 2 +- src/Symfony/Component/Routing/Loader/XmlFileLoader.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php b/src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php index 3920fc4bef9f6..65633ca075ba4 100644 --- a/src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php +++ b/src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php @@ -67,7 +67,7 @@ public function load($resource, $type = null) if (!$routeCollection instanceof RouteCollection) { $type = \is_object($routeCollection) ? \get_class($routeCollection) : \gettype($routeCollection); - throw new \LogicException(sprintf('The "%s"::%s method must return a RouteCollection: "%s" returned.', \get_class($loaderObject), $method, $type)); + throw new \LogicException(sprintf('The "%s::%s()" method must return a RouteCollection: "%s" returned.', \get_class($loaderObject), $method, $type)); } // make the service file tracked so that if it changes, the cache rebuilds diff --git a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php index 29dfdb1665b56..a9a9d09e0866b 100644 --- a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -240,9 +240,9 @@ private function parseConfigs(\DOMElement $node, $path) if ($controller = $node->getAttribute('controller')) { if (isset($defaults['_controller'])) { - $name = $node->hasAttribute('id') ? sprintf('"%s"', $node->getAttribute('id')) : sprintf('the "%s" tag', $node->tagName); + $name = $node->hasAttribute('id') ? sprintf('"%s".', $node->getAttribute('id')) : sprintf('the "%s" tag.', $node->tagName); - throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" attribute and the defaults key "_controller" for %s.', $path, $name)); + throw new \InvalidArgumentException(sprintf('The routing file "%s" must not specify both the "controller" attribute and the defaults key "_controller" for ', $path).$name); } $defaults['_controller'] = $controller; From 8b84ab60020c1452cb2a491f41219cbac5b9dada Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 12 Apr 2020 13:05:14 +0200 Subject: [PATCH 48/89] [Lock] remove mention of mongodb --- src/Symfony/Component/Lock/composer.json | 1 - src/Symfony/Component/Lock/phpunit.xml.dist | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Symfony/Component/Lock/composer.json b/src/Symfony/Component/Lock/composer.json index 8e82285b40f1e..d604d2bd6837d 100644 --- a/src/Symfony/Component/Lock/composer.json +++ b/src/Symfony/Component/Lock/composer.json @@ -21,7 +21,6 @@ }, "require-dev": { "doctrine/dbal": "~2.5", - "mongodb/mongodb": "~1.1", "predis/predis": "~1.0" }, "conflict": { diff --git a/src/Symfony/Component/Lock/phpunit.xml.dist b/src/Symfony/Component/Lock/phpunit.xml.dist index 96c3ea1903abe..4a066573f7d08 100644 --- a/src/Symfony/Component/Lock/phpunit.xml.dist +++ b/src/Symfony/Component/Lock/phpunit.xml.dist @@ -12,7 +12,6 @@ - From ad6f75e5c85ec9adebee716858a6c0f5feeab4b3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 12 Apr 2020 16:22:30 +0200 Subject: [PATCH 49/89] Tweak the code to avoid fabbot false positives --- .../Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php | 8 ++++---- .../Bridge/Doctrine/Security/User/EntityUserProvider.php | 2 +- .../Bundle/WebServerBundle/Command/ServerLogCommand.php | 2 +- .../Asset/VersionStrategy/JsonManifestVersionStrategy.php | 2 +- src/Symfony/Component/Cache/Traits/MemcachedTrait.php | 2 +- src/Symfony/Component/Config/Definition/BaseNode.php | 2 +- .../Compiler/AbstractRecursivePass.php | 2 +- .../DependencyInjection/Loader/YamlFileLoader.php | 2 +- src/Symfony/Component/Filesystem/Filesystem.php | 8 ++++---- src/Symfony/Component/Form/Form.php | 8 ++++---- .../HttpKernel/Controller/ControllerResolver.php | 2 +- .../Intl/Data/Bundle/Reader/JsonBundleReader.php | 2 +- src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php | 8 ++++---- src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php | 4 ++-- .../Component/Ldap/Adapter/ExtLdap/EntryManager.php | 8 ++++---- src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php | 2 +- src/Symfony/Component/Process/Pipes/WindowsPipes.php | 2 +- .../Component/Security/Core/Encoder/EncoderFactory.php | 4 ++-- src/Symfony/Component/Serializer/Encoder/XmlEncoder.php | 2 +- src/Symfony/Component/Serializer/Serializer.php | 2 +- .../Component/Translation/Loader/JsonFileLoader.php | 2 +- .../Component/Translation/Loader/XliffFileLoader.php | 4 ++-- .../Validator/Constraints/AbstractComparisonValidator.php | 2 +- .../Component/Validator/Constraints/CallbackValidator.php | 2 +- 24 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php b/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php index fc60d12d7b395..7d824100b76bf 100644 --- a/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php +++ b/src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php @@ -96,7 +96,7 @@ public function destroy($sessionId) $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); $stmt->execute(); } catch (\Exception $e) { - throw new \RuntimeException(sprintf('Exception was thrown when trying to delete a session: %s.', $e->getMessage()), 0, $e); + throw new \RuntimeException('Exception was thrown when trying to delete a session: '.$e->getMessage(), 0, $e); } return true; @@ -115,7 +115,7 @@ public function gc($maxlifetime) $stmt->bindValue(':time', time() - $maxlifetime, \PDO::PARAM_INT); $stmt->execute(); } catch (\Exception $e) { - throw new \RuntimeException(sprintf('Exception was thrown when trying to delete expired sessions: %s.', $e->getMessage()), 0, $e); + throw new \RuntimeException('Exception was thrown when trying to delete expired sessions: '.$e->getMessage(), 0, $e); } return true; @@ -142,7 +142,7 @@ public function read($sessionId) return ''; } catch (\Exception $e) { - throw new \RuntimeException(sprintf('Exception was thrown when trying to read the session data: %s.', $e->getMessage()), 0, $e); + throw new \RuntimeException('Exception was thrown when trying to read the session data: '.$e->getMessage(), 0, $e); } } @@ -212,7 +212,7 @@ public function write($sessionId, $data) } } } catch (\Exception $e) { - throw new \RuntimeException(sprintf('Exception was thrown when trying to write the session data: %s.', $e->getMessage()), 0, $e); + throw new \RuntimeException('Exception was thrown when trying to write the session data: '.$e->getMessage(), 0, $e); } return true; diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index 1fe8a5c53a5ab..818c44a3da2af 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -92,7 +92,7 @@ public function refreshUser(UserInterface $user) $refreshedUser = $repository->find($id); if (null === $refreshedUser) { - throw new UsernameNotFoundException(sprintf('User with id %s not found.', json_encode($id))); + throw new UsernameNotFoundException('User with id '.json_encode($id).' not found.')); } } diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php index 5c9ce910ddf54..75d94321f4f0b 100644 --- a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php +++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php @@ -99,7 +99,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } if (!$socket = stream_socket_server($host, $errno, $errstr)) { - throw new RuntimeException(sprintf('Server start failed on "%s": %s %s.', $host, $errstr, $errno)); + throw new RuntimeException(sprintf('Server start failed on "%s": '.$errstr.' '.$errno, $host)); } foreach ($this->getLogs($socket) as $clientId => $message) { diff --git a/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php b/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php index 2ab686a561956..d052317678c80 100644 --- a/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php +++ b/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php @@ -59,7 +59,7 @@ private function getManifestPath($path) $this->manifestData = json_decode(file_get_contents($this->manifestPath), true); if (0 < json_last_error()) { - throw new \RuntimeException(sprintf('Error parsing JSON from asset manifest file "%s" - %s.', $this->manifestPath, json_last_error_msg())); + throw new \RuntimeException(sprintf('Error parsing JSON from asset manifest file "%s": '.json_last_error_msg(), $this->manifestPath)); } } diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php index 3f4fb5243d0e2..3ff28d25b3576 100644 --- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php +++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php @@ -272,7 +272,7 @@ private function checkResultCode($result) return $result; } - throw new CacheException(sprintf('MemcachedAdapter client error: %s.', strtolower($this->client->getResultMessage()))); + throw new CacheException('MemcachedAdapter client error: '.strtolower($this->client->getResultMessage())); } /** diff --git a/src/Symfony/Component/Config/Definition/BaseNode.php b/src/Symfony/Component/Config/Definition/BaseNode.php index bf57a9fa17bc5..1f6ef7f834b8c 100644 --- a/src/Symfony/Component/Config/Definition/BaseNode.php +++ b/src/Symfony/Component/Config/Definition/BaseNode.php @@ -335,7 +335,7 @@ final public function finalize($value) } catch (Exception $e) { throw $e; } catch (\Exception $e) { - throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": %s.', $this->getPath(), $e->getMessage()), $e->getCode(), $e); + throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": '.$e->getMessage(), $this->getPath()), $e->getCode(), $e); } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php index 5ca2b2246b76b..27969e7067254 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php @@ -126,7 +126,7 @@ protected function getConstructor(Definition $definition, $required) throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class)); } } catch (\ReflectionException $e) { - throw new RuntimeException(sprintf('Invalid service "%s": %s.', $this->currentId, lcfirst(rtrim($e->getMessage(), '.')))); + throw new RuntimeException(sprintf('Invalid service "%s": '.lcfirst($e->getMessage()), $this->currentId)); } if (!$r = $r->getConstructor()) { if ($required) { diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index ca52ff36c0db6..bc0c55e94df41 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -660,7 +660,7 @@ protected function loadFile($file) try { $configuration = $this->yamlParser->parseFile($file, Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS); } catch (ParseException $e) { - throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML: %s.', $file, $e->getMessage()), 0, $e); + throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML: '.$e->getMessage(), $file), 0, $e); } finally { restore_error_handler(); } diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index f3d1fe44622a1..a8701533cbd38 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -101,7 +101,7 @@ public function mkdir($dirs, $mode = 0777) if (!is_dir($dir)) { // The directory was not created by a concurrent process. Let's throw an exception with a developer friendly error message if we have one if (self::$lastError) { - throw new IOException(sprintf('Failed to create "%s": %s.', $dir, self::$lastError), 0, null, $dir); + throw new IOException(sprintf('Failed to create "%s": '.self::$lastError, $dir), 0, null, $dir); } throw new IOException(sprintf('Failed to create "%s".', $dir), 0, null, $dir); } @@ -171,16 +171,16 @@ public function remove($files) if (is_link($file)) { // See https://bugs.php.net/52176 if (!(self::box('unlink', $file) || '\\' !== \DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) { - throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, self::$lastError)); + throw new IOException(sprintf('Failed to remove symlink "%s": '.self::$lastError, $file)); } } elseif (is_dir($file)) { $this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS)); if (!self::box('rmdir', $file) && file_exists($file)) { - throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, self::$lastError)); + throw new IOException(sprintf('Failed to remove directory "%s": '.self::$lastError, $file)); } } elseif (!self::box('unlink', $file) && file_exists($file)) { - throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, self::$lastError)); + throw new IOException(sprintf('Failed to remove file "%s": '.self::$lastError, $file)); } } } diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 53ac447d3d8bd..e9190b82b8466 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -1031,7 +1031,7 @@ private function modelToNorm($value) $value = $transformer->transform($value); } } catch (TransformationFailedException $exception) { - throw new TransformationFailedException(sprintf('Unable to transform data for property path "%s": %s', $this->getPropertyPath(), $exception->getMessage()), $exception->getCode(), $exception); + throw new TransformationFailedException(sprintf('Unable to transform data for property path "%s": '.$exception->getMessage(), $this->getPropertyPath()), $exception->getCode(), $exception); } return $value; @@ -1055,7 +1055,7 @@ private function normToModel($value) $value = $transformers[$i]->reverseTransform($value); } } catch (TransformationFailedException $exception) { - throw new TransformationFailedException(sprintf('Unable to reverse value for property path "%s": %s', $this->getPropertyPath(), $exception->getMessage()), $exception->getCode(), $exception); + throw new TransformationFailedException(sprintf('Unable to reverse value for property path "%s": '.$exception->getMessage(), $this->getPropertyPath()), $exception->getCode(), $exception); } return $value; @@ -1086,7 +1086,7 @@ private function normToView($value) $value = $transformer->transform($value); } } catch (TransformationFailedException $exception) { - throw new TransformationFailedException(sprintf('Unable to transform value for property path "%s": %s', $this->getPropertyPath(), $exception->getMessage()), $exception->getCode(), $exception); + throw new TransformationFailedException(sprintf('Unable to transform value for property path "%s": '.$exception->getMessage(), $this->getPropertyPath()), $exception->getCode(), $exception); } return $value; @@ -1112,7 +1112,7 @@ private function viewToNorm($value) $value = $transformers[$i]->reverseTransform($value); } } catch (TransformationFailedException $exception) { - throw new TransformationFailedException(sprintf('Unable to reverse value for property path "%s": %s', $this->getPropertyPath(), $exception->getMessage()), $exception->getCode(), $exception); + throw new TransformationFailedException(sprintf('Unable to reverse value for property path "%s": '.$exception->getMessage(), $this->getPropertyPath()), $exception->getCode(), $exception); } return $value; diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php index 4e11ac640bd90..6244fdb9e5eaa 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -88,7 +88,7 @@ public function getController(Request $request) try { $callable = $this->createController($controller); } catch (\InvalidArgumentException $e) { - throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s.', $request->getPathInfo(), $e->getMessage()), 0, $e); + throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: '.$e->getMessage(), $request->getPathInfo()), 0, $e); } return $callable; diff --git a/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php b/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php index a56fd6af1c233..555dd377c9341 100644 --- a/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php +++ b/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php @@ -46,7 +46,7 @@ public function read($path, $locale) $data = json_decode(file_get_contents($fileName), true); if (null === $data) { - throw new RuntimeException(sprintf('The resource bundle "%s" contains invalid JSON: %s.', $fileName, json_last_error_msg())); + throw new RuntimeException(sprintf('The resource bundle "%s" contains invalid JSON: '.json_last_error_msg(), $fileName)); } return $data; diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php index fade430753dcc..f166c3dd3fb9c 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php @@ -48,7 +48,7 @@ public function count() return $count; } - throw new LdapException(sprintf('Error while retrieving entry count: %s.', ldap_error($this->connection->getResource()))); + throw new LdapException('Error while retrieving entry count: '.ldap_error($this->connection->getResource())); } public function getIterator() @@ -62,7 +62,7 @@ public function getIterator() } if (false === $current) { - throw new LdapException(sprintf('Could not rewind entries array: %s.', ldap_error($con))); + throw new LdapException('Could not rewind entries array: '.ldap_error($con)); } yield $this->getSingleEntry($con, $current); @@ -105,7 +105,7 @@ private function getSingleEntry($con, $current) $attributes = ldap_get_attributes($con, $current); if (false === $attributes) { - throw new LdapException(sprintf('Could not fetch attributes: %s.', ldap_error($con))); + throw new LdapException('Could not fetch attributes: '.ldap_error($con)); } $attributes = $this->cleanupAttributes($attributes); @@ -113,7 +113,7 @@ private function getSingleEntry($con, $current) $dn = ldap_get_dn($con, $current); if (false === $dn) { - throw new LdapException(sprintf('Could not fetch DN: %s.', ldap_error($con))); + throw new LdapException('Could not fetch DN: '.ldap_error($con)); } return new Entry($dn, $attributes); diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php index 2dcb215b921a4..9e988a8e6c87f 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php @@ -138,11 +138,11 @@ private function connect() } if (false === $this->connection) { - throw new LdapException(sprintf('Could not connect to Ldap server: %s.', ldap_error($this->connection))); + throw new LdapException('Could not connect to Ldap server: '.ldap_error($this->connection)); } if ('tls' === $this->config['encryption'] && false === @ldap_start_tls($this->connection)) { - throw new LdapException(sprintf('Could not initiate TLS connection: %s.', ldap_error($this->connection))); + throw new LdapException('Could not initiate TLS connection: '.ldap_error($this->connection)); } } diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php index 871c4b049562d..789672e7b22ef 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php @@ -38,7 +38,7 @@ public function add(Entry $entry) $con = $this->getConnectionResource(); if (!@ldap_add($con, $entry->getDn(), $entry->getAttributes())) { - throw new LdapException(sprintf('Could not add entry "%s": %s.', $entry->getDn(), ldap_error($con))); + throw new LdapException(sprintf('Could not add entry "%s": '.ldap_error($con), $entry->getDn())); } return $this; @@ -52,7 +52,7 @@ public function update(Entry $entry) $con = $this->getConnectionResource(); if (!@ldap_modify($con, $entry->getDn(), $entry->getAttributes())) { - throw new LdapException(sprintf('Could not update entry "%s": %s.', $entry->getDn(), ldap_error($con))); + throw new LdapException(sprintf('Could not update entry "%s": '.ldap_error($con), $entry->getDn())); } } @@ -64,7 +64,7 @@ public function remove(Entry $entry) $con = $this->getConnectionResource(); if (!@ldap_delete($con, $entry->getDn())) { - throw new LdapException(sprintf('Could not remove entry "%s": %s.', $entry->getDn(), ldap_error($con))); + throw new LdapException(sprintf('Could not remove entry "%s": '.ldap_error($con), $entry->getDn())); } } @@ -76,7 +76,7 @@ public function rename(Entry $entry, $newRdn, $removeOldRdn = true) $con = $this->getConnectionResource(); if (!@ldap_rename($con, $entry->getDn(), $newRdn, null, $removeOldRdn)) { - throw new LdapException(sprintf('Could not rename entry "%s" to "%s": %s.', $entry->getDn(), $newRdn, ldap_error($con))); + throw new LdapException(sprintf('Could not rename entry "%s" to "%s": '.ldap_error($con), $entry->getDn(), $newRdn)); } } diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php index 33742039fb32b..a5c049b166125 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php @@ -45,7 +45,7 @@ public function __destruct() $this->search = null; if (!$success) { - throw new LdapException(sprintf('Could not free results: %s.', ldap_error($con))); + throw new LdapException('Could not free results: '.ldap_error($con)); } } diff --git a/src/Symfony/Component/Process/Pipes/WindowsPipes.php b/src/Symfony/Component/Process/Pipes/WindowsPipes.php index 44056d54cf65d..302b0509a86b7 100644 --- a/src/Symfony/Component/Process/Pipes/WindowsPipes.php +++ b/src/Symfony/Component/Process/Pipes/WindowsPipes.php @@ -57,7 +57,7 @@ public function __construct($input, $haveReadSupport) if (!$h = fopen($file.'.lock', 'w')) { restore_error_handler(); - throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s.', $lastError)); + throw new RuntimeException('A temporary file could not be opened to write the process output: '.$lastError); } if (!flock($h, LOCK_EX | LOCK_NB)) { continue 2; diff --git a/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php b/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php index f79eed1961fd5..feee0fe856a6d 100644 --- a/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php +++ b/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php @@ -71,10 +71,10 @@ private function createEncoder(array $config) $config = $this->getEncoderConfigFromAlgorithm($config); } if (!isset($config['class'])) { - throw new \InvalidArgumentException(sprintf('"class" must be set in %s.', json_encode($config))); + throw new \InvalidArgumentException('"class" must be set in '.json_encode($config)); } if (!isset($config['arguments'])) { - throw new \InvalidArgumentException(sprintf('"arguments" must be set in %s.', json_encode($config))); + throw new \InvalidArgumentException('"arguments" must be set in '.json_encode($config)); } $reflection = new \ReflectionClass($config['class']); diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php index d7551183ddff2..dc932222e953e 100644 --- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php @@ -431,7 +431,7 @@ private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null) return $this->appendNode($parentNode, $data, 'data'); } - throw new NotEncodableValueException(sprintf('An unexpected value could not be serialized: %s.', !\is_resource($data) ? var_export($data, true) : sprintf('%s resource', get_resource_type($data)))); + throw new NotEncodableValueException('An unexpected value could not be serialized: '.(!\is_resource($data) ? var_export($data, true) : sprintf('%s resource', get_resource_type($data)))); } /** diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index 1c125bc935df4..87b32a6ca5ba4 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -164,7 +164,7 @@ public function normalize($data, $format = null, array $context = []) throw new NotNormalizableValueException(sprintf('Could not normalize object of type "%s", no supporting normalizer found.', \get_class($data))); } - throw new NotNormalizableValueException(sprintf('An unexpected value could not be normalized: %s.', !\is_resource($data) ? var_export($data, true) : sprintf('%s resource', get_resource_type($data)))); + throw new NotNormalizableValueException('An unexpected value could not be normalized: '.(!\is_resource($data) ? var_export($data, true) : sprintf('%s resource', get_resource_type($data)))); } /** diff --git a/src/Symfony/Component/Translation/Loader/JsonFileLoader.php b/src/Symfony/Component/Translation/Loader/JsonFileLoader.php index 5ab2e989e7a76..a02732e8d8f40 100644 --- a/src/Symfony/Component/Translation/Loader/JsonFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/JsonFileLoader.php @@ -30,7 +30,7 @@ protected function loadResource($resource) $messages = json_decode($data, true); if (0 < $errorCode = json_last_error()) { - throw new InvalidResourceException(sprintf('Error parsing JSON - %s.', $this->getJSONErrorMessage($errorCode))); + throw new InvalidResourceException('Error parsing JSON: '.$this->getJSONErrorMessage($errorCode)); } } diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php index b5333f1e4e36b..d09f434985107 100644 --- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php @@ -53,7 +53,7 @@ private function extract($resource, MessageCatalogue $catalogue, $domain) try { $dom = XmlUtils::loadFile($resource); } catch (\InvalidArgumentException $e) { - throw new InvalidResourceException(sprintf('Unable to load "%s": %s.', $resource, $e->getMessage()), $e->getCode(), $e); + throw new InvalidResourceException(sprintf('Unable to load "%s": '.$e->getMessage(), $resource), $e->getCode(), $e); } $xliffVersion = $this->getVersionNumber($dom); @@ -194,7 +194,7 @@ private function validateSchema($file, \DOMDocument $dom, $schema) if (!@$dom->schemaValidateSource($schema)) { libxml_disable_entity_loader($disableEntities); - throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: %s.', $file, implode("\n", $this->getXmlErrors($internalErrors)))); + throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: '.implode("\n", $this->getXmlErrors($internalErrors)), $file)); } libxml_disable_entity_loader($disableEntities); diff --git a/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php b/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php index c0840845480dd..10db1586155f6 100644 --- a/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php +++ b/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php @@ -55,7 +55,7 @@ public function validate($value, Constraint $constraint) try { $comparedValue = $this->getPropertyAccessor()->getValue($object, $path); } catch (NoSuchPropertyException $e) { - throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: %s.', $path, \get_class($constraint), $e->getMessage()), 0, $e); + throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: '.$e->getMessage(), $path, \get_class($constraint)), 0, $e); } } else { $comparedValue = $constraint->value; diff --git a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php index 84f2c3295ceae..3accd2f9d6158 100644 --- a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php @@ -40,7 +40,7 @@ public function validate($object, Constraint $constraint) if (isset($method[0]) && \is_object($method[0])) { $method[0] = \get_class($method[0]); } - throw new ConstraintDefinitionException(sprintf('%s targeted by Callback constraint is not a valid callable.', json_encode($method))); + throw new ConstraintDefinitionException(json_encode($method).' targeted by Callback constraint is not a valid callable.'); } \call_user_func($method, $object, $this->context, $constraint->payload); From 7d2cab1644cde5429dfb56ca0d91800b7e6876e8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 12 Apr 2020 18:10:21 +0200 Subject: [PATCH 50/89] Tweak the code to avoid fabbot false positives --- src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php | 2 +- src/Symfony/Component/Form/ResolvedFormType.php | 2 +- src/Symfony/Component/HttpClient/HttpClientTrait.php | 4 ++-- src/Symfony/Component/HttpClient/Response/ResponseTrait.php | 4 ++-- .../Component/HttpKernel/Controller/ControllerResolver.php | 6 +++--- src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php | 4 ++-- src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php | 6 +++--- .../Mailer/Bridge/Amazon/Transport/SesApiTransport.php | 2 +- .../Mailer/Bridge/Amazon/Transport/SesHttpTransport.php | 2 +- .../Bridge/Mailchimp/Transport/MandrillApiTransport.php | 2 +- .../Bridge/Mailchimp/Transport/MandrillHttpTransport.php | 2 +- .../Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php | 4 ++-- .../Bridge/Mailgun/Transport/MailgunHttpTransport.php | 4 ++-- .../Bridge/Postmark/Transport/PostmarkApiTransport.php | 2 +- .../Bridge/Sendgrid/Transport/SendgridApiTransport.php | 2 +- .../Component/Mailer/Transport/AbstractApiTransport.php | 2 +- .../Mailer/Transport/Smtp/Stream/ProcessStream.php | 2 +- .../Component/Mailer/Transport/Smtp/Stream/SocketStream.php | 2 +- .../Component/Messenger/Transport/RedisExt/Connection.php | 4 ++-- .../Messenger/Transport/Serialization/Serializer.php | 4 ++-- src/Symfony/Component/Process/Process.php | 2 +- .../Serializer/Normalizer/AbstractObjectNormalizer.php | 2 +- .../Component/Translation/Formatter/IntlFormatter.php | 4 ++-- .../Component/Translation/Loader/XliffFileLoader.php | 2 +- .../Component/Validator/Constraints/BicValidator.php | 2 +- .../Component/Validator/Constraints/RangeValidator.php | 2 +- src/Symfony/Component/VarDumper/Server/DumpServer.php | 2 +- 27 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php index 60e7341db9e2c..eb1a4dc257677 100644 --- a/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php +++ b/src/Symfony/Bridge/Monolog/Command/ServerLogCommand.php @@ -102,7 +102,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } if (!$socket = stream_socket_server($host, $errno, $errstr)) { - throw new RuntimeException(sprintf('Server start failed on "%s": %s %s.', $host, $errstr, $errno)); + throw new RuntimeException(sprintf('Server start failed on "%s": '.$errstr.' '.$errno, $host)); } foreach ($this->getLogs($socket) as $clientId => $message) { diff --git a/src/Symfony/Component/Form/ResolvedFormType.php b/src/Symfony/Component/Form/ResolvedFormType.php index 02a06c85e1161..fdffc946a5eeb 100644 --- a/src/Symfony/Component/Form/ResolvedFormType.php +++ b/src/Symfony/Component/Form/ResolvedFormType.php @@ -96,7 +96,7 @@ public function createBuilder(FormFactoryInterface $factory, $name, array $optio try { $options = $this->getOptionsResolver()->resolve($options); } catch (ExceptionInterface $e) { - throw new $e(sprintf('An error has occurred resolving the options of the form "%s": %s.', \get_class($this->getInnerType()), $e->getMessage()), $e->getCode(), $e); + throw new $e(sprintf('An error has occurred resolving the options of the form "%s": '.$e->getMessage(), \get_class($this->getInnerType())), $e->getCode(), $e); } // Should be decoupled from the specific option at some point diff --git a/src/Symfony/Component/HttpClient/HttpClientTrait.php b/src/Symfony/Component/HttpClient/HttpClientTrait.php index e150e56a0c9c0..51856da9bfef4 100644 --- a/src/Symfony/Component/HttpClient/HttpClientTrait.php +++ b/src/Symfony/Component/HttpClient/HttpClientTrait.php @@ -343,11 +343,11 @@ private static function jsonEncode($value, int $flags = null, int $maxDepth = 51 try { $value = json_encode($value, $flags | (\PHP_VERSION_ID >= 70300 ? JSON_THROW_ON_ERROR : 0), $maxDepth); } catch (\JsonException $e) { - throw new InvalidArgumentException(sprintf('Invalid value for "json" option: %s.', $e->getMessage())); + throw new InvalidArgumentException('Invalid value for "json" option: '.$e->getMessage()); } if (\PHP_VERSION_ID < 70300 && JSON_ERROR_NONE !== json_last_error() && (false === $value || !($flags & JSON_PARTIAL_OUTPUT_ON_ERROR))) { - throw new InvalidArgumentException(sprintf('Invalid value for "json" option: %s.', json_last_error_msg())); + throw new InvalidArgumentException('Invalid value for "json" option: '.json_last_error_msg()); } return $value; diff --git a/src/Symfony/Component/HttpClient/Response/ResponseTrait.php b/src/Symfony/Component/HttpClient/Response/ResponseTrait.php index f49ca68338408..de4d7598b923e 100644 --- a/src/Symfony/Component/HttpClient/Response/ResponseTrait.php +++ b/src/Symfony/Component/HttpClient/Response/ResponseTrait.php @@ -153,11 +153,11 @@ public function toArray(bool $throw = true): array try { $content = json_decode($content, true, 512, JSON_BIGINT_AS_STRING | (\PHP_VERSION_ID >= 70300 ? JSON_THROW_ON_ERROR : 0)); } catch (\JsonException $e) { - throw new JsonException(sprintf('%s for "%s".', $e->getMessage(), $this->getInfo('url')), $e->getCode()); + throw new JsonException(sprintf($e->getMessage().' for "%s".', $this->getInfo('url')), $e->getCode()); } if (\PHP_VERSION_ID < 70300 && JSON_ERROR_NONE !== json_last_error()) { - throw new JsonException(sprintf('%s for "%s".', json_last_error_msg(), $this->getInfo('url')), json_last_error()); + throw new JsonException(sprintf(json_last_error_msg().' for "%s".', $this->getInfo('url')), json_last_error()); } if (!\is_array($content)) { diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php index 16a4a4a2e4260..b3e21e5f26c21 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -64,7 +64,7 @@ public function getController(Request $request) } if (!\is_callable($controller)) { - throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s.', $request->getPathInfo(), $this->getControllerError($controller))); + throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: '.$this->getControllerError($controller), $request->getPathInfo())); } return $controller; @@ -72,7 +72,7 @@ public function getController(Request $request) if (\is_object($controller)) { if (!\is_callable($controller)) { - throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s.', $request->getPathInfo(), $this->getControllerError($controller))); + throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: '.$this->getControllerError($controller), $request->getPathInfo())); } return $controller; @@ -89,7 +89,7 @@ public function getController(Request $request) } if (!\is_callable($callable)) { - throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s.', $request->getPathInfo(), $this->getControllerError($callable))); + throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: '.$this->getControllerError($callable), $request->getPathInfo())); } return $callable; diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php index 336edbab58562..5531a7c435321 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/Collection.php @@ -53,7 +53,7 @@ public function count() foreach ($searches as $search) { $searchCount = ldap_count_entries($con, $search); if (false === $searchCount) { - throw new LdapException(sprintf('Error while retrieving entry count: %s.', ldap_error($con))); + throw new LdapException('Error while retrieving entry count: '.ldap_error($con)); } $count += $searchCount; } @@ -76,7 +76,7 @@ public function getIterator() $current = ldap_first_entry($con, $search); if (false === $current) { - throw new LdapException(sprintf('Could not rewind entries array: %s.', ldap_error($con))); + throw new LdapException('Could not rewind entries array: '.ldap_error($con)); } yield $this->getSingleEntry($con, $current); diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php index 38a4f3a7c24e9..c08e2c1550303 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php @@ -79,7 +79,7 @@ public function addAttributeValues(Entry $entry, string $attribute, array $value $con = $this->getConnectionResource(); if (!@ldap_mod_add($con, $entry->getDn(), [$attribute => $values])) { - throw new LdapException(sprintf('Could not add values to entry "%s", attribute %s: %s.', $entry->getDn(), $attribute, ldap_error($con))); + throw new LdapException(sprintf('Could not add values to entry "%s", attribute %s: '.ldap_error($con), $entry->getDn(), $attribute)); } } @@ -94,7 +94,7 @@ public function removeAttributeValues(Entry $entry, string $attribute, array $va $con = $this->getConnectionResource(); if (!@ldap_mod_del($con, $entry->getDn(), [$attribute => $values])) { - throw new LdapException(sprintf('Could not remove values from entry "%s", attribute %s: %s.', $entry->getDn(), $attribute, ldap_error($con))); + throw new LdapException(sprintf('Could not remove values from entry "%s", attribute %s: '.ldap_error($con), $entry->getDn(), $attribute)); } } @@ -122,7 +122,7 @@ public function move(Entry $entry, string $newParent) $rdn = $this->parseRdnFromEntry($entry); // deleteOldRdn does not matter here, since the Rdn will not be changing in the move. if (!@ldap_rename($con, $entry->getDn(), $rdn, $newParent, true)) { - throw new LdapException(sprintf('Could not move entry "%s" to "%s": %s.', $entry->getDn(), $newParent, ldap_error($con))); + throw new LdapException(sprintf('Could not move entry "%s" to "%s": '.ldap_error($con), $entry->getDn(), $newParent)); } } diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php index c9cd0ad8cc6f6..95cbdbfd987b7 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php @@ -65,7 +65,7 @@ protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $e $result = new \SimpleXMLElement($response->getContent(false)); if (200 !== $response->getStatusCode()) { - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result->Error->Message, $result->Error->Code), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.$result->Error->Message.' (code %d).', $result->Error->Code), $response); } $property = $payload['Action'].'Result'; diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesHttpTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesHttpTransport.php index 9cedbdf4c7f7c..f11e970f23cf5 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesHttpTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesHttpTransport.php @@ -65,7 +65,7 @@ protected function doSendHttp(SentMessage $message): ResponseInterface $result = new \SimpleXMLElement($response->getContent(false)); if (200 !== $response->getStatusCode()) { - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result->Error->Message, $result->Error->Code), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.$result->Error->Message.' (code %d).', $result->Error->Code), $response); } $message->setMessageId($result->SendRawEmailResult->MessageId); diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php index 9b7c181b2943d..6ea7eae4d1eed 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php @@ -51,7 +51,7 @@ protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $e $result = $response->toArray(false); if (200 !== $response->getStatusCode()) { if ('error' === ($result['status'] ?? false)) { - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result['message'], $result['code']), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.$result['message'].' (code %d).', $result['code']), $response); } throw new HttpTransportException(sprintf('Unable to send an email (code %d).', $result['code']), $response); diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php index 92f90b8563fa5..d2058799ec957 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php @@ -58,7 +58,7 @@ protected function doSendHttp(SentMessage $message): ResponseInterface $result = $response->toArray(false); if (200 !== $response->getStatusCode()) { if ('error' === ($result['status'] ?? false)) { - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result['message'], $result['code']), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.$result['message'].' (code %d).', $result['code']), $response); } throw new HttpTransportException(sprintf('Unable to send an email (code %d).', $result['code']), $response); diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php index c8ed383fcc66b..2b6075c723eed 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php @@ -65,10 +65,10 @@ protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $e $result = $response->toArray(false); if (200 !== $response->getStatusCode()) { if ('application/json' === $response->getHeaders(false)['content-type'][0]) { - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result['message'], $response->getStatusCode()), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.$result['message'].' (code %d).', $response->getStatusCode()), $response); } - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $response->getContent(false), $response->getStatusCode()), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.$response->getContent(false).' (code %d).', $response->getStatusCode()), $response); } $sentMessage->setMessageId($result['id']); diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunHttpTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunHttpTransport.php index 3ed6f73369fc8..72fbaac1e77e3 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunHttpTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunHttpTransport.php @@ -67,10 +67,10 @@ protected function doSendHttp(SentMessage $message): ResponseInterface $result = $response->toArray(false); if (200 !== $response->getStatusCode()) { if ('application/json' === $response->getHeaders(false)['content-type'][0]) { - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result['message'], $response->getStatusCode()), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.$result['message'].' (code %d).', $response->getStatusCode()), $response); } - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $response->getContent(false), $response->getStatusCode()), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.$response->getContent(false).' (code %d).', $response->getStatusCode()), $response); } $message->setMessageId($result['id']); diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php index 352b2eded1568..a7c185264097f 100644 --- a/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php @@ -54,7 +54,7 @@ protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $e $result = $response->toArray(false); if (200 !== $response->getStatusCode()) { - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result['Message'], $result['ErrorCode']), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.$result['Message'].' (code %d).', $result['ErrorCode']), $response); } $sentMessage->setMessageId($result['MessageID']); diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php index 550fd4bf331a5..aee333ddb16cf 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php @@ -53,7 +53,7 @@ protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $e if (202 !== $response->getStatusCode()) { $errors = $response->toArray(false); - throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', implode('; ', array_column($errors['errors'], 'message')), $response->getStatusCode()), $response); + throw new HttpTransportException(sprintf('Unable to send an email: '.implode('; ', array_column($errors['errors'], 'message')).' (code %d).', $response->getStatusCode()), $response); } $sentMessage->setMessageId($response->getHeaders(false)['x-message-id'][0]); diff --git a/src/Symfony/Component/Mailer/Transport/AbstractApiTransport.php b/src/Symfony/Component/Mailer/Transport/AbstractApiTransport.php index e1a2d5eee2ac8..37b92a699bbc6 100644 --- a/src/Symfony/Component/Mailer/Transport/AbstractApiTransport.php +++ b/src/Symfony/Component/Mailer/Transport/AbstractApiTransport.php @@ -31,7 +31,7 @@ protected function doSendHttp(SentMessage $message): ResponseInterface try { $email = MessageConverter::toEmail($message->getOriginalMessage()); } catch (\Exception $e) { - throw new RuntimeException(sprintf('Unable to send message with the "%s" transport: %s.', __CLASS__, $e->getMessage()), 0, $e); + throw new RuntimeException(sprintf('Unable to send message with the "%s" transport: '.$e->getMessage(), __CLASS__), 0, $e); } return $this->doSendApi($message, $email, $message->getEnvelope()); diff --git a/src/Symfony/Component/Mailer/Transport/Smtp/Stream/ProcessStream.php b/src/Symfony/Component/Mailer/Transport/Smtp/Stream/ProcessStream.php index 455f739a15faa..a8a8603807d27 100644 --- a/src/Symfony/Component/Mailer/Transport/Smtp/Stream/ProcessStream.php +++ b/src/Symfony/Component/Mailer/Transport/Smtp/Stream/ProcessStream.php @@ -41,7 +41,7 @@ public function initialize(): void $this->stream = proc_open($this->command, $descriptorSpec, $pipes); stream_set_blocking($pipes[2], false); if ($err = stream_get_contents($pipes[2])) { - throw new TransportException(sprintf('Process could not be started: %s.', $err)); + throw new TransportException('Process could not be started: '.$err); } $this->in = &$pipes[0]; $this->out = &$pipes[1]; diff --git a/src/Symfony/Component/Mailer/Transport/Smtp/Stream/SocketStream.php b/src/Symfony/Component/Mailer/Transport/Smtp/Stream/SocketStream.php index debeeb4b01cb9..5aa86296cbc03 100644 --- a/src/Symfony/Component/Mailer/Transport/Smtp/Stream/SocketStream.php +++ b/src/Symfony/Component/Mailer/Transport/Smtp/Stream/SocketStream.php @@ -135,7 +135,7 @@ public function initialize(): void $streamContext = stream_context_create($options); set_error_handler(function ($type, $msg) { - throw new TransportException(sprintf('Connection could not be established with host "%s": %s.', $this->url, $msg)); + throw new TransportException(sprintf('Connection could not be established with host "%s": '.$msg, $this->url)); }); try { $this->stream = stream_socket_client($this->url, $errno, $errstr, $this->timeout, STREAM_CLIENT_CONNECT, $streamContext); diff --git a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php index 504fe0a10fa98..856c5f73787e2 100644 --- a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php @@ -56,11 +56,11 @@ public function __construct(array $configuration, array $connectionCredentials = $this->connection->setOption(\Redis::OPT_SERIALIZER, $redisOptions['serializer'] ?? \Redis::SERIALIZER_PHP); if (isset($connectionCredentials['auth']) && !$this->connection->auth($connectionCredentials['auth'])) { - throw new InvalidArgumentException(sprintf('Redis connection failed: %s.', $redis->getLastError())); + throw new InvalidArgumentException('Redis connection failed: '.$redis->getLastError()); } if (($dbIndex = $configuration['dbindex'] ?? self::DEFAULT_OPTIONS['dbindex']) && !$this->connection->select($dbIndex)) { - throw new InvalidArgumentException(sprintf('Redis connection failed: %s.', $redis->getLastError())); + throw new InvalidArgumentException('Redis connection failed: '.$redis->getLastError()); } $this->stream = $configuration['stream'] ?? self::DEFAULT_OPTIONS['stream']; diff --git a/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php b/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php index 8d466500fd9a6..22d48f7e23012 100644 --- a/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php +++ b/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php @@ -80,7 +80,7 @@ public function decode(array $encodedEnvelope): Envelope try { $message = $this->serializer->deserialize($encodedEnvelope['body'], $encodedEnvelope['headers']['type'], $this->format, $context); } catch (ExceptionInterface $e) { - throw new MessageDecodingFailedException(sprintf('Could not decode message: %s.', $e->getMessage()), $e->getCode(), $e); + throw new MessageDecodingFailedException('Could not decode message: '.$e->getMessage(), $e->getCode(), $e); } return new Envelope($message, $stamps); @@ -118,7 +118,7 @@ private function decodeStamps(array $encodedEnvelope): array try { $stamps[] = $this->serializer->deserialize($value, substr($name, \strlen(self::STAMP_HEADER_PREFIX)).'[]', $this->format, $this->context); } catch (ExceptionInterface $e) { - throw new MessageDecodingFailedException(sprintf('Could not decode stamp: %s.', $e->getMessage()), $e->getCode(), $e); + throw new MessageDecodingFailedException('Could not decode stamp: '.$e->getMessage(), $e->getCode(), $e); } } if ($stamps) { diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index db4c2919dff59..81568a1c03409 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -1648,7 +1648,7 @@ private function replacePlaceholders(string $commandline, array $env) { return preg_replace_callback('/"\$\{:([_a-zA-Z]++[_a-zA-Z0-9]*+)\}"/', function ($matches) use ($commandline, $env) { if (!isset($env[$matches[1]]) || false === $env[$matches[1]]) { - throw new InvalidArgumentException(sprintf('Command line is missing a value for parameter "%s": %s.', $matches[1], $commandline)); + throw new InvalidArgumentException(sprintf('Command line is missing a value for parameter "%s": '.$commandline, $matches[1])); } return $this->escapeArgument($env[$matches[1]]); diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index c012c8d1a6c47..4eb8468360435 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -359,7 +359,7 @@ public function denormalize($data, $type, $format = null, array $context = []) try { $this->setAttributeValue($object, $attribute, $value, $format, $context); } catch (InvalidArgumentException $e) { - throw new NotNormalizableValueException(sprintf('Failed to denormalize attribute "%s" value for class "%s": %s.', $attribute, $type, $e->getMessage()), $e->getCode(), $e); + throw new NotNormalizableValueException(sprintf('Failed to denormalize attribute "%s" value for class "%s": '.$e->getMessage(), $attribute, $type), $e->getCode(), $e); } } diff --git a/src/Symfony/Component/Translation/Formatter/IntlFormatter.php b/src/Symfony/Component/Translation/Formatter/IntlFormatter.php index ad4a45b95b5c0..9101a63aa2ee9 100644 --- a/src/Symfony/Component/Translation/Formatter/IntlFormatter.php +++ b/src/Symfony/Component/Translation/Formatter/IntlFormatter.php @@ -40,7 +40,7 @@ public function formatIntl(string $message, string $locale, array $parameters = try { $this->cache[$locale][$message] = $formatter = new \MessageFormatter($locale, $message); } catch (\IntlException $e) { - throw new InvalidArgumentException(sprintf('Invalid message format (error #%d): %s.', intl_get_error_code(), intl_get_error_message()), 0, $e); + throw new InvalidArgumentException(sprintf('Invalid message format (error #%d): '.intl_get_error_message(), intl_get_error_code()), 0, $e); } } @@ -52,7 +52,7 @@ public function formatIntl(string $message, string $locale, array $parameters = } if (false === $message = $formatter->format($parameters)) { - throw new InvalidArgumentException(sprintf('Unable to format message (error #%s): %s.', $formatter->getErrorCode(), $formatter->getErrorMessage())); + throw new InvalidArgumentException(sprintf('Unable to format message (error #%s): '.$formatter->getErrorMessage(), $formatter->getErrorCode())); } return $message; diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php index 566159fa8eebc..d7741a071007c 100644 --- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php @@ -58,7 +58,7 @@ private function extract($resource, MessageCatalogue $catalogue, string $domain) $xliffVersion = XliffUtils::getVersionNumber($dom); if ($errors = XliffUtils::validateSchema($dom)) { - throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: %s.', $resource, XliffUtils::getErrorsAsString($errors))); + throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: '.XliffUtils::getErrorsAsString($errors), $resource)); } if ('1.2' === $xliffVersion) { diff --git a/src/Symfony/Component/Validator/Constraints/BicValidator.php b/src/Symfony/Component/Validator/Constraints/BicValidator.php index c49986561e980..651d76dcf1c00 100644 --- a/src/Symfony/Component/Validator/Constraints/BicValidator.php +++ b/src/Symfony/Component/Validator/Constraints/BicValidator.php @@ -138,7 +138,7 @@ public function validate($value, Constraint $constraint) try { $iban = $this->getPropertyAccessor()->getValue($object, $path); } catch (NoSuchPropertyException $e) { - throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: %s.', $path, \get_class($constraint), $e->getMessage()), 0, $e); + throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: '.$e->getMessage(), $path, \get_class($constraint)), 0, $e); } } if (!$iban) { diff --git a/src/Symfony/Component/Validator/Constraints/RangeValidator.php b/src/Symfony/Component/Validator/Constraints/RangeValidator.php index 9b7c40ce5ae9a..3cfd43f998676 100644 --- a/src/Symfony/Component/Validator/Constraints/RangeValidator.php +++ b/src/Symfony/Component/Validator/Constraints/RangeValidator.php @@ -157,7 +157,7 @@ private function getLimit($propertyPath, $default, Constraint $constraint) try { return $this->getPropertyAccessor()->getValue($object, $propertyPath); } catch (NoSuchPropertyException $e) { - throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: %s.', $propertyPath, \get_class($constraint), $e->getMessage()), 0, $e); + throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: '.$e->getMessage(), $propertyPath, \get_class($constraint)), 0, $e); } } diff --git a/src/Symfony/Component/VarDumper/Server/DumpServer.php b/src/Symfony/Component/VarDumper/Server/DumpServer.php index ad920bd4fca67..46546d1675998 100644 --- a/src/Symfony/Component/VarDumper/Server/DumpServer.php +++ b/src/Symfony/Component/VarDumper/Server/DumpServer.php @@ -41,7 +41,7 @@ public function __construct(string $host, LoggerInterface $logger = null) public function start(): void { if (!$this->socket = stream_socket_server($this->host, $errno, $errstr)) { - throw new \RuntimeException(sprintf('Server start failed on "%s": %s %s.', $this->host, $errstr, $errno)); + throw new \RuntimeException(sprintf('Server start failed on "%s": '.$errstr.' '.$errno, $this->host)); } } From e4d4428bb3084c7a60fae6d1850983492b80e165 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 12 Apr 2020 18:39:58 +0200 Subject: [PATCH 51/89] Fix code --- .../Bridge/Doctrine/Security/User/EntityUserProvider.php | 2 +- .../Tests/Controller/ContainerControllerResolverTest.php | 2 +- .../Tests/Controller/ControllerResolverTest.php | 8 ++++---- .../Translation/Tests/Loader/JsonFileLoaderTest.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index 818c44a3da2af..180341012fd1c 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -92,7 +92,7 @@ public function refreshUser(UserInterface $user) $refreshedUser = $repository->find($id); if (null === $refreshedUser) { - throw new UsernameNotFoundException('User with id '.json_encode($id).' not found.')); + throw new UsernameNotFoundException('User with id '.json_encode($id).' not found.'); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ContainerControllerResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ContainerControllerResolverTest.php index b03169de93400..4c4abf5aa4d42 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ContainerControllerResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ContainerControllerResolverTest.php @@ -248,7 +248,7 @@ public function getUndefinedControllers() [ 'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::bar', \InvalidArgumentException::class, - '/.?[cC]ontroller(.*?) for URI "\/" is not callable\.( Expected method(.*) Available methods)?/', + '/.?[cC]ontroller(.*?) for URI "\/" is not callable:( Expected method(.*) Available methods)?/', ], ]; } diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php index e34427a32e5c4..d2684791fecb4 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php @@ -131,10 +131,10 @@ public function getUndefinedControllers() ['foo', 'InvalidArgumentException', 'Unable to find controller "foo".'], ['oof::bar', 'InvalidArgumentException', 'Class "oof" does not exist.'], ['stdClass', 'InvalidArgumentException', 'Unable to find controller "stdClass".'], - ['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::staticsAction', 'InvalidArgumentException', 'The controller for URI "/" is not callable. Expected method "staticsAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest", did you mean "staticAction"?'], - ['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::privateAction', 'InvalidArgumentException', 'The controller for URI "/" is not callable. Method "privateAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest" should be public and non-abstract'], - ['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::protectedAction', 'InvalidArgumentException', 'The controller for URI "/" is not callable. Method "protectedAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest" should be public and non-abstract'], - ['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::undefinedAction', 'InvalidArgumentException', 'The controller for URI "/" is not callable. Expected method "undefinedAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest". Available methods: "publicAction", "staticAction"'], + ['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::staticsAction', 'InvalidArgumentException', 'The controller for URI "/" is not callable: Expected method "staticsAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest", did you mean "staticAction"?'], + ['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::privateAction', 'InvalidArgumentException', 'The controller for URI "/" is not callable: Method "privateAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest" should be public and non-abstract'], + ['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::protectedAction', 'InvalidArgumentException', 'The controller for URI "/" is not callable: Method "protectedAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest" should be public and non-abstract'], + ['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::undefinedAction', 'InvalidArgumentException', 'The controller for URI "/" is not callable: Expected method "undefinedAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest". Available methods: "publicAction", "staticAction"'], ]; } diff --git a/src/Symfony/Component/Translation/Tests/Loader/JsonFileLoaderTest.php b/src/Symfony/Component/Translation/Tests/Loader/JsonFileLoaderTest.php index d264bb16b29d9..c5a9ca64d4d7f 100644 --- a/src/Symfony/Component/Translation/Tests/Loader/JsonFileLoaderTest.php +++ b/src/Symfony/Component/Translation/Tests/Loader/JsonFileLoaderTest.php @@ -50,7 +50,7 @@ public function testLoadNonExistingResource() public function testParseException() { $this->expectException('Symfony\Component\Translation\Exception\InvalidResourceException'); - $this->expectExceptionMessage('Error parsing JSON - Syntax error, malformed JSON'); + $this->expectExceptionMessage('Error parsing JSON: Syntax error, malformed JSON'); $loader = new JsonFileLoader(); $resource = __DIR__.'/../fixtures/malformed.json'; $loader->load($resource, 'en', 'domain1'); From 311a944a0809b6a02e89815a76e8ef13a8f6c9ab Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 12 Apr 2020 18:54:01 +0200 Subject: [PATCH 52/89] Fix test --- src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php index d130803d44cae..b63e0c224fde8 100644 --- a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php +++ b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php @@ -24,7 +24,7 @@ class LockHandlerTest extends TestCase public function testConstructWhenRepositoryDoesNotExist() { $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); - $this->expectExceptionMessage('Failed to create "/a/b/c/d/e": mkdir(): Permission denied.'); + $this->expectExceptionMessage('Failed to create "/a/b/c/d/e": mkdir(): Permission denied'); if (!getenv('USER') || 'root' === getenv('USER')) { $this->markTestSkipped('This test will fail if run under superuser'); } From 093a71500ad8afbaab8e59b60a9ec5ebd4bea192 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 12 Apr 2020 18:56:09 +0200 Subject: [PATCH 53/89] Fix tests --- src/Symfony/Component/Process/Tests/ProcessTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index ecbf271aeb8cf..1a7b4c7961cf8 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -1488,7 +1488,7 @@ public function testPreparedCommandWithQuoteInIt() public function testPreparedCommandWithMissingValue() { $this->expectException('Symfony\Component\Process\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Command line is missing a value for parameter "abc": echo "${:abc}".'); + $this->expectExceptionMessage('Command line is missing a value for parameter "abc": echo "${:abc}"'); $p = Process::fromShellCommandline('echo "${:abc}"'); $p->run(null, ['bcd' => 'BCD']); } @@ -1496,7 +1496,7 @@ public function testPreparedCommandWithMissingValue() public function testPreparedCommandWithNoValues() { $this->expectException('Symfony\Component\Process\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Command line is missing a value for parameter "abc": echo "${:abc}".'); + $this->expectExceptionMessage('Command line is missing a value for parameter "abc": echo "${:abc}"'); $p = Process::fromShellCommandline('echo "${:abc}"'); $p->run(null, []); } From 4f6381323c9e83cdaf091eb202324035531b32ce Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Mon, 13 Apr 2020 00:11:50 +0200 Subject: [PATCH 54/89] Fixed false-negative fabbot error on exception message --- .../SecurityBundle/DependencyInjection/SecurityExtension.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index b9258a93f8d1b..42114072d27fc 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -558,7 +558,7 @@ private function createEncoder(array $config) $config['algorithm'] = 'native'; $config['native_algorithm'] = PASSWORD_ARGON2I; } else { - throw new InvalidConfigurationException(sprintf('Algorithm "argon2i" is not available. Either use %s"auto" or upgrade to PHP 7.2+ instead.', \defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13') ? '"argon2id", ' : '')); + throw new InvalidConfigurationException(sprintf('Algorithm "argon2i" is not available. Either use "%s" or upgrade to PHP 7.2+ instead.', \defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13') ? 'argon2id", "auto' : 'auto')); } return $this->createEncoder($config); @@ -571,7 +571,7 @@ private function createEncoder(array $config) $config['algorithm'] = 'native'; $config['native_algorithm'] = PASSWORD_ARGON2ID; } else { - throw new InvalidConfigurationException(sprintf('Algorithm "argon2id" is not available. Either use %s"auto", upgrade to PHP 7.3+ or use libsodium 1.0.15+ instead.', \defined('PASSWORD_ARGON2I') || $hasSodium ? '"argon2i", ' : '')); + throw new InvalidConfigurationException(sprintf('Algorithm "argon2id" is not available. Either use "%s", upgrade to PHP 7.3+ or use libsodium 1.0.15+ instead.', \defined('PASSWORD_ARGON2I') || $hasSodium ? 'argon2i", "auto' : 'auto')); } return $this->createEncoder($config); From 51e0d3792caa7c53860b2c54bf2c949ddae8c7cd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 13 Apr 2020 11:14:49 +0200 Subject: [PATCH 55/89] [DI] fix loading defaults when using the PHP-DSL --- .../Compiler/CacheCollectorPass.php | 4 +++- .../Loader/Configurator/PrototypeConfigurator.php | 7 +++++-- .../Loader/Configurator/ServicesConfigurator.php | 12 +++++++++--- .../Tests/Fixtures/config/basic.expected.yml | 1 - .../Tests/Fixtures/config/child.expected.yml | 5 +---- .../Tests/Fixtures/config/defaults.expected.yml | 1 - .../Tests/Fixtures/config/instanceof.expected.yml | 2 -- .../Tests/Fixtures/config/php7.expected.yml | 1 - .../Tests/Fixtures/config/prototype.expected.yml | 2 -- .../Tests/Fixtures/config/services9.php | 3 +-- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CacheCollectorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CacheCollectorPass.php index 7f8494d98e0ad..6bb614489eeb8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CacheCollectorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CacheCollectorPass.php @@ -44,7 +44,9 @@ public function process(ContainerBuilder $container) $recorder = new Definition(is_subclass_of($definition->getClass(), TagAwareAdapterInterface::class) ? TraceableTagAwareAdapter::class : TraceableAdapter::class); $recorder->setTags($definition->getTags()); - $recorder->setPublic($definition->isPublic()); + if (!$definition->isPublic() || !$definition->isPrivate()) { + $recorder->setPublic($definition->isPublic()); + } $recorder->setArguments([new Reference($innerId = $id.'.recorder_inner')]); $definition->setTags([]); diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/PrototypeConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/PrototypeConfigurator.php index d80c8b13389f2..3d844798d431a 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/PrototypeConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/PrototypeConfigurator.php @@ -45,10 +45,13 @@ class PrototypeConfigurator extends AbstractServiceConfigurator public function __construct(ServicesConfigurator $parent, PhpFileLoader $loader, Definition $defaults, $namespace, $resource, $allowParent) { $definition = new Definition(); - $definition->setPublic($defaults->isPublic()); + if (!$defaults->isPublic() || !$defaults->isPrivate()) { + $definition->setPublic($defaults->isPublic()); + } $definition->setAutowired($defaults->isAutowired()); $definition->setAutoconfigured($defaults->isAutoconfigured()); - $definition->setBindings($defaults->getBindings()); + // deep clone, to avoid multiple process of the same instance in the passes + $definition->setBindings(unserialize(serialize($defaults->getBindings()))); $definition->setChanges([]); $this->loader = $loader; diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/ServicesConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/ServicesConfigurator.php index e7677eb5e6dc6..b6ccbc63b4e81 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/ServicesConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/ServicesConfigurator.php @@ -79,10 +79,13 @@ final public function set($id, $class = null) $allowParent = !$defaults->getChanges() && empty($this->instanceof); $definition = new Definition(); - $definition->setPublic($defaults->isPublic()); + if (!$defaults->isPublic() || !$defaults->isPrivate()) { + $definition->setPublic($defaults->isPublic() && !$defaults->isPrivate()); + } $definition->setAutowired($defaults->isAutowired()); $definition->setAutoconfigured($defaults->isAutoconfigured()); - $definition->setBindings($defaults->getBindings()); + // deep clone, to avoid multiple process of the same instance in the passes + $definition->setBindings(unserialize(serialize($defaults->getBindings()))); $definition->setChanges([]); $configurator = new ServiceConfigurator($this->container, $this->instanceof, $allowParent, $this, $definition, $id, $defaults->getTags()); @@ -101,7 +104,10 @@ final public function set($id, $class = null) final public function alias($id, $referencedId) { $ref = static::processValue($referencedId, true); - $alias = new Alias((string) $ref, $this->defaults->isPublic()); + $alias = new Alias((string) $ref); + if (!$this->defaults->isPublic() || !$this->defaults->isPrivate()) { + $alias->setPublic($this->defaults->isPublic()); + } $this->container->setAlias($id, $alias); return new AliasConfigurator($this, $alias); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/basic.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/basic.expected.yml index 1137961ade139..39a3b631b97eb 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/basic.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/basic.expected.yml @@ -6,5 +6,4 @@ services: synthetic: true App\BarService: class: App\BarService - public: true arguments: [!service { class: FooClass }] diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml index aaab7131c4697..f60d6bb5b72e2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml @@ -6,10 +6,7 @@ services: synthetic: true foo: class: Class2 - public: true file: file.php lazy: true arguments: [!service { class: Class1, public: false }] - bar: - alias: foo - public: true + bar: '@foo' diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.expected.yml index a534f7267a078..3f01b1099f73a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/defaults.expected.yml @@ -6,7 +6,6 @@ services: synthetic: true App\BarService: class: App\BarService - public: true arguments: [!service { class: FooClass }] Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/instanceof.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/instanceof.expected.yml index b12a304221dd8..1238a7bda4fbf 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/instanceof.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/instanceof.expected.yml @@ -6,7 +6,6 @@ services: synthetic: true Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo - public: true tags: - { name: tag, k: v } lazy: true @@ -18,4 +17,3 @@ services: configurator: c foo: class: App\FooService - public: true diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/php7.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/php7.expected.yml index 7c5b714ffbd7e..7cec320b2eec7 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/php7.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/php7.expected.yml @@ -13,7 +13,6 @@ services: arguments: ['@bar'] bar: class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo - public: true calls: - [setFoo, { }] diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml index ebfe087d779cf..24a79401531c9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml @@ -6,7 +6,6 @@ services: synthetic: true Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo - public: true tags: - { name: foo } - { name: baz } @@ -15,7 +14,6 @@ services: factory: f Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar: class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar - public: true tags: - { name: foo } - { name: baz } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php index d9373a2a6f9e6..ef390937687b1 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php @@ -14,7 +14,7 @@ $p->set('foo_class', FooClass::class) ->set('foo', 'bar'); - $s = $c->services(); + $s = $c->services()->defaults()->public(); $s->set('foo') ->args(['foo', ref('foo.baz'), ['%foo%' => 'foo is %foo%', 'foobar' => '%foo%'], true, ref('service_container')]) ->class(FooClass::class) @@ -120,7 +120,6 @@ ->tag('foo'); $s->set('tagged_iterator', 'Bar') - ->public() ->args([tagged('foo')]); $s->alias('alias_for_foo', 'foo')->private()->public(); From b3333e552dc221600dc0a44ecd49b3d2c8b4b639 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 14 Apr 2020 10:30:58 +0200 Subject: [PATCH 56/89] [DI] fix typo --- .../Component/DependencyInjection/Loader/YamlFileLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index ca510e7ad38eb..b35952e4522fb 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -763,7 +763,7 @@ private function resolveServices($value, string $file, bool $isParameter = false if (\is_array($argument) && isset($argument['tag']) && $argument['tag']) { if ($diff = array_diff(array_keys($argument), ['tag', 'index_by', 'default_index_method', 'default_priority_method'])) { - throw new InvalidArgumentException(sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "tag", "index_by", "default_index_method", and "default_priority_method".', $value->getTag(), implode('"", "', $diff))); + throw new InvalidArgumentException(sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "tag", "index_by", "default_index_method", and "default_priority_method".', $value->getTag(), implode('", "', $diff))); } $argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator, $argument['default_priority_method'] ?? null); From 55664c5a17ecdb5d291df21a10a9b87675130bb5 Mon Sep 17 00:00:00 2001 From: Giso Stallenberg Date: Tue, 14 Apr 2020 11:11:09 +0200 Subject: [PATCH 57/89] Remove return type for Twig function workflow_metadata() Technically it is allowed to have metadata other than string, even data that does not cast to string, like an array. Also see https://github.com/symfony/symfony/issues/36391 --- src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php b/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php index d5a2e759aa34a..b5f3badea88fd 100644 --- a/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php @@ -117,7 +117,7 @@ public function getMarkedPlaces($subject, $placesNameOnly = true, $name = null) * Use a string (the place name) to get place metadata * Use a Transition instance to get transition metadata */ - public function getMetadata($subject, string $key, $metadataSubject = null, string $name = null): ?string + public function getMetadata($subject, string $key, $metadataSubject = null, string $name = null) { return $this ->workflowRegistry From 68b3b898d8da284e585c005f772fab9326b2f576 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 14 Apr 2020 12:42:16 +0200 Subject: [PATCH 58/89] [Messenger] Make sure redis transports are initialized correctly --- .../Messenger/Tests/Transport/RedisExt/ConnectionTest.php | 8 ++++++++ .../Component/Messenger/Transport/RedisExt/Connection.php | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php index 0be034dd3de3d..e278cfb0ddf0e 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php @@ -62,6 +62,14 @@ public function testFromDsnWithOptions() ); } + public function testFromDsnWithOptionsAndTrailingSlash() + { + $this->assertEquals( + Connection::fromDsn('redis://localhost/', ['stream' => 'queue', 'group' => 'group1', 'consumer' => 'consumer1', 'auto_setup' => false, 'serializer' => 2]), + Connection::fromDsn('redis://localhost/queue/group1/consumer1?serializer=2&auto_setup=0') + ); + } + public function testFromDsnWithQueryOptions() { $this->assertEquals( diff --git a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php index 856c5f73787e2..bb818512c2fda 100644 --- a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php @@ -63,6 +63,12 @@ public function __construct(array $configuration, array $connectionCredentials = throw new InvalidArgumentException('Redis connection failed: '.$redis->getLastError()); } + foreach (['stream', 'group', 'consumer'] as $key) { + if (isset($configuration[$key]) && '' === $configuration[$key]) { + throw new InvalidArgumentException(sprintf('"%s" should be configured, got an empty string.', $key)); + } + } + $this->stream = $configuration['stream'] ?? self::DEFAULT_OPTIONS['stream']; $this->group = $configuration['group'] ?? self::DEFAULT_OPTIONS['group']; $this->consumer = $configuration['consumer'] ?? self::DEFAULT_OPTIONS['consumer']; @@ -77,7 +83,7 @@ public static function fromDsn(string $dsn, array $redisOptions = [], \Redis $re throw new InvalidArgumentException(sprintf('The given Redis DSN "%s" is invalid.', $dsn)); } - $pathParts = explode('/', $parsedUrl['path'] ?? ''); + $pathParts = explode('/', rtrim($parsedUrl['path'] ?? '', '/')); $stream = $pathParts[1] ?? $redisOptions['stream'] ?? null; $group = $pathParts[2] ?? $redisOptions['group'] ?? null; From cfd5a29eafeb1ccc1ed951d7e0b7ab412eac04f5 Mon Sep 17 00:00:00 2001 From: soyuka Date: Thu, 9 Apr 2020 19:51:19 +0200 Subject: [PATCH 59/89] [PhpUnitBridge] add PolyfillTestCaseTrait::expectExceptionMessageMatches to provide FC with recent phpunit versions --- composer.json | 2 +- .../PhpUnit/Legacy/PolyfillTestCaseTrait.php | 10 ++++++++ .../Tests/Loader/FilesystemLoaderTest.php | 2 +- .../Tests/Resource/DirectoryResourceTest.php | 2 +- .../Tests/Resource/FileResourceTest.php | 2 +- .../ResolveChildDefinitionsPassTest.php | 2 +- .../ResolveInstanceofConditionalsPassTest.php | 2 +- .../ValidateEnvPlaceholdersPassTest.php | 2 +- .../Tests/Loader/FileLoaderTest.php | 2 +- .../Tests/Loader/XmlFileLoaderTest.php | 2 +- .../Tests/Loader/YamlFileLoaderTest.php | 24 +++++++++---------- .../Tests/ExpressionLanguageTest.php | 2 +- .../Extension/Core/Type/CheckboxTypeTest.php | 2 +- .../Smtp/Stream/SocketStreamTest.php | 4 ++-- .../Serialization/PhpSerializerTest.php | 4 ++-- .../Component/Process/Tests/ProcessTest.php | 2 +- .../Tests/PropertyAccessorCollectionTest.php | 4 ++-- .../Tests/PropertyAccessorTest.php | 10 ++++---- .../Tests/Loader/XmlFileLoaderTest.php | 4 ++-- .../Tests/Loader/YamlFileLoaderTest.php | 4 ++-- .../GuardAuthenticationProviderTest.php | 2 +- .../VarExporter/Tests/InstantiatorTest.php | 2 +- .../VarExporter/Tests/VarExporterTest.php | 2 +- .../Component/Yaml/Tests/InlineTest.php | 6 ++--- .../Component/Yaml/Tests/ParserTest.php | 8 +++---- 25 files changed, 59 insertions(+), 49 deletions(-) diff --git a/composer.json b/composer.json index 2b089d9d48fba..ae4553377613e 100644 --- a/composer.json +++ b/composer.json @@ -118,7 +118,7 @@ "psr/http-client": "^1.0", "psr/simple-cache": "^1.0", "egulias/email-validator": "~1.2,>=1.2.8|~2.0", - "symfony/phpunit-bridge": "^3.4.31|^4.3.4|~5.0", + "symfony/phpunit-bridge": "^5.0.8", "symfony/security-acl": "~2.8|~3.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0", "twig/cssinliner-extra": "^2.12", diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/PolyfillTestCaseTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/PolyfillTestCaseTrait.php index ebb9db2c94acb..cb3fbf44903bd 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/PolyfillTestCaseTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/PolyfillTestCaseTrait.php @@ -95,6 +95,16 @@ public function expectExceptionMessage($message) $property->setValue($this, $message); } + /** + * @param string $messageRegExp + * + * @return void + */ + public function expectExceptionMessageMatches($messageRegExp) + { + $this->expectExceptionMessageRegExp($messageRegExp); + } + /** * @param string $messageRegExp * diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php index 2d678fa8f3502..b760cca92627e 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/Loader/FilesystemLoaderTest.php @@ -101,7 +101,7 @@ public function testTwigErrorIfLocatorReturnsFalse() public function testTwigErrorIfTemplateDoesNotExist() { $this->expectException('Twig\Error\LoaderError'); - $this->expectExceptionMessageRegExp('/Unable to find template "name\.format\.engine" \(looked into: .*Tests.Loader.\.\..DependencyInjection.Fixtures.templates\)/'); + $this->expectExceptionMessageMatches('/Unable to find template "name\.format\.engine" \(looked into: .*Tests.Loader.\.\..DependencyInjection.Fixtures.templates\)/'); $parser = $this->getMockBuilder('Symfony\Component\Templating\TemplateNameParserInterface')->getMock(); $locator = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock(); diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index aaadc8c4f430b..fbaed34a212a6 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -66,7 +66,7 @@ public function testGetPattern() public function testResourceDoesNotExist() { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The directory ".*" does not exist./'); + $this->expectExceptionMessageMatches('/The directory ".*" does not exist./'); new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999)); } diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php index f85a820fb95bb..e3a45566c2617 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -56,7 +56,7 @@ public function testToString() public function testResourceDoesNotExist() { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The file ".*" does not exist./'); + $this->expectExceptionMessageMatches('/The file ".*" does not exist./'); new FileResource('/____foo/foobar'.mt_rand(1, 999999)); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php index dfe37445d4e88..dd58f90990310 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php @@ -400,7 +400,7 @@ protected function process(ContainerBuilder $container) public function testProcessDetectsChildDefinitionIndirectCircularReference() { $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); - $this->expectExceptionMessageRegExp('/^Circular reference detected for service "c", path: "c -> b -> a -> c"./'); + $this->expectExceptionMessageMatches('/^Circular reference detected for service "c", path: "c -> b -> a -> c"./'); $container = new ContainerBuilder(); $container->register('a'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php index ebd8f3df1024a..3acfbed776f1f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php @@ -233,7 +233,7 @@ public function testProcessForAutoconfiguredCalls() public function testProcessThrowsExceptionForArguments() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/Autoconfigured instanceof for type "PHPUnit[\\\\_]Framework[\\\\_]TestCase" defines arguments but these are not supported and should be removed\./'); + $this->expectExceptionMessageMatches('/Autoconfigured instanceof for type "PHPUnit[\\\\_]Framework[\\\\_]TestCase" defines arguments but these are not supported and should be removed\./'); $container = new ContainerBuilder(); $container->registerForAutoconfiguration(parent::class) ->addArgument('bar'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php index 457c7a7e5cf03..8b50689dc0f5b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php @@ -105,7 +105,7 @@ public function testInvalidEnvInConfig() public function testNulledEnvInConfig() { $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); - $this->expectExceptionMessageRegexp('/^Invalid type for path "env_extension\.int_node"\. Expected "?int"?, but got (NULL|"null")\.$/'); + $this->expectExceptionMessageMatches('/^Invalid type for path "env_extension\.int_node"\. Expected "?int"?, but got (NULL|"null")\.$/'); $container = new ContainerBuilder(); $container->setParameter('env(NULLED)', null); $container->registerExtension(new EnvExtension()); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php index 57ea37e6f4964..61971f408c477 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php @@ -216,7 +216,7 @@ public function testMissingParentClass() public function testRegisterClassesWithBadPrefix() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/Expected to find class "Symfony\\\Component\\\DependencyInjection\\\Tests\\\Fixtures\\\Prototype\\\Bar" in file ".+" while importing services from resource "Prototype\/Sub\/\*", but it was not found\! Check the namespace prefix used with the resource/'); + $this->expectExceptionMessageMatches('/Expected to find class "Symfony\\\Component\\\DependencyInjection\\\Tests\\\Fixtures\\\Prototype\\\Bar" in file ".+" while importing services from resource "Prototype\/Sub\/\*", but it was not found\! Check the namespace prefix used with the resource/'); $container = new ContainerBuilder(); $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 14ba4c7f6e567..e5868edad2cea 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -378,7 +378,7 @@ public function testParseTagsWithoutNameThrowsException() public function testParseTagWithEmptyNameThrowsException() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The tag name for service ".+" in .* must be a non-empty string/'); + $this->expectExceptionMessageMatches('/The tag name for service ".+" in .* must be a non-empty string/'); $container = new ContainerBuilder(); $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); $loader->load('tag_with_empty_name.xml'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index f40fc22cc3452..aa348baa356c6 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -50,7 +50,7 @@ public static function setUpBeforeClass(): void public function testLoadUnExistFile() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The file ".+" does not exist./'); + $this->expectExceptionMessageMatches('/The file ".+" does not exist./'); $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini')); $r = new \ReflectionObject($loader); $m = $r->getMethod('loadFile'); @@ -62,7 +62,7 @@ public function testLoadUnExistFile() public function testLoadInvalidYamlFile() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The file ".+" does not contain valid YAML./'); + $this->expectExceptionMessageMatches('/The file ".+" does not contain valid YAML./'); $path = self::$fixturesPath.'/ini'; $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator($path)); $r = new \ReflectionObject($loader); @@ -384,7 +384,7 @@ public function testLoadYamlOnlyWithKeys() public function testTagWithEmptyNameThrowsException() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The tag name for service ".+" in .+ must be a non-empty string/'); + $this->expectExceptionMessageMatches('/The tag name for service ".+" in .+ must be a non-empty string/'); $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('tag_name_empty_string.yml'); } @@ -392,7 +392,7 @@ public function testTagWithEmptyNameThrowsException() public function testTagWithNonStringNameThrowsException() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The tag name for service ".+" in .+ must be a non-empty string/'); + $this->expectExceptionMessageMatches('/The tag name for service ".+" in .+ must be a non-empty string/'); $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('tag_name_no_string.yml'); } @@ -493,7 +493,7 @@ public function testPrototypeWithNamespace() public function testPrototypeWithNamespaceAndNoResource() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/A "resource" attribute must be set when the "namespace" attribute is set for service ".+" in .+/'); + $this->expectExceptionMessageMatches('/A "resource" attribute must be set when the "namespace" attribute is set for service ".+" in .+/'); $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('services_prototype_namespace_without_resource.yml'); @@ -621,7 +621,7 @@ public function testDecoratedServicesWithWrongOnInvalidSyntaxThrowsException() public function testInvalidTagsWithDefaults() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/Parameter "tags" must be an array for service "Foo\\\Bar" in ".+services31_invalid_tags\.yml"\. Check your YAML syntax./'); + $this->expectExceptionMessageMatches('/Parameter "tags" must be an array for service "Foo\\\Bar" in ".+services31_invalid_tags\.yml"\. Check your YAML syntax./'); $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('services31_invalid_tags.yml'); } @@ -711,7 +711,7 @@ public function testAnonymousServicesInInstanceof() public function testAnonymousServicesWithAliases() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/Creating an alias using the tag "!service" is not allowed in ".+anonymous_services_alias\.yml"\./'); + $this->expectExceptionMessageMatches('/Creating an alias using the tag "!service" is not allowed in ".+anonymous_services_alias\.yml"\./'); $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('anonymous_services_alias.yml'); @@ -720,7 +720,7 @@ public function testAnonymousServicesWithAliases() public function testAnonymousServicesInParameters() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/Using an anonymous service in a parameter is not allowed in ".+anonymous_services_in_parameters\.yml"\./'); + $this->expectExceptionMessageMatches('/Using an anonymous service in a parameter is not allowed in ".+anonymous_services_in_parameters\.yml"\./'); $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('anonymous_services_in_parameters.yml'); @@ -739,7 +739,7 @@ public function testAutoConfigureInstanceof() public function testEmptyDefaultsThrowsClearException() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/Service "_defaults" key must be an array, "NULL" given in ".+bad_empty_defaults\.yml"\./'); + $this->expectExceptionMessageMatches('/Service "_defaults" key must be an array, "NULL" given in ".+bad_empty_defaults\.yml"\./'); $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('bad_empty_defaults.yml'); @@ -748,7 +748,7 @@ public function testEmptyDefaultsThrowsClearException() public function testEmptyInstanceofThrowsClearException() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/Service "_instanceof" key must be an array, "NULL" given in ".+bad_empty_instanceof\.yml"\./'); + $this->expectExceptionMessageMatches('/Service "_instanceof" key must be an array, "NULL" given in ".+bad_empty_instanceof\.yml"\./'); $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('bad_empty_instanceof.yml'); @@ -757,7 +757,7 @@ public function testEmptyInstanceofThrowsClearException() public function testUnsupportedKeywordThrowsException() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/^The configuration key "private" is unsupported for definition "bar"/'); + $this->expectExceptionMessageMatches('/^The configuration key "private" is unsupported for definition "bar"/'); $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('bad_keyword.yml'); @@ -766,7 +766,7 @@ public function testUnsupportedKeywordThrowsException() public function testUnsupportedKeywordInServiceAliasThrowsException() { $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/^The configuration key "calls" is unsupported for the service "bar" which is defined as an alias/'); + $this->expectExceptionMessageMatches('/^The configuration key "calls" is unsupported for the service "bar" which is defined as an alias/'); $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); $loader->load('bad_alias.yml'); diff --git a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php index 9c7b30dc225d9..ed8b6852a5dbc 100644 --- a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php +++ b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php @@ -231,7 +231,7 @@ public function testRegisterAfterEval($registerCallback) public function testCallBadCallable() { $this->expectException('RuntimeException'); - $this->expectExceptionMessageRegExp('/Unable to call method "\w+" of object "\w+"./'); + $this->expectExceptionMessageMatches('/Unable to call method "\w+" of object "\w+"./'); $el = new ExpressionLanguage(); $el->evaluate('foo.myfunction()', ['foo' => new \stdClass()]); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php index 8391805b22666..e12347405dee9 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php @@ -197,7 +197,7 @@ public function provideCustomFalseValues() public function testDontAllowNonArrayFalseValues() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessageRegExp('/"false_values" with value "invalid" is expected to be of type "array"/'); + $this->expectExceptionMessageMatches('/"false_values" with value "invalid" is expected to be of type "array"/'); $this->factory->create(static::TESTED_TYPE, null, [ 'false_values' => 'invalid', ]); diff --git a/src/Symfony/Component/Mailer/Tests/Transport/Smtp/Stream/SocketStreamTest.php b/src/Symfony/Component/Mailer/Tests/Transport/Smtp/Stream/SocketStreamTest.php index d7912f9ccba2d..a67a1629d0169 100644 --- a/src/Symfony/Component/Mailer/Tests/Transport/Smtp/Stream/SocketStreamTest.php +++ b/src/Symfony/Component/Mailer/Tests/Transport/Smtp/Stream/SocketStreamTest.php @@ -19,7 +19,7 @@ class SocketStreamTest extends TestCase public function testSocketErrorNoConnection() { $this->expectException('Symfony\Component\Mailer\Exception\TransportException'); - $this->expectExceptionMessageRegExp('/Connection refused|unable to connect/'); + $this->expectExceptionMessageMatches('/Connection refused|unable to connect/'); $s = new SocketStream(); $s->setTimeout(0.1); $s->setPort(9999); @@ -29,7 +29,7 @@ public function testSocketErrorNoConnection() public function testSocketErrorBeforeConnectError() { $this->expectException('Symfony\Component\Mailer\Exception\TransportException'); - $this->expectExceptionMessageRegExp('/no valid certs found cafile stream|Unable to find the socket transport "ssl"/'); + $this->expectExceptionMessageMatches('/no valid certs found cafile stream|Unable to find the socket transport "ssl"/'); $s = new SocketStream(); $s->setStreamOptions([ 'ssl' => [ diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Serialization/PhpSerializerTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Serialization/PhpSerializerTest.php index 6439873fe94cc..5076577b023fc 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Serialization/PhpSerializerTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Serialization/PhpSerializerTest.php @@ -44,7 +44,7 @@ public function testDecodingFailsWithMissingBodyKey() public function testDecodingFailsWithBadFormat() { $this->expectException(MessageDecodingFailedException::class); - $this->expectExceptionMessageRegExp('/Could not decode/'); + $this->expectExceptionMessageMatches('/Could not decode/'); $serializer = new PhpSerializer(); @@ -56,7 +56,7 @@ public function testDecodingFailsWithBadFormat() public function testDecodingFailsWithBadClass() { $this->expectException(MessageDecodingFailedException::class); - $this->expectExceptionMessageRegExp('/class "ReceivedSt0mp" not found/'); + $this->expectExceptionMessageMatches('/class "ReceivedSt0mp" not found/'); $serializer = new PhpSerializer(); diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index ecbf271aeb8cf..4df824abc04dd 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -50,7 +50,7 @@ protected function tearDown(): void public function testInvalidCwd() { $this->expectException('Symfony\Component\Process\Exception\RuntimeException'); - $this->expectExceptionMessageRegExp('/The provided cwd ".*" does not exist\./'); + $this->expectExceptionMessageMatches('/The provided cwd ".*" does not exist\./'); try { // Check that it works fine if the CWD exists $cmd = new Process(['echo', 'test'], __DIR__); diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php index 09aebab87b135..94655b9762742 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php @@ -149,7 +149,7 @@ public function testSetValueCallsAdderAndRemoverForNestedCollections() public function testSetValueFailsIfNoAdderNorRemoverFound() { $this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException'); - $this->expectExceptionMessageRegExp('/Could not determine access type for property "axes" in class "Mock_PropertyAccessorCollectionTest_CarNoAdderAndRemover_[^"]*"./'); + $this->expectExceptionMessageMatches('/Could not determine access type for property "axes" in class "Mock_PropertyAccessorCollectionTest_CarNoAdderAndRemover_[^"]*"./'); $car = $this->getMockBuilder(__CLASS__.'_CarNoAdderAndRemover')->getMock(); $axesBefore = $this->getContainer([1 => 'second', 3 => 'fourth']); $axesAfter = $this->getContainer([0 => 'first', 1 => 'second', 2 => 'third']); @@ -188,7 +188,7 @@ public function testIsWritableReturnsFalseIfNoAdderNorRemoverExists() public function testSetValueFailsIfAdderAndRemoverExistButValueIsNotTraversable() { $this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException'); - $this->expectExceptionMessageRegExp('/Could not determine access type for property "axes" in class "Symfony\\\\Component\\\\PropertyAccess\\\\Tests\\\\PropertyAccessorCollectionTest_Car[^"]*": The property "axes" in class "Symfony\\\\Component\\\\PropertyAccess\\\\Tests\\\\PropertyAccessorCollectionTest_Car[^"]*" can be defined with the methods "addAxis\(\)", "removeAxis\(\)" but the new value must be an array or an instance of \\\\Traversable, "string" given./'); + $this->expectExceptionMessageMatches('/Could not determine access type for property "axes" in class "Symfony\\\\Component\\\\PropertyAccess\\\\Tests\\\\PropertyAccessorCollectionTest_Car[^"]*": The property "axes" in class "Symfony\\\\Component\\\\PropertyAccess\\\\Tests\\\\PropertyAccessorCollectionTest_Car[^"]*" can be defined with the methods "addAxis\(\)", "removeAxis\(\)" but the new value must be an array or an instance of \\\\Traversable, "string" given./'); $car = new PropertyAccessorCollectionTest_Car(); $this->propertyAccessor->setValue($car, 'axes', 'Not an array or Traversable'); diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index c42076ea06da8..eeabf7e9f8de1 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -768,7 +768,7 @@ public function testAdderAndRemoverArePreferredOverSetterForSameSingularAndPlura public function testAdderWithoutRemover() { $this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException'); - $this->expectExceptionMessageRegExp('/.*The add method "addFoo" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidMethods" was found, but the corresponding remove method "removeFoo" was not found\./'); + $this->expectExceptionMessageMatches('/.*The add method "addFoo" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidMethods" was found, but the corresponding remove method "removeFoo" was not found\./'); $object = new TestAdderRemoverInvalidMethods(); $this->propertyAccessor->setValue($object, 'foos', [1, 2]); } @@ -776,7 +776,7 @@ public function testAdderWithoutRemover() public function testRemoverWithoutAdder() { $this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException'); - $this->expectExceptionMessageRegExp('/.*The remove method "removeBar" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidMethods" was found, but the corresponding add method "addBar" was not found\./'); + $this->expectExceptionMessageMatches('/.*The remove method "removeBar" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidMethods" was found, but the corresponding add method "addBar" was not found\./'); $object = new TestAdderRemoverInvalidMethods(); $this->propertyAccessor->setValue($object, 'bars', [1, 2]); } @@ -784,7 +784,7 @@ public function testRemoverWithoutAdder() public function testAdderAndRemoveNeedsTheExactParametersDefined() { $this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException'); - $this->expectExceptionMessageRegExp('/.*The method "addFoo" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidArgumentLength" requires 0 arguments, but should accept only 1\. The method "removeFoo" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidArgumentLength" requires 2 arguments, but should accept only 1\./'); + $this->expectExceptionMessageMatches('/.*The method "addFoo" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidArgumentLength" requires 0 arguments, but should accept only 1\. The method "removeFoo" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidArgumentLength" requires 2 arguments, but should accept only 1\./'); $object = new TestAdderRemoverInvalidArgumentLength(); $this->propertyAccessor->setValue($object, 'foo', [1, 2]); } @@ -792,7 +792,7 @@ public function testAdderAndRemoveNeedsTheExactParametersDefined() public function testSetterNeedsTheExactParametersDefined() { $this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException'); - $this->expectExceptionMessageRegExp('/.*The method "setBar" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidArgumentLength" requires 2 arguments, but should accept only 1\./'); + $this->expectExceptionMessageMatches('/.*The method "setBar" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestAdderRemoverInvalidArgumentLength" requires 2 arguments, but should accept only 1\./'); $object = new TestAdderRemoverInvalidArgumentLength(); $this->propertyAccessor->setValue($object, 'bar', [1, 2]); } @@ -800,7 +800,7 @@ public function testSetterNeedsTheExactParametersDefined() public function testSetterNeedsPublicAccess() { $this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException'); - $this->expectExceptionMessageRegExp('/.*The method "setFoo" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestClassSetValue" was found but does not have public access./'); + $this->expectExceptionMessageMatches('/.*The method "setFoo" in class "Symfony\\\Component\\\PropertyAccess\\\Tests\\\Fixtures\\\TestClassSetValue" was found but does not have public access./'); $object = new TestClassSetValue(0); $this->propertyAccessor->setValue($object, 'foo', 1); } diff --git a/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php index 66d54fc985c4c..02e1e14d4aa97 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php @@ -439,7 +439,7 @@ public function testLoadRouteWithControllerSetInDefaults() public function testOverrideControllerInDefaults() { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for "app_blog"/'); + $this->expectExceptionMessageMatches('/The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for "app_blog"/'); $loader = new XmlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller'])); $loader->load('override_defaults.xml'); } @@ -471,7 +471,7 @@ public function provideFilesImportingRoutesWithControllers() public function testImportWithOverriddenController() { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for the "import" tag/'); + $this->expectExceptionMessageMatches('/The routing file "[^"]*" must not specify both the "controller" attribute and the defaults key "_controller" for the "import" tag/'); $loader = new XmlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller'])); $loader->load('import_override_defaults.xml'); } diff --git a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php index 52c21c287fcf6..3878663e6b01f 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php @@ -144,7 +144,7 @@ public function testLoadRouteWithControllerSetInDefaults() public function testOverrideControllerInDefaults() { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "app_blog"/'); + $this->expectExceptionMessageMatches('/The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "app_blog"/'); $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller'])); $loader->load('override_defaults.yml'); } @@ -176,7 +176,7 @@ public function provideFilesImportingRoutesWithControllers() public function testImportWithOverriddenController() { $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessageRegExp('/The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "_static"/'); + $this->expectExceptionMessageMatches('/The routing file "[^"]*" must not specify both the "controller" key and the defaults key "_controller" for "_static"/'); $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller'])); $loader->load('import_override_defaults.yml'); } diff --git a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php index 816bd097309e8..e00fb12dfb392 100644 --- a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php @@ -190,7 +190,7 @@ public function testSupportsChecksGuardAuthenticatorsTokenOrigin() public function testAuthenticateFailsOnNonOriginatingToken() { $this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationException'); - $this->expectExceptionMessageRegExp('/second_firewall_0/'); + $this->expectExceptionMessageMatches('/second_firewall_0/'); $authenticatorA = $this->getMockBuilder(AuthenticatorInterface::class)->getMock(); $authenticators = [$authenticatorA]; diff --git a/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php b/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php index 3da602383fc7c..6d0deb68dc9ac 100644 --- a/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php +++ b/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php @@ -29,7 +29,7 @@ public function testNotFoundClass() public function testFailingInstantiation(string $class) { $this->expectException('Symfony\Component\VarExporter\Exception\NotInstantiableTypeException'); - $this->expectExceptionMessageRegExp('/Type ".*" is not instantiable\./'); + $this->expectExceptionMessageMatches('/Type ".*" is not instantiable\./'); Instantiator::instantiate($class); } diff --git a/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php b/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php index ec4cb4896980d..5fc46644c976a 100644 --- a/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php +++ b/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php @@ -38,7 +38,7 @@ public function testPhpIncompleteClassesAreForbidden() public function testFailingSerialization($value) { $this->expectException('Symfony\Component\VarExporter\Exception\NotInstantiableTypeException'); - $this->expectExceptionMessageRegExp('/Type ".*" is not instantiable\./'); + $this->expectExceptionMessageMatches('/Type ".*" is not instantiable\./'); $expectedDump = $this->getDump($value); try { VarExporter::export($value); diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index fc3a1ede33d29..24c1b8a5de9b7 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -74,7 +74,7 @@ public function testParsePhpConstantThrowsExceptionWhenUndefined() public function testParsePhpConstantThrowsExceptionOnInvalidType() { $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); - $this->expectExceptionMessageRegExp('#The string "!php/const PHP_INT_MAX" could not be parsed as a constant.*#'); + $this->expectExceptionMessageMatches('#The string "!php/const PHP_INT_MAX" could not be parsed as a constant.*#'); Inline::parse('!php/const PHP_INT_MAX', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); } @@ -599,7 +599,7 @@ public function getBinaryData() public function testParseInvalidBinaryData($data, $expectedMessage) { $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); - $this->expectExceptionMessageRegExp($expectedMessage); + $this->expectExceptionMessageMatches($expectedMessage); Inline::parse($data); } @@ -787,7 +787,7 @@ public function phpConstTagWithEmptyValueProvider() public function testUnquotedExclamationMarkThrows(string $value) { $this->expectException(ParseException::class); - $this->expectExceptionMessageRegExp('/^Using the unquoted scalar value "!" is not supported\. You must quote it at line 1 \(near "/'); + $this->expectExceptionMessageMatches('/^Using the unquoted scalar value "!" is not supported\. You must quote it at line 1 \(near "/'); Inline::parse($value); } diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 4ed79466e6138..6caf8738855a0 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -602,7 +602,7 @@ public function testShortcutKeyUnindentedCollectionException() public function testMultipleDocumentsNotSupportedException() { $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); - $this->expectExceptionMessageRegExp('/^Multiple documents are not supported.+/'); + $this->expectExceptionMessageMatches('/^Multiple documents are not supported.+/'); Yaml::parse(<<<'EOL' # Ranking of 1998 home runs --- @@ -1348,7 +1348,7 @@ public function getBinaryData() public function testParseInvalidBinaryData($data, $expectedMessage) { $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); - $this->expectExceptionMessageRegExp($expectedMessage); + $this->expectExceptionMessageMatches($expectedMessage); $this->parser->parse($data); } @@ -2102,14 +2102,14 @@ public function testParseFile() public function testParsingNonExistentFilesThrowsException() { $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); - $this->expectExceptionMessageRegExp('#^File ".+/Fixtures/nonexistent.yml" does not exist\.$#'); + $this->expectExceptionMessageMatches('#^File ".+/Fixtures/nonexistent.yml" does not exist\.$#'); $this->parser->parseFile(__DIR__.'/Fixtures/nonexistent.yml'); } public function testParsingNotReadableFilesThrowsException() { $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); - $this->expectExceptionMessageRegExp('#^File ".+/Fixtures/not_readable.yml" cannot be read\.$#'); + $this->expectExceptionMessageMatches('#^File ".+/Fixtures/not_readable.yml" cannot be read\.$#'); if ('\\' === \DIRECTORY_SEPARATOR) { $this->markTestSkipped('chmod is not supported on Windows'); } From 15a8610c0c4aa69a13c6a3d25a604e27ed69abb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Wed, 15 Apr 2020 20:00:38 +0200 Subject: [PATCH 60/89] [Cache] Avoid memory leak in TraceableAdapter::reset() --- .../Component/Cache/Adapter/TraceableAdapter.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php index 4aed2d7181f83..cc855c132a83c 100644 --- a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php @@ -191,15 +191,11 @@ public function prune() */ public function reset() { - if (!$this->pool instanceof ResettableInterface) { - return; - } - $event = $this->start(__FUNCTION__); - try { + if ($this->pool instanceof ResettableInterface) { $this->pool->reset(); - } finally { - $event->end = microtime(true); } + + $this->clearCalls(); } public function getCalls() From e885860edc4a78f561dc546b6a8975575df5bf1c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 16 Apr 2020 16:21:43 +0200 Subject: [PATCH 61/89] Fix From/Sender handling in Emails --- .../Mailer/EventListener/EnvelopeListener.php | 8 ++++++ .../Mailer/Transport/AbstractTransport.php | 4 --- src/Symfony/Component/Mime/Message.php | 15 ++++++++--- .../Mime/Tests/Crypto/SMimeSignerTest.php | 4 ++- .../Component/Mime/Tests/EmailTest.php | 27 ++++++++++--------- .../Mime/Tests/MessageConverterTest.php | 2 +- .../Mime/Tests/Part/MessagePartTest.php | 2 +- 7 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/Symfony/Component/Mailer/EventListener/EnvelopeListener.php b/src/Symfony/Component/Mailer/EventListener/EnvelopeListener.php index cbb3922a19a46..570a9e39551f5 100644 --- a/src/Symfony/Component/Mailer/EventListener/EnvelopeListener.php +++ b/src/Symfony/Component/Mailer/EventListener/EnvelopeListener.php @@ -14,6 +14,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Mailer\Event\MessageEvent; use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Message; /** * Manipulates the Envelope of a Message. @@ -43,6 +44,13 @@ public function onMessage(MessageEvent $event): void { if ($this->sender) { $event->getEnvelope()->setSender($this->sender); + + $message = $event->getMessage(); + if ($message instanceof Message) { + if (!$message->getHeaders()->has('Sender') && !$message->getHeaders()->has('From')) { + $message->getHeaders()->addMailboxHeader('Sender', $this->sender->getAddress()); + } + } } if ($this->recipients) { diff --git a/src/Symfony/Component/Mailer/Transport/AbstractTransport.php b/src/Symfony/Component/Mailer/Transport/AbstractTransport.php index 1bc3fa12a5616..33f75fb3faa4f 100644 --- a/src/Symfony/Component/Mailer/Transport/AbstractTransport.php +++ b/src/Symfony/Component/Mailer/Transport/AbstractTransport.php @@ -63,10 +63,6 @@ public function send(RawMessage $message, Envelope $envelope = null): ?SentMessa $envelope = $event->getEnvelope(); } - if (!$envelope->getRecipients()) { - return null; - } - $message = new SentMessage($message, $envelope); $this->doSend($message); diff --git a/src/Symfony/Component/Mime/Message.php b/src/Symfony/Component/Mime/Message.php index 5b4e67f1dbc5b..94a49764e4912 100644 --- a/src/Symfony/Component/Mime/Message.php +++ b/src/Symfony/Component/Mime/Message.php @@ -74,7 +74,10 @@ public function getPreparedHeaders(): Headers $headers = clone $this->headers; if (!$headers->has('From')) { - throw new LogicException('An email must have a "From" header.'); + if (!$headers->has('Sender')) { + throw new LogicException('An email must have a "From" or a "Sender" header.'); + } + $headers->addMailboxListHeader('From', [$headers->get('Sender')->getAddress()]); } $headers->addTextHeader('MIME-Version', '1.0'); @@ -119,8 +122,12 @@ public function toIterable(): iterable public function ensureValidity() { - if (!$this->headers->has('From')) { - throw new LogicException('An email must have a "From" header.'); + if (!$this->headers->has('To')) { + throw new LogicException('An email must have a "To" header.'); + } + + if (!$this->headers->has('From') && !$this->headers->has('Sender')) { + throw new LogicException('An email must have a "From" or a "Sender" header.'); } parent::ensureValidity(); @@ -133,7 +140,7 @@ public function generateMessageId(): string } elseif ($this->headers->has('From')) { $sender = $this->headers->get('From')->getAddresses()[0]; } else { - throw new LogicException('An email must have a "From" or a "Sender" header to compute a Messsage ID.'); + throw new LogicException('An email must have a "From" or a "Sender" header.'); } return bin2hex(random_bytes(16)).strstr($sender->getAddress(), '@'); diff --git a/src/Symfony/Component/Mime/Tests/Crypto/SMimeSignerTest.php b/src/Symfony/Component/Mime/Tests/Crypto/SMimeSignerTest.php index 0a86c3c90e1e7..5522bc6f55cd7 100644 --- a/src/Symfony/Component/Mime/Tests/Crypto/SMimeSignerTest.php +++ b/src/Symfony/Component/Mime/Tests/Crypto/SMimeSignerTest.php @@ -99,6 +99,7 @@ public function testSignedMessageWithBcc() { $message = (new Email()) ->date(new \DateTime('2019-04-07 10:36:30', new \DateTimeZone('Europe/Paris'))) + ->to('fabien@symfony.com') ->addBcc('fabien@symfony.com', 's.stok@rollerscapes.net') ->subject('I am your sign of fear') ->from('noreply@example.com') @@ -115,8 +116,9 @@ public function testSignedMessageWithAttachments() $message = new Email((new Headers()) ->addDateHeader('Date', new \DateTime('2019-04-07 10:36:30', new \DateTimeZone('Europe/Paris'))) ->addMailboxListHeader('From', ['fabien@symfony.com']) + ->addMailboxListHeader('To', ['fabien@symfony.com']) ); - $message->html($content = 'html content '); + $message->html('html content '); $message->text('text content'); $message->attach(fopen(__DIR__.'/../Fixtures/mimetypes/test', 'r')); $message->attach(fopen(__DIR__.'/../Fixtures/mimetypes/test.gif', 'r'), 'test.gif'); diff --git a/src/Symfony/Component/Mime/Tests/EmailTest.php b/src/Symfony/Component/Mime/Tests/EmailTest.php index bfd30053af09e..230df0791e15b 100644 --- a/src/Symfony/Component/Mime/Tests/EmailTest.php +++ b/src/Symfony/Component/Mime/Tests/EmailTest.php @@ -251,62 +251,62 @@ public function testGenerateBody() $att = new DataPart($file = fopen(__DIR__.'/Fixtures/mimetypes/test', 'r')); $img = new DataPart($image = fopen(__DIR__.'/Fixtures/mimetypes/test.gif', 'r'), 'test.gif'); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->text('text content'); $this->assertEquals($text, $e->getBody()); $this->assertEquals('text content', $e->getTextBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->html('html content'); $this->assertEquals($html, $e->getBody()); $this->assertEquals('html content', $e->getHtmlBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->html('html content'); $e->text('text content'); $this->assertEquals(new AlternativePart($text, $html), $e->getBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->html('html content', 'iso-8859-1'); $e->text('text content', 'iso-8859-1'); $this->assertEquals('iso-8859-1', $e->getTextCharset()); $this->assertEquals('iso-8859-1', $e->getHtmlCharset()); $this->assertEquals(new AlternativePart(new TextPart('text content', 'iso-8859-1'), new TextPart('html content', 'iso-8859-1', 'html')), $e->getBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->attach($file); $e->text('text content'); $this->assertEquals(new MixedPart($text, $att), $e->getBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->attach($file); $e->html('html content'); $this->assertEquals(new MixedPart($html, $att), $e->getBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->attach($file); $this->assertEquals(new MixedPart($att), $e->getBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->html('html content'); $e->text('text content'); $e->attach($file); $this->assertEquals(new MixedPart(new AlternativePart($text, $html), $att), $e->getBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->html('html content'); $e->text('text content'); $e->attach($file); $e->attach($image, 'test.gif'); $this->assertEquals(new MixedPart(new AlternativePart($text, $html), $att, $img), $e->getBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->text('text content'); $e->attach($file); $e->attach($image, 'test.gif'); $this->assertEquals(new MixedPart($text, $att, $img), $e->getBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->html($content = 'html content '); $e->text('text content'); $e->attach($file); @@ -314,7 +314,7 @@ public function testGenerateBody() $fullhtml = new TextPart($content, 'utf-8', 'html'); $this->assertEquals(new MixedPart(new AlternativePart($text, $fullhtml), $att, $img), $e->getBody()); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->html($content = 'html content '); $e->text('text content'); $e->attach($file); @@ -334,7 +334,7 @@ public function testGenerateBody() fwrite($r, $content); rewind($r); - $e = (new Email())->from('me@example.com'); + $e = (new Email())->from('me@example.com')->to('you@example.com'); $e->html($r); // embedding the same image twice results in one image only in the email $e->embed($image, 'test.gif'); @@ -373,6 +373,7 @@ public function testSerialize() $e = new Email(); $e->from('fabien@symfony.com'); + $e->to('you@example.com'); $e->text($r); $e->html($r); $name = __DIR__.'/Fixtures/mimetypes/test'; diff --git a/src/Symfony/Component/Mime/Tests/MessageConverterTest.php b/src/Symfony/Component/Mime/Tests/MessageConverterTest.php index 6a78086246377..a0e71a08a9416 100644 --- a/src/Symfony/Component/Mime/Tests/MessageConverterTest.php +++ b/src/Symfony/Component/Mime/Tests/MessageConverterTest.php @@ -21,7 +21,7 @@ class MessageConverterTest extends TestCase public function testToEmail() { $file = file_get_contents(__DIR__.'/Fixtures/mimetypes/test.gif'); - $email = (new Email())->from('fabien@symfony.com'); + $email = (new Email())->from('fabien@symfony.com')->to('you@example.com'); $this->assertSame($email, MessageConverter::toEmail($email)); $this->assertConversion((clone $email)->text('text content')); diff --git a/src/Symfony/Component/Mime/Tests/Part/MessagePartTest.php b/src/Symfony/Component/Mime/Tests/Part/MessagePartTest.php index 21a4eb03b1292..2713d5bc079c7 100644 --- a/src/Symfony/Component/Mime/Tests/Part/MessagePartTest.php +++ b/src/Symfony/Component/Mime/Tests/Part/MessagePartTest.php @@ -22,7 +22,7 @@ class MessagePartTest extends TestCase { public function testConstructor() { - $p = new MessagePart((new Email())->from('fabien@symfony.com')->text('content')); + $p = new MessagePart((new Email())->from('fabien@symfony.com')->to('you@example.com')->text('content')); $this->assertStringContainsString('content', $p->getBody()); $this->assertStringContainsString('content', $p->bodyToString()); $this->assertStringContainsString('content', implode('', iterator_to_array($p->bodyToIterable()))); From 24150370c3cad7564bed19d112fb4c8dd281d32a Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Wed, 15 Apr 2020 11:19:47 +0200 Subject: [PATCH 62/89] [DependencyInjection][ServiceSubscriber] Support late aliases --- .../DependencyInjection/Dumper/PhpDumper.php | 6 ++++- .../RegisterServiceSubscribersPassTest.php | 3 +++ .../Tests/Dumper/PhpDumperTest.php | 17 +++++++++++++ .../Tests/Fixtures/TestServiceSubscriber.php | 1 + .../Fixtures/php/services_subscriber.php | 24 +++++++++++++++---- 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 982472f5adf07..4a84cd1a24f11 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1700,7 +1700,11 @@ private function dumpValue($value, bool $interpolate = true): string if (!$v) { continue; } - $definition = $this->container->findDefinition($id = (string) $v); + $id = (string) $v; + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + $definition = $this->container->getDefinition($id); $load = !($definition->hasErrors() && $e = $definition->getErrors()) ? $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) : reset($e); $serviceMap .= sprintf("\n %s => [%s, %s, %s, %s],", $this->export($k), diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterServiceSubscribersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterServiceSubscribersPassTest.php index 77b1969f60b1c..d8e7d62d478f4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterServiceSubscribersPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterServiceSubscribersPassTest.php @@ -88,6 +88,7 @@ public function testNoAttributes() CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), 'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')), 'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')), + 'late_alias' => new ServiceClosureArgument(new TypedReference(TestDefinition1::class, TestDefinition1::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'late_alias')), ]; $this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0)); @@ -118,6 +119,7 @@ public function testWithAttributes() CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), 'bar' => new ServiceClosureArgument(new TypedReference('bar', CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')), 'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')), + 'late_alias' => new ServiceClosureArgument(new TypedReference(TestDefinition1::class, TestDefinition1::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'late_alias')), ]; $this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0)); @@ -260,6 +262,7 @@ public function testBinding() CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), 'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')), 'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')), + 'late_alias' => new ServiceClosureArgument(new TypedReference(TestDefinition1::class, TestDefinition1::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'late_alias')), ]; $this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0)); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 60f1ab1d4f070..51a88705d6fe6 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -19,6 +19,8 @@ use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Argument\ServiceLocator as ArgumentServiceLocator; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface; use Symfony\Component\DependencyInjection\Definition; @@ -35,6 +37,7 @@ use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition; use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory; use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator; +use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1; use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber; use Symfony\Component\DependencyInjection\TypedReference; use Symfony\Component\DependencyInjection\Variable; @@ -906,6 +909,20 @@ public function testServiceSubscriber() $container->register(CustomDefinition::class, CustomDefinition::class) ->setPublic(false); + + $container->register(TestDefinition1::class, TestDefinition1::class)->setPublic(true); + + $container->addCompilerPass(new class() implements CompilerPassInterface { + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $container->setDefinition('late_alias', new Definition(TestDefinition1::class)); + $container->setAlias(TestDefinition1::class, 'late_alias'); + } + }, PassConfig::TYPE_AFTER_REMOVING); + $container->compile(); $dumper = new PhpDumper($container); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/TestServiceSubscriber.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/TestServiceSubscriber.php index 6876fc5cca53d..f4a4bdda6451e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/TestServiceSubscriber.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/TestServiceSubscriber.php @@ -22,6 +22,7 @@ public static function getSubscribedServices(): array '?'.CustomDefinition::class, 'bar' => CustomDefinition::class, 'baz' => '?'.CustomDefinition::class, + 'late_alias' => TestDefinition1::class, ]; } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php index e184fad7bdf0c..caec312fdda41 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php @@ -27,9 +27,11 @@ public function __construct() $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', ]; - - $this->aliases = []; } public function compile(): void @@ -45,11 +47,13 @@ public function isCompiled(): bool public function getRemovedIds(): array { return [ - '.service_locator.bPEFRiK' => true, - '.service_locator.bPEFRiK.foo_service' => true, + '.service_locator.CpwjbIa' => true, + '.service_locator.CpwjbIa.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, ]; } @@ -75,14 +79,26 @@ protected function getFooServiceService() '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. * From dfb61c204c3d2149e36bcce7a9aefd020ff2f0c2 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Fri, 3 Apr 2020 17:40:36 +0200 Subject: [PATCH 63/89] [Form] Fixed handling groups sequence validation --- .../Validator/Constraints/FormValidator.php | 79 ++++++++++++++----- .../Form/Resources/config/validation.xml | 2 +- .../Constraints/FormValidatorTest.php | 39 ++++++++- .../Type/FormTypeValidatorExtensionTest.php | 65 ++++++++++++++- .../Validator/ValidatorExtensionTest.php | 56 ++++++++++++- 5 files changed, 212 insertions(+), 29 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index 07ecabdad1346..14158f4c1cf74 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -24,6 +24,8 @@ */ class FormValidator extends ConstraintValidator { + private $resolvedGroups; + /** * {@inheritdoc} */ @@ -44,42 +46,68 @@ public function validate($form, Constraint $formConstraint) if ($form->isSubmitted() && $form->isSynchronized()) { // Validate the form data only if transformation succeeded - $groups = self::getValidationGroups($form); + $groups = $this->getValidationGroups($form); if (!$groups) { return; } $data = $form->getData(); - // Validate the data against its own constraints - if ($form->isRoot() && (\is_object($data) || \is_array($data))) { - if (($groups && \is_array($groups)) || ($groups instanceof GroupSequence && $groups->groups)) { - $validator->atPath('data')->validate($form->getData(), null, $groups); - } - } + $validateDataGraph = $form->isRoot() + && (\is_object($data) || \is_array($data)) + && (($groups && \is_array($groups)) || ($groups instanceof GroupSequence && $groups->groups)) + ; - // Validate the data against the constraints defined - // in the form + // Validate the data against the constraints defined in the form + /** @var Constraint[] $constraints */ $constraints = $config->getOption('constraints', []); if ($groups instanceof GroupSequence) { - $validator->atPath('data')->validate($form->getData(), $constraints, $groups); - // Otherwise validate a constraint only once for the first - // matching group - foreach ($groups as $group) { - if (\in_array($group, $formConstraint->groups)) { - $validator->atPath('data')->validate($form->getData(), $formConstraint, $group); - if (\count($this->context->getViolations()) > 0) { - break; + // Validate the data, the form AND nested fields in sequence + $violationsCount = $this->context->getViolations()->count(); + $fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s'; + $hasChildren = $form->count() > 0; + $this->resolvedGroups = $hasChildren ? new \SplObjectStorage() : null; + + foreach ($groups->groups as $group) { + if ($validateDataGraph) { + $validator->atPath('data')->validate($data, null, $group); + } + + if ($groupedConstraints = self::getConstraintsInGroups($constraints, $group)) { + $validator->atPath('data')->validate($data, $groupedConstraints, $group); + } + + foreach ($form->all() as $field) { + if ($field->isSubmitted()) { + // remember to validate this field is one group only + // otherwise resolving the groups would reuse the same + // sequence recursively, thus some fields could fail + // in different steps without breaking early enough + $this->resolvedGroups[$field] = (array) $group; + $validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $formConstraint); } } + + if ($violationsCount < $this->context->getViolations()->count()) { + break; + } + } + + if ($hasChildren) { + // destroy storage at the end of the sequence to avoid memory leaks + $this->resolvedGroups = null; } } else { + if ($validateDataGraph) { + $validator->atPath('data')->validate($data, null, $groups); + } + foreach ($constraints as $constraint) { // For the "Valid" constraint, validate the data in all groups if ($constraint instanceof Valid) { - $validator->atPath('data')->validate($form->getData(), $constraint, $groups); + $validator->atPath('data')->validate($data, $constraint, $groups); continue; } @@ -88,7 +116,7 @@ public function validate($form, Constraint $formConstraint) // matching group foreach ($groups as $group) { if (\in_array($group, $constraint->groups)) { - $validator->atPath('data')->validate($form->getData(), $constraint, $group); + $validator->atPath('data')->validate($data, $constraint, $group); // Prevent duplicate validation if (!$constraint instanceof Composite) { @@ -147,7 +175,7 @@ public function validate($form, Constraint $formConstraint) * * @return string|GroupSequence|(string|GroupSequence)[] The validation groups */ - private static function getValidationGroups(FormInterface $form) + private function getValidationGroups(FormInterface $form) { // Determine the clicked button of the complete form tree $clickedButton = null; @@ -171,6 +199,10 @@ private static function getValidationGroups(FormInterface $form) return self::resolveValidationGroups($groups, $form); } + if (isset($this->resolvedGroups[$form])) { + return $this->resolvedGroups[$form]; + } + $form = $form->getParent(); } while (null !== $form); @@ -197,4 +229,11 @@ private static function resolveValidationGroups($groups, FormInterface $form) return (array) $groups; } + + private static function getConstraintsInGroups($constraints, $group) + { + return array_filter($constraints, static function (Constraint $constraint) use ($group) { + return \in_array($group, $constraint->groups, true); + }); + } } diff --git a/src/Symfony/Component/Form/Resources/config/validation.xml b/src/Symfony/Component/Form/Resources/config/validation.xml index cbd586b915451..b2b935442d467 100644 --- a/src/Symfony/Component/Form/Resources/config/validation.xml +++ b/src/Symfony/Component/Form/Resources/config/validation.xml @@ -7,7 +7,7 @@ - + diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php index e19620e790f7c..5181e4122516e 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -401,8 +401,8 @@ public function testHandleGroupSequenceValidationGroups() $form = $this->getCompoundForm($object, $options); $form->submit([]); - $this->expectValidateAt(0, 'data', $object, new GroupSequence(['group1', 'group2'])); - $this->expectValidateAt(1, 'data', $object, new GroupSequence(['group1', 'group2'])); + $this->expectValidateAt(0, 'data', $object, 'group1'); + $this->expectValidateAt(1, 'data', $object, 'group2'); $this->validator->validate($form, new Form()); @@ -756,6 +756,39 @@ public function testCompositeConstraintValidatedInEachGroup() $this->assertSame('data[field2]', $context->getViolations()[1]->getPropertyPath()); } + public function testCompositeConstraintValidatedInSequence() + { + $form = $this->getCompoundForm([], [ + 'constraints' => [ + new Collection([ + 'field1' => new NotBlank([ + 'groups' => ['field1'], + ]), + 'field2' => new NotBlank([ + 'groups' => ['field2'], + ]), + ]), + ], + 'validation_groups' => new GroupSequence(['field1', 'field2']), + ]) + ->add($this->getForm('field1')) + ->add($this->getForm('field2')) + ; + + $form->submit([ + 'field1' => '', + 'field2' => '', + ]); + + $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + + $this->assertCount(1, $context->getViolations()); + $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); + $this->assertSame('data[field1]', $context->getViolations()[0]->getPropertyPath()); + } + protected function createValidator() { return new FormValidator(); @@ -784,7 +817,7 @@ private function getForm($name = 'name', $dataClass = null, array $options = []) private function getCompoundForm($data, array $options = []) { - return $this->getBuilder('name', \get_class($data), $options) + return $this->getBuilder('name', \is_object($data) ? \get_class($data) : null, $options) ->setData($data) ->setCompound(true) ->setDataMapper(new PropertyPathMapper()) diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php index 57f92b6574e3b..4c90cc6316db8 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php @@ -12,15 +12,19 @@ namespace Symfony\Component\Form\Tests\Extension\Validator\Type; use Symfony\Component\Form\Extension\Validator\ValidatorExtension; +use Symfony\Component\Form\Form; use Symfony\Component\Form\Forms; use Symfony\Component\Form\Test\Traits\ValidatorExtensionTrait; use Symfony\Component\Form\Tests\Extension\Core\Type\FormTypeTest; use Symfony\Component\Form\Tests\Extension\Core\Type\TextTypeTest; -use Symfony\Component\Validator\Constraints\Email; +use Symfony\Component\Form\Tests\Fixtures\Author; use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\Length; +use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\ConstraintViolationList; +use Symfony\Component\Validator\Mapping\ClassMetadata; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; use Symfony\Component\Validator\Validation; class FormTypeValidatorExtensionTest extends BaseValidatorExtensionTest @@ -64,14 +68,69 @@ public function testGroupSequenceWithConstraintsOption() ->add('field', TextTypeTest::TESTED_TYPE, [ 'constraints' => [ new Length(['min' => 10, 'groups' => ['First']]), - new Email(['groups' => ['Second']]), + new NotBlank(['groups' => ['Second']]), ], ]) ; $form->submit(['field' => 'wrong']); - $this->assertCount(1, $form->getErrors(true)); + $errors = $form->getErrors(true); + + $this->assertCount(1, $errors); + $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); + } + + public function testManyFieldsGroupSequenceWithConstraintsOption() + { + $formMetadata = new ClassMetadata(Form::class); + $authorMetadata = (new ClassMetadata(Author::class)) + ->addPropertyConstraint('firstName', new NotBlank(['groups' => 'Second'])) + ; + $metadataFactory = $this->createMock(MetadataFactoryInterface::class); + $metadataFactory->expects($this->any()) + ->method('getMetadataFor') + ->willReturnCallback(static function ($classOrObject) use ($formMetadata, $authorMetadata) { + if (Author::class === $classOrObject || $classOrObject instanceof Author) { + return $authorMetadata; + } + + if (Form::class === $classOrObject || $classOrObject instanceof Form) { + return $formMetadata; + } + + return new ClassMetadata(\is_string($classOrObject) ? $classOrObject : \get_class($classOrObject)); + }) + ; + + $validator = Validation::createValidatorBuilder() + ->setMetadataFactory($metadataFactory) + ->getValidator() + ; + $form = Forms::createFormFactoryBuilder() + ->addExtension(new ValidatorExtension($validator)) + ->getFormFactory() + ->create(FormTypeTest::TESTED_TYPE, new Author(), (['validation_groups' => new GroupSequence(['First', 'Second'])])) + ->add('firstName', TextTypeTest::TESTED_TYPE) + ->add('lastName', TextTypeTest::TESTED_TYPE, [ + 'constraints' => [ + new Length(['min' => 10, 'groups' => ['First']]), + ], + ]) + ->add('australian', TextTypeTest::TESTED_TYPE, [ + 'constraints' => [ + new NotBlank(['groups' => ['Second']]), + ], + ]) + ; + + $form->submit(['firstName' => '', 'lastName' => 'wrong_1', 'australian' => '']); + + $errors = $form->getErrors(true); + + $this->assertCount(1, $errors); + $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); + $this->assertSame('children[lastName].data', $errors[0]->getCause()->getPropertyPath()); } protected function createForm(array $options = []) diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php index 136086a5e5ba8..cb9b93abdbf61 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php @@ -13,6 +13,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\FormType; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Validator\Constraints\Form as FormConstraint; use Symfony\Component\Form\Extension\Validator\ValidatorExtension; use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser; @@ -20,6 +22,8 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormFactoryBuilder; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Mapping\CascadingStrategy; use Symfony\Component\Validator\Mapping\ClassMetadata; @@ -49,6 +53,8 @@ public function test2Dot5ValidationApi() $this->assertCount(1, $metadata->getConstraints()); $this->assertInstanceOf(FormConstraint::class, $metadata->getConstraints()[0]); + $this->assertSame(CascadingStrategy::NONE, $metadata->cascadingStrategy); + $this->assertSame(TraversalStrategy::IMPLICIT, $metadata->traversalStrategy); $this->assertSame(CascadingStrategy::CASCADE, $metadata->getPropertyMetadata('children')[0]->cascadingStrategy); $this->assertSame(TraversalStrategy::IMPLICIT, $metadata->getPropertyMetadata('children')[0]->traversalStrategy); } @@ -86,7 +92,53 @@ public function testFieldConstraintsInvalidateFormIfFieldIsSubmitted() $this->assertFalse($form->get('baz')->isValid()); } - private function createForm($type) + public function testFieldsValidateInSequence() + { + $form = $this->createForm(FormType::class, null, [ + 'validation_groups' => new GroupSequence(['group1', 'group2']), + ]) + ->add('foo', TextType::class, [ + 'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])], + ]) + ->add('bar', TextType::class, [ + 'constraints' => [new NotBlank(['groups' => ['group2']])], + ]) + ; + + $form->submit(['foo' => 'invalid', 'bar' => null]); + + $errors = $form->getErrors(true); + + $this->assertCount(1, $errors); + $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); + } + + public function testFieldsValidateInSequenceWithNestedGroupsArray() + { + $form = $this->createForm(FormType::class, null, [ + 'validation_groups' => new GroupSequence([['group1', 'group2'], 'group3']), + ]) + ->add('foo', TextType::class, [ + 'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])], + ]) + ->add('bar', TextType::class, [ + 'constraints' => [new Length(['min' => 10, 'groups' => ['group2']])], + ]) + ->add('baz', TextType::class, [ + 'constraints' => [new NotBlank(['groups' => ['group3']])], + ]) + ; + + $form->submit(['foo' => 'invalid', 'bar' => 'invalid', 'baz' => null]); + + $errors = $form->getErrors(true); + + $this->assertCount(2, $errors); + $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); + $this->assertInstanceOf(Length::class, $errors[1]->getCause()->getConstraint()); + } + + private function createForm($type, $data = null, array $options = []) { $validator = Validation::createValidatorBuilder() ->setMetadataFactory(new LazyLoadingMetadataFactory(new StaticMethodLoader())) @@ -95,7 +147,7 @@ private function createForm($type) $formFactoryBuilder->addExtension(new ValidatorExtension($validator)); $formFactory = $formFactoryBuilder->getFormFactory(); - return $formFactory->create($type); + return $formFactory->create($type, $data, $options); } } From 46c278316c7306de7e323866072e3c4422b14d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Talha=20Zekeriya=20Durmu=C5=9F?= Date: Fri, 17 Apr 2020 19:05:47 +0300 Subject: [PATCH 64/89] [SecurityBundle] fix accepting env vars in remember-me configurations --- .../DependencyInjection/Security/Factory/RememberMeFactory.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php index 624deb0283fd7..cd7202019c2eb 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php @@ -146,8 +146,6 @@ public function addConfiguration(NodeDefinition $node) foreach ($this->options as $name => $value) { if (\is_bool($value)) { $builder->booleanNode($name)->defaultValue($value); - } elseif (\is_int($value)) { - $builder->integerNode($name)->defaultValue($value); } else { $builder->scalarNode($name)->defaultValue($value); } From f815b011c3d02c486e29b682886b6eb8583bd8c8 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 18 Apr 2020 16:27:57 +0200 Subject: [PATCH 65/89] [Cache] fix FilesystemTagAwareAdapter failing when a tag link preexists --- .../Component/Cache/Adapter/FilesystemTagAwareAdapter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php index d9a1ad39ac6ef..2ce9eeb977fc5 100644 --- a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php @@ -107,7 +107,7 @@ protected function doSave(array $values, ?int $lifetime, array $addTagData = [], $file = $this->getFile($id); - if (!@symlink($file, $this->getFile($id, true, $tagFolder))) { + if (!@symlink($file, $tagLink = $this->getFile($id, true, $tagFolder)) && !is_link($tagLink)) { @unlink($file); $failed[] = $id; } From d082eca7ddde683fd8e0be56f13f4b865dc6294d Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Wed, 15 Apr 2020 14:44:16 +0200 Subject: [PATCH 66/89] Add reproducer to for hit after update expire cacheItem --- .../Cache/Tests/Traits/TagAwareTestTrait.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/Symfony/Component/Cache/Tests/Traits/TagAwareTestTrait.php b/src/Symfony/Component/Cache/Tests/Traits/TagAwareTestTrait.php index 7f1544af5b41d..8b687b5a7564c 100644 --- a/src/Symfony/Component/Cache/Tests/Traits/TagAwareTestTrait.php +++ b/src/Symfony/Component/Cache/Tests/Traits/TagAwareTestTrait.php @@ -155,4 +155,42 @@ public function testGetMetadata() $i = $pool->getItem('k'); $this->assertSame(['foo' => 'foo'], $i->getMetadata()[CacheItem::METADATA_TAGS]); } + + public function testRefreshAfterExpires() + { + $pool = $this->createCachePool(); + $pool->clear(); + + $cacheItem = $pool->getItem('test'); + + $this->assertFalse($cacheItem->isHit()); + + // write cache with expires + $cacheItem->set('test'); + $cacheItem->tag('1234'); + $cacheItem->expiresAfter(1); + + $pool->save($cacheItem); + + $cacheItem = $pool->getItem('test'); + $this->assertTrue($cacheItem->isHit()); + + // wait until expired + sleep(2); + + // item should not longer be a hit + $cacheItem = $pool->getItem('test'); + $this->assertFalse($cacheItem->isHit()); + + // update expired item + $cacheItem->set('test'); + $cacheItem->tag('1234'); + $cacheItem->expiresAfter(1); + + $pool->save($cacheItem); + + // item should be again a hit + $cacheItem = $pool->getItem('test'); + $this->assertTrue($cacheItem->isHit()); + } } From 0cbca19edcd7d64ae18f7d1a02c0e1ba2aaa8132 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 18 Apr 2020 22:23:17 +0200 Subject: [PATCH 67/89] [HttpFoundation] workaround PHP bug in the session module --- .../Session/Storage/Handler/AbstractSessionHandler.php | 9 +++++++++ .../Session/Storage/Handler/Fixtures/regenerate.expected | 1 + 2 files changed, 10 insertions(+) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php index ec59d895ce3a3..c80da20466b4a 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/AbstractSessionHandler.php @@ -71,6 +71,15 @@ public function validateId($sessionId) $this->prefetchData = $this->read($sessionId); $this->prefetchId = $sessionId; + if (\PHP_VERSION_ID < 70317 || (70400 <= \PHP_VERSION_ID && \PHP_VERSION_ID < 70405)) { + // work around https://bugs.php.net/79413 + foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) { + if (!isset($frame['class']) && isset($frame['function']) && \in_array($frame['function'], ['session_regenerate_id', 'session_create_id'], true)) { + return '' === $this->prefetchData; + } + } + } + return '' !== $this->prefetchData; } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/Fixtures/regenerate.expected b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/Fixtures/regenerate.expected index baa5f2f6f5cb0..d825f44f7cb86 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/Fixtures/regenerate.expected +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/Fixtures/regenerate.expected @@ -11,6 +11,7 @@ validateId read doRead: abc|i:123; read +doRead: abc|i:123; write doWrite: abc|i:123; From 4bda68a9a25f2a99addd2e53315f3a1523b25848 Mon Sep 17 00:00:00 2001 From: stoccc Date: Sun, 19 Apr 2020 23:34:01 +0200 Subject: [PATCH 68/89] Update LdapBindAuthenticationProvider.php --- .../Provider/LdapBindAuthenticationProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php index 00092c431373c..e68649801b1cc 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php +++ b/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php @@ -87,9 +87,8 @@ protected function checkAuthentication(UserInterface $user, UsernamePasswordToke } try { - $username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_DN); - if ($this->queryString) { + $username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_FILTER); $query = str_replace('{username}', $username, $this->queryString); $result = $this->ldap->query($this->dnString, $query)->execute(); if (1 !== $result->count()) { @@ -98,6 +97,7 @@ protected function checkAuthentication(UserInterface $user, UsernamePasswordToke $dn = $result[0]->getDn(); } else { + $username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_DN); $dn = str_replace('{username}', $username, $this->dnString); } From 9fd62f79fb20ffa660fe99096471437f032ba0e0 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Mon, 20 Apr 2020 14:15:01 +0200 Subject: [PATCH 69/89] [Routing] Add missing _locale requirements Co-authored-by: Nicolas Grekas --- .../Routing/Loader/Configurator/ImportConfigurator.php | 2 ++ src/Symfony/Component/Routing/Loader/XmlFileLoader.php | 1 + src/Symfony/Component/Routing/Loader/YamlFileLoader.php | 1 + .../Component/Routing/Tests/Fixtures/php_dsl_sub_i18n.php | 2 ++ .../Component/Routing/Tests/Loader/PhpFileLoaderTest.php | 1 + .../Component/Routing/Tests/Loader/XmlFileLoaderTest.php | 3 +++ .../Component/Routing/Tests/Loader/YamlFileLoaderTest.php | 3 +++ 7 files changed, 13 insertions(+) diff --git a/src/Symfony/Component/Routing/Loader/Configurator/ImportConfigurator.php b/src/Symfony/Component/Routing/Loader/Configurator/ImportConfigurator.php index f11b7957525b1..0059a632a1977 100644 --- a/src/Symfony/Component/Routing/Loader/Configurator/ImportConfigurator.php +++ b/src/Symfony/Component/Routing/Loader/Configurator/ImportConfigurator.php @@ -13,6 +13,7 @@ use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RouteCompiler; /** * @author Nicolas Grekas @@ -63,6 +64,7 @@ final public function prefix($prefix, bool $trailingSlashOnRoot = true): self foreach ($prefix as $locale => $localePrefix) { $localizedRoute = clone $route; $localizedRoute->setDefault('_locale', $locale); + $localizedRoute->setRequirement('_locale', preg_quote($locale, RouteCompiler::REGEX_DELIMITER)); $localizedRoute->setDefault('_canonical_route', $name); $localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath())); $this->route->add($name.'.'.$locale, $localizedRoute); diff --git a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php index 49b552d627c9c..31c614950e41a 100644 --- a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -211,6 +211,7 @@ protected function parseImport(RouteCollection $collection, \DOMElement $node, $ $localizedRoute = clone $route; $localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath())); $localizedRoute->setDefault('_locale', $locale); + $localizedRoute->setRequirement('_locale', preg_quote($locale, RouteCompiler::REGEX_DELIMITER)); $localizedRoute->setDefault('_canonical_route', $name); $subCollection->add($name.'.'.$locale, $localizedRoute); } diff --git a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php index 868da9bd30b4b..8d4b9abdb10fa 100644 --- a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php @@ -216,6 +216,7 @@ protected function parseImport(RouteCollection $collection, array $config, $path foreach ($prefix as $locale => $localePrefix) { $localizedRoute = clone $route; $localizedRoute->setDefault('_locale', $locale); + $localizedRoute->setRequirement('_locale', preg_quote($locale, RouteCompiler::REGEX_DELIMITER)); $localizedRoute->setDefault('_canonical_route', $name); $localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath())); $subCollection->add($name.'.'.$locale, $localizedRoute); diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/php_dsl_sub_i18n.php b/src/Symfony/Component/Routing/Tests/Fixtures/php_dsl_sub_i18n.php index e79edc869d2de..e6d846dd463cf 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/php_dsl_sub_i18n.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/php_dsl_sub_i18n.php @@ -8,4 +8,6 @@ $add('foo', ['fr' => '/foo']); $add('bar', ['fr' => '/bar']); + + $routes->add('non_localized', '/non-localized'); }; diff --git a/src/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php index 789848c66021a..b84d5ff3543be 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php @@ -234,6 +234,7 @@ public function testRoutingI18nConfigurator() $expectedCollection->add('baz.en', (new Route('/baz'))->setDefaults(['_locale' => 'en', '_canonical_route' => 'baz'])->setRequirement('_locale', 'en')); $expectedCollection->add('c_foo.fr', (new Route('/ench/pub/foo'))->setDefaults(['_locale' => 'fr', '_canonical_route' => 'c_foo'])->setRequirement('_locale', 'fr')); $expectedCollection->add('c_bar.fr', (new Route('/ench/pub/bar'))->setDefaults(['_locale' => 'fr', '_canonical_route' => 'c_bar'])->setRequirement('_locale', 'fr')); + $expectedCollection->add('non_localized.fr', (new Route('/ench/non-localized'))->setDefaults(['_locale' => 'fr', '_canonical_route' => 'non_localized'])->setRequirement('_locale', 'fr')); $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_sub_i18n.php'))); $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_i18n.php'))); diff --git a/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php index 02e1e14d4aa97..383cda0176952 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/XmlFileLoaderTest.php @@ -201,6 +201,9 @@ public function testLocalizedImportsOfNotLocalizedRoutes() $this->assertEquals('/le-prefix/suffix', $routeCollection->get('imported.fr')->getPath()); $this->assertEquals('/the-prefix/suffix', $routeCollection->get('imported.en')->getPath()); + + $this->assertSame('fr', $routeCollection->get('imported.fr')->getRequirement('_locale')); + $this->assertSame('en', $routeCollection->get('imported.en')->getRequirement('_locale')); } /** diff --git a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php index 3878663e6b01f..e5571b0b7a6eb 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php @@ -334,6 +334,9 @@ public function testImportingNonLocalizedRoutesWithLocales() $this->assertCount(2, $routes); $this->assertEquals('/nl/imported', $routes->get('imported.nl')->getPath()); $this->assertEquals('/en/imported', $routes->get('imported.en')->getPath()); + + $this->assertSame('nl', $routes->get('imported.nl')->getRequirement('_locale')); + $this->assertSame('en', $routes->get('imported.en')->getRequirement('_locale')); } public function testImportingRoutesWithOfficialLocales() From 9ac1c76fd52464af7b851c7fc34c6c34242ec90d Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Mon, 20 Apr 2020 16:41:27 +0200 Subject: [PATCH 70/89] [Routing] Remove unused properties from the Route annotation --- src/Symfony/Component/Routing/Annotation/Route.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Symfony/Component/Routing/Annotation/Route.php b/src/Symfony/Component/Routing/Annotation/Route.php index 8183b6fc55e97..52b208c41b067 100644 --- a/src/Symfony/Component/Routing/Annotation/Route.php +++ b/src/Symfony/Component/Routing/Annotation/Route.php @@ -31,9 +31,6 @@ class Route private $methods = []; private $schemes = []; private $condition; - private $locale; - private $format; - private $utf8; /** * @param array $data An array of key/value parameters From 76072c6424840a137bd9cad609db3d7a79ce7ab0 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Mon, 20 Apr 2020 18:08:44 +0200 Subject: [PATCH 71/89] [FrameworkBundle] Fix session.attribute_bag service definition --- .../Bundle/FrameworkBundle/Resources/config/session.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml index 9f3a5b78c1e2e..9080af9379899 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml @@ -41,7 +41,8 @@ - + + attributes From d34b437ce0e3f6a28f3bc5bcf8d8979c972ae5da Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Tue, 21 Apr 2020 14:33:50 -0400 Subject: [PATCH 72/89] Fixing a bug where class_alias would cause incorrect items in debug:autowiring --- .../Command/DebugAutowiringCommand.php | 3 ++- .../Tests/Fixtures/ClassAliasExampleClass.php | 14 ++++++++++++++ .../Tests/Fixtures/ClassAliasTargetClass.php | 7 +++++++ .../Functional/DebugAutowiringCommandTest.php | 12 ++++++++++++ .../Tests/Functional/app/ContainerDebug/config.yml | 1 + 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/ClassAliasExampleClass.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/ClassAliasTargetClass.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php index 04d391da17775..32bd630f32516 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/DebugAutowiringCommand.php @@ -103,9 +103,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $serviceIdsNb = 0; foreach ($serviceIds as $serviceId) { $text = []; + $resolvedServiceId = $serviceId; if (0 !== strpos($serviceId, $previousId)) { $text[] = ''; - if ('' !== $description = Descriptor::getClassDescription($serviceId, $serviceId)) { + if ('' !== $description = Descriptor::getClassDescription($serviceId, $resolvedServiceId)) { if (isset($hasAlias[$serviceId])) { continue; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/ClassAliasExampleClass.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/ClassAliasExampleClass.php new file mode 100644 index 0000000000000..c1298658597b1 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/ClassAliasExampleClass.php @@ -0,0 +1,14 @@ +run(['command' => 'debug:autowiring', 'search' => 'redirect', '--all' => true]); $this->assertStringContainsString('Pro-tip: use interfaces in your type-hints instead of classes to benefit from the dependency inversion principle.', $tester->getDisplay()); } + + public function testNotConfusedByClassAliases() + { + static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml']); + + $application = new Application(static::$kernel); + $application->setAutoExit(false); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'debug:autowiring', 'search' => 'ClassAlias']); + $this->assertStringContainsString('Symfony\Bundle\FrameworkBundle\Tests\Fixtures\ClassAliasExampleClass (public)', $tester->getDisplay()); + } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ContainerDebug/config.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ContainerDebug/config.yml index 0cc73dbc81422..25c1c784298b5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ContainerDebug/config.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ContainerDebug/config.yml @@ -13,6 +13,7 @@ services: public: false Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BackslashClass: class: Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BackslashClass + Symfony\Bundle\FrameworkBundle\Tests\Fixtures\ClassAliasExampleClass: '@public' env: class: stdClass arguments: From 15d2b77632ae54ef9900d6872bc6880da7161f97 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 21 Apr 2020 23:19:23 +0200 Subject: [PATCH 73/89] fix merge --- .../LdapBindAuthenticationProviderTest.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php index 893c8909719fa..fcc950dbe622b 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php @@ -111,16 +111,16 @@ public function testQueryForDn() ; $ldap = $this->getMockBuilder(LdapInterface::class)->getMock(); + $ldap + ->expects($this->at(0)) + ->method('bind') + ->with('elsa', 'test1234A$'); $ldap ->expects($this->once()) ->method('escape') ->with('foo', '') ->willReturn('foo') ; - $ldap - ->expects($this->at(1)) - ->method('bind') - ->with('elsa', 'test1234A$'); $ldap ->expects($this->once()) ->method('query') @@ -151,16 +151,16 @@ public function testQueryWithUserForDn() ; $ldap = $this->getMockBuilder(LdapInterface::class)->getMock(); + $ldap + ->expects($this->at(0)) + ->method('bind') + ->with('elsa', 'test1234A$'); $ldap ->expects($this->once()) ->method('escape') ->with('foo', '') ->willReturn('foo') ; - $ldap - ->expects($this->at(1)) - ->method('bind') - ->with('elsa', 'test1234A$'); $ldap ->expects($this->once()) ->method('query') @@ -195,7 +195,7 @@ public function testEmptyQueryResultShouldThrowAnException() $ldap = $this->getMockBuilder(LdapInterface::class)->getMock(); $ldap - ->expects($this->at(1)) + ->expects($this->at(0)) ->method('bind') ->with('elsa', 'test1234A$'); $ldap From 3c24cfecdd3ae40ffdc4450bc2f6a9df8f18ff88 Mon Sep 17 00:00:00 2001 From: Dimitri Gritsajuk Date: Wed, 22 Apr 2020 12:28:41 +0200 Subject: [PATCH 74/89] [Form] apply automatically step=1 for datetime-local input --- .../Form/Extension/Core/Type/DateTimeType.php | 8 +++++ .../Extension/Core/Type/DateTimeTypeTest.php | 31 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php index 4a7c75b2652a0..fc701d5203dce 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php @@ -203,6 +203,14 @@ public function buildView(FormView $view, FormInterface $form, array $options) // * the html5 is set to true if ($options['html5'] && 'single_text' === $options['widget'] && self::HTML5_FORMAT === $options['format']) { $view->vars['type'] = 'datetime-local'; + + // we need to force the browser to display the seconds by + // adding the HTML attribute step if not already defined. + // Otherwise the browser will not display and so not send the seconds + // therefore the value will always be considered as invalid. + if ($options['with_seconds'] && !isset($view->vars['attr']['step'])) { + $view->vars['attr']['step'] = 1; + } } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php index 8af524f1fceae..53edd21b91c5d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php @@ -444,6 +444,37 @@ public function testDontPassHtml5TypeIfNotSingleText() $this->assertArrayNotHasKey('type', $view->vars); } + public function testSingleTextWidgetWithSecondsShouldHaveRightStepAttribute() + { + $view = $this->factory + ->create(static::TESTED_TYPE, null, [ + 'widget' => 'single_text', + 'with_seconds' => true, + ]) + ->createView() + ; + + $this->assertArrayHasKey('step', $view->vars['attr']); + $this->assertEquals(1, $view->vars['attr']['step']); + } + + public function testSingleTextWidgetWithSecondsShouldNotOverrideStepAttribute() + { + $view = $this->factory + ->create(static::TESTED_TYPE, null, [ + 'widget' => 'single_text', + 'with_seconds' => true, + 'attr' => [ + 'step' => 30, + ], + ]) + ->createView() + ; + + $this->assertArrayHasKey('step', $view->vars['attr']); + $this->assertEquals(30, $view->vars['attr']['step']); + } + public function testDateTypeChoiceErrorsBubbleUp() { $error = new FormError('Invalid!'); From 444e616f6b264b1bcae3078896e8e4b326d7af44 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 23 Apr 2020 14:38:20 +0200 Subject: [PATCH 75/89] [Mailer] Add a comment to avoid more wrong PRs on this piece of code --- src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransport.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransport.php b/src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransport.php index 3f68227ba4190..afa522ae97e13 100644 --- a/src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransport.php +++ b/src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransport.php @@ -106,6 +106,9 @@ protected function doHeloCommand(): void /** @var SocketStream $stream */ $stream = $this->getStream(); + // WARNING: !$stream->isTLS() is right, 100% sure :) + // if you think that the ! should be removed, read the code again + // if doing so "fixes" your issue then it probably means your SMTP server behaves incorrectly or is wrongly configured if (!$stream->isTLS() && \defined('OPENSSL_VERSION_NUMBER') && \array_key_exists('STARTTLS', $capabilities)) { $this->executeCommand("STARTTLS\r\n", [220]); From 5a7208481d777b78ad3038d54f3e10d9a8a21397 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 23 Apr 2020 23:34:23 +0200 Subject: [PATCH 76/89] [Cache] skip APCu in chains when the backend is disabled --- src/Symfony/Component/Cache/Adapter/AbstractAdapter.php | 7 ++----- src/Symfony/Component/Cache/Adapter/ChainAdapter.php | 3 +++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index dad0dc8f66f55..ce1262ae17557 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -14,7 +14,6 @@ use Psr\Cache\CacheItemInterface; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\ResettableInterface; @@ -116,14 +115,12 @@ public static function createSystemCache($namespace, $defaultLifetime, $version, if (null !== $logger) { $fs->setLogger($logger); } - if (!self::$apcuSupported) { + if (!self::$apcuSupported || (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN))) { return $fs; } $apcu = new ApcuAdapter($namespace, (int) $defaultLifetime / 5, $version); - if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) { - $apcu->setLogger(new NullLogger()); - } elseif (null !== $logger) { + if (null !== $logger) { $apcu->setLogger($logger); } diff --git a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php index 0080db711bce7..c2c9f4a8008ac 100644 --- a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php @@ -46,6 +46,9 @@ public function __construct(array $adapters, $defaultLifetime = 0) if (!$adapter instanceof CacheItemPoolInterface) { throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($adapter), CacheItemPoolInterface::class)); } + if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && $adapter instanceof ApcuAdapter && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) { + continue; // skip putting APCu in the chain when the backend is disabled + } if ($adapter instanceof AdapterInterface) { $this->adapters[] = $adapter; From e27ed28bae708102b011c7a8c4744e01b0173d14 Mon Sep 17 00:00:00 2001 From: Massimiliano Arione Date: Thu, 23 Apr 2020 09:31:24 +0200 Subject: [PATCH 77/89] fix compatibility with phpunit 9 --- .../Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php | 7 +++++-- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 4 ++++ src/Symfony/Bridge/PhpUnit/composer.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index 69bbcfc09eab0..77693421bacdd 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -46,9 +46,12 @@ class SymfonyTestsListenerTrait public function __construct(array $mockedNamespaces = array()) { if (class_exists('PHPUnit_Util_Blacklist')) { - \PHPUnit_Util_Blacklist::$blacklistedClassNames['\Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait'] = 2; + \PHPUnit_Util_Blacklist::$blacklistedClassNames[__CLASS__] = 2; + } elseif (method_exists(Blacklist::class, 'addDirectory')) { + (new BlackList())->getBlacklistedDirectories(); + Blacklist::addDirectory(\dirname(\dirname((new \ReflectionClass(__CLASS__))->getFileName()))); } else { - Blacklist::$blacklistedClassNames['\Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait'] = 2; + Blacklist::$blacklistedClassNames[__CLASS__] = 2; } $warn = false; diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index d2c23f2025b74..3043daababc1d 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -126,6 +126,10 @@ if (!class_exists('SymfonyBlacklistPhpunit', false)) { if (class_exists('PHPUnit_Util_Blacklist')) { PHPUnit_Util_Blacklist::$blacklistedClassNames['SymfonyBlacklistPhpunit'] = 1; PHPUnit_Util_Blacklist::$blacklistedClassNames['SymfonyBlacklistSimplePhpunit'] = 1; +} elseif (method_exists('PHPUnit\Util\Blacklist', 'addDirectory')) { + (new PHPUnit\Util\BlackList())->getBlacklistedDirectories(); + PHPUnit\Util\Blacklist::addDirectory(\dirname((new \ReflectionClass('SymfonyBlacklistPhpunit'))->getFileName())); + PHPUnit\Util\Blacklist::addDirectory(\dirname((new \ReflectionClass('SymfonyBlacklistSimplePhpunit'))->getFileName())); } else { PHPUnit\Util\Blacklist::$blacklistedClassNames['SymfonyBlacklistPhpunit'] = 1; PHPUnit\Util\Blacklist::$blacklistedClassNames['SymfonyBlacklistSimplePhpunit'] = 1; diff --git a/src/Symfony/Bridge/PhpUnit/composer.json b/src/Symfony/Bridge/PhpUnit/composer.json index f7d9492613ab6..30b3cc23f63d8 100644 --- a/src/Symfony/Bridge/PhpUnit/composer.json +++ b/src/Symfony/Bridge/PhpUnit/composer.json @@ -24,7 +24,7 @@ "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" }, "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0" + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0|9.1.2" }, "autoload": { "files": [ "bootstrap.php" ], From 734d97bdccca86bc5c669713b34dc84b9855229f Mon Sep 17 00:00:00 2001 From: sdkawata Date: Fri, 24 Apr 2020 19:16:04 +0900 Subject: [PATCH 78/89] [YAML] escape DEL(\x7f) --- src/Symfony/Component/Yaml/Escaper.php | 4 +++- src/Symfony/Component/Yaml/Tests/DumperTest.php | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Escaper.php b/src/Symfony/Component/Yaml/Escaper.php index 4d3ce244c2ada..9413d7a2c4804 100644 --- a/src/Symfony/Component/Yaml/Escaper.php +++ b/src/Symfony/Component/Yaml/Escaper.php @@ -22,7 +22,7 @@ class Escaper { // Characters that would cause a dumped string to require double quoting. - const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9"; + const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\x7f|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9"; // Mapping arrays for escaping a double quoted string. The backslash is // first to ensure proper escaping because str_replace operates iteratively @@ -33,6 +33,7 @@ class Escaper "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", + "\x7f", "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9", ]; private static $escaped = ['\\\\', '\\"', '\\\\', '\\"', @@ -40,6 +41,7 @@ class Escaper '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f', '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f', + '\\x7f', '\\N', '\\_', '\\L', '\\P', ]; diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index bb2a575eebdab..e4dc49f331d72 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -289,6 +289,7 @@ public function getEscapeSequences() 'double-quote' => ['"', "'\"'"], 'slash' => ['/', '/'], 'backslash' => ['\\', '\\'], + 'del' => ["\x7f", '"\x7f"'], 'next-line' => ["\xC2\x85", '"\\N"'], 'non-breaking-space' => ["\xc2\xa0", '"\\_"'], 'line-separator' => ["\xE2\x80\xA8", '"\\L"'], From 28fdb3a8797e9a908ea8b0a71bb3477d1de2545e Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Wed, 22 Apr 2020 21:54:02 +0200 Subject: [PATCH 79/89] Allow invalidateTags calls to be traced by data collector --- .../CacheCollectorPass.php | 45 +++++++++++-------- .../CacheCollectorPassTest.php | 14 ++++++ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Component/Cache/DependencyInjection/CacheCollectorPass.php b/src/Symfony/Component/Cache/DependencyInjection/CacheCollectorPass.php index 68671dc23830a..b534e5dc8a7fb 100644 --- a/src/Symfony/Component/Cache/DependencyInjection/CacheCollectorPass.php +++ b/src/Symfony/Component/Cache/DependencyInjection/CacheCollectorPass.php @@ -46,29 +46,38 @@ public function process(ContainerBuilder $container) return; } - $collectorDefinition = $container->getDefinition($this->dataCollectorCacheId); foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $attributes) { - $definition = $container->getDefinition($id); - if ($definition->isAbstract()) { - continue; - } + $this->addToCollector($id, $container); - $recorder = new Definition(is_subclass_of($definition->getClass(), TagAwareAdapterInterface::class) ? TraceableTagAwareAdapter::class : TraceableAdapter::class); - $recorder->setTags($definition->getTags()); - if (!$definition->isPublic() || !$definition->isPrivate()) { - $recorder->setPublic($definition->isPublic()); + if (($attributes[0]['name'] ?? $id) !== $id) { + $this->addToCollector($attributes[0]['name'], $container); } - $recorder->setArguments([new Reference($innerId = $id.$this->cachePoolRecorderInnerSuffix)]); - - $definition->setTags([]); - $definition->setPublic(false); + } + } - $container->setDefinition($innerId, $definition); - $container->setDefinition($id, $recorder); + private function addToCollector(string $id, ContainerBuilder $container) + { + $definition = $container->getDefinition($id); + if ($definition->isAbstract()) { + return; + } - // Tell the collector to add the new instance - $collectorDefinition->addMethodCall('addInstance', [$id, new Reference($id)]); - $collectorDefinition->setPublic(false); + $collectorDefinition = $container->getDefinition($this->dataCollectorCacheId); + $recorder = new Definition(is_subclass_of($definition->getClass(), TagAwareAdapterInterface::class) ? TraceableTagAwareAdapter::class : TraceableAdapter::class); + $recorder->setTags($definition->getTags()); + if (!$definition->isPublic() || !$definition->isPrivate()) { + $recorder->setPublic($definition->isPublic()); } + $recorder->setArguments([new Reference($innerId = $id.$this->cachePoolRecorderInnerSuffix)]); + + $definition->setTags([]); + $definition->setPublic(false); + + $container->setDefinition($innerId, $definition); + $container->setDefinition($id, $recorder); + + // Tell the collector to add the new instance + $collectorDefinition->addMethodCall('addInstance', [$id, new Reference($id)]); + $collectorDefinition->setPublic(false); } } diff --git a/src/Symfony/Component/Cache/Tests/DependencyInjection/CacheCollectorPassTest.php b/src/Symfony/Component/Cache/Tests/DependencyInjection/CacheCollectorPassTest.php index 7e77491de867b..8aff19fc3e14b 100644 --- a/src/Symfony/Component/Cache/Tests/DependencyInjection/CacheCollectorPassTest.php +++ b/src/Symfony/Component/Cache/Tests/DependencyInjection/CacheCollectorPassTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\Adapter\PhpArrayAdapter; use Symfony\Component\Cache\Adapter\TagAwareAdapter; use Symfony\Component\Cache\Adapter\TraceableAdapter; use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter; @@ -34,16 +35,29 @@ public function testProcess() ->addArgument(new Reference('fs')) ->addTag('cache.pool'); + $container + ->register('.php.inner', PhpArrayAdapter::class) + ->addTag('cache.pool', ['name' => 'php']); + $container + ->register('php', TagAwareAdapter::class) + ->addArgument(new Reference('.php.inner')); + $collector = $container->register('data_collector.cache', CacheDataCollector::class); (new CacheCollectorPass())->process($container); $this->assertEquals([ ['addInstance', ['fs', new Reference('fs')]], ['addInstance', ['tagged_fs', new Reference('tagged_fs')]], + ['addInstance', ['.php.inner', new Reference('.php.inner')]], + ['addInstance', ['php', new Reference('php')]], ], $collector->getMethodCalls()); $this->assertSame(TraceableAdapter::class, $container->findDefinition('fs')->getClass()); $this->assertSame(TraceableTagAwareAdapter::class, $container->getDefinition('tagged_fs')->getClass()); + + $this->assertSame(TraceableAdapter::class, $container->findDefinition('.php.inner')->getClass()); + $this->assertSame(TraceableTagAwareAdapter::class, $container->getDefinition('php')->getClass()); + $this->assertFalse($collector->isPublic(), 'The "data_collector.cache" should be private after processing'); } } From 6dce90d47bc8ff944d670f6b6d418efb1506fa33 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 24 Apr 2020 14:56:41 +0200 Subject: [PATCH 80/89] [PhpUnitBridge] Use COMPOSER_BINARY env var if available --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index 3043daababc1d..92d4d6994af9c 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -65,11 +65,13 @@ foreach ($defaultEnvs as $envName => $envValue) { } } -$COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') - || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar 2> /dev/null`)) - || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer`) : `which composer 2> /dev/null`)) - ? (file_get_contents($COMPOSER, false, null, 0, 18) === '#!/usr/bin/env php' ? $PHP : '').' '.escapeshellarg($COMPOSER) // detect shell wrappers by looking at the shebang - : 'composer'; +if (false === $COMPOSER = \getenv('COMPOSER_BINARY')) { + $COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') + || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar 2> /dev/null`)) + || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer`) : `which composer 2> /dev/null`)) + ? (file_get_contents($COMPOSER, false, null, 0, 18) === '#!/usr/bin/env php' ? $PHP : '').' '.escapeshellarg($COMPOSER) // detect shell wrappers by looking at the shebang + : 'composer'; +} if (false === $SYMFONY_PHPUNIT_REMOVE = getenv('SYMFONY_PHPUNIT_REMOVE')) { $SYMFONY_PHPUNIT_REMOVE = 'phpspec/prophecy symfony/yaml'; From e721cfd65cbf4f42702d904757dd3ecc0da8c0a2 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 24 Apr 2020 16:08:51 +0200 Subject: [PATCH 81/89] Improve dirname usage --- src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index 77693421bacdd..e260fb8dd6854 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -49,7 +49,7 @@ public function __construct(array $mockedNamespaces = array()) \PHPUnit_Util_Blacklist::$blacklistedClassNames[__CLASS__] = 2; } elseif (method_exists(Blacklist::class, 'addDirectory')) { (new BlackList())->getBlacklistedDirectories(); - Blacklist::addDirectory(\dirname(\dirname((new \ReflectionClass(__CLASS__))->getFileName()))); + Blacklist::addDirectory(\dirname((new \ReflectionClass(__CLASS__))->getFileName(), 2)); } else { Blacklist::$blacklistedClassNames[__CLASS__] = 2; } From fb3aaefbf2c301744395c5b6e75806f9ade29951 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 26 Apr 2020 10:08:16 +0200 Subject: [PATCH 82/89] add tests for the ConstraintViolationBuilder class --- .../ConstraintViolationBuilderTest.php | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php diff --git a/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php b/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php new file mode 100644 index 0000000000000..4121dc2622e96 --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Tests\Violation; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Translation\IdentityTranslator; +use Symfony\Component\Validator\Constraints\Valid; +use Symfony\Component\Validator\ConstraintViolation; +use Symfony\Component\Validator\ConstraintViolationList; +use Symfony\Component\Validator\Test\ForwardCompatTestTrait; +use Symfony\Component\Validator\Violation\ConstraintViolationBuilder; + +class ConstraintViolationBuilderTest extends TestCase +{ + use ForwardCompatTestTrait; + + private $root; + private $violations; + private $messageTemplate = '%value% is invalid'; + private $builder; + + private function doSetUp() + { + $this->root = [ + 'data' => [ + 'foo' => 'bar', + 'baz' => 'foobar', + ], + ]; + $this->violations = new ConstraintViolationList(); + $this->builder = new ConstraintViolationBuilder($this->violations, new Valid(), $this->messageTemplate, [], $this->root, 'data', 'foo', new IdentityTranslator()); + } + + public function testAddViolation() + { + $this->builder->addViolation(); + + $this->assertViolationEquals(new ConstraintViolation($this->messageTemplate, $this->messageTemplate, [], $this->root, 'data', 'foo', null, null, new Valid())); + } + + public function testAppendPropertyPath() + { + $this->builder + ->atPath('foo') + ->addViolation(); + + $this->assertViolationEquals(new ConstraintViolation($this->messageTemplate, $this->messageTemplate, [], $this->root, 'data.foo', 'foo', null, null, new Valid())); + } + + public function testAppendMultiplePropertyPaths() + { + $this->builder + ->atPath('foo') + ->atPath('bar') + ->addViolation(); + + $this->assertViolationEquals(new ConstraintViolation($this->messageTemplate, $this->messageTemplate, [], $this->root, 'data.foo.bar', 'foo', null, null, new Valid())); + } + + public function testCodeCanBeSet() + { + $this->builder + ->setCode(5) + ->addViolation(); + + $this->assertViolationEquals(new ConstraintViolation($this->messageTemplate, $this->messageTemplate, [], $this->root, 'data', 'foo', null, 5, new Valid())); + } + + public function testCauseCanBeSet() + { + $cause = new \LogicException(); + + $this->builder + ->setCause($cause) + ->addViolation(); + + $this->assertViolationEquals(new ConstraintViolation($this->messageTemplate, $this->messageTemplate, [], $this->root, 'data', 'foo', null, null, new Valid(), $cause)); + } + + private function assertViolationEquals(ConstraintViolation $expectedViolation) + { + $this->assertCount(1, $this->violations); + + $violation = $this->violations->get(0); + + $this->assertSame($expectedViolation->getMessage(), $violation->getMessage()); + $this->assertSame($expectedViolation->getMessageTemplate(), $violation->getMessageTemplate()); + $this->assertSame($expectedViolation->getParameters(), $violation->getParameters()); + $this->assertSame($expectedViolation->getPlural(), $violation->getPlural()); + $this->assertSame($expectedViolation->getRoot(), $violation->getRoot()); + $this->assertSame($expectedViolation->getPropertyPath(), $violation->getPropertyPath()); + $this->assertSame($expectedViolation->getInvalidValue(), $violation->getInvalidValue()); + $this->assertSame($expectedViolation->getCode(), $violation->getCode()); + $this->assertEquals($expectedViolation->getConstraint(), $violation->getConstraint()); + $this->assertSame($expectedViolation->getCause(), $violation->getCause()); + } +} From 89fb0799cd950867d998d9d3de60d3761f2ac76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Beurlet?= Date: Fri, 24 Apr 2020 18:48:20 +0200 Subject: [PATCH 83/89] [WebProfilerBundle] changed label of peak memory usage in the time & memory panels (MB into MiB) --- .../Resources/views/Collector/memory.html.twig | 6 +++--- .../Resources/views/Collector/time.html.twig | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig index 268f8fdc7e3f6..49878a72d5d65 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/memory.html.twig @@ -5,18 +5,18 @@ {% set status_color = (collector.memory / 1024 / 1024) > 50 ? 'yellow' : '' %} {{ include('@WebProfiler/Icon/memory.svg') }} {{ '%.1f'|format(collector.memory / 1024 / 1024) }} - MB + MiB {% endset %} {% set text %}
Peak memory usage - {{ '%.1f'|format(collector.memory / 1024 / 1024) }} MB + {{ '%.1f'|format(collector.memory / 1024 / 1024) }} MiB
PHP memory limit - {{ collector.memoryLimit == -1 ? 'Unlimited' : '%.0f MB'|format(collector.memoryLimit / 1024 / 1024) }} + {{ collector.memoryLimit == -1 ? 'Unlimited' : '%.0f MiB'|format(collector.memoryLimit / 1024 / 1024) }}
{% endset %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig index dd95b511b40ea..a9fd19225d2d6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig @@ -64,7 +64,7 @@ {% if profile.collectors.memory %}
- {{ '%.2f'|format(profile.collectors.memory.memory / 1024 / 1024) }} MB + {{ '%.2f'|format(profile.collectors.memory.memory / 1024 / 1024) }} MiB Peak memory usage
{% endif %} @@ -386,7 +386,7 @@ ctx.fillStyle = "#444"; ctx.font = "12px sans-serif"; text = event.name; - ms = " " + (event.duration < 1 ? event.duration : parseInt(event.duration, 10)) + " ms / " + event.memory + " MB"; + ms = " " + (event.duration < 1 ? event.duration : parseInt(event.duration, 10)) + " ms / " + event.memory + " MiB"; if (x + event.starttime * ratio + ctx.measureText(text + ms).width > width) { ctx.textAlign = "end"; ctx.font = "10px sans-serif"; From 99080bdbe7afb344c7d96dcd30393e564767c799 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 28 Apr 2020 19:40:55 +0200 Subject: [PATCH 84/89] updated CHANGELOG for 3.4.40 --- CHANGELOG-3.4.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 8e7a8406ff391..7fc92f86eb326 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,35 @@ in 3.4 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.4.0...v3.4.1 +* 3.4.40 (2020-04-28) + + * bug #36566 [PhpUnitBridge] Use COMPOSER_BINARY env var if available (fancyweb) + * bug #36560 [YAML] escape DEL(\x7f) (sdkawata) + * bug #36539 [PhpUnitBridge] fix compatibility with phpunit 9 (garak) + * bug #36555 [Cache] skip APCu in chains when the backend is disabled (nicolas-grekas) + * bug #36523 [Form] apply automatically step=1 for datetime-local input (ottaviano) + * bug #36498 [Security/Core] fix escape for username in LdapBindAuthenticationProvider.php (stoccc) + * bug #36506 [FrameworkBundle] Fix session.attribute_bag service definition (fancyweb) + * bug #36490 [HttpFoundation] workaround PHP bug in the session module (nicolas-grekas) + * bug #36483 [SecurityBundle] fix accepting env vars in remember-me configurations (zek) + * bug #36343 [Form] Fixed handling groups sequence validation (HeahDude) + * bug #36460 [Cache] Avoid memory leak in TraceableAdapter::reset() (lyrixx) + * bug #36411 [Form] RepeatedType should always have inner types mapped (biozshock) + * bug #36441 [DI] fix loading defaults when using the PHP-DSL (nicolas-grekas) + * bug #36434 [HttpKernel] silence E_NOTICE triggered since PHP 7.4 (xabbuh) + * bug #36365 [Validator] Fixed default group for nested composite constraints (HeahDude) + * bug #35591 [Validator] do not merge constraints within interfaces (greedyivan) + * bug #36375 [Workflow] Use a strict comparison when retrieving raw marking in MarkingStore (lyrixx) + * bug #36305 [PropertyInfo][ReflectionExtractor] Check the array mutator prefixes last when the property is singular (fancyweb) + * bug #35656 [HttpFoundation] Fixed session migration with custom cookie lifetime (Guite) + * bug #36315 [WebProfilerBundle] Support for Content Security Policy style-src-elem and script-src-elem in WebProfiler (ampaze) + * bug #36286 [Validator] Allow URL-encoded special characters in basic auth part of URLs (cweiske) + * bug #36332 [Serializer] Fix unitialized properties (from PHP 7.4.2) when serializing context for the cache key (alanpoulain) + * bug #36239 [HttpKernel][LoggerDataCollector] Prevent keys collisions in the sanitized logs processing (fancyweb) + * bug #36245 [Validator] Fixed calling getters before resolving groups (HeahDude) + * bug #36252 [Security/Http] Allow setting cookie security settings for delete_cookies (wouterj) + * bug #36261 [FrameworkBundle] revert to legacy wiring of the session when circular refs are detected (nicolas-grekas) + * 3.4.39 (2020-03-30) * bug #36216 [Validator] Assert Valid with many groups (phucwan91) From 1822b065d7f83101f3d6e098e60a60c4b313bb20 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 28 Apr 2020 19:41:24 +0200 Subject: [PATCH 85/89] update CONTRIBUTORS for 3.4.40 --- CONTRIBUTORS.md | 77 ++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 53a2faec2f45f..449973d7578eb 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -24,10 +24,10 @@ Symfony is the result of the work of many people who made the code better - Kris Wallsmith (kriswallsmith) - Yonel Ceruto (yonelceruto) - Hugo Hamon (hhamon) + - Wouter de Jong (wouterj) + - Thomas Calvet (fancyweb) - Abdellatif Ait boudad (aitboudad) - Samuel ROZE (sroze) - - Thomas Calvet (fancyweb) - - Wouter de Jong (wouterj) - Romain Neutron (romain) - Pascal Borreli (pborreli) - Joseph Bielawski (stloyd) @@ -37,8 +37,8 @@ Symfony is the result of the work of many people who made the code better - Jules Pietri (heah) - Hamza Amrouche (simperfit) - Martin Hasoň (hason) - - Jeremy Mikola (jmikola) - Jérémy DERUSSÉ (jderusse) + - Jeremy Mikola (jmikola) - Jean-François Simon (jfsimon) - Benjamin Eberlei (beberlei) - Igor Wiedler (igorw) @@ -50,9 +50,9 @@ Symfony is the result of the work of many people who made the code better - Lynn van der Berg (kjarli) - Diego Saint Esteben (dosten) - Matthias Pigulla (mpdude) + - Pierre du Plessis (pierredup) - Alexandre Salomé (alexandresalome) - William Durand (couac) - - Pierre du Plessis (pierredup) - ornicar - Dany Maillard (maidmaid) - Francis Besset (francisbesset) @@ -69,10 +69,10 @@ Symfony is the result of the work of many people who made the code better - Gabriel Ostrolucký (gadelat) - Miha Vrhovnik - David Maicher (dmaicher) - - Diego Saint Esteben (dii3g0) - Gábor Egyed (1ed) - - Titouan Galopin (tgalopin) + - Diego Saint Esteben (dii3g0) - Jan Schädlich (jschaedl) + - Titouan Galopin (tgalopin) - Konstantin Kudryashov (everzet) - Bilal Amarni (bamarni) - Mathieu Piot (mpiot) @@ -110,6 +110,7 @@ Symfony is the result of the work of many people who made the code better - Baptiste Clavié (talus) - Michal Piotrowski (eventhorizon) - Tim Nagel (merk) + - Sebastiaan Stok (sstok) - Chris Wilkinson (thewilkybarkid) - Brice BERNARD (brikou) - marc.weistroff @@ -119,7 +120,6 @@ Symfony is the result of the work of many people who made the code better - lenar - Alexander Schwenn (xelaris) - Włodzimierz Gajda (gajdaw) - - Sebastiaan Stok (sstok) - Adrien Brault (adrienbrault) - Jacob Dreesen (jdreesen) - Florian Voutzinos (florianv) @@ -139,18 +139,18 @@ Symfony is the result of the work of many people who made the code better - Przemysław Bogusz (przemyslaw-bogusz) - Eric GELOEN (gelo) - Lars Strojny (lstrojny) + - Massimiliano Arione (garak) - Jannik Zschiesche (apfelbox) - Robert Schönthal (digitalkaoz) - Gregor Harlan (gharlan) - Florian Lonqueu-Brochard (florianlb) + - Alexander Schranz (alexander-schranz) - Gabriel Caruso (carusogabriel) - Stefano Sala (stefano.sala) - Evgeniy (ewgraf) - - Massimiliano Arione (garak) - Julien Falque (julienfalque) - Vincent AUBERT (vincent) - Juti Noppornpitak (shiroyuki) - - Alexander Schranz (alexander-schranz) - Anthony MARTIN (xurudragon) - Tigran Azatyan (tigranazatyan) - Sebastian Hörl (blogsh) @@ -176,6 +176,7 @@ Symfony is the result of the work of many people who made the code better - Richard van Laak (rvanlaak) - Richard Shank (iampersistent) - Thomas Rabaix (rande) + - Ahmed TAILOULOUTE (ahmedtai) - Vincent Touzet (vincenttouzet) - jeremyFreeAgent (jeremyfreeagent) - Rouven Weßling (realityking) @@ -198,6 +199,7 @@ Symfony is the result of the work of many people who made the code better - James Halsall (jaitsu) - Matthieu Napoli (mnapoli) - Florent Mata (fmata) + - Antoine Makdessi (amakdessi) - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) @@ -213,15 +215,18 @@ Symfony is the result of the work of many people who made the code better - Dennis Benkert (denderello) - DQNEO - Andre Rømcke (andrerom) + - Saif (╯°□°)╯ (azjezz) - mcfedr (mcfedr) - Gary PEGEOT (gary-p) - Ruben Gonzalez (rubenrua) - Benjamin Dulau (dbenjamin) + - Jan Rosier (rosier) - Andreas Braun - Mathieu Lemoine (lemoinem) - Christian Schmidt - Andreas Hucks (meandmymonkey) - Tom Van Looy (tvlooy) + - Guillaume Pédelagrabe - Noel Guilbert (noel) - Anthony GRASSIOT (antograssiot) - Stadly @@ -233,7 +238,7 @@ Symfony is the result of the work of many people who made the code better - Nikolay Labinskiy (e-moe) - Martin Schuhfuß (usefulthink) - apetitpa - - Antoine Makdessi (amakdessi) + - Maxime Helias (maxhelias) - Matthieu Bontemps (mbontemps) - apetitpa - Pierre Minnieur (pminnieur) @@ -243,14 +248,13 @@ Symfony is the result of the work of many people who made the code better - Laurent VOULLEMIER (lvo) - Michael Lee (zerustech) - Matthieu Auger (matthieuauger) - - Ahmed TAILOULOUTE (ahmedtai) + - Mathias Arlaud (mtarld) - Leszek Prabucki (l3l0) - Fabien Bourigault (fbourigault) - François Zaninotto (fzaninotto) - Dustin Whittle (dustinwhittle) - jeff - John Kary (johnkary) - - Jan Rosier (rosier) - Justin Hileman (bobthecow) - Blanchon Vincent (blanchonvincent) - Michele Orselli (orso) @@ -270,7 +274,6 @@ Symfony is the result of the work of many people who made the code better - Marcel Beerta (mazen) - Christopher Hertel (chertel) - Ruud Kamphuis (ruudk) - - Maxime Helias (maxhelias) - Pavel Batanov (scaytrase) - Mantis Development - David Prévot @@ -283,7 +286,6 @@ Symfony is the result of the work of many people who made the code better - Lorenz Schori - Sébastien Lavoie (lavoiesl) - Dariusz - - Saif (╯°□°)╯ (azjezz) - Dmitrii Poddubnyi (karser) - Michael Babker (mbabker) - Francois Zaninotto @@ -307,7 +309,6 @@ Symfony is the result of the work of many people who made the code better - Arjen Brouwer (arjenjb) - Katsuhiro OGAWA - Patrick McDougle (patrick-mcdougle) - - Guillaume Pédelagrabe - Alif Rachmawadi - Anton Chernikov (anton_ch1989) - Kristen Gilden (kgilden) @@ -336,9 +337,9 @@ Symfony is the result of the work of many people who made the code better - Jeroen Spee (jeroens) - Nikita Konstantinov - Wodor Wodorski + - Olivier Dolbeau (odolbeau) - Thomas Lallement (raziel057) - Colin O'Dell (colinodell) - - Mathias Arlaud (mtarld) - Giorgio Premi - renanbr - Alex Rock (pierstoval) @@ -364,6 +365,7 @@ Symfony is the result of the work of many people who made the code better - Vilius Grigaliūnas - David Badura (davidbadura) - Chad Sikorra (chadsikorra) + - Alan Poulain (alanpoulain) - Chris Smith (cs278) - Thomas Bisignani (toma) - Florian Klein (docteurklein) @@ -413,7 +415,6 @@ Symfony is the result of the work of many people who made the code better - Thomas Royer (cydonia7) - Nicolas LEFEVRE (nicoweb) - alquerci - - Olivier Dolbeau (odolbeau) - Oleg Andreyev - Mateusz Sip (mateusz_sip) - Francesco Levorato @@ -426,6 +427,7 @@ Symfony is the result of the work of many people who made the code better - Tomasz Kowalczyk (thunderer) - Artur Eshenbrener - Timo Bakx (timobakx) + - Antonio Pauletich (x-coder264) - Thomas Perez (scullwm) - Felix Labrecque - Yaroslav Kiliba @@ -443,7 +445,6 @@ Symfony is the result of the work of many people who made the code better - Eduardo Gulias (egulias) - giulio de donato (liuggio) - ShinDarth - - Alan Poulain - Stéphane PY (steph_py) - Philipp Kräutli (pkraeutli) - Grzegorz (Greg) Zdanowski (kiler129) @@ -540,10 +541,10 @@ Symfony is the result of the work of many people who made the code better - Martijn Cuppens - Vlad Gregurco (vgregurco) - Boris Vujicic (boris.vujicic) + - Artem Lopata - Chris Sedlmayr (catchamonkey) - Kamil Kokot (pamil) - Seb Koelen - - Antonio Pauletich (x-coder264) - Christoph Mewes (xrstf) - Vitaliy Tverdokhlib (vitaliytv) - Ariel Ferrandini (aferrandini) @@ -553,14 +554,17 @@ Symfony is the result of the work of many people who made the code better - Jonas Flodén (flojon) - Tobias Weichart - Gonzalo Vilaseca (gonzalovilaseca) + - Daniel STANCU - Tarmo Leppänen (tarlepp) - Marcin Sikoń (marphi) - Dominik Zogg (dominik.zogg) - Marek Pietrzak - Luc Vieillescazes (iamluc) - franek (franek) + - soyuka - Raulnet - Christian Wahler + - Giso Stallenberg (gisostallenberg) - Gintautas Miselis - Rob Bast - Roberto Espinoza (respinoza) @@ -599,6 +603,7 @@ Symfony is the result of the work of many people who made the code better - Philipp Rieber (bicpi) - Manuel de Ruiter (manuel) - Nathanael Noblet (gnat) + - Dimitri Gritsajuk (ottaviano) - nikos.sotiropoulos - Eduardo Oliveira (entering) - Ilya Antipenko (aivus) @@ -744,6 +749,7 @@ Symfony is the result of the work of many people who made the code better - Benjamin Cremer (bcremer) - Javier López (loalf) - Reinier Kip + - Jérôme Tamarelle (jtamarelle-prismamedia) - Geoffrey Brier (geoffrey-brier) - Alexandre Parent - Vladimir Tsykun @@ -778,7 +784,6 @@ Symfony is the result of the work of many people who made the code better - Miquel Rodríguez Telep (mrtorrent) - Sergey Kolodyazhnyy (skolodyazhnyy) - umpirski - - Artem Lopata - M. Vondano - Quentin de Longraye (quentinus95) - Chris Heng (gigablah) @@ -786,10 +791,10 @@ Symfony is the result of the work of many people who made the code better - Richard Bradley - Ulumuddin Yunus (joenoez) - rtek + - Ivan Grigoriev - Johann Saunier (prophet777) - Sergey (upyx) - Andreas Erhard - - Giso Stallenberg (gisostallenberg) - Michael Devery (mickadoo) - Antoine Corcy - Ahmed Ashraf (ahmedash95) @@ -810,6 +815,7 @@ Symfony is the result of the work of many people who made the code better - Cameron Porter - Hossein Bukhamsin - Oliver Hoff + - William Arslett - Christian Sciberras (uuf6429) - Disparity - origaminal @@ -856,7 +862,6 @@ Symfony is the result of the work of many people who made the code better - Markus Fasselt (digilist) - Julien DIDIER (juliendidier) - Dominik Ritter (dritter) - - Dimitri Gritsajuk (ottaviano) - Sebastian Grodzicki (sgrodzicki) - Mohamed Gamal - Jeroen van den Enden (stoefke) @@ -871,6 +876,7 @@ Symfony is the result of the work of many people who made the code better - Yuen-Chi Lian - Tarjei Huse (tarjei) - Besnik Br + - Axel Guckelsberger (guite) - Jose Gonzalez - Jonathan (jls-esokia) - Oleksii Zhurbytskyi @@ -881,12 +887,14 @@ Symfony is the result of the work of many people who made the code better - Jakub Kulhan (jakubkulhan) - Shaharia Azam - avorobiev + - stoccc - Grégoire Penverne (gpenverne) - Venu - Lars Vierbergen - Jonatan Männchen - Dennis Hotson - Andrew Tchircoff (andrewtch) + - Ahmed Raafat - michaelwilliams - Martin Kirilov - 1emming @@ -894,6 +902,7 @@ Symfony is the result of the work of many people who made the code better - Tri Pham (phamuyentri) - Jordan Deitch - Casper Valdemar Poulsen + - Laurent Masforné (heisenberg) - Josiah (josiah) - Guillaume Verstraete (versgui) - Greg ORIOL @@ -961,10 +970,8 @@ Symfony is the result of the work of many people who made the code better - Laurent Bassin (lbassin) - andrey1s - Abhoryo - - Daniel STANCU - Fabian Vogler (fabian) - Korvin Szanto - - soyuka - Stéphan Kochen - Arjan Keeman - Alaattin Kahramanlar (alaattin) @@ -1133,6 +1140,7 @@ Symfony is the result of the work of many people who made the code better - Nicolas Le Goff (nlegoff) - Ben Oman - Chris de Kok + - Eduard Bulava (nonanerz) - Lorenzo Millucci - Andreas Kleemann - Manuele Menozzi @@ -1150,6 +1158,7 @@ Symfony is the result of the work of many people who made the code better - hamza - dantleech - Bastien DURAND (deamon) + - Kajetan Kołtuniak (kajtii) - Sander Goossens (sandergo90) - Rudy Onfroy - Tero Alén (tero) @@ -1237,7 +1246,6 @@ Symfony is the result of the work of many people who made the code better - Benjamin Paap (benjaminpaap) - Claus Due (namelesscoder) - Christian - - William Arslett - Denis Golubovskiy (bukashk0zzz) - Sergii Smertin (nfx) - Mikkel Paulson @@ -1246,6 +1254,7 @@ Symfony is the result of the work of many people who made the code better - Marc Duboc (icemad) - Matthias Krauser (mkrauser) - Martynas Narbutas + - Nilmar Sanchez Muguercia - Toon Verwerft (veewee) - Bailey Parker - Eddie Jaoude @@ -1289,6 +1298,7 @@ Symfony is the result of the work of many people who made the code better - Stephen Clouse - e-ivanov - Michał (bambucha15) + - Benjamin Dos Santos - Einenlum - Jérémy Jarrié (gagnar) - Jochen Bayer (jocl) @@ -1344,6 +1354,7 @@ Symfony is the result of the work of many people who made the code better - Klaus Purer - arnaud (arnooo999) - Gilles Doge (gido) + - Oscar Esteve (oesteve) - abulford - Philipp Kretzschmar - antograssiot @@ -1367,7 +1378,6 @@ Symfony is the result of the work of many people who made the code better - Derek Lambert - MightyBranch - Kacper Gunia (cakper) - - Jérôme Tamarelle (jtamarelle-prismamedia) - Peter Thompson (petert82) - error56 - Felicitus @@ -1392,6 +1402,7 @@ Symfony is the result of the work of many people who made the code better - Nyro (nyro) - Marco - Marc Torres + - Mark Spink - Alberto Aldegheri - Dmitri Petmanson - heccjj @@ -1412,7 +1423,6 @@ Symfony is the result of the work of many people who made the code better - David Négrier (moufmouf) - Quique Porta (quiqueporta) - mohammadreza honarkhah - - stoccc - Andrea Quintino (dirk39) - Tomasz Szymczyk (karion) - Alex Vasilchenko @@ -1468,7 +1478,6 @@ Symfony is the result of the work of many people who made the code better - Walter Dal Mut (wdalmut) - abluchet - Ruud Arentsen - - Ahmed Raafat - Harald Tollefsen - Matthieu - Albin Kerouaton @@ -1504,7 +1513,6 @@ Symfony is the result of the work of many people who made the code better - Antal Áron (antalaron) - Vašek Purchart (vasek-purchart) - Janusz Jabłoński (yanoosh) - - Ivan Grigoriev - Fleuv - Sandro Hopf - Łukasz Makuch @@ -1522,6 +1530,7 @@ Symfony is the result of the work of many people who made the code better - Philip Frank - David Brooks - Lance McNearney + - Serhiy Lunak (slunak) - Giorgio Premi - Aurélien Fontaine - ncou @@ -1531,6 +1540,7 @@ Symfony is the result of the work of many people who made the code better - Matt Daum (daum) - Alberto Pirovano (geezmo) - Pete Mitchell (peterjmit) + - phuc vo (phucwan) - Tom Corrigan (tomcorrigan) - Luis Galeas - Bogdan Scordaliu @@ -1543,7 +1553,6 @@ Symfony is the result of the work of many people who made the code better - WedgeSama - Felds Liscia - Chihiro Adachi (chihiro-adachi) - - Axel Guckelsberger (guite) - Raphaëll Roussel - Tadcka - Beth Binkovitz @@ -1651,6 +1660,7 @@ Symfony is the result of the work of many people who made the code better - Flavian (2much) - Gautier Deuette - mike + - tadas - Kirk Madera - Keith Maika - Mephistofeles @@ -1834,6 +1844,7 @@ Symfony is the result of the work of many people who made the code better - alefranz - David Barratt - Andrea Giannantonio + - Dries Vints - Pavel.Batanov - avi123 - Pavel Prischepa @@ -1900,6 +1911,7 @@ Symfony is the result of the work of many people who made the code better - Yannick Warnier (ywarnier) - Kevin Decherf - Jason Woods + - Christian Weiske - Maria Grazia Patteri - klemens - dened @@ -2149,6 +2161,7 @@ Symfony is the result of the work of many people who made the code better - Evgeniy Tetenchuk - Sjoerd Adema - Shrey Puranik + - Evgeniy Koval - Lars Moelleken - dasmfm - Mathias Geat @@ -2208,6 +2221,7 @@ Symfony is the result of the work of many people who made the code better - Niklas Keller - Andras Debreczeni - Vladimir Sazhin + - Michel Bardelmeijer - Tomas Kmieliauskas - Billie Thompson - lol768 @@ -2241,6 +2255,7 @@ Symfony is the result of the work of many people who made the code better - Michael Schneider - Cédric Bertolini - n-aleha + - Talha Zekeriya Durmuş - Anatol Belski - Anderson Müller - Şəhriyar İmanov @@ -2268,6 +2283,7 @@ Symfony is the result of the work of many people who made the code better - Neophy7e - bokonet - Arrilot + - ampaze - Markus Staab - Pierre-Louis LAUNAY - djama @@ -2417,6 +2433,7 @@ Symfony is the result of the work of many people who made the code better - Michal Čihař (mcihar) - Matt Drollette (mdrollette) - Adam Monsen (meonkeys) + - Mike Milano (mmilano) - diego aguiar (mollokhan) - Hugo Monteiro (monteiro) - Ala Eddine Khefifi (nayzo) From f59e0e9c236c1b31440e120be2fd0a2794509310 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 28 Apr 2020 19:41:38 +0200 Subject: [PATCH 86/89] updated VERSION for 3.4.40 --- 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 9422d90e9ee9b..dc9cc048eb53f 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.40-DEV'; + const VERSION = '3.4.40'; const VERSION_ID = 30440; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; const RELEASE_VERSION = 40; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From dfc4a71eacf979e0b561ddeefac1de9f09e255a1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 28 Apr 2020 20:23:58 +0200 Subject: [PATCH 87/89] [Validator] fix merge --- .../Tests/Violation/ConstraintViolationBuilderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php b/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php index 07ef55cd81258..b455441e33ad1 100644 --- a/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php +++ b/src/Symfony/Component/Validator/Tests/Violation/ConstraintViolationBuilderTest.php @@ -70,10 +70,10 @@ public function testAppendMultiplePropertyPaths() public function testCodeCanBeSet() { $this->builder - ->setCode(5) + ->setCode('5') ->addViolation(); - $this->assertViolationEquals(new ConstraintViolation($this->messageTemplate, $this->messageTemplate, [], $this->root, 'data', 'foo', null, 5, new Valid())); + $this->assertViolationEquals(new ConstraintViolation($this->messageTemplate, $this->messageTemplate, [], $this->root, 'data', 'foo', null, '5', new Valid())); } public function testCauseCanBeSet() From d408c5584547ec0f014b8556e4e8d4b1c11385e2 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 28 Apr 2020 20:47:32 +0200 Subject: [PATCH 88/89] updated CHANGELOG for 4.4.8 --- CHANGELOG-4.4.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/CHANGELOG-4.4.md b/CHANGELOG-4.4.md index 68eceda5b9742..be58f04b95501 100644 --- a/CHANGELOG-4.4.md +++ b/CHANGELOG-4.4.md @@ -7,6 +7,56 @@ in 4.4 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.4.0...v4.4.1 +* 4.4.8 (2020-04-28) + + * bug #36536 [Cache] Allow invalidateTags calls to be traced by data collector (l-vo) + * bug #36566 [PhpUnitBridge] Use COMPOSER_BINARY env var if available (fancyweb) + * bug #36560 [YAML] escape DEL(\x7f) (sdkawata) + * bug #36539 [PhpUnitBridge] fix compatibility with phpunit 9 (garak) + * bug #36555 [Cache] skip APCu in chains when the backend is disabled (nicolas-grekas) + * bug #36523 [Form] apply automatically step=1 for datetime-local input (ottaviano) + * bug #36519 [FrameworkBundle] debug:autowiring: Fix wrong display when using class_alias (weaverryan) + * bug #36454 [DependencyInjection][ServiceSubscriber] Support late aliases (fancyweb) + * bug #36498 [Security/Core] fix escape for username in LdapBindAuthenticationProvider.php (stoccc) + * bug #36506 [FrameworkBundle] Fix session.attribute_bag service definition (fancyweb) + * bug #36500 [Routing][PrefixTrait] Add the _locale requirement (fancyweb) + * bug #36457 [Cache] CacheItem with tag is never a hit after expired (alexander-schranz, nicolas-grekas) + * bug #36490 [HttpFoundation] workaround PHP bug in the session module (nicolas-grekas) + * bug #36483 [SecurityBundle] fix accepting env vars in remember-me configurations (zek) + * bug #36343 [Form] Fixed handling groups sequence validation (HeahDude) + * bug #36460 [Cache] Avoid memory leak in TraceableAdapter::reset() (lyrixx) + * bug #36467 Mailer from sender fixes (fabpot) + * bug #36408 [PhpUnitBridge] add PolyfillTestCaseTrait::expectExceptionMessageMatches to provide FC with recent phpunit versions (soyuka) + * bug #36447 Remove return type for Twig function workflow_metadata() (gisostallenberg) + * bug #36449 [Messenger] Make sure redis transports are initialized correctly (Seldaek) + * bug #36411 [Form] RepeatedType should always have inner types mapped (biozshock) + * bug #36441 [DI] fix loading defaults when using the PHP-DSL (nicolas-grekas) + * bug #36434 [HttpKernel] silence E_NOTICE triggered since PHP 7.4 (xabbuh) + * bug #36365 [Validator] Fixed default group for nested composite constraints (HeahDude) + * bug #36422 [HttpClient] fix HTTP/2 support on non-SSL connections - CurlHttpClient only (nicolas-grekas) + * bug #36417 Force ping after transport exception (oesteve) + * bug #35591 [Validator] do not merge constraints within interfaces (greedyivan) + * bug #36377 [HttpClient] Fix scoped client without query option configuration (X-Coder264) + * bug #36387 [DI] fix detecting short service syntax in yaml (nicolas-grekas) + * bug #36392 [DI] add missing property declarations in InlineServiceConfigurator (nicolas-grekas) + * bug #36400 Allowing empty secrets to be set (weaverryan) + * bug #36380 [Process] Fixed input/output error on PHP 7.4 (mbardelmeijer) + * bug #36376 [Workflow] Use a strict comparison when retrieving raw marking in MarkingStore (lyrixx) + * bug #36375 [Workflow] Use a strict comparison when retrieving raw marking in MarkingStore (lyrixx) + * bug #36305 [PropertyInfo][ReflectionExtractor] Check the array mutator prefixes last when the property is singular (fancyweb) + * bug #35656 [HttpFoundation] Fixed session migration with custom cookie lifetime (Guite) + * bug #36342 [HttpKernel][FrameworkBundle] fix compat with Debug component (nicolas-grekas) + * bug #36315 [WebProfilerBundle] Support for Content Security Policy style-src-elem and script-src-elem in WebProfiler (ampaze) + * bug #36286 [Validator] Allow URL-encoded special characters in basic auth part of URLs (cweiske) + * bug #36335 [Security] Track session usage whenever a new token is set (wouterj) + * bug #36332 [Serializer] Fix unitialized properties (from PHP 7.4.2) when serializing context for the cache key (alanpoulain) + * bug #36337 [MonologBridge] Fix $level type (fancyweb) + * bug #36223 [Security][Http][SwitchUserListener] Ignore all non existent username protection errors (fancyweb) + * bug #36239 [HttpKernel][LoggerDataCollector] Prevent keys collisions in the sanitized logs processing (fancyweb) + * bug #36245 [Validator] Fixed calling getters before resolving groups (HeahDude) + * bug #36265 Fix the reporting of deprecations in twig:lint (stof) + * bug #36283 [Security] forward multiple attributes voting flag (xabbuh) + * 4.4.7 (2020-03-30) * security #cve-2020-5255 [HttpFoundation] Do not set the default Content-Type based on the Accept header (yceruto) From f7b9d93cb2321943663af210bf04efc7d5969c1e Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 28 Apr 2020 20:47:42 +0200 Subject: [PATCH 89/89] updated VERSION for 4.4.8 --- 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 c583aa66d7650..9cb3a034d6961 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '4.4.8-DEV'; + const VERSION = '4.4.8'; const VERSION_ID = 40408; const MAJOR_VERSION = 4; const MINOR_VERSION = 4; const RELEASE_VERSION = 8; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2022'; const END_OF_LIFE = '11/2023'; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy