diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php
index 5415d3f5ad..d26bdd19ff 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php
@@ -14,6 +14,8 @@ namespace Symfony\Bundle\FrameworkBundle\Routing;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\Config\Resource\FileExistenceResource;
+use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\Config\ContainerParametersResource;
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
@@ -71,6 +73,16 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI
$this->collection = $this->container->get('routing.loader')->load($this->resource, $this->options['resource_type']);
$this->resolveParameters($this->collection);
$this->collection->addResource(new ContainerParametersResource($this->collectedParameters));
+
+ try {
+ $containerFile = ($this->paramFetcher)('kernel.cache_dir').'/'.($this->paramFetcher)('kernel.container_class').'.php';
+ if (file_exists($containerFile)) {
+ $this->collection->addResource(new FileResource($containerFile));
+ } else {
+ $this->collection->addResource(new FileExistenceResource($containerFile));
+ }
+ } catch (ParameterNotFoundException $exception) {
+ }
}
return $this->collection;
diff --git a/src/Symfony/Component/ErrorHandler/ErrorHandler.php b/src/Symfony/Component/ErrorHandler/ErrorHandler.php
index c98eea89e5..0c8edfcd9d 100644
--- a/src/Symfony/Component/ErrorHandler/ErrorHandler.php
+++ b/src/Symfony/Component/ErrorHandler/ErrorHandler.php
@@ -519,7 +519,7 @@ class ErrorHandler
if ($this->isRecursive) {
$log = 0;
} else {
- if (!\defined('HHVM_VERSION')) {
+ if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404)) {
$currentErrorHandler = set_error_handler('var_dump');
restore_error_handler();
}
@@ -531,7 +531,7 @@ class ErrorHandler
} finally {
$this->isRecursive = false;
- if (!\defined('HHVM_VERSION')) {
+ if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404)) {
set_error_handler($currentErrorHandler);
}
}
diff --git a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php
index 70710302fd..28b3115492 100644
--- a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php
+++ b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php
@@ -363,8 +363,6 @@ class ErrorHandlerTest extends TestCase
$handler = new ErrorHandler();
$handler->setDefaultLogger($logger);
@$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);
-
- restore_error_handler();
}
/**
@@ -618,6 +616,10 @@ class ErrorHandlerTest extends TestCase
public function testAssertQuietEval()
{
+ if ('-1' === ini_get('zend.assertions')) {
+ $this->markTestSkipped('zend.assertions is forcibly disabled');
+ }
+
$ini = [
ini_set('zend.assertions', 1),
ini_set('assert.active', 1),
diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
index 2dfbbf17d6..b5288920ac 100644
--- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
+++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
@@ -117,11 +117,16 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
// date-only patterns require parsing to be done in UTC, as midnight might not exist in the local timezone due
// to DST changes
$dateOnly = $this->isPatternDateOnly();
+ $dateFormatter = $this->getIntlDateFormatter($dateOnly);
- $timestamp = $this->getIntlDateFormatter($dateOnly)->parse($value);
+ try {
+ $timestamp = @$dateFormatter->parse($value);
+ } catch (\IntlException $e) {
+ throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
+ }
if (0 != intl_get_error_code()) {
- throw new TransformationFailedException(intl_get_error_message());
+ throw new TransformationFailedException(intl_get_error_message(), intl_get_error_code());
} elseif ($timestamp > 253402214400) {
// This timestamp represents UTC midnight of 9999-12-31 to prevent 5+ digit years
throw new TransformationFailedException('Years beyond 9999 are not supported.');
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php
index 808571cbef..c9821bfe74 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php
@@ -27,6 +27,12 @@ class DateTimeToLocalizedStringTransformerTest extends TestCase
{
parent::setUp();
+ // Normalize intl. configuration settings.
+ if (\extension_loaded('intl')) {
+ $this->iniSet('intl.use_exceptions', 0);
+ $this->iniSet('intl.error_level', 0);
+ }
+
// Since we test against "de_AT", we need the full implementation
IntlTestHelper::requireFullIntl($this, '57.1');
@@ -322,4 +328,44 @@ class DateTimeToLocalizedStringTransformerTest extends TestCase
$transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', null, null, \IntlDateFormatter::GREGORIAN, 'yyyy-MM-dd HH:mm:ss');
$transformer->reverseTransform('20107-03-21 12:34:56');
}
+
+ public function testReverseTransformWrapsIntlErrorsWithErrorLevel()
+ {
+ if (!\extension_loaded('intl')) {
+ $this->markTestSkipped('intl extension is not loaded');
+ }
+
+ $this->iniSet('intl.error_level', E_WARNING);
+
+ $this->expectException('Symfony\Component\Form\Exception\TransformationFailedException');
+ $transformer = new DateTimeToLocalizedStringTransformer();
+ $transformer->reverseTransform('12345');
+ }
+
+ public function testReverseTransformWrapsIntlErrorsWithExceptions()
+ {
+ if (!\extension_loaded('intl')) {
+ $this->markTestSkipped('intl extension is not loaded');
+ }
+
+ $this->iniSet('intl.use_exceptions', 1);
+
+ $this->expectException('Symfony\Component\Form\Exception\TransformationFailedException');
+ $transformer = new DateTimeToLocalizedStringTransformer();
+ $transformer->reverseTransform('12345');
+ }
+
+ public function testReverseTransformWrapsIntlErrorsWithExceptionsAndErrorLevel()
+ {
+ if (!\extension_loaded('intl')) {
+ $this->markTestSkipped('intl extension is not loaded');
+ }
+
+ $this->iniSet('intl.use_exceptions', 1);
+ $this->iniSet('intl.error_level', E_WARNING);
+
+ $this->expectException('Symfony\Component\Form\Exception\TransformationFailedException');
+ $transformer = new DateTimeToLocalizedStringTransformer();
+ $transformer->reverseTransform('12345');
+ }
}
diff --git a/src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php b/src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
index 56b9245f93..5acefc9c96 100644
--- a/src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
+++ b/src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
@@ -239,9 +239,9 @@ class ResponseHeaderBag extends HeaderBag
/**
* Clears a cookie in the browser.
*/
- public function clearCookie(string $name, ?string $path = '/', string $domain = null, bool $secure = false, bool $httpOnly = true)
+ public function clearCookie(string $name, ?string $path = '/', string $domain = null, bool $secure = false, bool $httpOnly = true, string $sameSite = null)
{
- $this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly, false, null));
+ $this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly, false, $sameSite));
}
/**
diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
index 4d92441223..18b3c36a6a 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
@@ -128,6 +128,14 @@ class ResponseHeaderBagTest extends TestCase
$this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0; path=/; secure', $bag);
}
+ public function testClearCookieSamesite()
+ {
+ $bag = new ResponseHeaderBag([]);
+
+ $bag->clearCookie('foo', '/', null, true, false, 'none');
+ $this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0; path=/; secure; samesite=none', $bag);
+ }
+
public function testReplace()
{
$bag = new ResponseHeaderBag([]);
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index 5b00a5cd48..658d4860f6 100644
--- a/src/Symfony/Component/HttpKernel/Kernel.php
+++ b/src/Symfony/Component/HttpKernel/Kernel.php
@@ -38,9 +38,6 @@ use Symfony\Component\HttpKernel\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\AddAnnotatedClassesToCachePass;
use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
-// Help opcache.preload discover always-needed symbols
-class_exists(ConfigCache::class);
-
/**
* The Kernel is the heart of the Symfony system.
*
@@ -452,47 +449,20 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
try {
is_dir($cacheDir) ?: mkdir($cacheDir, 0777, true);
- if ($lock = fopen($cachePath, 'w')) {
- chmod($cachePath, 0666 & ~umask());
+ if ($lock = fopen($cachePath.'.lock', 'w')) {
flock($lock, LOCK_EX | LOCK_NB, $wouldBlock);
if (!flock($lock, $wouldBlock ? LOCK_SH : LOCK_EX)) {
fclose($lock);
- } else {
- $cache = new class($cachePath, $this->debug) extends ConfigCache {
- public $lock;
+ $lock = null;
+ } elseif (!\is_object($this->container = include $cachePath)) {
+ $this->container = null;
+ } elseif (!$oldContainer || \get_class($this->container) !== $oldContainer->name) {
+ flock($lock, LOCK_UN);
+ fclose($lock);
+ $this->container->set('kernel', $this);
- public function write(string $content, array $metadata = null)
- {
- rewind($this->lock);
- ftruncate($this->lock, 0);
- fwrite($this->lock, $content);
-
- if (null !== $metadata) {
- file_put_contents($this->getPath().'.meta', serialize($metadata));
- @chmod($this->getPath().'.meta', 0666 & ~umask());
- }
-
- if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
- @opcache_invalidate($this->getPath(), true);
- }
- }
-
- public function release()
- {
- flock($this->lock, LOCK_UN);
- fclose($this->lock);
- }
- };
- $cache->lock = $lock;
-
- if (!\is_object($this->container = include $cachePath)) {
- $this->container = null;
- } elseif (!$oldContainer || \get_class($this->container) !== $oldContainer->name) {
- $this->container->set('kernel', $this);
-
- return;
- }
+ return;
}
}
} catch (\Throwable $e) {
@@ -556,8 +526,10 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
}
$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
- if (method_exists($cache, 'release')) {
- $cache->release();
+
+ if ($lock) {
+ flock($lock, LOCK_UN);
+ fclose($lock);
}
$this->container = require $cachePath;
diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php
index 22ef23e84b..c9cd0ad8cc 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 @@ class SesApiTransport extends AbstractApiTransport
$result = new \SimpleXMLElement($response->getContent(false));
if (200 !== $response->getStatusCode()) {
- throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $result->Error->Message, $result->Error->Code), $response);
+ throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result->Error->Message, $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 1bb6c5486e..9cedbdf4c7 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 @@ class SesHttpTransport extends AbstractHttpTransport
$result = new \SimpleXMLElement($response->getContent(false));
if (200 !== $response->getStatusCode()) {
- throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $result->Error->Message, $result->Error->Code), $response);
+ throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result->Error->Message, $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 af221ca66e..9b7c181b29 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php
+++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php
@@ -51,10 +51,10 @@ class MandrillApiTransport extends AbstractApiTransport
$result = $response->toArray(false);
if (200 !== $response->getStatusCode()) {
if ('error' === ($result['status'] ?? false)) {
- throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $result['message'], $result['code']), $response);
+ 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 (code %s).', $result['code']), $response);
+ throw new HttpTransportException(sprintf('Unable to send an email (code %d).', $result['code']), $response);
}
$firstRecipient = reset($result);
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php
index 6ead154906..92f90b8563 100644
--- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php
+++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php
@@ -58,10 +58,10 @@ class MandrillHttpTransport extends AbstractHttpTransport
$result = $response->toArray(false);
if (200 !== $response->getStatusCode()) {
if ('error' === ($result['status'] ?? false)) {
- throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $result['message'], $result['code']), $response);
+ 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 (code %s).', $result['code']), $response);
+ throw new HttpTransportException(sprintf('Unable to send an email (code %d).', $result['code']), $response);
}
$message->setMessageId($result[0]['_id']);
diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php
index cf40a8cf1e..c8ed383fcc 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 @@ class MailgunApiTransport extends AbstractApiTransport
$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 %s).', $result['message'], $response->getStatusCode()), $response);
+ 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: %s (code %s).', $response->getContent(false), $response->getStatusCode()), $response);
+ throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $response->getContent(false), $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 a42598a0b5..3ed6f73369 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 @@ class MailgunHttpTransport extends AbstractHttpTransport
$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 %s).', $result['message'], $response->getStatusCode()), $response);
+ 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: %s (code %s).', $response->getContent(false), $response->getStatusCode()), $response);
+ throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $response->getContent(false), $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 610f858260..352b2eded1 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 @@ class PostmarkApiTransport extends AbstractApiTransport
$result = $response->toArray(false);
if (200 !== $response->getStatusCode()) {
- throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $result['Message'], $result['ErrorCode']), $response);
+ throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', $result['Message'], $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 df90d21472..550fd4bf33 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 @@ class SendgridApiTransport extends AbstractApiTransport
if (202 !== $response->getStatusCode()) {
$errors = $response->toArray(false);
- throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', implode('; ', array_column($errors['errors'], 'message')), $response->getStatusCode()), $response);
+ throw new HttpTransportException(sprintf('Unable to send an email: %s (code %d).', implode('; ', array_column($errors['errors'], 'message')), $response->getStatusCode()), $response);
}
$sentMessage->setMessageId($response->getHeaders(false)['x-message-id'][0]);
diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php
index 0f50ab303b..8bd8cc28b5 100644
--- a/src/Symfony/Component/Process/Process.php
+++ b/src/Symfony/Component/Process/Process.php
@@ -332,7 +332,7 @@ class Process implements \IteratorAggregate
throw new RuntimeException(sprintf('The provided cwd "%s" does not exist.', $this->cwd));
}
- $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $options);
+ $this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $options);
if (!\is_resource($this->process)) {
throw new RuntimeException('Unable to launch a new process.');
diff --git a/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php
index d6b7c0ba4d..e6d7e5dbd0 100644
--- a/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php
+++ b/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php
@@ -35,7 +35,7 @@ final class SodiumPasswordEncoder implements PasswordEncoderInterface, SelfSalti
}
$this->opsLimit = $opsLimit ?? max(4, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE') ? SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE : 4);
- $this->memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 2014);
+ $this->memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 1024);
if (3 > $this->opsLimit) {
throw new \InvalidArgumentException('$opsLimit must be 3 or greater.');
diff --git a/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php b/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php
index e5b9cfb0b7..eb2e70a694 100644
--- a/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php
+++ b/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php
@@ -120,7 +120,7 @@ class GuardAuthenticatorHandler
private function migrateSession(Request $request, TokenInterface $token, ?string $providerKey)
{
- if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession() || \in_array($providerKey, $this->statelessProviderKeys, true)) {
+ if (\in_array($providerKey, $this->statelessProviderKeys, true) || !$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) {
return;
}
diff --git a/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php b/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php
index 0256ec22ff..e078a6be12 100644
--- a/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php
+++ b/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php
@@ -153,6 +153,22 @@ class GuardAuthenticatorHandlerTest extends TestCase
$handler->authenticateWithToken($this->token, $this->request, 'some_provider_key');
}
+ public function testSessionIsNotInstantiatedOnStatelessFirewall()
+ {
+ $sessionFactory = $this->getMockBuilder(\stdClass::class)
+ ->setMethods(['__invoke'])
+ ->getMock();
+
+ $sessionFactory->expects($this->never())
+ ->method('__invoke');
+
+ $this->request->setSessionFactory($sessionFactory);
+
+ $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher, ['stateless_provider_key']);
+ $handler->setSessionAuthenticationStrategy($this->sessionStrategy);
+ $handler->authenticateWithToken($this->token, $this->request, 'stateless_provider_key');
+ }
+
protected function setUp(): void
{
$this->tokenStorage = $this->getMockBuilder(TokenStorageInterface::class)->getMock();
diff --git a/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php
index 33366a9ae7..fe5aa6d3f7 100644
--- a/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php
+++ b/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php
@@ -39,6 +39,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
protected $options = [
'secure' => false,
'httponly' => true,
+ 'samesite' => null,
];
private $providerKey;
private $secret;
@@ -274,7 +275,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
$this->logger->debug('Clearing remember-me cookie.', ['name' => $this->options['name']]);
}
- $request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie($this->options['name'], null, 1, $this->options['path'], $this->options['domain'], $this->options['secure'] ?? $request->isSecure(), $this->options['httponly'], false, $this->options['samesite'] ?? null));
+ $request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie($this->options['name'], null, 1, $this->options['path'], $this->options['domain'], $this->options['secure'] ?? $request->isSecure(), $this->options['httponly'], false, $this->options['samesite']));
}
/**
diff --git a/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
index 61b1257b4a..167a094741 100644
--- a/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
+++ b/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
@@ -86,7 +86,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
$this->options['secure'] ?? $request->isSecure(),
$this->options['httponly'],
false,
- $this->options['samesite'] ?? null
+ $this->options['samesite']
)
);
@@ -121,7 +121,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
$this->options['secure'] ?? $request->isSecure(),
$this->options['httponly'],
false,
- $this->options['samesite'] ?? null
+ $this->options['samesite']
)
);
}
diff --git a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php
index 33427517ca..4dbc05c15f 100644
--- a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php
+++ b/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php
@@ -83,7 +83,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
$this->options['secure'] ?? $request->isSecure(),
$this->options['httponly'],
false,
- $this->options['samesite'] ?? null
+ $this->options['samesite']
)
);
}
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
index 8f8d2d0a0f..674ccf5c30 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
@@ -374,6 +374,14 @@
The number of elements in this collection should be a multiple of {{ 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.
+