From be6612060c82b45d039c0679249739b6c68a83d2 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Fri, 27 Mar 2020 20:34:28 +0100 Subject: [PATCH 01/18] 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 a16d9d7fcb..03b258ec82 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 42311d5c29a47c17ca2bf7620f5dfc39e8482186 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Wed, 1 Apr 2020 11:15:47 +0200 Subject: [PATCH 02/18] [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 21bd1bc1cd..a6718a7232 100644 --- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php @@ -168,7 +168,7 @@ class SwitchUserListener extends AbstractListener implements ListenerInterface 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 03/18] [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 dcb06ee192..3306946a9b 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 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp $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 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp $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 5a5c0c7b62..36fc9d55e3 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -61,6 +61,7 @@ class ReflectionExtractorTest extends TestCase 'realParent', 'xTotals', 'YT', + 'date', 'c', 'd', 'e', @@ -96,6 +97,7 @@ class ReflectionExtractorTest extends TestCase 'foo4', 'foo5', 'files', + 'date', 'c', 'd', 'e', @@ -156,6 +158,8 @@ class ReflectionExtractorTest extends TestCase ['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 663fef84c7..4a7b7c0951 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php @@ -190,4 +190,12 @@ class Dummy extends ParentDummy 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 04/18] 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 a38e7c686f..e62895fe6d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php @@ -128,7 +128,7 @@ class ContentSecurityPolicyHandler $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 05/18] 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 5165b5d0d8..d6ce2a79de 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -223,10 +223,6 @@ class NativeSessionStorage implements SessionStorageInterface $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 d9c06814f9a0fa05762aa6a0ecdae510619501b1 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 3 Apr 2020 16:59:55 +0200 Subject: [PATCH 06/18] [5.0][MonologBridge] Fix $level type --- src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php | 7 +++++-- src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php b/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php index 6152dece8f..be60c7dcbf 100644 --- a/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php @@ -26,11 +26,14 @@ class NotifierHandler extends AbstractHandler { private $notifier; - public function __construct(NotifierInterface $notifier, int $level = Logger::ERROR, bool $bubble = true) + /** + * @param string|int $level The minimum logging level at which this handler will be triggered + */ + public function __construct(NotifierInterface $notifier, $level = Logger::ERROR, bool $bubble = true) { $this->notifier = $notifier; - parent::__construct($level < Logger::ERROR ? Logger::ERROR : $level, $bubble); + parent::__construct(Logger::toMonologLevel($level) < Logger::ERROR ? Logger::ERROR : $level, $bubble); } public function handle(array $record): bool diff --git a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php index 4016d402b9..d6d0c5dabf 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php @@ -54,7 +54,10 @@ trait ServerLogHandlerTrait 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 19a8905d321530de1301df19de092dfa7a10dbf0 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 3 Apr 2020 16:53:29 +0200 Subject: [PATCH 07/18] [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 b8b0f7b9e9..99ba3bbc3d 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 28582d3172..e5a26ccd22 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 08/18] 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 fef2732759..22d378835e 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 0000000000..9833d05513 --- /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 bb0969c36a..83cd4118d7 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/GuardedTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/GuardedTest.php @@ -21,4 +21,14 @@ class GuardedTest extends AbstractWebTestCase $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 2d1f779a53..7f87c307d2 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 4d11154375..146aa811a1 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 bf491797aa..dd8a5ae004 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 @@ class TokenStorage implements TokenStorageInterface, ResetInterface @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 3ce8913aa4..b90d5ab28b 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 @@ final class UsageTrackingTokenStorage implements TokenStorageInterface, ServiceS 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 82a5f917d9..7e89c0b1b3 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 @@ class ContextListenerTest extends TestCase 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 @@ class ContextListenerTest extends TestCase $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 699ffcf703..6b23f5cc8e 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 09/18] [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 80911a9902..3c03fd8525 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 cba6191554..688e11fbe9 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 10/18] [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 56dc3c590e..1eba26343d 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -400,6 +400,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer */ 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 d5d7cace36..d269da27e8 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -163,6 +163,14 @@ class AbstractObjectNormalizerTest extends TestCase $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 @@ class ArrayDenormalizerDummy implements DenormalizerInterface, SerializerAwareIn $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 11/18] 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 d934162eee..97a0545075 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 0357172680..6bcc5c54c5 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php @@ -122,6 +122,8 @@ class UrlValidatorTest extends ConstraintValidatorTestCase ['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 @@ class UrlValidatorTest extends ConstraintValidatorTestCase ['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 12/18] [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 1eba26343d..c1fc4ad82f 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -304,7 +304,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer */ 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 13/18] [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 b505daf131..0dc2860229 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -35,6 +35,7 @@ use Symfony\Component\Cache\DependencyInjection\CachePoolPass; 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 dcb54ea891..0e672a299d 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php @@ -15,6 +15,7 @@ use Psr\Log\LoggerInterface; 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 @@ class DebugHandlersListener implements EventSubscriberInterface 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 @@ class DebugHandlersListener implements EventSubscriberInterface } } 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 14/18] [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 7502897a44..66343cd31e 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -152,7 +152,7 @@ class NativeSessionStorage implements SessionStorageInterface // 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 @@ class NativeSessionStorage implements SessionStorageInterface 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 @@ class NativeSessionStorage implements SessionStorageInterface 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 d2cf324525..7cfcd223e0 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 @@ class NativeSessionStorageTest extends TestCase $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 15/18] [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 66b38eaf3c..d1b3625fb1 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -505,7 +505,7 @@ class PropertyAccessor implements PropertyAccessorInterface 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 62a95d68e9..6ccf674113 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -126,7 +126,7 @@ class PropertyAccessorTest extends TestCase 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 16/18] 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 8d6e9f63f6..5fdb9e2657 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/Debug/OptionsResolverIntrospectorTest.php @@ -44,7 +44,7 @@ class OptionsResolverIntrospectorTest extends TestCase $resolver->setDefined($option = 'foo'); $debug = new OptionsResolverIntrospector($resolver); - $this->assertSame('bar', $debug->getDefault($option)); + $debug->getDefault($option); } public function testGetDefaultThrowsOnNotDefinedOption() @@ -54,7 +54,7 @@ class OptionsResolverIntrospectorTest extends TestCase $resolver = new OptionsResolver(); $debug = new OptionsResolverIntrospector($resolver); - $this->assertSame('bar', $debug->getDefault('foo')); + $debug->getDefault('foo'); } public function testGetLazyClosures() @@ -75,7 +75,7 @@ class OptionsResolverIntrospectorTest extends TestCase $resolver->setDefined($option = 'foo'); $debug = new OptionsResolverIntrospector($resolver); - $this->assertSame('bar', $debug->getLazyClosures($option)); + $debug->getLazyClosures($option); } public function testGetLazyClosuresThrowsOnNotDefinedOption() @@ -85,7 +85,7 @@ class OptionsResolverIntrospectorTest extends TestCase $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 17/18] [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 acccc7cbfb..349db2aaf7 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php @@ -41,7 +41,7 @@ class ContentSecurityPolicyHandlerTest extends TestCase $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 @@ class ContentSecurityPolicyHandlerTest extends TestCase ['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 18/18] [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 d1b3625fb1..6f715d6204 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -472,7 +472,7 @@ class PropertyAccessor implements PropertyAccessorInterface } 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 @@ class PropertyAccessor implements PropertyAccessorInterface 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 6ccf674113..d8331e76ad 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -137,7 +137,7 @@ class PropertyAccessorTest extends TestCase 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 7198d07798..4c7d37428e 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -720,7 +720,7 @@ class Inline 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 @@ class Inline 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;