From 7fa6cea8233d4f714c5c052176ed012e76e550ba Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 29 Dec 2022 19:57:48 +0100 Subject: [PATCH 01/34] Bump Symfony version to 5.4.19 --- 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 62af9c6acc9d..8f12b88e8102 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -78,12 +78,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ private static $freshCache = []; - public const VERSION = '5.4.18'; - public const VERSION_ID = 50418; + public const VERSION = '5.4.19-DEV'; + public const VERSION_ID = 50419; public const MAJOR_VERSION = 5; public const MINOR_VERSION = 4; - public const RELEASE_VERSION = 18; - public const EXTRA_VERSION = ''; + public const RELEASE_VERSION = 19; + public const EXTRA_VERSION = 'DEV'; public const END_OF_MAINTENANCE = '11/2024'; public const END_OF_LIFE = '11/2025'; From bb5788005eed6255332697d377256a86a6b3df5c Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 30 Dec 2022 09:44:21 +0100 Subject: [PATCH 02/34] [Uid] Fix validating nil and max uuid --- src/Symfony/Component/Uid/Tests/UuidTest.php | 19 +++++++++++++++++++ src/Symfony/Component/Uid/Uuid.php | 10 +++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Uid/Tests/UuidTest.php b/src/Symfony/Component/Uid/Tests/UuidTest.php index 3e3c36c02ab0..8e73eb0d2d05 100644 --- a/src/Symfony/Component/Uid/Tests/UuidTest.php +++ b/src/Symfony/Component/Uid/Tests/UuidTest.php @@ -170,6 +170,25 @@ public function testIsValid() $this->assertTrue(UuidV4::isValid(self::A_UUID_V4)); } + public function testIsValidWithNilUuid() + { + $this->assertTrue(Uuid::isValid('00000000-0000-0000-0000-000000000000')); + $this->assertTrue(NilUuid::isValid('00000000-0000-0000-0000-000000000000')); + + $this->assertFalse(UuidV1::isValid('00000000-0000-0000-0000-000000000000')); + $this->assertFalse(UuidV4::isValid('00000000-0000-0000-0000-000000000000')); + } + + public function testIsValidWithMaxUuid() + { + $this->assertTrue(Uuid::isValid('ffffffff-ffff-ffff-ffff-ffffffffffff')); + $this->assertTrue(Uuid::isValid('FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF')); + $this->assertTrue(Uuid::isValid('fFFFFFFF-ffff-FFFF-FFFF-FFFFffFFFFFF')); + + $this->assertFalse(UuidV5::isValid('ffffffff-ffff-ffff-ffff-ffffffffffff')); + $this->assertFalse(UuidV6::isValid('ffffffff-ffff-ffff-ffff-ffffffffffff')); + } + public function testEquals() { $uuid1 = new UuidV1(self::A_UUID_V1); diff --git a/src/Symfony/Component/Uid/Uuid.php b/src/Symfony/Component/Uid/Uuid.php index a68c5092f09d..6140b4083721 100644 --- a/src/Symfony/Component/Uid/Uuid.php +++ b/src/Symfony/Component/Uid/Uuid.php @@ -58,7 +58,7 @@ public static function fromString(string $uuid): parent $uuid = substr_replace($uuid, '-', 18, 0); $uuid = substr_replace($uuid, '-', 23, 0); } elseif (26 === \strlen($uuid) && Ulid::isValid($uuid)) { - $ulid = new Ulid('00000000000000000000000000'); + $ulid = new NilUlid(); $ulid->uid = strtoupper($uuid); $uuid = $ulid->toRfc4122(); } @@ -117,6 +117,14 @@ final public static function v6(): UuidV6 public static function isValid(string $uuid): bool { + if (self::NIL === $uuid && \in_array(static::class, [__CLASS__, NilUuid::class], true)) { + return true; + } + + if (__CLASS__ === static::class && 'ffffffff-ffff-ffff-ffff-ffffffffffff' === strtr($uuid, 'F', 'f')) { + return true; + } + if (!preg_match('{^[0-9a-f]{8}(?:-[0-9a-f]{4}){2}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$}Di', $uuid)) { return false; } From 313c087cd6bf3a039d21b781aceb5a6b6eba1c52 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 1 Jan 2023 09:32:19 +0100 Subject: [PATCH 03/34] Bump license year to 2023 --- src/Symfony/Bridge/Doctrine/LICENSE | 2 +- src/Symfony/Bridge/Monolog/LICENSE | 2 +- src/Symfony/Bridge/PhpUnit/LICENSE | 2 +- src/Symfony/Bridge/ProxyManager/LICENSE | 2 +- src/Symfony/Bridge/Twig/LICENSE | 2 +- src/Symfony/Bundle/DebugBundle/LICENSE | 2 +- src/Symfony/Bundle/FrameworkBundle/LICENSE | 2 +- src/Symfony/Bundle/SecurityBundle/LICENSE | 2 +- src/Symfony/Bundle/TwigBundle/LICENSE | 2 +- src/Symfony/Bundle/WebProfilerBundle/LICENSE | 2 +- src/Symfony/Component/Asset/LICENSE | 2 +- src/Symfony/Component/BrowserKit/LICENSE | 2 +- src/Symfony/Component/Cache/LICENSE | 2 +- src/Symfony/Component/Config/LICENSE | 2 +- src/Symfony/Component/Console/LICENSE | 2 +- src/Symfony/Component/CssSelector/LICENSE | 2 +- src/Symfony/Component/DependencyInjection/LICENSE | 2 +- src/Symfony/Component/DomCrawler/LICENSE | 2 +- src/Symfony/Component/Dotenv/LICENSE | 2 +- src/Symfony/Component/ErrorHandler/LICENSE | 2 +- src/Symfony/Component/EventDispatcher/LICENSE | 2 +- src/Symfony/Component/ExpressionLanguage/LICENSE | 2 +- src/Symfony/Component/Filesystem/LICENSE | 2 +- src/Symfony/Component/Finder/LICENSE | 2 +- src/Symfony/Component/Form/LICENSE | 2 +- src/Symfony/Component/HttpClient/LICENSE | 2 +- src/Symfony/Component/HttpFoundation/LICENSE | 2 +- src/Symfony/Component/HttpKernel/LICENSE | 2 +- src/Symfony/Component/Inflector/LICENSE | 2 +- src/Symfony/Component/Intl/LICENSE | 2 +- src/Symfony/Component/Ldap/LICENSE | 2 +- src/Symfony/Component/Lock/LICENSE | 2 +- src/Symfony/Component/Mailer/Bridge/Amazon/LICENSE | 2 +- src/Symfony/Component/Mailer/Bridge/Google/LICENSE | 2 +- src/Symfony/Component/Mailer/Bridge/Mailchimp/LICENSE | 2 +- src/Symfony/Component/Mailer/Bridge/Mailgun/LICENSE | 2 +- src/Symfony/Component/Mailer/Bridge/Mailjet/LICENSE | 2 +- src/Symfony/Component/Mailer/Bridge/OhMySmtp/LICENSE | 2 +- src/Symfony/Component/Mailer/Bridge/Postmark/LICENSE | 2 +- src/Symfony/Component/Mailer/Bridge/Sendgrid/LICENSE | 2 +- src/Symfony/Component/Mailer/Bridge/Sendinblue/LICENSE | 2 +- src/Symfony/Component/Mailer/LICENSE | 2 +- src/Symfony/Component/Messenger/Bridge/AmazonSqs/LICENSE | 2 +- src/Symfony/Component/Messenger/Bridge/Amqp/LICENSE | 2 +- src/Symfony/Component/Messenger/Bridge/Beanstalkd/LICENSE | 2 +- src/Symfony/Component/Messenger/Bridge/Doctrine/LICENSE | 2 +- src/Symfony/Component/Messenger/Bridge/Redis/LICENSE | 2 +- src/Symfony/Component/Messenger/LICENSE | 2 +- src/Symfony/Component/Mime/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/AllMySms/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/AmazonSns/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Clickatell/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Discord/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Esendex/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Expo/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/FakeChat/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/FakeSms/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Firebase/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/FreeMobile/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/GatewayApi/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Gitter/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/GoogleChat/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Infobip/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Iqsms/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/LightSms/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/LinkedIn/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Mailjet/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Mattermost/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Mercure/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/MessageBird/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/MessageMedia/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/MicrosoftTeams/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Mobyt/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Nexmo/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Octopush/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/OneSignal/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/OvhCloud/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/RocketChat/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Sendinblue/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Sinch/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Slack/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Sms77/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/SmsBiuras/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Smsapi/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Smsc/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/SpotHit/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Telegram/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Telnyx/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/TurboSms/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Twilio/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Vonage/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Yunpian/LICENSE | 2 +- src/Symfony/Component/Notifier/Bridge/Zulip/LICENSE | 2 +- src/Symfony/Component/Notifier/LICENSE | 2 +- src/Symfony/Component/OptionsResolver/LICENSE | 2 +- src/Symfony/Component/PasswordHasher/LICENSE | 2 +- src/Symfony/Component/Process/LICENSE | 2 +- src/Symfony/Component/PropertyAccess/LICENSE | 2 +- src/Symfony/Component/PropertyInfo/LICENSE | 2 +- src/Symfony/Component/RateLimiter/LICENSE | 2 +- src/Symfony/Component/Routing/LICENSE | 2 +- src/Symfony/Component/Runtime/LICENSE | 2 +- src/Symfony/Component/Security/Core/LICENSE | 2 +- src/Symfony/Component/Security/Csrf/LICENSE | 2 +- src/Symfony/Component/Security/Guard/LICENSE | 2 +- src/Symfony/Component/Security/Http/LICENSE | 2 +- src/Symfony/Component/Semaphore/LICENSE | 2 +- src/Symfony/Component/Serializer/LICENSE | 2 +- src/Symfony/Component/Stopwatch/LICENSE | 2 +- src/Symfony/Component/String/LICENSE | 2 +- src/Symfony/Component/Templating/LICENSE | 2 +- src/Symfony/Component/Translation/Bridge/Crowdin/LICENSE | 2 +- src/Symfony/Component/Translation/Bridge/Loco/LICENSE | 2 +- src/Symfony/Component/Translation/Bridge/Lokalise/LICENSE | 2 +- src/Symfony/Component/Translation/LICENSE | 2 +- src/Symfony/Component/Uid/LICENSE | 2 +- src/Symfony/Component/Validator/LICENSE | 2 +- src/Symfony/Component/VarDumper/LICENSE | 2 +- src/Symfony/Component/VarExporter/LICENSE | 2 +- src/Symfony/Component/WebLink/LICENSE | 2 +- src/Symfony/Component/Workflow/LICENSE | 2 +- src/Symfony/Component/Yaml/LICENSE | 2 +- src/Symfony/Contracts/Cache/LICENSE | 2 +- src/Symfony/Contracts/Deprecation/LICENSE | 2 +- src/Symfony/Contracts/EventDispatcher/LICENSE | 2 +- src/Symfony/Contracts/HttpClient/LICENSE | 2 +- src/Symfony/Contracts/LICENSE | 2 +- src/Symfony/Contracts/Service/LICENSE | 2 +- src/Symfony/Contracts/Translation/LICENSE | 2 +- 129 files changed, 129 insertions(+), 129 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/LICENSE b/src/Symfony/Bridge/Doctrine/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Bridge/Doctrine/LICENSE +++ b/src/Symfony/Bridge/Doctrine/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Bridge/Monolog/LICENSE b/src/Symfony/Bridge/Monolog/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Bridge/Monolog/LICENSE +++ b/src/Symfony/Bridge/Monolog/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Bridge/PhpUnit/LICENSE b/src/Symfony/Bridge/PhpUnit/LICENSE index a843ec124ea7..72412a62b202 100644 --- a/src/Symfony/Bridge/PhpUnit/LICENSE +++ b/src/Symfony/Bridge/PhpUnit/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2022 Fabien Potencier +Copyright (c) 2014-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Bridge/ProxyManager/LICENSE b/src/Symfony/Bridge/ProxyManager/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Bridge/ProxyManager/LICENSE +++ b/src/Symfony/Bridge/ProxyManager/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Bridge/Twig/LICENSE b/src/Symfony/Bridge/Twig/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Bridge/Twig/LICENSE +++ b/src/Symfony/Bridge/Twig/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Bundle/DebugBundle/LICENSE b/src/Symfony/Bundle/DebugBundle/LICENSE index a843ec124ea7..72412a62b202 100644 --- a/src/Symfony/Bundle/DebugBundle/LICENSE +++ b/src/Symfony/Bundle/DebugBundle/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2022 Fabien Potencier +Copyright (c) 2014-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Bundle/FrameworkBundle/LICENSE b/src/Symfony/Bundle/FrameworkBundle/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Bundle/FrameworkBundle/LICENSE +++ b/src/Symfony/Bundle/FrameworkBundle/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Bundle/SecurityBundle/LICENSE b/src/Symfony/Bundle/SecurityBundle/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Bundle/SecurityBundle/LICENSE +++ b/src/Symfony/Bundle/SecurityBundle/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Bundle/TwigBundle/LICENSE b/src/Symfony/Bundle/TwigBundle/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Bundle/TwigBundle/LICENSE +++ b/src/Symfony/Bundle/TwigBundle/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Bundle/WebProfilerBundle/LICENSE b/src/Symfony/Bundle/WebProfilerBundle/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/LICENSE +++ b/src/Symfony/Bundle/WebProfilerBundle/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Asset/LICENSE b/src/Symfony/Component/Asset/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Asset/LICENSE +++ b/src/Symfony/Component/Asset/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/BrowserKit/LICENSE b/src/Symfony/Component/BrowserKit/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/BrowserKit/LICENSE +++ b/src/Symfony/Component/BrowserKit/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Cache/LICENSE b/src/Symfony/Component/Cache/LICENSE index 7fa953905492..f2345234aa9e 100644 --- a/src/Symfony/Component/Cache/LICENSE +++ b/src/Symfony/Component/Cache/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2022 Fabien Potencier +Copyright (c) 2016-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Config/LICENSE b/src/Symfony/Component/Config/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Config/LICENSE +++ b/src/Symfony/Component/Config/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Console/LICENSE b/src/Symfony/Component/Console/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Console/LICENSE +++ b/src/Symfony/Component/Console/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/CssSelector/LICENSE b/src/Symfony/Component/CssSelector/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/CssSelector/LICENSE +++ b/src/Symfony/Component/CssSelector/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/DependencyInjection/LICENSE b/src/Symfony/Component/DependencyInjection/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/DependencyInjection/LICENSE +++ b/src/Symfony/Component/DependencyInjection/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/DomCrawler/LICENSE b/src/Symfony/Component/DomCrawler/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/DomCrawler/LICENSE +++ b/src/Symfony/Component/DomCrawler/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Dotenv/LICENSE b/src/Symfony/Component/Dotenv/LICENSE index 7fa953905492..f2345234aa9e 100644 --- a/src/Symfony/Component/Dotenv/LICENSE +++ b/src/Symfony/Component/Dotenv/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2022 Fabien Potencier +Copyright (c) 2016-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/ErrorHandler/LICENSE b/src/Symfony/Component/ErrorHandler/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/ErrorHandler/LICENSE +++ b/src/Symfony/Component/ErrorHandler/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/EventDispatcher/LICENSE b/src/Symfony/Component/EventDispatcher/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/EventDispatcher/LICENSE +++ b/src/Symfony/Component/EventDispatcher/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/ExpressionLanguage/LICENSE b/src/Symfony/Component/ExpressionLanguage/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/ExpressionLanguage/LICENSE +++ b/src/Symfony/Component/ExpressionLanguage/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Filesystem/LICENSE b/src/Symfony/Component/Filesystem/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Filesystem/LICENSE +++ b/src/Symfony/Component/Filesystem/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Finder/LICENSE b/src/Symfony/Component/Finder/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Finder/LICENSE +++ b/src/Symfony/Component/Finder/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Form/LICENSE b/src/Symfony/Component/Form/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Form/LICENSE +++ b/src/Symfony/Component/Form/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/HttpClient/LICENSE b/src/Symfony/Component/HttpClient/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Component/HttpClient/LICENSE +++ b/src/Symfony/Component/HttpClient/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/HttpFoundation/LICENSE b/src/Symfony/Component/HttpFoundation/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/HttpFoundation/LICENSE +++ b/src/Symfony/Component/HttpFoundation/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/HttpKernel/LICENSE b/src/Symfony/Component/HttpKernel/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/HttpKernel/LICENSE +++ b/src/Symfony/Component/HttpKernel/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Inflector/LICENSE b/src/Symfony/Component/Inflector/LICENSE index 9f862df30507..7c46c8b00007 100644 --- a/src/Symfony/Component/Inflector/LICENSE +++ b/src/Symfony/Component/Inflector/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012-2022 Fabien Potencier +Copyright (c) 2012-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Intl/LICENSE b/src/Symfony/Component/Intl/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Intl/LICENSE +++ b/src/Symfony/Component/Intl/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Ldap/LICENSE b/src/Symfony/Component/Ldap/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Ldap/LICENSE +++ b/src/Symfony/Component/Ldap/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Lock/LICENSE b/src/Symfony/Component/Lock/LICENSE index 7fa953905492..f2345234aa9e 100644 --- a/src/Symfony/Component/Lock/LICENSE +++ b/src/Symfony/Component/Lock/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2022 Fabien Potencier +Copyright (c) 2016-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/LICENSE b/src/Symfony/Component/Mailer/Bridge/Amazon/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/LICENSE +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/Bridge/Google/LICENSE b/src/Symfony/Component/Mailer/Bridge/Google/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Mailer/Bridge/Google/LICENSE +++ b/src/Symfony/Component/Mailer/Bridge/Google/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/LICENSE b/src/Symfony/Component/Mailer/Bridge/Mailchimp/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/LICENSE +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/LICENSE b/src/Symfony/Component/Mailer/Bridge/Mailgun/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/LICENSE +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/Bridge/Mailjet/LICENSE b/src/Symfony/Component/Mailer/Bridge/Mailjet/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailjet/LICENSE +++ b/src/Symfony/Component/Mailer/Bridge/Mailjet/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/LICENSE b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Mailer/Bridge/OhMySmtp/LICENSE +++ b/src/Symfony/Component/Mailer/Bridge/OhMySmtp/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/LICENSE b/src/Symfony/Component/Mailer/Bridge/Postmark/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Mailer/Bridge/Postmark/LICENSE +++ b/src/Symfony/Component/Mailer/Bridge/Postmark/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/LICENSE b/src/Symfony/Component/Mailer/Bridge/Sendgrid/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/LICENSE +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/Bridge/Sendinblue/LICENSE b/src/Symfony/Component/Mailer/Bridge/Sendinblue/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendinblue/LICENSE +++ b/src/Symfony/Component/Mailer/Bridge/Sendinblue/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mailer/LICENSE b/src/Symfony/Component/Mailer/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Mailer/LICENSE +++ b/src/Symfony/Component/Mailer/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/LICENSE b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/LICENSE index 406242ff2855..0f262c225767 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/LICENSE +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 Fabien Potencier +Copyright (c) 2020-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Messenger/Bridge/Amqp/LICENSE b/src/Symfony/Component/Messenger/Bridge/Amqp/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Component/Messenger/Bridge/Amqp/LICENSE +++ b/src/Symfony/Component/Messenger/Bridge/Amqp/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Messenger/Bridge/Beanstalkd/LICENSE b/src/Symfony/Component/Messenger/Bridge/Beanstalkd/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Component/Messenger/Bridge/Beanstalkd/LICENSE +++ b/src/Symfony/Component/Messenger/Bridge/Beanstalkd/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Messenger/Bridge/Doctrine/LICENSE b/src/Symfony/Component/Messenger/Bridge/Doctrine/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Component/Messenger/Bridge/Doctrine/LICENSE +++ b/src/Symfony/Component/Messenger/Bridge/Doctrine/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/LICENSE b/src/Symfony/Component/Messenger/Bridge/Redis/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/LICENSE +++ b/src/Symfony/Component/Messenger/Bridge/Redis/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Messenger/LICENSE b/src/Symfony/Component/Messenger/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Component/Messenger/LICENSE +++ b/src/Symfony/Component/Messenger/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Mime/LICENSE b/src/Symfony/Component/Mime/LICENSE index 298be14166c2..58b42bc8a98f 100644 --- a/src/Symfony/Component/Mime/LICENSE +++ b/src/Symfony/Component/Mime/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2010-2022 Fabien Potencier +Copyright (c) 2010-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/AllMySms/LICENSE b/src/Symfony/Component/Notifier/Bridge/AllMySms/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/AllMySms/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/AllMySms/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/AmazonSns/LICENSE b/src/Symfony/Component/Notifier/Bridge/AmazonSns/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/AmazonSns/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/AmazonSns/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Clickatell/LICENSE b/src/Symfony/Component/Notifier/Bridge/Clickatell/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Clickatell/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Clickatell/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Discord/LICENSE b/src/Symfony/Component/Notifier/Bridge/Discord/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Discord/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Discord/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Esendex/LICENSE b/src/Symfony/Component/Notifier/Bridge/Esendex/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Esendex/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Esendex/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Expo/LICENSE b/src/Symfony/Component/Notifier/Bridge/Expo/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Expo/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Expo/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/LICENSE b/src/Symfony/Component/Notifier/Bridge/FakeChat/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeChat/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/FakeSms/LICENSE b/src/Symfony/Component/Notifier/Bridge/FakeSms/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeSms/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/FakeSms/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Firebase/LICENSE b/src/Symfony/Component/Notifier/Bridge/Firebase/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Firebase/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Firebase/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/FreeMobile/LICENSE b/src/Symfony/Component/Notifier/Bridge/FreeMobile/LICENSE index 406242ff2855..0f262c225767 100644 --- a/src/Symfony/Component/Notifier/Bridge/FreeMobile/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/FreeMobile/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 Fabien Potencier +Copyright (c) 2020-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/GatewayApi/LICENSE b/src/Symfony/Component/Notifier/Bridge/GatewayApi/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/GatewayApi/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/GatewayApi/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Gitter/LICENSE b/src/Symfony/Component/Notifier/Bridge/Gitter/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Gitter/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Gitter/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/GoogleChat/LICENSE b/src/Symfony/Component/Notifier/Bridge/GoogleChat/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/GoogleChat/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/GoogleChat/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Infobip/LICENSE b/src/Symfony/Component/Notifier/Bridge/Infobip/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Infobip/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Infobip/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Iqsms/LICENSE b/src/Symfony/Component/Notifier/Bridge/Iqsms/LICENSE index 406242ff2855..0f262c225767 100644 --- a/src/Symfony/Component/Notifier/Bridge/Iqsms/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Iqsms/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 Fabien Potencier +Copyright (c) 2020-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/LightSms/LICENSE b/src/Symfony/Component/Notifier/Bridge/LightSms/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/LightSms/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/LightSms/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/LinkedIn/LICENSE b/src/Symfony/Component/Notifier/Bridge/LinkedIn/LICENSE index 406242ff2855..0f262c225767 100644 --- a/src/Symfony/Component/Notifier/Bridge/LinkedIn/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/LinkedIn/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 Fabien Potencier +Copyright (c) 2020-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Mailjet/LICENSE b/src/Symfony/Component/Notifier/Bridge/Mailjet/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Mailjet/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Mailjet/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Mattermost/LICENSE b/src/Symfony/Component/Notifier/Bridge/Mattermost/LICENSE index 406242ff2855..0f262c225767 100644 --- a/src/Symfony/Component/Notifier/Bridge/Mattermost/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Mattermost/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 Fabien Potencier +Copyright (c) 2020-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Mercure/LICENSE b/src/Symfony/Component/Notifier/Bridge/Mercure/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Mercure/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Mercure/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/MessageBird/LICENSE b/src/Symfony/Component/Notifier/Bridge/MessageBird/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/MessageBird/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/MessageBird/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/MessageMedia/LICENSE b/src/Symfony/Component/Notifier/Bridge/MessageMedia/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/MessageMedia/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/MessageMedia/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/MicrosoftTeams/LICENSE b/src/Symfony/Component/Notifier/Bridge/MicrosoftTeams/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/MicrosoftTeams/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/MicrosoftTeams/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Mobyt/LICENSE b/src/Symfony/Component/Notifier/Bridge/Mobyt/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Mobyt/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Mobyt/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Nexmo/LICENSE b/src/Symfony/Component/Notifier/Bridge/Nexmo/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Nexmo/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Nexmo/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Octopush/LICENSE b/src/Symfony/Component/Notifier/Bridge/Octopush/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Octopush/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Octopush/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/OneSignal/LICENSE b/src/Symfony/Component/Notifier/Bridge/OneSignal/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/OneSignal/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/OneSignal/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/OvhCloud/LICENSE b/src/Symfony/Component/Notifier/Bridge/OvhCloud/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/OvhCloud/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/OvhCloud/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/RocketChat/LICENSE b/src/Symfony/Component/Notifier/Bridge/RocketChat/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/RocketChat/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/RocketChat/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Sendinblue/LICENSE b/src/Symfony/Component/Notifier/Bridge/Sendinblue/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Sendinblue/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Sendinblue/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Sinch/LICENSE b/src/Symfony/Component/Notifier/Bridge/Sinch/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Sinch/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Sinch/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Slack/LICENSE b/src/Symfony/Component/Notifier/Bridge/Slack/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Slack/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Slack/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Sms77/LICENSE b/src/Symfony/Component/Notifier/Bridge/Sms77/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Sms77/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Sms77/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/SmsBiuras/LICENSE b/src/Symfony/Component/Notifier/Bridge/SmsBiuras/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/SmsBiuras/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/SmsBiuras/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Smsapi/LICENSE b/src/Symfony/Component/Notifier/Bridge/Smsapi/LICENSE index 406242ff2855..0f262c225767 100644 --- a/src/Symfony/Component/Notifier/Bridge/Smsapi/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Smsapi/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 Fabien Potencier +Copyright (c) 2020-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Smsc/LICENSE b/src/Symfony/Component/Notifier/Bridge/Smsc/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Smsc/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Smsc/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/SpotHit/LICENSE b/src/Symfony/Component/Notifier/Bridge/SpotHit/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/SpotHit/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/SpotHit/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Telegram/LICENSE b/src/Symfony/Component/Notifier/Bridge/Telegram/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Telegram/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Telegram/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Telnyx/LICENSE b/src/Symfony/Component/Notifier/Bridge/Telnyx/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Telnyx/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Telnyx/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/TurboSms/LICENSE b/src/Symfony/Component/Notifier/Bridge/TurboSms/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/TurboSms/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/TurboSms/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Twilio/LICENSE b/src/Symfony/Component/Notifier/Bridge/Twilio/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/Bridge/Twilio/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Twilio/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Vonage/LICENSE b/src/Symfony/Component/Notifier/Bridge/Vonage/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Vonage/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Vonage/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Yunpian/LICENSE b/src/Symfony/Component/Notifier/Bridge/Yunpian/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Notifier/Bridge/Yunpian/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Yunpian/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/Bridge/Zulip/LICENSE b/src/Symfony/Component/Notifier/Bridge/Zulip/LICENSE index 406242ff2855..0f262c225767 100644 --- a/src/Symfony/Component/Notifier/Bridge/Zulip/LICENSE +++ b/src/Symfony/Component/Notifier/Bridge/Zulip/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 Fabien Potencier +Copyright (c) 2020-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Notifier/LICENSE b/src/Symfony/Component/Notifier/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/Notifier/LICENSE +++ b/src/Symfony/Component/Notifier/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/OptionsResolver/LICENSE b/src/Symfony/Component/OptionsResolver/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/OptionsResolver/LICENSE +++ b/src/Symfony/Component/OptionsResolver/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/PasswordHasher/LICENSE b/src/Symfony/Component/PasswordHasher/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/PasswordHasher/LICENSE +++ b/src/Symfony/Component/PasswordHasher/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Process/LICENSE b/src/Symfony/Component/Process/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Process/LICENSE +++ b/src/Symfony/Component/Process/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/PropertyAccess/LICENSE b/src/Symfony/Component/PropertyAccess/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/PropertyAccess/LICENSE +++ b/src/Symfony/Component/PropertyAccess/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/PropertyInfo/LICENSE b/src/Symfony/Component/PropertyInfo/LICENSE index 4e90b1b5ae4d..63af57a7115e 100644 --- a/src/Symfony/Component/PropertyInfo/LICENSE +++ b/src/Symfony/Component/PropertyInfo/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2022 Fabien Potencier +Copyright (c) 2015-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/RateLimiter/LICENSE b/src/Symfony/Component/RateLimiter/LICENSE index 7fa953905492..f2345234aa9e 100644 --- a/src/Symfony/Component/RateLimiter/LICENSE +++ b/src/Symfony/Component/RateLimiter/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2022 Fabien Potencier +Copyright (c) 2016-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Routing/LICENSE b/src/Symfony/Component/Routing/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Routing/LICENSE +++ b/src/Symfony/Component/Routing/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Runtime/LICENSE b/src/Symfony/Component/Runtime/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Runtime/LICENSE +++ b/src/Symfony/Component/Runtime/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Security/Core/LICENSE b/src/Symfony/Component/Security/Core/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Security/Core/LICENSE +++ b/src/Symfony/Component/Security/Core/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Security/Csrf/LICENSE b/src/Symfony/Component/Security/Csrf/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Security/Csrf/LICENSE +++ b/src/Symfony/Component/Security/Csrf/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Security/Guard/LICENSE b/src/Symfony/Component/Security/Guard/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Security/Guard/LICENSE +++ b/src/Symfony/Component/Security/Guard/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Security/Http/LICENSE b/src/Symfony/Component/Security/Http/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Security/Http/LICENSE +++ b/src/Symfony/Component/Security/Http/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Semaphore/LICENSE b/src/Symfony/Component/Semaphore/LICENSE index 7fa953905492..f2345234aa9e 100644 --- a/src/Symfony/Component/Semaphore/LICENSE +++ b/src/Symfony/Component/Semaphore/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2022 Fabien Potencier +Copyright (c) 2016-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Serializer/LICENSE b/src/Symfony/Component/Serializer/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Serializer/LICENSE +++ b/src/Symfony/Component/Serializer/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Stopwatch/LICENSE b/src/Symfony/Component/Stopwatch/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Stopwatch/LICENSE +++ b/src/Symfony/Component/Stopwatch/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/String/LICENSE b/src/Symfony/Component/String/LICENSE index 9c907a46a621..5c7ba0551cb6 100644 --- a/src/Symfony/Component/String/LICENSE +++ b/src/Symfony/Component/String/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Templating/LICENSE b/src/Symfony/Component/Templating/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Templating/LICENSE +++ b/src/Symfony/Component/Templating/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Translation/Bridge/Crowdin/LICENSE b/src/Symfony/Component/Translation/Bridge/Crowdin/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Translation/Bridge/Crowdin/LICENSE +++ b/src/Symfony/Component/Translation/Bridge/Crowdin/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Translation/Bridge/Loco/LICENSE b/src/Symfony/Component/Translation/Bridge/Loco/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Translation/Bridge/Loco/LICENSE +++ b/src/Symfony/Component/Translation/Bridge/Loco/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Translation/Bridge/Lokalise/LICENSE b/src/Symfony/Component/Translation/Bridge/Lokalise/LICENSE index 48d17c4fb34f..d354b95ffee0 100644 --- a/src/Symfony/Component/Translation/Bridge/Lokalise/LICENSE +++ b/src/Symfony/Component/Translation/Bridge/Lokalise/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 Fabien Potencier +Copyright (c) 2021-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Translation/LICENSE b/src/Symfony/Component/Translation/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Translation/LICENSE +++ b/src/Symfony/Component/Translation/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Uid/LICENSE b/src/Symfony/Component/Uid/LICENSE index 406242ff2855..0f262c225767 100644 --- a/src/Symfony/Component/Uid/LICENSE +++ b/src/Symfony/Component/Uid/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 Fabien Potencier +Copyright (c) 2020-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Validator/LICENSE b/src/Symfony/Component/Validator/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Validator/LICENSE +++ b/src/Symfony/Component/Validator/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/VarDumper/LICENSE b/src/Symfony/Component/VarDumper/LICENSE index a843ec124ea7..72412a62b202 100644 --- a/src/Symfony/Component/VarDumper/LICENSE +++ b/src/Symfony/Component/VarDumper/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2022 Fabien Potencier +Copyright (c) 2014-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/VarExporter/LICENSE b/src/Symfony/Component/VarExporter/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Component/VarExporter/LICENSE +++ b/src/Symfony/Component/VarExporter/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/WebLink/LICENSE b/src/Symfony/Component/WebLink/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/WebLink/LICENSE +++ b/src/Symfony/Component/WebLink/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Workflow/LICENSE b/src/Symfony/Component/Workflow/LICENSE index a843ec124ea7..72412a62b202 100644 --- a/src/Symfony/Component/Workflow/LICENSE +++ b/src/Symfony/Component/Workflow/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2022 Fabien Potencier +Copyright (c) 2014-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Component/Yaml/LICENSE b/src/Symfony/Component/Yaml/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/src/Symfony/Component/Yaml/LICENSE +++ b/src/Symfony/Component/Yaml/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Contracts/Cache/LICENSE b/src/Symfony/Contracts/Cache/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Contracts/Cache/LICENSE +++ b/src/Symfony/Contracts/Cache/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Contracts/Deprecation/LICENSE b/src/Symfony/Contracts/Deprecation/LICENSE index 406242ff2855..0f262c225767 100644 --- a/src/Symfony/Contracts/Deprecation/LICENSE +++ b/src/Symfony/Contracts/Deprecation/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 Fabien Potencier +Copyright (c) 2020-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Contracts/EventDispatcher/LICENSE b/src/Symfony/Contracts/EventDispatcher/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Contracts/EventDispatcher/LICENSE +++ b/src/Symfony/Contracts/EventDispatcher/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Contracts/HttpClient/LICENSE b/src/Symfony/Contracts/HttpClient/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Contracts/HttpClient/LICENSE +++ b/src/Symfony/Contracts/HttpClient/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Contracts/LICENSE b/src/Symfony/Contracts/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Contracts/LICENSE +++ b/src/Symfony/Contracts/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Contracts/Service/LICENSE b/src/Symfony/Contracts/Service/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Contracts/Service/LICENSE +++ b/src/Symfony/Contracts/Service/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/Contracts/Translation/LICENSE b/src/Symfony/Contracts/Translation/LICENSE index 74cdc2dbf6db..99757d517117 100644 --- a/src/Symfony/Contracts/Translation/LICENSE +++ b/src/Symfony/Contracts/Translation/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 Fabien Potencier +Copyright (c) 2018-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 2f62c4a7951ed05e722638beb3dcdea7c650a3a2 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 1 Jan 2023 09:35:34 +0100 Subject: [PATCH 04/34] Fix LICENSE year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 88bf75bb4d6a..008370457251 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2022 Fabien Potencier +Copyright (c) 2004-2023 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From af52de08d3754b25d31c21b141e7d21a45349d56 Mon Sep 17 00:00:00 2001 From: Fran Moreno Date: Fri, 6 Jan 2023 12:50:46 +0100 Subject: [PATCH 05/34] Fix detecting mapping with one line annotations --- .../AbstractDoctrineExtension.php | 4 +- .../DoctrineExtensionTest.php | 1 + .../AnnotationsOneLineBundle.php | 18 +++++++++ .../Entity/Person.php | 37 +++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsOneLineBundle/AnnotationsOneLineBundle.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsOneLineBundle/Entity/Person.php diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index a3083d2b1e07..4b0e1ff532b8 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -318,8 +318,8 @@ private function detectMappingType(string $directory, ContainerBuilder $containe break; } if ( - preg_match('/^ \* @.*'.$quotedMappingObjectName.'\b/m', $content) || - preg_match('/^ \* @.*Embeddable\b/m', $content) + preg_match('/^(?: \*|\/\*\*) @.*'.$quotedMappingObjectName.'\b/m', $content) || + preg_match('/^(?: \*|\/\*\*) @.*Embeddable\b/m', $content) ) { $type = 'annotation'; break; diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php index a7ed7ad5abad..b6f415e2145f 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -279,6 +279,7 @@ public function testUnrecognizedCacheDriverException() public function providerBundles() { yield ['AnnotationsBundle', 'annotation', '/Entity']; + yield ['AnnotationsOneLineBundle', 'annotation', '/Entity']; yield ['FullEmbeddableAnnotationsBundle', 'annotation', '/Entity']; if (\PHP_VERSION_ID >= 80000) { yield ['AttributesBundle', 'attribute', '/Entity']; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsOneLineBundle/AnnotationsOneLineBundle.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsOneLineBundle/AnnotationsOneLineBundle.php new file mode 100644 index 000000000000..6d401bae4f98 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsOneLineBundle/AnnotationsOneLineBundle.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\AnnotationsOneLineBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class AnnotationsOneLineBundle extends Bundle +{ +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsOneLineBundle/Entity/Person.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsOneLineBundle/Entity/Person.php new file mode 100644 index 000000000000..b55fe6f86503 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsOneLineBundle/Entity/Person.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\AnnotationsOneLineBundle\Entity; + +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; + +/** @Entity */ +class Person +{ + /** @Id @Column(type="integer") */ + protected $id; + + /** @Column(type="string") */ + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString(): string + { + return (string) $this->name; + } +} From 6af950a0342eded7b6a4fa181033f98bb05b33dc Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Sat, 7 Jan 2023 13:11:13 +0100 Subject: [PATCH 06/34] [Validator] Allow egulias/email-validator v4 --- composer.json | 2 +- src/Symfony/Component/Validator/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index c322ed90f60d..0bf1e017dfdd 100644 --- a/composer.json +++ b/composer.json @@ -140,7 +140,7 @@ "predis/predis": "~1.1", "psr/http-client": "^1.0", "psr/simple-cache": "^1.0|^2.0", - "egulias/email-validator": "^2.1.10|^3.1", + "egulias/email-validator": "^2.1.10|^3.1|^4", "symfony/mercure-bundle": "^0.3", "symfony/phpunit-bridge": "^5.2|^6.0", "symfony/runtime": "self.version", diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index 4799c7be301d..019a46fc1528 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -43,7 +43,7 @@ "symfony/translation": "^4.4|^5.0|^6.0", "doctrine/annotations": "^1.13|^2", "doctrine/cache": "^1.11|^2.0", - "egulias/email-validator": "^2.1.10|^3" + "egulias/email-validator": "^2.1.10|^3|^4" }, "conflict": { "doctrine/annotations": "<1.13", From ee9d357bfd4ce089957e0b7ecb93cddf86dff630 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Sun, 8 Jan 2023 14:17:15 +0100 Subject: [PATCH 07/34] [Config] Fix XML dump when node example is an array --- .../Config/Definition/Dumper/XmlReferenceDumper.php | 2 +- .../Tests/Definition/Dumper/XmlReferenceDumperTest.php | 2 ++ .../Tests/Definition/Dumper/YamlReferenceDumperTest.php | 5 +++++ .../Tests/Fixtures/Configuration/ExampleConfiguration.php | 3 +++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php index a8b18a0239e7..4979ae96c813 100644 --- a/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php +++ b/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php @@ -147,7 +147,7 @@ private function writeNode(NodeInterface $node, int $depth = 0, bool $root = fal } if ($child instanceof BaseNode && $example = $child->getExample()) { - $comments[] = 'Example: '.$example; + $comments[] = 'Example: '.(\is_array($example) ? implode(', ', $example) : $example); } if ($child->isRequired()) { diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php index 8d84ae50babe..520d25666a1c 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php @@ -42,6 +42,7 @@ private function getConfigurationAsString() + diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php index 88340d1afbad..7d8c2d951897 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php @@ -114,6 +114,11 @@ enum: ~ # One of "this"; "that" # which should be indented child3: ~ # Example: 'example setting' scalar_prototyped: [] + variable: + + # Examples: + - foo + - bar parameters: # Prototype: Parameter name diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php index 919240f1f7ac..126008831796 100644 --- a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php +++ b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php @@ -58,6 +58,9 @@ public function getConfigTreeBuilder(): TreeBuilder ->arrayNode('scalar_prototyped') ->prototype('scalar')->end() ->end() + ->variableNode('variable') + ->example(['foo', 'bar']) + ->end() ->arrayNode('parameters') ->useAttributeAsKey('name') ->prototype('scalar')->info('Parameter name')->end() From 56a0a1b8008912bf3841faad34ceaaacba8668b7 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 9 Jan 2023 12:43:46 +0700 Subject: [PATCH 08/34] Allow EmailValidator 4 --- src/Symfony/Bridge/Twig/composer.json | 2 +- src/Symfony/Component/Mailer/composer.json | 2 +- src/Symfony/Component/Mime/composer.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 52aeba8f8cb0..c67b92f79b83 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -23,7 +23,7 @@ }, "require-dev": { "doctrine/annotations": "^1.12|^2", - "egulias/email-validator": "^2.1.10|^3", + "egulias/email-validator": "^2.1.10|^3|^4", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/asset": "^4.4|^5.0|^6.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", diff --git a/src/Symfony/Component/Mailer/composer.json b/src/Symfony/Component/Mailer/composer.json index 53cf0f5119ad..86093d875fee 100644 --- a/src/Symfony/Component/Mailer/composer.json +++ b/src/Symfony/Component/Mailer/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=7.2.5", - "egulias/email-validator": "^2.1.10|^3", + "egulias/email-validator": "^2.1.10|^3|^4", "psr/event-dispatcher": "^1", "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.1|^3", diff --git a/src/Symfony/Component/Mime/composer.json b/src/Symfony/Component/Mime/composer.json index ec96dff5d0b6..5472deab1a4b 100644 --- a/src/Symfony/Component/Mime/composer.json +++ b/src/Symfony/Component/Mime/composer.json @@ -23,7 +23,7 @@ "symfony/polyfill-php80": "^1.16" }, "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1", + "egulias/email-validator": "^2.1.10|^3.1|^4", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", "symfony/property-access": "^4.4|^5.1|^6.0", From e058874665849e37cb652574ca36b1e8f284b4e5 Mon Sep 17 00:00:00 2001 From: Alexis Lefebvre Date: Sun, 8 Jan 2023 14:02:25 +0100 Subject: [PATCH 09/34] [FrameworkBundle] restore call to addGlobalIgnoredName --- .../FrameworkBundle/DependencyInjection/FrameworkExtension.php | 3 +++ .../Bundle/FrameworkBundle/Resources/config/annotations.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index b69254687c6d..00412e5c6805 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1631,11 +1631,14 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde $loader->load('annotations.php'); + // registerUniqueLoader exists since doctrine/annotations v1.6 if (!method_exists(AnnotationRegistry::class, 'registerUniqueLoader')) { + // registerLoader exists only in doctrine/annotations v1 if (method_exists(AnnotationRegistry::class, 'registerLoader')) { $container->getDefinition('annotations.dummy_registry') ->setMethodCalls([['registerLoader', ['class_exists']]]); } else { + // remove the dummy registry when doctrine/annotations v2 is used $container->removeDefinition('annotations.dummy_registry'); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php index 8bb408e2aba6..33a2f46989de 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php @@ -26,7 +26,7 @@ ->set('annotations.reader', AnnotationReader::class) ->call('addGlobalIgnoredName', [ 'required', - service('annotations.dummy_registry')->ignoreOnInvalid(), // dummy arg to register class_exists as annotation loader only when required + service('annotations.dummy_registry')->nullOnInvalid(), // dummy arg to register class_exists as annotation loader only when required ]) ->set('annotations.dummy_registry', AnnotationRegistry::class) From a899bedd279a080e50a74411f73c1633355f32d0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 9 Jan 2023 14:49:47 +0100 Subject: [PATCH 10/34] [DependencyInjection] Fix support for named arguments on non-autowired services --- .../Compiler/ResolveNamedArgumentsPass.php | 11 +++++++ .../DependencyInjection/ContainerBuilder.php | 2 +- .../ResolveNamedArgumentsPassTest.php | 2 +- .../Tests/ContainerBuilderTest.php | 30 +++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php index c1c5748e8d60..71234d5cca54 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php @@ -43,6 +43,7 @@ protected function processValue($value, bool $isRoot = false) foreach ($calls as $i => $call) { [$method, $arguments] = $call; $parameters = null; + $resolvedKeys = []; $resolvedArguments = []; foreach ($arguments as $key => $argument) { @@ -51,6 +52,7 @@ protected function processValue($value, bool $isRoot = false) } if (\is_int($key)) { + $resolvedKeys[$key] = $key; $resolvedArguments[$key] = $argument; continue; } @@ -71,9 +73,11 @@ protected function processValue($value, bool $isRoot = false) if ($key === '$'.$p->name) { if ($p->isVariadic() && \is_array($argument)) { foreach ($argument as $variadicArgument) { + $resolvedKeys[$j] = $j; $resolvedArguments[$j++] = $variadicArgument; } } else { + $resolvedKeys[$j] = $p->name; $resolvedArguments[$j] = $argument; } @@ -91,6 +95,7 @@ protected function processValue($value, bool $isRoot = false) $typeFound = false; foreach ($parameters as $j => $p) { if (!\array_key_exists($j, $resolvedArguments) && ProxyHelper::getTypeHint($r, $p, true) === $key) { + $resolvedKeys[$j] = $p->name; $resolvedArguments[$j] = $argument; $typeFound = true; } @@ -103,6 +108,12 @@ protected function processValue($value, bool $isRoot = false) if ($resolvedArguments !== $call[1]) { ksort($resolvedArguments); + + if (!$value->isAutowired() && !array_is_list($resolvedArguments)) { + ksort($resolvedKeys); + $resolvedArguments = array_combine($resolvedKeys, $resolvedArguments); + } + $calls[$i][1] = $resolvedArguments; } } diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index db1ea84c2cf7..bcfa623d7b2d 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1102,7 +1102,7 @@ private function createService(Definition $definition, array &$inlineServices, b } else { $r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass())); - $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs(array_values($arguments)); + $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments); if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ")) { trigger_deprecation('', '', 'The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveNamedArgumentsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveNamedArgumentsPassTest.php index 4e9973bb30e9..2c28949486f2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveNamedArgumentsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveNamedArgumentsPassTest.php @@ -165,7 +165,7 @@ public function testInterfaceTypedArgument() $pass = new ResolveNamedArgumentsPass(); $pass->process($container); - $this->assertSame($expected, $definition->getArgument(3)); + $this->assertSame($expected, $definition->getArgument('container')); } public function testResolvesMultipleArgumentsOfTheSameType() diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 1dfd8f86eaf4..6ab7232d23a5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1773,6 +1773,24 @@ public function testFindTags() $this->assertSame(['tag1', 'tag2', 'tag3'], $container->findTags()); } + + /** + * @requires PHP 8 + */ + public function testNamedArgument() + { + $container = new ContainerBuilder(); + $container->register(E::class) + ->setPublic(true) + ->setArguments(['$second' => 2]); + + $container->compile(); + + $e = $container->get(E::class); + + $this->assertSame('', $e->first); + $this->assertSame(2, $e->second); + } } class FooClass @@ -1801,3 +1819,15 @@ class C implements X class D implements X { } + +class E +{ + public $first; + public $second; + + public function __construct($first = '', $second = '') + { + $this->first = $first; + $this->second = $second; + } +} From 692a631b9eecdaf1f9e4d1f1933817505f78485c Mon Sep 17 00:00:00 2001 From: Pierre Foresi Date: Fri, 6 Jan 2023 17:12:55 +0100 Subject: [PATCH 11/34] [HttpClient] Move Http clients data collecting at a late level --- .../DataCollector/HttpClientDataCollector.php | 9 ++++----- .../DataCollector/HttpClientDataCollectorTest.php | 12 +++++------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/HttpClient/DataCollector/HttpClientDataCollector.php b/src/Symfony/Component/HttpClient/DataCollector/HttpClientDataCollector.php index db8bbbdd6952..cd065961b936 100644 --- a/src/Symfony/Component/HttpClient/DataCollector/HttpClientDataCollector.php +++ b/src/Symfony/Component/HttpClient/DataCollector/HttpClientDataCollector.php @@ -37,6 +37,10 @@ public function registerClient(string $name, TraceableHttpClient $client) * {@inheritdoc} */ public function collect(Request $request, Response $response, \Throwable $exception = null) + { + } + + public function lateCollect() { $this->reset(); @@ -50,12 +54,7 @@ public function collect(Request $request, Response $response, \Throwable $except $this->data['request_count'] += \count($traces); $this->data['error_count'] += $errorCount; - } - } - public function lateCollect() - { - foreach ($this->clients as $client) { $client->reset(); } } diff --git a/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php b/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php index 76bbbe7c57c6..15a3136da6b7 100755 --- a/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php +++ b/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php @@ -15,8 +15,6 @@ use Symfony\Component\HttpClient\DataCollector\HttpClientDataCollector; use Symfony\Component\HttpClient\NativeHttpClient; use Symfony\Component\HttpClient\TraceableHttpClient; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; use Symfony\Contracts\HttpClient\Test\TestHttpServer; class HttpClientDataCollectorTest extends TestCase @@ -50,7 +48,7 @@ public function testItCollectsRequestCount() $sut->registerClient('http_client2', $httpClient2); $sut->registerClient('http_client3', $httpClient3); $this->assertEquals(0, $sut->getRequestCount()); - $sut->collect(new Request(), new Response()); + $sut->lateCollect(); $this->assertEquals(3, $sut->getRequestCount()); } @@ -79,7 +77,7 @@ public function testItCollectsErrorCount() $sut->registerClient('http_client2', $httpClient2); $sut->registerClient('http_client3', $httpClient3); $this->assertEquals(0, $sut->getErrorCount()); - $sut->collect(new Request(), new Response()); + $sut->lateCollect(); $this->assertEquals(1, $sut->getErrorCount()); } @@ -108,7 +106,7 @@ public function testItCollectsErrorCountByClient() $sut->registerClient('http_client2', $httpClient2); $sut->registerClient('http_client3', $httpClient3); $this->assertEquals([], $sut->getClients()); - $sut->collect(new Request(), new Response()); + $sut->lateCollect(); $collectedData = $sut->getClients(); $this->assertEquals(0, $collectedData['http_client1']['error_count']); $this->assertEquals(1, $collectedData['http_client2']['error_count']); @@ -140,7 +138,7 @@ public function testItCollectsTracesByClient() $sut->registerClient('http_client2', $httpClient2); $sut->registerClient('http_client3', $httpClient3); $this->assertEquals([], $sut->getClients()); - $sut->collect(new Request(), new Response()); + $sut->lateCollect(); $collectedData = $sut->getClients(); $this->assertCount(2, $collectedData['http_client1']['traces']); $this->assertCount(1, $collectedData['http_client2']['traces']); @@ -157,7 +155,7 @@ public function testItIsEmptyAfterReset() ]); $sut = new HttpClientDataCollector(); $sut->registerClient('http_client1', $httpClient1); - $sut->collect(new Request(), new Response()); + $sut->lateCollect(); $collectedData = $sut->getClients(); $this->assertCount(1, $collectedData['http_client1']['traces']); $sut->reset(); From 455ace0e03af640faab7936461aa0be7a39f67a3 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 9 Jan 2023 20:26:12 +0100 Subject: [PATCH 12/34] [DependencyInjection] Fix dumping inlined withers --- .../Component/DependencyInjection/Dumper/PhpDumper.php | 2 +- .../DependencyInjection/Tests/Dumper/PhpDumperTest.php | 3 ++- .../Tests/Fixtures/includes/autowiring_classes.php | 8 ++++++++ .../Tests/Fixtures/php/services_wither.php | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index e4a7ae55d5a6..9d662d5ed26e 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -754,7 +754,7 @@ private function addServiceMethodCalls(Definition $definition, string $variableN $witherAssignation = ''; if ($call[2] ?? false) { - if (null !== $sharedNonLazyId && $lastWitherIndex === $k) { + if (null !== $sharedNonLazyId && $lastWitherIndex === $k && 'instance' === $variableName) { $witherAssignation = sprintf('$this->%s[\'%s\'] = ', $definition->isPublic() ? 'services' : 'privates', $sharedNonLazyId); } $witherAssignation .= sprintf('$%s = ', $variableName); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index fe747281ff55..4c05bc49a2a6 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -1439,7 +1439,8 @@ public function testAliasCanBeFoundInTheDumpedContainerWhenBothTheAliasAndTheSer public function testWither() { $container = new ContainerBuilder(); - $container->register(Foo::class); + $container->register(Foo::class) + ->setAutowired(true); $container ->register('wither', Wither::class) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php index 96c2b68b7d08..ad1f06a49231 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php @@ -17,6 +17,14 @@ class Foo { + /** + * @required + * @return static + */ + public function cloneFoo() + { + return clone $this; + } } class Bar diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_wither.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_wither.php index 79f2e8dfe3a1..35035d33e645 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_wither.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_wither.php @@ -55,6 +55,7 @@ protected function getWitherService() $instance = new \Symfony\Component\DependencyInjection\Tests\Compiler\Wither(); $a = new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo(); + $a = $a->cloneFoo(); $instance = $instance->withFoo1($a); $this->services['wither'] = $instance = $instance->withFoo2($a); From 8a6a320897d07584f1aff9be317cbb00ff13cb10 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 10 Jan 2023 18:21:13 +0100 Subject: [PATCH 13/34] [FrameworkBundle] Fix deprecation when accessing a "container.private" service from the test container --- .../Compiler/TestServiceContainerRealRefPass.php | 11 +++++++++++ .../Compiler/TestServiceContainerRefPassesTest.php | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TestServiceContainerRealRefPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TestServiceContainerRealRefPass.php index 222b5c7b75af..942eb635b26f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TestServiceContainerRealRefPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TestServiceContainerRealRefPass.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -38,6 +39,16 @@ public function process(ContainerBuilder $container) } } + foreach ($container->getAliases() as $id => $target) { + while ($container->hasAlias($target = (string) $target)) { + $target = $container->getAlias($target); + } + + if ($definitions[$target]->hasTag('container.private')) { + $privateServices[$id] = new ServiceClosureArgument(new Reference($target)); + } + } + $privateContainer->replaceArgument(0, $privateServices); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TestServiceContainerRefPassesTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TestServiceContainerRefPassesTest.php index 7dc9e6f59ec9..355b1527d64b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TestServiceContainerRefPassesTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TestServiceContainerRefPassesTest.php @@ -43,6 +43,13 @@ public function testProcess() ->setPublic(true) ->addTag('container.private', ['package' => 'foo/bar', 'version' => '1.42']) ; + $container->register('Test\soon_private_service_decorated') + ->setPublic(true) + ->addTag('container.private', ['package' => 'foo/bar', 'version' => '1.42']) + ; + $container->register('Test\soon_private_service_decorator') + ->setDecoratedService('Test\soon_private_service_decorated') + ->setArguments(['Test\soon_private_service_decorator.inner']); $container->register('Test\private_used_shared_service'); $container->register('Test\private_unused_shared_service'); @@ -55,6 +62,8 @@ public function testProcess() 'Test\private_used_shared_service' => new ServiceClosureArgument(new Reference('Test\private_used_shared_service')), 'Test\private_used_non_shared_service' => new ServiceClosureArgument(new Reference('Test\private_used_non_shared_service')), 'Test\soon_private_service' => new ServiceClosureArgument(new Reference('.container.private.Test\soon_private_service')), + 'Test\soon_private_service_decorator' => new ServiceClosureArgument(new Reference('.container.private.Test\soon_private_service_decorated')), + 'Test\soon_private_service_decorated' => new ServiceClosureArgument(new Reference('.container.private.Test\soon_private_service_decorated')), ]; $privateServices = $container->getDefinition('test.private_services_locator')->getArgument(0); From a535f000665e1e100665d295fb98be0effe897d2 Mon Sep 17 00:00:00 2001 From: Antoine Lamirault Date: Mon, 9 Jan 2023 21:33:27 +0100 Subject: [PATCH 14/34] [Yaml] Minor: Update Inline parse phpdoc --- src/Symfony/Component/Yaml/Inline.php | 2 +- src/Symfony/Component/Yaml/Parser.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index f93f59676d9a..8118a43ab8f3 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -51,7 +51,7 @@ public static function initialize(int $flags, int $parsedLineNumber = null, stri * Converts a YAML string to a PHP value. * * @param string $value A YAML string - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * @param int $flags A bit field of Yaml::PARSE_* constants to customize the YAML parser behavior * @param array $references Mapping of variable names to values * * @return mixed diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 6b4c790ba092..d8886bb1860b 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -43,7 +43,7 @@ class Parser * Parses a YAML file into a PHP value. * * @param string $filename The path to the YAML file to be parsed - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * @param int $flags A bit field of Yaml::PARSE_* constants to customize the YAML parser behavior * * @return mixed * @@ -72,7 +72,7 @@ public function parseFile(string $filename, int $flags = 0) * Parses a YAML string to a PHP value. * * @param string $value A YAML string - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * @param int $flags A bit field of Yaml::PARSE_* constants to customize the YAML parser behavior * * @return mixed * @@ -711,7 +711,7 @@ private function moveToPreviousLine(): bool * Parses a YAML value. * * @param string $value A YAML value - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * @param int $flags A bit field of Yaml::PARSE_* constants to customize the YAML parser behavior * @param string $context The parser context (either sequence or mapping) * * @return mixed From b6d424411b712fe77c188a70225172f4f55e39b5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 11 Jan 2023 10:56:09 +0100 Subject: [PATCH 15/34] Revert "minor #47721 [Notifier] Use local copy of stella-maris/clock when testing (nicolas-grekas)" This reverts commit fcc217486184c0743f13368ad287f26ce51809c2, reversing changes made to a5f8bb2e32f1960f0c3b496f12d1cc635e2eee12. --- .github/workflows/package-tests.yml | 2 +- .github/workflows/unit-tests.yml | 2 +- composer.json | 9 -------- .../stella-maris-clock/ClockInterface.php | 23 ------------------- .../Tests/stella-maris-clock/composer.json | 17 -------------- .../Notifier/Bridge/Mercure/composer.json | 11 --------- 6 files changed, 2 insertions(+), 62 deletions(-) delete mode 100644 src/Symfony/Component/Notifier/Bridge/Mercure/Tests/stella-maris-clock/ClockInterface.php delete mode 100644 src/Symfony/Component/Notifier/Bridge/Mercure/Tests/stella-maris-clock/composer.json diff --git a/.github/workflows/package-tests.yml b/.github/workflows/package-tests.yml index 859e1e632838..f04bacd0170d 100644 --- a/.github/workflows/package-tests.yml +++ b/.github/workflows/package-tests.yml @@ -21,7 +21,7 @@ jobs: - name: Find packages id: find-packages - run: echo "packages=$(php .github/get-modified-packages.php $(find src/Symfony -mindepth 2 -maxdepth 6 -type f -name composer.json -printf '%h\n' | jq -R -s -c 'split("\n")[:-1]') $(git diff --name-only origin/${{ github.base_ref }} HEAD | grep src/ | jq -R -s -c 'split("\n")[:-1]'))" >> $GITHUB_OUTPUT + run: echo "packages=$(php .github/get-modified-packages.php $(find src/Symfony -mindepth 2 -type f -name composer.json -printf '%h\n' | jq -R -s -c 'split("\n")[:-1]') $(git diff --name-only origin/${{ github.base_ref }} HEAD | grep src/ | jq -R -s -c 'split("\n")[:-1]'))" >> $GITHUB_OUTPUT - name: Verify meta files are correct run: | diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 64f18e9a65a8..7ffdbdb335f3 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -94,7 +94,7 @@ jobs: echo SYMFONY_DEPRECATIONS_HELPER=weak >> $GITHUB_ENV cp composer.json composer.json.orig echo -e '{\n"require":{'"$(grep phpunit-bridge composer.json)"'"php":"*"},"minimum-stability":"dev"}' > composer.json - php .github/build-packages.php HEAD^ $SYMFONY_VERSION $(find src/Symfony -mindepth 2 -maxdepth 6 -type f -name composer.json -printf '%h\n') + php .github/build-packages.php HEAD^ $SYMFONY_VERSION $(find src/Symfony -mindepth 2 -type f -name composer.json -printf '%h\n') mv composer.json composer.json.phpunit mv composer.json.orig composer.json fi diff --git a/composer.json b/composer.json index 0bf1e017dfdd..66ffa86d7bcd 100644 --- a/composer.json +++ b/composer.json @@ -204,15 +204,6 @@ { "type": "path", "url": "src/Symfony/Component/Runtime" - }, - { - "type": "path", - "url": "src/Symfony/Component/Notifier/Bridge/Mercure/Tests/stella-maris-clock", - "options": { - "versions": { - "stella-maris/clock": "0.1.x-dev" - } - } } ], "minimum-stability": "dev" diff --git a/src/Symfony/Component/Notifier/Bridge/Mercure/Tests/stella-maris-clock/ClockInterface.php b/src/Symfony/Component/Notifier/Bridge/Mercure/Tests/stella-maris-clock/ClockInterface.php deleted file mode 100644 index d8b2e8669226..000000000000 --- a/src/Symfony/Component/Notifier/Bridge/Mercure/Tests/stella-maris-clock/ClockInterface.php +++ /dev/null @@ -1,23 +0,0 @@ - and ClockInterfaceContributors - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - -namespace StellaMaris\Clock; - -use DateTimeImmutable; - -interface ClockInterface -{ - /** - * Return the current point in time as a DateTimeImmutable object - */ - public function now() : DateTimeImmutable; -} diff --git a/src/Symfony/Component/Notifier/Bridge/Mercure/Tests/stella-maris-clock/composer.json b/src/Symfony/Component/Notifier/Bridge/Mercure/Tests/stella-maris-clock/composer.json deleted file mode 100644 index fb838caed6e8..000000000000 --- a/src/Symfony/Component/Notifier/Bridge/Mercure/Tests/stella-maris-clock/composer.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "stella-maris/clock", - "description": "A local fork to workaround gitlab failing to serve the package reliably", - "homepage": "https://gitlab.com/stella-maris/clock", - "license": "MIT", - "authors": [ - { - "name": "Andreas Heigl", - "role": "Maintainer" - } - ], - "autoload": { - "psr-4": { - "StellaMaris\\Clock\\": "" - } - } -} diff --git a/src/Symfony/Component/Notifier/Bridge/Mercure/composer.json b/src/Symfony/Component/Notifier/Bridge/Mercure/composer.json index eb7532353c4c..ed13323a2816 100644 --- a/src/Symfony/Component/Notifier/Bridge/Mercure/composer.json +++ b/src/Symfony/Component/Notifier/Bridge/Mercure/composer.json @@ -28,16 +28,5 @@ "/Tests/" ] }, - "repositories": [ - { - "type": "path", - "url": "Tests/stella-maris-clock", - "options": { - "versions": { - "stella-maris/clock": "0.1.x-dev" - } - } - } - ], "minimum-stability": "dev" } From af188b0ece8a0263eb0dcedfe0e0b49c8d82bd67 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 11 Jan 2023 14:49:35 +0100 Subject: [PATCH 16/34] [Intl] Fix tests --- .../DateFormat/QuarterTransformer.php | 10 ++++++- .../AbstractIntlDateFormatterTest.php | 30 +++++++++++++++++-- .../DateFormatter/IntlDateFormatterTest.php | 4 +++ .../Verification/IntlDateFormatterTest.php | 8 +++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Intl/DateFormatter/DateFormat/QuarterTransformer.php b/src/Symfony/Component/Intl/DateFormatter/DateFormat/QuarterTransformer.php index 71b95c8b9e7e..83d840020664 100644 --- a/src/Symfony/Component/Intl/DateFormatter/DateFormat/QuarterTransformer.php +++ b/src/Symfony/Component/Intl/DateFormatter/DateFormat/QuarterTransformer.php @@ -35,10 +35,18 @@ public function format(\DateTime $dateTime, int $length): string return $this->padLeft($quarter, $length); case 3: return 'Q'.$quarter; - default: + case 4: $map = [1 => '1st quarter', 2 => '2nd quarter', 3 => '3rd quarter', 4 => '4th quarter']; return $map[$quarter]; + default: + if (\defined('INTL_ICU_VERSION') && version_compare(\INTL_ICU_VERSION, '70.1', '<')) { + $map = [1 => '1st quarter', 2 => '2nd quarter', 3 => '3rd quarter', 4 => '4th quarter']; + + return $map[$quarter]; + } else { + return $quarter; + } } } diff --git a/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php b/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php index 6c1dc2f7c685..c6328ab20e24 100644 --- a/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php @@ -96,6 +96,12 @@ public function formatProvider() $dateTime = new \DateTime('@0'); $dateTimeImmutable = new \DateTimeImmutable('@0'); + /* https://unicode-org.atlassian.net/browse/ICU-21647 */ + $expectedQuarterX5 = '1'; + if (\defined('INTL_ICU_VERSION') && version_compare(\INTL_ICU_VERSION, '70.1', '<')) { + $expectedQuarterX5 = '1st quarter'; + } + $formatData = [ /* general */ ['y-M-d', 0, '1970-1-1'], @@ -144,13 +150,13 @@ public function formatProvider() ['QQ', 0, '01'], ['QQQ', 0, 'Q1'], ['QQQQ', 0, '1st quarter'], - ['QQQQQ', 0, '1st quarter'], + ['QQQQQ', 0, $expectedQuarterX5], ['q', 0, '1'], ['qq', 0, '01'], ['qqq', 0, 'Q1'], ['qqqq', 0, '1st quarter'], - ['qqqqq', 0, '1st quarter'], + ['qqqqq', 0, $expectedQuarterX5], // 4 months ['Q', 7776000, '2'], @@ -363,6 +369,10 @@ public function formatWithTimezoneProvider() */ public function testFormatTimezone($pattern, $timezone, $expected) { + if ((80114 === \PHP_VERSION_ID || 80201 === \PHP_VERSION_ID) && str_contains($timezone, 'GMT')) { + $this->markTestSkipped('Broken version of PHP'); + } + $formatter = $this->getDefaultDateFormatter($pattern); $formatter->setTimeZone(new \DateTimeZone($timezone)); @@ -421,6 +431,10 @@ public function formatTimezoneProvider() public function testFormatWithGmtTimezone() { + if (80114 === \PHP_VERSION_ID || 80201 === \PHP_VERSION_ID) { + $this->markTestSkipped('Broken version of PHP'); + } + $formatter = $this->getDefaultDateFormatter('zzzz'); $formatter->setTimeZone('GMT+03:00'); @@ -430,6 +444,10 @@ public function testFormatWithGmtTimezone() public function testFormatWithGmtTimeZoneAndMinutesOffset() { + if (80114 === \PHP_VERSION_ID || 80201 === \PHP_VERSION_ID) { + $this->markTestSkipped('Broken version of PHP'); + } + $formatter = $this->getDefaultDateFormatter('zzzz'); $formatter->setTimeZone('GMT+00:30'); @@ -794,6 +812,10 @@ public function parseSecondProvider() public function parseTimezoneProvider() { + if (80114 === \PHP_VERSION_ID || 80201 === \PHP_VERSION_ID) { + return [['y-M-d HH:mm:ss', '1970-1-1 00:00:00', 0]]; + } + return [ ['y-M-d HH:mm:ss zzzz', '1970-1-1 00:00:00 GMT-03:00', 10800], ['y-M-d HH:mm:ss zzzz', '1970-1-1 00:00:00 GMT-04:00', 14400], @@ -912,6 +934,10 @@ public function testSetPattern() */ public function testSetTimeZoneId($timeZoneId, $expectedTimeZoneId) { + if ((80114 === \PHP_VERSION_ID || 80201 === \PHP_VERSION_ID) && str_contains($timeZoneId ?? '', 'GMT')) { + $this->markTestSkipped('Broken version of PHP'); + } + $formatter = $this->getDefaultDateFormatter(); $formatter->setTimeZone($timeZoneId); diff --git a/src/Symfony/Component/Intl/Tests/DateFormatter/IntlDateFormatterTest.php b/src/Symfony/Component/Intl/Tests/DateFormatter/IntlDateFormatterTest.php index 765ac9cf9b8a..9113403fa112 100644 --- a/src/Symfony/Component/Intl/Tests/DateFormatter/IntlDateFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/DateFormatter/IntlDateFormatterTest.php @@ -186,6 +186,10 @@ public function testParseThreeDigitsYears() protected function getDateFormatter($locale, $datetype, $timetype, $timezone = null, $calendar = IntlDateFormatter::GREGORIAN, $pattern = null) { + if ((80114 === \PHP_VERSION_ID || 80201 === \PHP_VERSION_ID) && \is_string($timezone) && str_contains($timezone, 'GMT')) { + $this->markTestSkipped('Broken version of PHP'); + } + return new class($locale, $datetype, $timetype, $timezone, $calendar, $pattern) extends IntlDateFormatter { }; } diff --git a/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php b/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php index 9ce1a6227a97..ff8e9971ce5d 100644 --- a/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php @@ -35,6 +35,10 @@ protected function setUp(): void */ public function testFormatTimezone($pattern, $timezone, $expected) { + if ((80114 === \PHP_VERSION_ID || 80201 === \PHP_VERSION_ID) && str_contains($timezone, 'GMT')) { + $this->markTestSkipped('Broken version of PHP'); + } + IntlTestHelper::requireFullIntl($this, '59.1'); parent::testFormatTimezone($pattern, $timezone, $expected); @@ -59,6 +63,10 @@ public function testDateAndTimeType($timestamp, $datetype, $timetype, $expected) protected function getDateFormatter($locale, $datetype, $timetype, $timezone = null, $calendar = IntlDateFormatter::GREGORIAN, $pattern = null) { + if ((80114 === \PHP_VERSION_ID || 80201 === \PHP_VERSION_ID) && \is_string($timezone) && str_contains($timezone, 'GMT')) { + $this->markTestSkipped('Broken version of PHP'); + } + IntlTestHelper::requireFullIntl($this, '55.1'); if (!$formatter = new \IntlDateFormatter($locale, $datetype ?? IntlDateFormatter::FULL, $timetype ?? IntlDateFormatter::FULL, $timezone, $calendar, $pattern)) { From 5b27dc2bc942e016423619302afc631853540f7f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 12 Jan 2023 16:25:57 +0100 Subject: [PATCH 17/34] [HttpClient] Let curl handle content-length headers --- .../Component/HttpClient/CurlHttpClient.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 3807244dc6a0..4ed34b83b3a4 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -204,8 +204,14 @@ public function request(string $method, string $url, array $options = []): Respo if (\extension_loaded('zlib') && !isset($options['normalized_headers']['accept-encoding'])) { $options['headers'][] = 'Accept-Encoding: gzip'; // Expose only one encoding, some servers mess up when more are provided } + $body = $options['body']; - foreach ($options['headers'] as $header) { + foreach ($options['headers'] as $i => $header) { + if (\is_string($body) && '' !== $body && 0 === stripos($header, 'Content-Length: ')) { + // Let curl handle Content-Length headers + unset($options['headers'][$i]); + continue; + } if (':' === $header[-2] && \strlen($header) - 2 === strpos($header, ': ')) { // curl requires a special syntax to send empty headers $curlopts[\CURLOPT_HTTPHEADER][] = substr_replace($header, ';', -2); @@ -221,7 +227,7 @@ public function request(string $method, string $url, array $options = []): Respo } } - if (!\is_string($body = $options['body'])) { + if (!\is_string($body)) { if (\is_resource($body)) { $curlopts[\CURLOPT_INFILE] = $body; } else { @@ -233,15 +239,16 @@ public function request(string $method, string $url, array $options = []): Respo } if (isset($options['normalized_headers']['content-length'][0])) { - $curlopts[\CURLOPT_INFILESIZE] = substr($options['normalized_headers']['content-length'][0], \strlen('Content-Length: ')); - } elseif (!isset($options['normalized_headers']['transfer-encoding'])) { - $curlopts[\CURLOPT_HTTPHEADER][] = 'Transfer-Encoding: chunked'; // Enable chunked request bodies + $curlopts[\CURLOPT_INFILESIZE] = (int) substr($options['normalized_headers']['content-length'][0], \strlen('Content-Length: ')); + } + if (!isset($options['normalized_headers']['transfer-encoding'])) { + $curlopts[\CURLOPT_HTTPHEADER][] = 'Transfer-Encoding:'.(isset($curlopts[\CURLOPT_INFILESIZE]) ? '' : ' chunked'); } if ('POST' !== $method) { $curlopts[\CURLOPT_UPLOAD] = true; - if (!isset($options['normalized_headers']['content-type'])) { + if (!isset($options['normalized_headers']['content-type']) && 0 !== ($curlopts[\CURLOPT_INFILESIZE] ?? null)) { $curlopts[\CURLOPT_HTTPHEADER][] = 'Content-Type: application/x-www-form-urlencoded'; } } From 4574d8760851b6a34558cb4703c3739f919ac51f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 12 Jan 2023 17:39:29 +0100 Subject: [PATCH 18/34] [VarExporter] Fix exporting enums --- src/Symfony/Component/VarExporter/Internal/Exporter.php | 2 +- src/Symfony/Component/VarExporter/Tests/Fixtures/unit-enum.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/VarExporter/Internal/Exporter.php b/src/Symfony/Component/VarExporter/Internal/Exporter.php index f4e5746f15e4..6ee3ee7f4ea0 100644 --- a/src/Symfony/Component/VarExporter/Internal/Exporter.php +++ b/src/Symfony/Component/VarExporter/Internal/Exporter.php @@ -198,7 +198,7 @@ public static function export($value, string $indent = '') case true === $value: return 'true'; case null === $value: return 'null'; case '' === $value: return "''"; - case $value instanceof \UnitEnum: return ltrim(var_export($value, true), '\\'); + case $value instanceof \UnitEnum: return '\\'.ltrim(var_export($value, true), '\\'); } if ($value instanceof Reference) { diff --git a/src/Symfony/Component/VarExporter/Tests/Fixtures/unit-enum.php b/src/Symfony/Component/VarExporter/Tests/Fixtures/unit-enum.php index 48ab51dd0141..98bc12272ed5 100644 --- a/src/Symfony/Component/VarExporter/Tests/Fixtures/unit-enum.php +++ b/src/Symfony/Component/VarExporter/Tests/Fixtures/unit-enum.php @@ -1,5 +1,5 @@ Date: Fri, 13 Jan 2023 08:47:26 +0100 Subject: [PATCH 19/34] [DependencyInjection] Fix dump order of inlined deps --- .../Component/DependencyInjection/Dumper/PhpDumper.php | 2 +- .../Fixtures/php/services_almost_circular_private.php | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 9d662d5ed26e..dd548f3c123d 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -497,7 +497,7 @@ private function collectCircularReferences(string $sourceId, array $edges, array $loop = []; } } - $this->addCircularReferences($first, $loop, true); + $this->addCircularReferences($first, $loop, $loopByConstructor); break; } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php index 1dbcdb10ed01..33a45361a866 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php @@ -421,17 +421,16 @@ protected function getMonologInline_LoggerService() */ protected function getPAService() { - $a = new \stdClass(); - - $b = ($this->privates['pC'] ?? $this->getPCService()); + $a = ($this->privates['pC'] ?? $this->getPCService()); if (isset($this->services['pA'])) { return $this->services['pA']; } + $b = new \stdClass(); - $this->services['pA'] = $instance = new \stdClass($a, $b); + $this->services['pA'] = $instance = new \stdClass($b, $a); - $a->d = ($this->privates['pD'] ?? $this->getPDService()); + $b->d = ($this->privates['pD'] ?? $this->getPDService()); return $instance; } From c5899058e973ef4c944de51f9755f1619882b59c Mon Sep 17 00:00:00 2001 From: Robert Meijers Date: Tue, 10 Jan 2023 11:56:30 +0100 Subject: [PATCH 20/34] [SecurityBundle] Fix using same handler for multiple authenticators Using a reference for custom success/failure handler breaks using the same service for multiple authenticators. This as the options will be overriden by any later authenticators. So use a ChildDefinition instead so every authenticator gets a unique instance. Fixes: #48923 --- .../Security/Factory/AbstractFactory.php | 4 +- .../Security/Factory/AbstractFactoryTest.php | 23 ++++++++-- .../Tests/Functional/AuthenticatorTest.php | 34 +++++++++++++++ .../AuthenticatorBundle.php | 34 +++++++++++++++ .../DummyFormLoginFactory.php | 43 +++++++++++++++++++ .../Functional/app/Authenticator/bundles.php | 1 + .../app/Authenticator/custom_handlers.yml | 34 +++++++++++++++ .../Functional/app/Authenticator/routing.yml | 3 ++ 8 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/AuthenticatorBundle.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/DummyFormLoginFactory.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/custom_handlers.yml diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php index e8bfa9412aff..e6d89236dd29 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php @@ -164,7 +164,7 @@ protected function createAuthenticationSuccessHandler(ContainerBuilder $containe if (isset($config['success_handler'])) { $successHandler = $container->setDefinition($successHandlerId, new ChildDefinition('security.authentication.custom_success_handler')); - $successHandler->replaceArgument(0, new Reference($config['success_handler'])); + $successHandler->replaceArgument(0, new ChildDefinition($config['success_handler'])); $successHandler->replaceArgument(1, $options); $successHandler->replaceArgument(2, $id); } else { @@ -183,7 +183,7 @@ protected function createAuthenticationFailureHandler(ContainerBuilder $containe if (isset($config['failure_handler'])) { $failureHandler = $container->setDefinition($id, new ChildDefinition('security.authentication.custom_failure_handler')); - $failureHandler->replaceArgument(0, new Reference($config['failure_handler'])); + $failureHandler->replaceArgument(0, new ChildDefinition($config['failure_handler'])); $failureHandler->replaceArgument(1, $options); } else { $failureHandler = $container->setDefinition($id, new ChildDefinition('security.authentication.failure_handler')); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php index 12f7f4a03f22..8bb45f7cea2e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory; +use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -69,12 +70,19 @@ public function testDefaultFailureHandler($serviceId, $defaultHandlerInjection) $this->assertEquals(new Reference('security.authentication.failure_handler.foo.abstract_factory'), $arguments['index_6']); $failureHandler = $container->findDefinition((string) $arguments['index_6']); + $expectedFailureHandlerOptions = ['login_path' => '/bar']; $methodCalls = $failureHandler->getMethodCalls(); if ($defaultHandlerInjection) { $this->assertEquals('setOptions', $methodCalls[0][0]); - $this->assertEquals(['login_path' => '/bar'], $methodCalls[0][1][0]); + $this->assertEquals($expectedFailureHandlerOptions, $methodCalls[0][1][0]); } else { $this->assertCount(0, $methodCalls); + $this->assertInstanceOf(ChildDefinition::class, $failureHandler); + $this->assertEquals('security.authentication.custom_failure_handler', $failureHandler->getParent()); + $failureHandlerArguments = $failureHandler->getArguments(); + $this->assertInstanceOf(ChildDefinition::class, $failureHandlerArguments['index_0']); + $this->assertEquals($serviceId, $failureHandlerArguments['index_0']->getParent()); + $this->assertEquals($expectedFailureHandlerOptions, $failureHandlerArguments['index_1']); } } @@ -108,13 +116,22 @@ public function testDefaultSuccessHandler($serviceId, $defaultHandlerInjection) $successHandler = $container->findDefinition((string) $arguments['index_5']); $methodCalls = $successHandler->getMethodCalls(); + $expectedSuccessHandlerOptions = ['default_target_path' => '/bar']; + $expectedFirewallName = 'foo'; if ($defaultHandlerInjection) { $this->assertEquals('setOptions', $methodCalls[0][0]); - $this->assertEquals(['default_target_path' => '/bar'], $methodCalls[0][1][0]); + $this->assertEquals($expectedSuccessHandlerOptions, $methodCalls[0][1][0]); $this->assertEquals('setFirewallName', $methodCalls[1][0]); - $this->assertEquals(['foo'], $methodCalls[1][1]); + $this->assertEquals($expectedFirewallName, $methodCalls[1][1][0]); } else { $this->assertCount(0, $methodCalls); + $this->assertInstanceOf(ChildDefinition::class, $successHandler); + $this->assertEquals('security.authentication.custom_success_handler', $successHandler->getParent()); + $successHandlerArguments = $successHandler->getArguments(); + $this->assertInstanceOf(ChildDefinition::class, $successHandlerArguments['index_0']); + $this->assertEquals($serviceId, $successHandlerArguments['index_0']->getParent()); + $this->assertEquals($expectedSuccessHandlerOptions, $successHandlerArguments['index_1']); + $this->assertEquals($expectedFirewallName, $successHandlerArguments['index_2']); } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php index 10eeb39ca8c5..970a9dc9ae74 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php @@ -102,4 +102,38 @@ public function testMultipleFirewalls() $client->request('GET', '/firewall2/profile'); $this->assertResponseRedirects('http://localhost/login'); } + + public function testCustomSuccessHandler() + { + $client = $this->createClient(['test_case' => 'Authenticator', 'root_config' => 'custom_handlers.yml']); + + $client->request('POST', '/firewall1/login', [ + '_username' => 'jane@example.org', + '_password' => 'test', + ]); + $this->assertResponseRedirects('http://localhost/firewall1/test'); + + $client->request('POST', '/firewall1/dummy_login', [ + '_username' => 'jane@example.org', + '_password' => 'test', + ]); + $this->assertResponseRedirects('http://localhost/firewall1/dummy'); + } + + public function testCustomFailureHandler() + { + $client = $this->createClient(['test_case' => 'Authenticator', 'root_config' => 'custom_handlers.yml']); + + $client->request('POST', '/firewall1/login', [ + '_username' => 'jane@example.org', + '_password' => '', + ]); + $this->assertResponseRedirects('http://localhost/firewall1/login'); + + $client->request('POST', '/firewall1/dummy_login', [ + '_username' => 'jane@example.org', + '_password' => '', + ]); + $this->assertResponseRedirects('http://localhost/firewall1/dummy_login'); + } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/AuthenticatorBundle.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/AuthenticatorBundle.php new file mode 100644 index 000000000000..730974f17f16 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/AuthenticatorBundle.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle; + +use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class AuthenticatorBundle extends Bundle +{ + public function build(ContainerBuilder $container) + { + parent::build($container); + + $this->configureSecurityExtension($container); + } + + private function configureSecurityExtension(ContainerBuilder $container): void + { + /** @var SecurityExtension $extension */ + $extension = $container->getExtension('security'); + + $extension->addAuthenticatorFactory(new DummyFormLoginFactory()); + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/DummyFormLoginFactory.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/DummyFormLoginFactory.php new file mode 100644 index 000000000000..fc728fe5c6f4 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/DummyFormLoginFactory.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle; + +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FormLoginFactory; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +class DummyFormLoginFactory extends FormLoginFactory +{ + public function getKey(): string + { + return 'dummy_form_login'; + } + + public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string + { + $authenticatorId = 'security.authenticator.dummy_form_login.'.$firewallName; + $options = array_intersect_key($config, $this->options); + $authenticator = $container + ->setDefinition($authenticatorId, new ChildDefinition('security.authenticator.form_login')) + ->replaceArgument(1, new Reference($userProviderId)) + ->replaceArgument(2, new Reference($this->createAuthenticationSuccessHandler($container, $firewallName, $config))) + ->replaceArgument(3, new Reference($this->createAuthenticationFailureHandler($container, $firewallName, $config))) + ->replaceArgument(4, $options); + + if ($options['use_forward'] ?? false) { + $authenticator->addMethodCall('setHttpKernel', [new Reference('http_kernel')]); + } + + return $authenticatorId; + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/bundles.php index d1e9eb7e0d36..372700495208 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/bundles.php @@ -12,4 +12,5 @@ return [ new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(), + new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\AuthenticatorBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/custom_handlers.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/custom_handlers.yml new file mode 100644 index 000000000000..96e9762d9683 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/custom_handlers.yml @@ -0,0 +1,34 @@ +imports: + - { resource: ./config.yml } + - { resource: ./security.yml } + +security: + enable_authenticator_manager: true + firewalls: + firewall1: + pattern: /firewall1 + provider: in_memory + entry_point: form_login + form_login: + check_path: /firewall1/login + success_handler: success_handler + failure_handler: failure_handler + default_target_path: /firewall1/test + login_path: /firewall1/login + dummy_form_login: + check_path: /firewall1/dummy_login + success_handler: success_handler + failure_handler: failure_handler + default_target_path: /firewall1/dummy + login_path: /firewall1/dummy_login + +services: + success_handler: + class: Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler + arguments: + - '@security.http_utils' + failure_handler: + class: Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler + arguments: + - '@http_kernel' + - '@security.http_utils' diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml index 4796a3f6bc00..76d894d9de90 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml @@ -22,6 +22,9 @@ security_custom_profile: firewall1_login: path: /firewall1/login +firewall_dummy_login: + path: /firewall1/dummy_login + firewall2_profile: path: /firewall2/profile defaults: From 0e883a9b3dd4ae58fb3b19a98246987e686c282b Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 14 Jan 2023 09:18:16 +0100 Subject: [PATCH 21/34] use method_exists() instead of catching reflection exceptions --- .../Serializer/Normalizer/GetSetMethodNormalizer.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php index 962bf6a5b9b5..b67a808cb9ab 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php @@ -152,14 +152,7 @@ protected function setAttributeValue(object $object, string $attribute, $value, $key = \get_class($object).':'.$setter; if (!isset(self::$setterAccessibleCache[$key])) { - try { - // We have to use is_callable() here since method_exists() - // does not "see" protected/private methods - self::$setterAccessibleCache[$key] = \is_callable([$object, $setter]) && !(new \ReflectionMethod($object, $setter))->isStatic(); - } catch (\ReflectionException $e) { - // Method does not exist in the class, probably a magic method - self::$setterAccessibleCache[$key] = false; - } + self::$setterAccessibleCache[$key] = method_exists($object, $setter) && \is_callable([$object, $setter]) && !(new \ReflectionMethod($object, $setter))->isStatic(); } if (self::$setterAccessibleCache[$key]) { From 4edd3478dcc60a183d643286acc9388039e6a736 Mon Sep 17 00:00:00 2001 From: "michael.kubovic" Date: Thu, 12 Jan 2023 17:09:46 +0100 Subject: [PATCH 22/34] [PropertyInfo] Fixes constructor extractor for mixed type --- .../Component/PropertyInfo/Extractor/PhpDocExtractor.php | 2 +- .../PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php | 1 + .../Component/PropertyInfo/Tests/Fixtures/ConstructorDummy.php | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index 0f2fba5ad443..ef1967b671a4 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -200,7 +200,7 @@ public function getTypesFromConstructor(string $class, string $property): ?array } } - if (!isset($types[0])) { + if (!isset($types[0]) || [] === $types[0]) { return null; } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php index dec09cc70b7b..f053832f0124 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php @@ -443,6 +443,7 @@ public function constructorTypesProvider() ['dateObject', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTimeInterface')]], ['dateTime', null], ['ddd', null], + ['mixed', null], ]; } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ConstructorDummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ConstructorDummy.php index 1c50c67e73ed..94173ba5fe4a 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ConstructorDummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ConstructorDummy.php @@ -29,8 +29,9 @@ class ConstructorDummy * @param \DateTimeZone $timezone * @param int $date Timestamp * @param \DateTimeInterface $dateObject + * @param mixed $mixed */ - public function __construct(\DateTimeZone $timezone, $date, $dateObject, \DateTime $dateTime) + public function __construct(\DateTimeZone $timezone, $date, $dateObject, \DateTime $dateTime, $mixed) { $this->timezone = $timezone->getName(); $this->date = \DateTime::createFromFormat('U', $date); From 6fb7cb9eb2cefe39e1a032d54776f9609065263e Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Sat, 14 Jan 2023 17:44:03 +0100 Subject: [PATCH 23/34] [Tests] Remove `$this` occurrences in future static data providers --- .../Tests/Html5ParserCrawlerTest.php | 6 ++--- .../Tests/ExpressionLanguageTest.php | 15 +++++++++-- .../Component/Filesystem/Tests/PathTest.php | 27 ++++++++++++++++--- .../Iterator/DepthRangeFilterIteratorTest.php | 8 +++--- .../ExcludeDirectoryFilterIteratorTest.php | 6 ++--- .../Iterator/FileTypeFilterIteratorTest.php | 4 +-- .../Tests/Iterator/SortableIteratorTest.php | 14 +++++----- .../Tests/EventListener/ErrorListenerTest.php | 2 +- .../HandleMessageMiddlewareTest.php | 24 ++++++++++++----- 9 files changed, 74 insertions(+), 32 deletions(-) diff --git a/src/Symfony/Component/DomCrawler/Tests/Html5ParserCrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/Html5ParserCrawlerTest.php index 05d1bc76a9f1..92370616598b 100644 --- a/src/Symfony/Component/DomCrawler/Tests/Html5ParserCrawlerTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/Html5ParserCrawlerTest.php @@ -52,7 +52,7 @@ public function testHtml5ParserWithInvalidHeadedContent(string $content) public function validHtml5Provider(): iterable { - $html = $this->getDoctype().'

Foo

'; + $html = static::getDoctype().'

Foo

'; $BOM = \chr(0xEF).\chr(0xBB).\chr(0xBF); yield 'BOM first' => [$BOM.$html]; @@ -60,12 +60,12 @@ public function validHtml5Provider(): iterable yield 'Multiline comment' => ["".$html]; yield 'Several comments' => [' '.$html]; yield 'Whitespaces' => [' '.$html]; - yield 'All together' => [$BOM.' '.''.$html]; + yield 'All together' => [$BOM.' '.$html]; } public function invalidHtml5Provider(): iterable { - $html = $this->getDoctype().'

Foo

'; + $html = static::getDoctype().'

Foo

'; yield 'Text' => ['hello world'.$html]; yield 'Text between comments' => [' test '.$html]; diff --git a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php index c0bd560d31ba..c4c98dd88006 100644 --- a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php +++ b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php @@ -121,8 +121,19 @@ public function testParseThrowsInsteadOfNotice() public function shortCircuitProviderEvaluate() { - $object = $this->getMockBuilder(\stdClass::class)->setMethods(['foo'])->getMock(); - $object->expects($this->never())->method('foo'); + $object = new class(\Closure::fromCallable([static::class, 'fail'])) { + private $fail; + + public function __construct(callable $fail) + { + $this->fail = $fail; + } + + public function foo() + { + ($this->fail)(); + } + }; return [ ['false and object.foo()', ['object' => $object], false], diff --git a/src/Symfony/Component/Filesystem/Tests/PathTest.php b/src/Symfony/Component/Filesystem/Tests/PathTest.php index 2f04c790c396..3d0f2beb1108 100644 --- a/src/Symfony/Component/Filesystem/Tests/PathTest.php +++ b/src/Symfony/Component/Filesystem/Tests/PathTest.php @@ -458,11 +458,30 @@ public function providePathTests(): \Generator yield ['..', '/webmozart/symfony', '/webmozart']; } + private static function getPathTests(): \Generator + { + yield from [ + // relative to absolute path + ['css/style.css', '/webmozart/symfony', '/webmozart/symfony/css/style.css'], + ['../css/style.css', '/webmozart/symfony', '/webmozart/css/style.css'], + ['../../css/style.css', '/webmozart/symfony', '/css/style.css'], + + // relative to root + ['css/style.css', '/', '/css/style.css'], + ['css/style.css', 'C:', 'C:/css/style.css'], + ['css/style.css', 'C:/', 'C:/css/style.css'], + + // same sub directories in different base directories + ['../../symfony/css/style.css', '/webmozart/css', '/symfony/css/style.css'], + + ['', '/webmozart/symfony', '/webmozart/symfony'], + ['..', '/webmozart/symfony', '/webmozart'], + ]; + } + public function provideMakeAbsoluteTests(): \Generator { - foreach ($this->providePathTests() as $set) { - yield $set; - } + yield from static::getPathTests(); // collapse dots yield ['css/./style.css', '/webmozart/symfony', '/webmozart/symfony/css/style.css']; @@ -589,7 +608,7 @@ public function testMakeAbsoluteDoesNotFailIfDifferentRoot(string $basePath, str public function provideMakeRelativeTests(): \Generator { - foreach ($this->providePathTests() as $set) { + foreach (static::getPathTests() as $set) { yield [$set[2], $set[1], $set[0]]; } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php index b2a5303b58d3..a66e50287e74 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php @@ -93,11 +93,11 @@ public function getAcceptData() ]; return [ - [0, 0, $this->toAbsolute($lessThan1)], - [0, 1, $this->toAbsolute($lessThanOrEqualTo1)], + [0, 0, static::toAbsolute($lessThan1)], + [0, 1, static::toAbsolute($lessThanOrEqualTo1)], [2, \PHP_INT_MAX, []], - [1, \PHP_INT_MAX, $this->toAbsolute($graterThanOrEqualTo1)], - [1, 1, $this->toAbsolute($equalTo1)], + [1, \PHP_INT_MAX, static::toAbsolute($graterThanOrEqualTo1)], + [1, 1, static::toAbsolute($equalTo1)], ]; } } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php index 1729766fe4bd..572029a17f8f 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php @@ -99,9 +99,9 @@ public function getAcceptData() ]; return [ - [['foo'], $this->toAbsolute($foo)], - [['fo'], $this->toAbsolute($fo)], - [['toto/'], $this->toAbsolute($toto)], + [['foo'], static::toAbsolute($foo)], + [['fo'], static::toAbsolute($fo)], + [['toto/'], static::toAbsolute($toto)], ]; } } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php index e15c03521af9..be7beb1d146a 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php @@ -57,8 +57,8 @@ public function getAcceptData() ]; return [ - [FileTypeFilterIterator::ONLY_FILES, $this->toAbsolute($onlyFiles)], - [FileTypeFilterIterator::ONLY_DIRECTORIES, $this->toAbsolute($onlyDirectories)], + [FileTypeFilterIterator::ONLY_FILES, static::toAbsolute($onlyFiles)], + [FileTypeFilterIterator::ONLY_DIRECTORIES, static::toAbsolute($onlyDirectories)], ]; } } diff --git a/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php index 098cd75674f3..049961452b18 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php @@ -247,13 +247,13 @@ public function getAcceptData() ]; return [ - [SortableIterator::SORT_BY_NAME, $this->toAbsolute($sortByName)], - [SortableIterator::SORT_BY_TYPE, $this->toAbsolute($sortByType)], - [SortableIterator::SORT_BY_ACCESSED_TIME, $this->toAbsolute($sortByAccessedTime)], - [SortableIterator::SORT_BY_CHANGED_TIME, $this->toAbsolute($sortByChangedTime)], - [SortableIterator::SORT_BY_MODIFIED_TIME, $this->toAbsolute($sortByModifiedTime)], - [SortableIterator::SORT_BY_NAME_NATURAL, $this->toAbsolute($sortByNameNatural)], - [function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); }, $this->toAbsolute($customComparison)], + [SortableIterator::SORT_BY_NAME, static::toAbsolute($sortByName)], + [SortableIterator::SORT_BY_TYPE, static::toAbsolute($sortByType)], + [SortableIterator::SORT_BY_ACCESSED_TIME, static::toAbsolute($sortByAccessedTime)], + [SortableIterator::SORT_BY_CHANGED_TIME, static::toAbsolute($sortByChangedTime)], + [SortableIterator::SORT_BY_MODIFIED_TIME, static::toAbsolute($sortByModifiedTime)], + [SortableIterator::SORT_BY_NAME_NATURAL, static::toAbsolute($sortByNameNatural)], + [function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); }, static::toAbsolute($customComparison)], ]; } } diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/ErrorListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/ErrorListenerTest.php index 00a6bde9004c..73cc19afc8c6 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/ErrorListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/ErrorListenerTest.php @@ -209,7 +209,7 @@ public function controllerProvider() }]; yield [function ($exception) { - $this->assertInstanceOf(FlattenException::class, $exception); + static::assertInstanceOf(FlattenException::class, $exception); return new Response('OK: '.$exception->getMessage()); }]; diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/HandleMessageMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/HandleMessageMiddlewareTest.php index 34b84596c67d..eb0beaa8a584 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/HandleMessageMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/HandleMessageMiddlewareTest.php @@ -69,16 +69,28 @@ public function testItAddsHandledStamps(array $handlers, array $expectedStamps, public function itAddsHandledStampsProvider(): iterable { - $first = $this->createPartialMock(HandleMessageMiddlewareTestCallable::class, ['__invoke']); - $first->method('__invoke')->willReturn('first result'); + $first = new class() extends HandleMessageMiddlewareTestCallable { + public function __invoke() + { + return 'first result'; + } + }; $firstClass = \get_class($first); - $second = $this->createPartialMock(HandleMessageMiddlewareTestCallable::class, ['__invoke']); - $second->method('__invoke')->willReturn(null); + $second = new class() extends HandleMessageMiddlewareTestCallable { + public function __invoke() + { + return null; + } + }; $secondClass = \get_class($second); - $failing = $this->createPartialMock(HandleMessageMiddlewareTestCallable::class, ['__invoke']); - $failing->method('__invoke')->will($this->throwException(new \Exception('handler failed.'))); + $failing = new class() extends HandleMessageMiddlewareTestCallable { + public function __invoke() + { + throw new \Exception('handler failed.'); + } + }; yield 'A stamp is added' => [ [$first], From adb9287f8d29150b21e01409306a6cd9987a238a Mon Sep 17 00:00:00 2001 From: Uladzimir Tsykun Date: Sun, 15 Jan 2023 04:16:57 +0100 Subject: [PATCH 24/34] Fix user_identifier support after username has been deprecated in favor of it. --- .../Component/Ldap/Security/CheckLdapCredentialsListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Ldap/Security/CheckLdapCredentialsListener.php b/src/Symfony/Component/Ldap/Security/CheckLdapCredentialsListener.php index c8458909b7b6..81e4f5fb98d6 100644 --- a/src/Symfony/Component/Ldap/Security/CheckLdapCredentialsListener.php +++ b/src/Symfony/Component/Ldap/Security/CheckLdapCredentialsListener.php @@ -85,7 +85,7 @@ public function onCheckPassport(CheckPassportEvent $event) } // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 $username = $ldap->escape(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), '', LdapInterface::ESCAPE_FILTER); - $query = str_replace('{username}', $username, $ldapBadge->getQueryString()); + $query = str_replace(['{username}', '{user_identifier}'], $username, $ldapBadge->getQueryString()); $result = $ldap->query($ldapBadge->getDnString(), $query)->execute(); if (1 !== $result->count()) { throw new BadCredentialsException('The presented username is invalid.'); From ef7906dab3172fa753b58de9680c20d450832df0 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 15 Jan 2023 15:54:19 +0100 Subject: [PATCH 25/34] [Validator] Fix Email validator logic --- src/Symfony/Component/Validator/Constraints/EmailValidator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/EmailValidator.php b/src/Symfony/Component/Validator/Constraints/EmailValidator.php index ee78024d6798..11fc7be2dd35 100644 --- a/src/Symfony/Component/Validator/Constraints/EmailValidator.php +++ b/src/Symfony/Component/Validator/Constraints/EmailValidator.php @@ -16,6 +16,7 @@ use Egulias\EmailValidator\Validation\NoRFCWarningsValidation; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\LogicException; use Symfony\Component\Validator\Exception\UnexpectedTypeException; use Symfony\Component\Validator\Exception\UnexpectedValueException; @@ -71,7 +72,7 @@ public function validate($value, Constraint $constraint) if (null === $constraint->mode) { if (Email::VALIDATION_MODE_STRICT === $this->defaultMode && !class_exists(EguliasEmailValidator::class)) { - throw new LogicException(sprintf('The "egulias/email-validator" component is required to make the "%s" constraint default to strict mode.', EguliasEmailValidator::class)); + throw new LogicException(sprintf('The "egulias/email-validator" component is required to make the "%s" constraint default to strict mode.', Email::class)); } $constraint->mode = $this->defaultMode; From 19add9703a0beab5e8b326b7a01bb67e9291ae56 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 16 Jan 2023 11:52:33 +0100 Subject: [PATCH 26/34] [VarDumper] Fix JS to expand / collapse --- src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php index af4de9613656..75cbe2fcbf6e 100644 --- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php @@ -167,9 +167,9 @@ protected function getDumpHeader() }; refStyle.innerHTML = 'pre.sf-dump .sf-dump-compact, .sf-dump-str-collapse .sf-dump-str-collapse, .sf-dump-str-expand .sf-dump-str-expand { display: none; }'; -(doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle); +doc.head.appendChild(refStyle); refStyle = doc.createElement('style'); -(doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle); +doc.head.appendChild(refStyle); if (!doc.addEventListener) { addEventListener = function (element, eventName, callback) { From 52a0e43a977ca9df442c2a17e2d4d0c11a6ec791 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 19 Jan 2023 09:39:39 +0100 Subject: [PATCH 27/34] [Cache] fix collecting cache stats when nesting computations --- .../DataCollector/CacheDataCollector.php | 8 +++--- .../DataCollector/CacheDataCollectorTest.php | 26 ++++++++++++++++--- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php index 9590436dc463..e121596e8384 100644 --- a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php +++ b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php @@ -114,7 +114,7 @@ private function calculateStatistics(): array /** @var TraceableAdapterEvent $call */ foreach ($calls as $call) { ++$statistics[$name]['calls']; - $statistics[$name]['time'] += $call->end - $call->start; + $statistics[$name]['time'] += ($call->end ?? microtime(true)) - $call->start; if ('get' === $call->name) { ++$statistics[$name]['reads']; if ($call->hits) { @@ -136,10 +136,8 @@ private function calculateStatistics(): array $statistics[$name]['misses'] += $call->misses; } elseif ('hasItem' === $call->name) { ++$statistics[$name]['reads']; - if (false === $call->result) { - ++$statistics[$name]['misses']; - } else { - ++$statistics[$name]['hits']; + foreach ($call->result ?? [] as $result) { + ++$statistics[$name][$result ? 'hits' : 'misses']; } } elseif ('save' === $call->name) { ++$statistics[$name]['writes']; diff --git a/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php b/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php index 6aa94c2c6338..a00954b6cb82 100644 --- a/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php +++ b/src/Symfony/Component/Cache/Tests/DataCollector/CacheDataCollectorTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Cache\Tests\DataCollector; use PHPUnit\Framework\TestCase; +use Symfony\Component\Cache\Adapter\NullAdapter; use Symfony\Component\Cache\Adapter\TraceableAdapter; use Symfony\Component\Cache\DataCollector\CacheDataCollector; use Symfony\Component\HttpFoundation\Request; @@ -55,7 +56,7 @@ public function testHitedEventDataCollector() $traceableAdapterEvent->name = 'hasItem'; $traceableAdapterEvent->start = 0; $traceableAdapterEvent->end = 0; - $traceableAdapterEvent->hits = 1; + $traceableAdapterEvent->hits = 0; $traceableAdapterEvent->misses = 0; $traceableAdapterEvent->result = ['foo' => false]; @@ -63,8 +64,8 @@ public function testHitedEventDataCollector() $this->assertEquals($statistics[self::INSTANCE_NAME]['calls'], 1, 'calls'); $this->assertEquals($statistics[self::INSTANCE_NAME]['reads'], 1, 'reads'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 1, 'hits'); - $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 0, 'misses'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['hits'], 0, 'hits'); + $this->assertEquals($statistics[self::INSTANCE_NAME]['misses'], 1, 'misses'); $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 0, 'writes'); } @@ -84,6 +85,25 @@ public function testSavedEventDataCollector() $this->assertEquals($statistics[self::INSTANCE_NAME]['writes'], 1, 'writes'); } + public function testCollectBeforeEnd() + { + $adapter = new TraceableAdapter(new NullAdapter()); + + $collector = new CacheDataCollector(); + $collector->addInstance(self::INSTANCE_NAME, $adapter); + + $adapter->get('foo', function () use ($collector) { + $collector->collect(new Request(), new Response()); + + return 123; + }); + + $stats = $collector->getStatistics(); + $this->assertGreaterThan(0, $stats[self::INSTANCE_NAME]['time']); + $this->assertEquals($stats[self::INSTANCE_NAME]['hits'], 0, 'hits'); + $this->assertEquals($stats[self::INSTANCE_NAME]['misses'], 1, 'misses'); + } + private function getCacheDataCollectorStatisticsFromEvents(array $traceableAdapterEvents) { $traceableAdapterMock = $this->createMock(TraceableAdapter::class); From d41f0bfbab406010397c1d6f68fba2ef5f0b4b00 Mon Sep 17 00:00:00 2001 From: Farhad Safarov Date: Wed, 18 Jan 2023 19:36:09 +0300 Subject: [PATCH 28/34] [Notifier] [OvhCloud] handle invalid receiver --- .../Bridge/OvhCloud/OvhCloudTransport.php | 4 ++++ .../OvhCloud/Tests/OvhCloudTransportTest.php | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/Symfony/Component/Notifier/Bridge/OvhCloud/OvhCloudTransport.php b/src/Symfony/Component/Notifier/Bridge/OvhCloud/OvhCloudTransport.php index 3d50fc8f7fcc..0c07729ed570 100644 --- a/src/Symfony/Component/Notifier/Bridge/OvhCloud/OvhCloudTransport.php +++ b/src/Symfony/Component/Notifier/Bridge/OvhCloud/OvhCloudTransport.php @@ -121,6 +121,10 @@ protected function doSend(MessageInterface $message): SentMessage $success = $response->toArray(false); + if (!isset($success['ids'][0])) { + throw new TransportException(sprintf('Attempt to send the SMS to invalid receivers: "%s".', implode(',', $success['invalidReceivers'])), $response); + } + $sentMessage = new SentMessage($message, (string) $this); $sentMessage->setMessageId($success['ids'][0]); diff --git a/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportTest.php b/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportTest.php index 9bfac2249cc9..c3fdbbb04706 100644 --- a/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportTest.php +++ b/src/Symfony/Component/Notifier/Bridge/OvhCloud/Tests/OvhCloudTransportTest.php @@ -14,6 +14,7 @@ use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\Notifier\Bridge\OvhCloud\OvhCloudTransport; +use Symfony\Component\Notifier\Exception\TransportException; use Symfony\Component\Notifier\Message\ChatMessage; use Symfony\Component\Notifier\Message\MessageInterface; use Symfony\Component\Notifier\Message\SmsMessage; @@ -92,4 +93,26 @@ public function testValidSignature(string $message) $toSign = 'applicationSecret+consumerKey+POST+'.$endpoint.'+'.$body.'+'.$time; $this->assertSame('$1$'.sha1($toSign), $signature); } + + public function testInvalidReceiver() + { + $smsMessage = new SmsMessage('invalid_receiver', 'lorem ipsum'); + + $data = json_encode([ + 'totalCreditsRemoved' => '1', + 'invalidReceivers' => ['invalid_receiver'], + 'ids' => [], + 'validReceivers' => [], + ]); + $responses = [ + new MockResponse((string) time()), + new MockResponse($data), + ]; + + $transport = $this->createTransport(new MockHttpClient($responses)); + + $this->expectException(TransportException::class); + $this->expectExceptionMessage('Attempt to send the SMS to invalid receivers: "invalid_receiver"'); + $transport->send($smsMessage); + } } From 6bbc46c6399392bc38e0b1ee4343a56d3b13d87c Mon Sep 17 00:00:00 2001 From: nerdgod Date: Fri, 20 Jan 2023 08:30:02 -0800 Subject: [PATCH 29/34] Update ComposerPlugin.php On Windows systems where the project directory is a junction or symlink, realpath() must be called on any directories (withing a subtree) you wish to compare relative paths for, because otherwise the directory upon which realpath() was called will point to the link target (original) and the other will point to the link (copy) which may be on a different filesystem (resulting in an invalid projectDir path like `C:\project\\Z:\project\` in the autoload_runtime.php) --- src/Symfony/Component/Runtime/Internal/ComposerPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Runtime/Internal/ComposerPlugin.php b/src/Symfony/Component/Runtime/Internal/ComposerPlugin.php index 8247b858e66b..d689e7f2dedb 100644 --- a/src/Symfony/Component/Runtime/Internal/ComposerPlugin.php +++ b/src/Symfony/Component/Runtime/Internal/ComposerPlugin.php @@ -58,7 +58,7 @@ public function uninstall(Composer $composer, IOInterface $io): void public function updateAutoloadFile(): void { - $vendorDir = $this->composer->getConfig()->get('vendor-dir'); + $vendorDir = realpath($this->composer->getConfig()->get('vendor-dir')); if (!is_file($autoloadFile = $vendorDir.'/autoload.php') || false === $extra = $this->composer->getPackage()->getExtra()['runtime'] ?? [] From 0d2f828a15e1b8d375a415cdaeccddba63cbabf1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 23 Jan 2023 16:37:22 +0100 Subject: [PATCH 30/34] [DependencyInjection] Fix named arguments when using ContainerBuilder before compilation --- .../DependencyInjection/ContainerBuilder.php | 4 ++++ .../Tests/ContainerBuilderTest.php | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index bcfa623d7b2d..e51691006e7c 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1089,6 +1089,10 @@ private function createService(Definition $definition, array &$inlineServices, b return $this->services[$id] ?? $this->privates[$id]; } + if (!array_is_list($arguments)) { + $arguments = array_combine(array_map(function ($k) { return preg_replace('/^.*\\$/', '', $k); }, array_keys($arguments)), $arguments); + } + if (null !== $factory) { $service = $factory(...$arguments); diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 6ab7232d23a5..5fa9c5dfbd81 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1777,7 +1777,7 @@ public function testFindTags() /** * @requires PHP 8 */ - public function testNamedArgument() + public function testNamedArgumentAfterCompile() { $container = new ContainerBuilder(); $container->register(E::class) @@ -1791,6 +1791,21 @@ public function testNamedArgument() $this->assertSame('', $e->first); $this->assertSame(2, $e->second); } + + /** + * @requires PHP 8 + */ + public function testNamedArgumentBeforeCompile() + { + $container = new ContainerBuilder(); + $container->register(E::class, E::class) + ->setPublic(true) + ->setArguments(['$first' => 1]); + + $e = $container->get(E::class); + + $this->assertSame(1, $e->first); + } } class FooClass From 889d73939bd4651ed4264c9f0596a44b37bef543 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 6 Sep 2022 14:31:39 +0200 Subject: [PATCH 31/34] [Security/Http] Check tokens before loading users from providers --- .../Core/Signature/SignatureHasher.php | 44 ++++++++++++++--- .../Http/LoginLink/LoginLinkHandler.php | 22 ++++----- .../PersistentRememberMeHandler.php | 45 +++++++++-------- .../Http/RememberMe/RememberMeDetails.php | 7 +-- .../RememberMe/SignatureRememberMeHandler.php | 16 ++++-- .../Tests/LoginLink/LoginLinkHandlerTest.php | 38 ++++++-------- .../PersistentRememberMeHandlerTest.php | 4 +- .../SignatureRememberMeHandlerTest.php | 49 ++++++------------- .../Component/Security/Http/composer.json | 2 +- 9 files changed, 123 insertions(+), 104 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Signature/SignatureHasher.php b/src/Symfony/Component/Security/Core/Signature/SignatureHasher.php index e2b5dcb31f65..f604dd208bb1 100644 --- a/src/Symfony/Component/Security/Core/Signature/SignatureHasher.php +++ b/src/Symfony/Component/Security/Core/Signature/SignatureHasher.php @@ -45,7 +45,9 @@ public function __construct(PropertyAccessorInterface $propertyAccessor, array $ } /** - * Verifies the hash using the provided user and expire time. + * Verifies the hash using the provided user identifier and expire time. + * + * This method must be called before the user object is loaded from a provider. * * @param int $expires The expiry time as a unix timestamp * @param string $hash The plaintext hash provided by the request @@ -53,16 +55,38 @@ public function __construct(PropertyAccessorInterface $propertyAccessor, array $ * @throws InvalidSignatureException If the signature does not match the provided parameters * @throws ExpiredSignatureException If the signature is no longer valid */ - public function verifySignatureHash(UserInterface $user, int $expires, string $hash): void + public function acceptSignatureHash(string $userIdentifier, int $expires, string $hash): void { - if (!hash_equals($hash, $this->computeSignatureHash($user, $expires))) { + if ($expires < time()) { + throw new ExpiredSignatureException('Signature has expired.'); + } + $hmac = substr($hash, 0, 44); + $payload = substr($hash, 44).':'.$expires.':'.$userIdentifier; + + if (!hash_equals($hmac, $this->generateHash($payload))) { throw new InvalidSignatureException('Invalid or expired signature.'); } + } + /** + * Verifies the hash using the provided user and expire time. + * + * @param int $expires The expiry time as a unix timestamp + * @param string $hash The plaintext hash provided by the request + * + * @throws InvalidSignatureException If the signature does not match the provided parameters + * @throws ExpiredSignatureException If the signature is no longer valid + */ + public function verifySignatureHash(UserInterface $user, int $expires, string $hash): void + { if ($expires < time()) { throw new ExpiredSignatureException('Signature has expired.'); } + if (!hash_equals($hash, $this->computeSignatureHash($user, $expires))) { + throw new InvalidSignatureException('Invalid or expired signature.'); + } + if ($this->expiredSignaturesStorage && $this->maxUses) { if ($this->expiredSignaturesStorage->countUsages($hash) >= $this->maxUses) { throw new ExpiredSignatureException(sprintf('Signature can only be used "%d" times.', $this->maxUses)); @@ -79,7 +103,8 @@ public function verifySignatureHash(UserInterface $user, int $expires, string $h */ public function computeSignatureHash(UserInterface $user, int $expires): string { - $signatureFields = [base64_encode(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername()), $expires]; + $userIdentifier = method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(); + $fieldsHash = hash_init('sha256'); foreach ($this->signatureProperties as $property) { $value = $this->propertyAccessor->getValue($user, $property) ?? ''; @@ -90,9 +115,16 @@ public function computeSignatureHash(UserInterface $user, int $expires): string if (!\is_scalar($value) && !(\is_object($value) && method_exists($value, '__toString'))) { throw new \InvalidArgumentException(sprintf('The property path "%s" on the user object "%s" must return a value that can be cast to a string, but "%s" was returned.', $property, \get_class($user), get_debug_type($value))); } - $signatureFields[] = base64_encode($value); + hash_update($fieldsHash, ':'.base64_encode($value)); } - return base64_encode(hash_hmac('sha256', implode(':', $signatureFields), $this->secret)); + $fieldsHash = strtr(base64_encode(hash_final($fieldsHash, true)), '+/=', '-_~'); + + return $this->generateHash($fieldsHash.':'.$expires.':'.$userIdentifier).$fieldsHash; + } + + private function generateHash(string $tokenValue): string + { + return strtr(base64_encode(hash_hmac('sha256', $tokenValue, $this->secret, true)), '+/=', '-_~'); } } diff --git a/src/Symfony/Component/Security/Http/LoginLink/LoginLinkHandler.php b/src/Symfony/Component/Security/Http/LoginLink/LoginLinkHandler.php index 74c6c7e74fb3..15e3c7f25e00 100644 --- a/src/Symfony/Component/Security/Http/LoginLink/LoginLinkHandler.php +++ b/src/Symfony/Component/Security/Http/LoginLink/LoginLinkHandler.php @@ -84,7 +84,16 @@ public function consumeLoginLink(Request $request): UserInterface { $userIdentifier = $request->get('user'); + if (!$hash = $request->get('hash')) { + throw new InvalidLoginLinkException('Missing "hash" parameter.'); + } + if (!$expires = $request->get('expires')) { + throw new InvalidLoginLinkException('Missing "expires" parameter.'); + } + try { + $this->signatureHasher->acceptSignatureHash($userIdentifier, $expires, $hash); + // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 if (method_exists($this->userProvider, 'loadUserByIdentifier')) { $user = $this->userProvider->loadUserByIdentifier($userIdentifier); @@ -93,19 +102,10 @@ public function consumeLoginLink(Request $request): UserInterface $user = $this->userProvider->loadUserByUsername($userIdentifier); } - } catch (UserNotFoundException $exception) { - throw new InvalidLoginLinkException('User not found.', 0, $exception); - } - if (!$hash = $request->get('hash')) { - throw new InvalidLoginLinkException('Missing "hash" parameter.'); - } - if (!$expires = $request->get('expires')) { - throw new InvalidLoginLinkException('Missing "expires" parameter.'); - } - - try { $this->signatureHasher->verifySignatureHash($user, $expires, $hash); + } catch (UserNotFoundException $e) { + throw new InvalidLoginLinkException('User not found.', 0, $e); } catch (ExpiredSignatureException $e) { throw new ExpiredLoginLinkException(ucfirst(str_ireplace('signature', 'login link', $e->getMessage())), 0, $e); } catch (InvalidSignatureException $e) { diff --git a/src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php b/src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php index 8d9360355282..75fd6b582a6a 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php +++ b/src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php @@ -53,18 +53,16 @@ public function __construct(TokenProviderInterface $tokenProvider, string $secre */ public function createRememberMeCookie(UserInterface $user): void { - $series = base64_encode(random_bytes(64)); - $tokenValue = $this->generateHash(base64_encode(random_bytes(64))); + $series = random_bytes(66); + $tokenValue = strtr(base64_encode(substr($series, 33)), '+/=', '-_~'); + $series = strtr(base64_encode(substr($series, 0, 33)), '+/=', '-_~'); $token = new PersistentToken(\get_class($user), method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), $series, $tokenValue, new \DateTime()); $this->tokenProvider->createNewToken($token); $this->createCookie(RememberMeDetails::fromPersistentToken($token, time() + $this->options['lifetime'])); } - /** - * {@inheritdoc} - */ - public function processRememberMe(RememberMeDetails $rememberMeDetails, UserInterface $user): void + public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): UserInterface { if (!str_contains($rememberMeDetails->getValue(), ':')) { throw new AuthenticationException('The cookie is incorrectly formatted.'); @@ -86,18 +84,28 @@ public function processRememberMe(RememberMeDetails $rememberMeDetails, UserInte throw new AuthenticationException('The cookie has expired.'); } + return parent::consumeRememberMeCookie($rememberMeDetails->withValue($persistentToken->getLastUsed()->getTimestamp().':'.$rememberMeDetails->getValue().':'.$persistentToken->getClass())); + } + + public function processRememberMe(RememberMeDetails $rememberMeDetails, UserInterface $user): void + { + [$lastUsed, $series, $tokenValue, $class] = explode(':', $rememberMeDetails->getValue(), 4); + $persistentToken = new PersistentToken($class, $rememberMeDetails->getUserIdentifier(), $series, $tokenValue, new \DateTime('@'.$lastUsed)); + // if a token was regenerated less than a minute ago, there is no need to regenerate it // if multiple concurrent requests reauthenticate a user we do not want to update the token several times - if ($persistentToken->getLastUsed()->getTimestamp() + 60 < time()) { - $tokenValue = $this->generateHash(base64_encode(random_bytes(64))); - $tokenLastUsed = new \DateTime(); - if ($this->tokenVerifier) { - $this->tokenVerifier->updateExistingToken($persistentToken, $tokenValue, $tokenLastUsed); - } - $this->tokenProvider->updateToken($series, $tokenValue, $tokenLastUsed); - - $this->createCookie($rememberMeDetails->withValue($series.':'.$tokenValue)); + if ($persistentToken->getLastUsed()->getTimestamp() + 60 >= time()) { + return; + } + + $tokenValue = strtr(base64_encode(random_bytes(33)), '+/=', '-_~'); + $tokenLastUsed = new \DateTime(); + if ($this->tokenVerifier) { + $this->tokenVerifier->updateExistingToken($persistentToken, $tokenValue, $tokenLastUsed); } + $this->tokenProvider->updateToken($series, $tokenValue, $tokenLastUsed); + + $this->createCookie($rememberMeDetails->withValue($series.':'.$tokenValue)); } /** @@ -113,7 +121,7 @@ public function clearRememberMeCookie(): void } $rememberMeDetails = RememberMeDetails::fromRawCookie($cookie); - [$series, ] = explode(':', $rememberMeDetails->getValue()); + [$series] = explode(':', $rememberMeDetails->getValue()); $this->tokenProvider->deleteTokenBySeries($series); } @@ -124,9 +132,4 @@ public function getTokenProvider(): TokenProviderInterface { return $this->tokenProvider; } - - private function generateHash(string $tokenValue): string - { - return hash_hmac('sha256', $tokenValue, $this->secret); - } } diff --git a/src/Symfony/Component/Security/Http/RememberMe/RememberMeDetails.php b/src/Symfony/Component/Security/Http/RememberMe/RememberMeDetails.php index 3126ca5d5e25..fea0955ca80e 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/RememberMeDetails.php +++ b/src/Symfony/Component/Security/Http/RememberMe/RememberMeDetails.php @@ -36,13 +36,14 @@ public function __construct(string $userFqcn, string $userIdentifier, int $expir public static function fromRawCookie(string $rawCookie): self { - $cookieParts = explode(self::COOKIE_DELIMITER, base64_decode($rawCookie), 4); + $cookieParts = explode(self::COOKIE_DELIMITER, $rawCookie, 4); if (4 !== \count($cookieParts)) { throw new AuthenticationException('The cookie contains invalid data.'); } - if (false === $cookieParts[1] = base64_decode($cookieParts[1], true)) { + if (false === $cookieParts[1] = base64_decode(strtr($cookieParts[1], '-_~', '+/='), true)) { throw new AuthenticationException('The user identifier contains a character from outside the base64 alphabet.'); } + $cookieParts[0] = strtr($cookieParts[0], '.', '\\'); return new static(...$cookieParts); } @@ -83,6 +84,6 @@ public function getValue(): string public function toString(): string { // $userIdentifier is encoded because it might contain COOKIE_DELIMITER, we assume other values don't - return base64_encode(implode(self::COOKIE_DELIMITER, [$this->userFqcn, base64_encode($this->userIdentifier), $this->expires, $this->value])); + return implode(self::COOKIE_DELIMITER, [strtr($this->userFqcn, '\\', '.'), strtr(base64_encode($this->userIdentifier), '+/=', '-_~'), $this->expires, $this->value]); } } diff --git a/src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php b/src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php index 834b3e14df6b..7fe048471ab6 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php +++ b/src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php @@ -53,9 +53,19 @@ public function createRememberMeCookie(UserInterface $user): void $this->createCookie($details); } - /** - * {@inheritdoc} - */ + public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): UserInterface + { + try { + $this->signatureHasher->acceptSignatureHash($rememberMeDetails->getUserIdentifier(), $rememberMeDetails->getExpires(), $rememberMeDetails->getValue()); + } catch (InvalidSignatureException $e) { + throw new AuthenticationException('The cookie\'s hash is invalid.', 0, $e); + } catch (ExpiredSignatureException $e) { + throw new AuthenticationException('The cookie has expired.', 0, $e); + } + + return parent::consumeRememberMeCookie($rememberMeDetails); + } + public function processRememberMe(RememberMeDetails $rememberMeDetails, UserInterface $user): void { try { diff --git a/src/Symfony/Component/Security/Http/Tests/LoginLink/LoginLinkHandlerTest.php b/src/Symfony/Component/Security/Http/Tests/LoginLink/LoginLinkHandlerTest.php index c29bb9a85fbd..f2d03eed1c0f 100644 --- a/src/Symfony/Component/Security/Http/Tests/LoginLink/LoginLinkHandlerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/LoginLink/LoginLinkHandlerTest.php @@ -53,6 +53,7 @@ protected function setUp(): void /** * @group time-sensitive + * * @dataProvider provideCreateLoginLinkData */ public function testCreateLoginLink($user, array $extraProperties, Request $request = null) @@ -68,7 +69,7 @@ public function testCreateLoginLink($user, array $extraProperties, Request $requ // allow a small expiration offset to avoid time-sensitivity && abs(time() + 600 - $parameters['expires']) <= 1 // make sure hash is what we expect - && $parameters['hash'] === $this->createSignatureHash('weaverryan', $parameters['expires'], array_values($extraProperties)); + && $parameters['hash'] === $this->createSignatureHash('weaverryan', $parameters['expires'], $extraProperties); }), UrlGeneratorInterface::ABSOLUTE_URL ) @@ -115,7 +116,7 @@ public function provideCreateLoginLinkData() public function testConsumeLoginLink() { $expires = time() + 500; - $signature = $this->createSignatureHash('weaverryan', $expires, ['ryan@symfonycasts.com', 'pwhash']); + $signature = $this->createSignatureHash('weaverryan', $expires); $request = Request::create(sprintf('/login/verify?user=weaverryan&hash=%s&expires=%d', $signature, $expires)); $user = new TestLoginLinkHandlerUser('weaverryan', 'ryan@symfonycasts.com', 'pwhash'); @@ -131,44 +132,37 @@ public function testConsumeLoginLink() public function testConsumeLoginLinkWithExpired() { - $this->expectException(ExpiredLoginLinkException::class); $expires = time() - 500; - $signature = $this->createSignatureHash('weaverryan', $expires, ['ryan@symfonycasts.com', 'pwhash']); + $signature = $this->createSignatureHash('weaverryan', $expires); $request = Request::create(sprintf('/login/verify?user=weaverryan&hash=%s&expires=%d', $signature, $expires)); - $user = new TestLoginLinkHandlerUser('weaverryan', 'ryan@symfonycasts.com', 'pwhash'); - $this->userProvider->createUser($user); - $linker = $this->createLinker(['max_uses' => 3]); + $this->expectException(ExpiredLoginLinkException::class); $linker->consumeLoginLink($request); } public function testConsumeLoginLinkWithUserNotFound() { - $this->expectException(InvalidLoginLinkException::class); - $request = Request::create('/login/verify?user=weaverryan&hash=thehash&expires=10000'); + $request = Request::create('/login/verify?user=weaverryan&hash=thehash&expires='.(time() + 500)); $linker = $this->createLinker(); + $this->expectException(InvalidLoginLinkException::class); $linker->consumeLoginLink($request); } public function testConsumeLoginLinkWithDifferentSignature() { - $this->expectException(InvalidLoginLinkException::class); $request = Request::create(sprintf('/login/verify?user=weaverryan&hash=fake_hash&expires=%d', time() + 500)); - $user = new TestLoginLinkHandlerUser('weaverryan', 'ryan@symfonycasts.com', 'pwhash'); - $this->userProvider->createUser($user); - $linker = $this->createLinker(); + $this->expectException(InvalidLoginLinkException::class); $linker->consumeLoginLink($request); } public function testConsumeLoginLinkExceedsMaxUsage() { - $this->expectException(ExpiredLoginLinkException::class); $expires = time() + 500; - $signature = $this->createSignatureHash('weaverryan', $expires, ['ryan@symfonycasts.com', 'pwhash']); + $signature = $this->createSignatureHash('weaverryan', $expires); $request = Request::create(sprintf('/login/verify?user=weaverryan&hash=%s&expires=%d', $signature, $expires)); $user = new TestLoginLinkHandlerUser('weaverryan', 'ryan@symfonycasts.com', 'pwhash'); @@ -179,6 +173,7 @@ public function testConsumeLoginLinkExceedsMaxUsage() $this->expiredLinkCache->save($item); $linker = $this->createLinker(['max_uses' => 3]); + $this->expectException(ExpiredLoginLinkException::class); $linker->consumeLoginLink($request); } @@ -206,15 +201,12 @@ public function testConsumeLoginLinkWithMissingExpiration() $linker->consumeLoginLink($request); } - private function createSignatureHash(string $username, int $expires, array $extraFields): string + private function createSignatureHash(string $username, int $expires, array $extraFields = ['emailProperty' => 'ryan@symfonycasts.com', 'passwordProperty' => 'pwhash']): string { - $fields = [base64_encode($username), $expires]; - foreach ($extraFields as $extraField) { - $fields[] = base64_encode($extraField); - } + $hasher = new SignatureHasher($this->propertyAccessor, array_keys($extraFields), 's3cret'); + $user = new TestLoginLinkHandlerUser($username, $extraFields['emailProperty'] ?? '', $extraFields['passwordProperty'] ?? '', $extraFields['lastAuthenticatedAt'] ?? null); - // matches hash logic in the class - return base64_encode(hash_hmac('sha256', implode(':', $fields), 's3cret')); + return $hasher->computeSignatureHash($user, $expires); } private function createLinker(array $options = [], array $extraProperties = ['emailProperty', 'passwordProperty']): LoginLinkHandler @@ -298,7 +290,7 @@ public function loadUserByIdentifier(string $userIdentifier): TestLoginLinkHandl public function refreshUser(UserInterface $user): TestLoginLinkHandlerUser { - return $this->users[$username]; + return $this->users[$user->getUserIdentifier()]; } public function supportsClass(string $class): bool diff --git a/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentRememberMeHandlerTest.php b/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentRememberMeHandlerTest.php index 4e2c0980ba0a..da4f26eaaf6d 100644 --- a/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentRememberMeHandlerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentRememberMeHandlerTest.php @@ -93,8 +93,8 @@ public function testConsumeRememberMeCookieValid() /** @var Cookie $cookie */ $cookie = $this->request->attributes->get(ResponseListener::COOKIE_ATTR_NAME); - $rememberParts = explode(':', base64_decode($rememberMeDetails->toString()), 4); - $cookieParts = explode(':', base64_decode($cookie->getValue()), 4); + $rememberParts = explode(':', $rememberMeDetails->toString(), 4); + $cookieParts = explode(':', $cookie->getValue(), 4); $this->assertSame($rememberParts[0], $cookieParts[0]); // class $this->assertSame($rememberParts[1], $cookieParts[1]); // identifier diff --git a/src/Symfony/Component/Security/Http/Tests/RememberMe/SignatureRememberMeHandlerTest.php b/src/Symfony/Component/Security/Http/Tests/RememberMe/SignatureRememberMeHandlerTest.php index d7b7b85673cd..8205009448a6 100644 --- a/src/Symfony/Component/Security/Http/Tests/RememberMe/SignatureRememberMeHandlerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/RememberMe/SignatureRememberMeHandlerTest.php @@ -12,13 +12,11 @@ namespace Symfony\Component\Security\Http\Tests\RememberMe; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ClockMock; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Signature\Exception\ExpiredSignatureException; -use Symfony\Component\Security\Core\Signature\Exception\InvalidSignatureException; use Symfony\Component\Security\Core\Signature\SignatureHasher; use Symfony\Component\Security\Core\User\InMemoryUser; use Symfony\Component\Security\Core\User\InMemoryUserProvider; @@ -36,10 +34,8 @@ class SignatureRememberMeHandlerTest extends TestCase protected function setUp(): void { - $this->signatureHasher = $this->createMock(SignatureHasher::class); + $this->signatureHasher = new SignatureHasher(PropertyAccess::createPropertyAccessor(), [], 's3cret'); $this->userProvider = new InMemoryUserProvider(); - $user = new InMemoryUser('wouter', null); - $this->userProvider->createUser($user); $this->requestStack = new RequestStack(); $this->request = Request::create('/login'); $this->requestStack->push($this->request); @@ -51,10 +47,9 @@ protected function setUp(): void */ public function testCreateRememberMeCookie() { - ClockMock::register(SignatureRememberMeHandler::class); - $user = new InMemoryUser('wouter', null); - $this->signatureHasher->expects($this->once())->method('computeSignatureHash')->with($user, $expire = time() + 31536000)->willReturn('abc'); + $signature = $this->signatureHasher->computeSignatureHash($user, $expire = time() + 31536000); + $this->userProvider->createUser(new InMemoryUser('wouter', null)); $this->handler->createRememberMeCookie($user); @@ -62,7 +57,7 @@ public function testCreateRememberMeCookie() /** @var Cookie $cookie */ $cookie = $this->request->attributes->get(ResponseListener::COOKIE_ATTR_NAME); - $this->assertEquals(base64_encode(InMemoryUser::class.':d291dGVy:'.$expire.':abc'), $cookie->getValue()); + $this->assertEquals(strtr(InMemoryUser::class, '\\', '.').':d291dGVy:'.$expire.':'.$signature, $cookie->getValue()); } public function testClearRememberMeCookie() @@ -76,50 +71,36 @@ public function testClearRememberMeCookie() $this->assertNull($cookie->getValue()); } - /** - * @group time-sensitive - */ public function testConsumeRememberMeCookieValid() { - $this->signatureHasher->expects($this->once())->method('verifySignatureHash')->with($user = new InMemoryUser('wouter', null), 360, 'signature'); - $this->signatureHasher->expects($this->any()) - ->method('computeSignatureHash') - ->with($user, $expire = time() + 31536000) - ->willReturn('newsignature'); + $user = new InMemoryUser('wouter', null); + $signature = $this->signatureHasher->computeSignatureHash($user, $expire = time() + 3600); + $this->userProvider->createUser(new InMemoryUser('wouter', null)); - $rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'signature'); + $rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', $expire, $signature); $this->handler->consumeRememberMeCookie($rememberMeDetails); $this->assertTrue($this->request->attributes->has(ResponseListener::COOKIE_ATTR_NAME)); /** @var Cookie $cookie */ $cookie = $this->request->attributes->get(ResponseListener::COOKIE_ATTR_NAME); - $this->assertEquals((new RememberMeDetails(InMemoryUser::class, 'wouter', $expire, 'newsignature'))->toString(), $cookie->getValue()); + $this->assertNotEquals((new RememberMeDetails(InMemoryUser::class, 'wouter', $expire, $signature))->toString(), $cookie->getValue()); } public function testConsumeRememberMeCookieInvalidHash() { $this->expectException(AuthenticationException::class); $this->expectExceptionMessage('The cookie\'s hash is invalid.'); - - $this->signatureHasher->expects($this->any()) - ->method('verifySignatureHash') - ->with(new InMemoryUser('wouter', null), 360, 'badsignature') - ->will($this->throwException(new InvalidSignatureException())); - - $this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'badsignature')); + $this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', time() + 600, 'badsignature')); } public function testConsumeRememberMeCookieExpired() { + $user = new InMemoryUser('wouter', null); + $signature = $this->signatureHasher->computeSignatureHash($user, 360); + $this->expectException(AuthenticationException::class); $this->expectExceptionMessage('The cookie has expired.'); - - $this->signatureHasher->expects($this->any()) - ->method('verifySignatureHash') - ->with(new InMemoryUser('wouter', null), 360, 'signature') - ->will($this->throwException(new ExpiredSignatureException())); - - $this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'signature')); + $this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', 360, $signature)); } } diff --git a/src/Symfony/Component/Security/Http/composer.json b/src/Symfony/Component/Security/Http/composer.json index dc0deba03d20..a5378b3ce581 100644 --- a/src/Symfony/Component/Security/Http/composer.json +++ b/src/Symfony/Component/Security/Http/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1|^3", - "symfony/security-core": "^5.4|^6.0", + "symfony/security-core": "^5.4.19|~6.0.19|~6.1.11|^6.2.5", "symfony/http-foundation": "^5.3|^6.0", "symfony/http-kernel": "^5.3|^6.0", "symfony/polyfill-mbstring": "~1.0", From 5574133750a4e19a9e651753ef3c0db40aa2bd1f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 24 Jan 2023 14:37:36 +0100 Subject: [PATCH 32/34] Update CHANGELOG for 5.4.19 --- CHANGELOG-5.4.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG-5.4.md b/CHANGELOG-5.4.md index 50d58aacaef5..8c687fa6ef99 100644 --- a/CHANGELOG-5.4.md +++ b/CHANGELOG-5.4.md @@ -7,6 +7,32 @@ in 5.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/v5.4.0...v5.4.1 +* 5.4.19 (2023-01-24) + + * bug #49078 [Security/Http] Check tokens before loading users from providers (nicolas-grekas) + * bug #49077 [DependencyInjection] Fix named arguments when using ContainerBuilder before compilation (nicolas-grekas) + * bug #49031 [Cache] fix collecting cache stats when nesting computations (nicolas-grekas) + * bug #49046 Fix for Windows when projects are deployed on junctions/symlinks (nerdgod) + * bug #49025 [Notifier] [OvhCloud] handle invalid receiver (seferov) + * bug #48993 [VarDumper] Fix JS to expand / collapse (nicolas-grekas) + * bug #48983 Fix BC user_identifier support after deprecation username (vtsykun) + * bug #48986 [Validator] Fix Email validator logic (fabpot) + * bug #48969 [PropertyInfo] Fixes constructor extractor for mixed type (michael.kubovic) + * bug #48978 [Serializer] use method_exists() instead of catching reflection exceptions (xabbuh) + * bug #48937 [SecurityBundle] Fix using same handler for multiple authenticators (RobertMe) + * bug #48971 [DependencyInjection] Fix dump order of inlined deps (nicolas-grekas) + * bug #48966 [HttpClient] Let curl handle content-length headers (nicolas-grekas) + * bug #48968 [VarExporter] Fix exporting enums (nicolas-grekas) + * bug #48926 [DependencyInjection] Fix support for named arguments on non-autowired services (nicolas-grekas) + * bug #48943 [FrameworkBundle] Fix deprecation when accessing a "container.private" service from the test container (nicolas-grekas) + * bug #48931 [DependencyInjection] Fix dumping inlined withers (nicolas-grekas) + * bug #48898 [HttpClient] Move Http clients data collecting at a late level (pforesi) + * bug #48896 [DoctrineBridge] Fix detecting mapping with one line annotations (franmomu) + * bug #48916 [FrameworkBundle] restore call to addGlobalIgnoredName (alexislefebvre) + * bug #48917 [Config] Fix XML dump when node example is an array (alexandre-daubois) + * bug #48904 [Validator] Allow egulias/email-validator v4 (chalasr) + * bug #48831 [Uid] Fix validating nil and max uuid (fancyweb) + * 5.4.18 (2022-12-29) * bug #48823 [Cache] Fix possibly null value passed to preg_match() in RedisTrait (chalasr) From 46b2043606a55a1461c5ec3e41cdbd41ca665d1d Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 24 Jan 2023 14:37:40 +0100 Subject: [PATCH 33/34] Update CONTRIBUTORS for 5.4.19 --- CONTRIBUTORS.md | 57 +++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 94862ab99db4..016a12f53a9c 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -23,8 +23,8 @@ The Symfony Connect username in parenthesis allows to get more information - Victor Berchet (victor) - Yonel Ceruto (yonelceruto) - Tobias Nyholm (tobias) - - Oskar Stark (oskarstark) - Javier Eguiluz (javier.eguiluz) + - Oskar Stark (oskarstark) - Ryan Weaver (weaverryan) - Johannes S (johannes) - Jakub Zalas (jakubzalas) @@ -33,8 +33,8 @@ The Symfony Connect username in parenthesis allows to get more information - Hamza Amrouche (simperfit) - Samuel ROZE (sroze) - Pascal Borreli (pborreli) - - Romain Neutron - Jules Pietri (heah) + - Romain Neutron - Joseph Bielawski (stloyd) - Drak (drak) - Abdellatif Ait boudad (aitboudad) @@ -57,12 +57,12 @@ The Symfony Connect username in parenthesis allows to get more information - Grégoire Paris (greg0ire) - Gabriel Ostrolucký (gadelat) - Jonathan Wage (jwage) + - Alexandre Daubois (alexandre-daubois) - Titouan Galopin (tgalopin) - David Maicher (dmaicher) - - Alexandre Daubois (alexandre-daubois) + - Alexander Schranz (alexander-schranz) - Alexandre Salomé (alexandresalome) - William DURAND - - Alexander Schranz (alexander-schranz) - ornicar - Dany Maillard (maidmaid) - Mathieu Santostefano (welcomattic) @@ -80,13 +80,13 @@ The Symfony Connect username in parenthesis allows to get more information - Saša Stamenković (umpirsky) - Antoine Lamirault - Alex Pott - - Vincent Langlet (deviling) - Mathieu Lechat (mat_the_cat) + - Vincent Langlet (deviling) - Guilhem N (guilhemn) - Vladimir Reznichenko (kalessil) - Sarah Khalil (saro0h) - - Konstantin Kudryashov (everzet) - Tomas Norkūnas (norkunas) + - Konstantin Kudryashov (everzet) - Bilal Amarni (bamarni) - Eriksen Costa - Florin Patan (florinpatan) @@ -99,13 +99,13 @@ The Symfony Connect username in parenthesis allows to get more information - Massimiliano Arione (garak) - Douglas Greenshields (shieldo) - Christian Raue + - Fran Moreno (franmomu) - Jáchym Toušek (enumag) - Mathias Arlaud (mtarld) - Graham Campbell (graham) - Michel Weimerskirch (mweimerskirch) - Eric Clemmons (ericclemmons) - Issei Murasawa (issei_m) - - Fran Moreno (franmomu) - Malte Schlüter (maltemaltesich) - Vasilij Dusko - Denis (yethee) @@ -218,7 +218,9 @@ The Symfony Connect username in parenthesis allows to get more information - Juti Noppornpitak (shiroyuki) - Joe Bennett (kralos) - Nate Wiebe (natewiebe13) + - Farhad Safarov (safarov) - Anthony MARTIN + - Nicolas Philippe (nikophil) - Colin O'Dell (colinodell) - Sebastian Hörl (blogsh) - Ben Davies (bendavies) @@ -229,11 +231,11 @@ The Symfony Connect username in parenthesis allows to get more information - Albert Casademont (acasademont) - Arnaud Kleinpeter (nanocom) - Guilherme Blanco (guilhermeblanco) + - Sergey (upyx) - Michael Voříšek - - Farhad Safarov (safarov) - SpacePossum - - Nicolas Philippe (nikophil) - Pablo Godel (pgodel) + - Hubert Lenoir (hubert_lenoir) - Denis Brumann (dbrumann) - Romaric Drigon (romaricdrigon) - Andréia Bohner (andreia) @@ -248,9 +250,7 @@ The Symfony Connect username in parenthesis allows to get more information - Vincent Touzet (vincenttouzet) - Fabien Bourigault (fbourigault) - soyuka - - Sergey (upyx) - Jérémy Derussé - - Hubert Lenoir (hubert_lenoir) - Florent Mata (fmata) - mcfedr (mcfedr) - Maciej Malarz (malarzm) @@ -298,6 +298,7 @@ The Symfony Connect username in parenthesis allows to get more information - Yoann RENARD (yrenard) - Thomas Lallement (raziel057) - Timothée Barray (tyx) + - Alexis Lefebvre - James Halsall (jaitsu) - Mikael Pajunen - Warnar Boekkooi (boekkooi) @@ -323,6 +324,7 @@ The Symfony Connect username in parenthesis allows to get more information - D (denderello) - Jonathan Scheiber (jmsche) - DQNEO + - Romain Monteil (ker0x) - Andrii Bodnar - gnito-org - Artem (artemgenvald) @@ -370,7 +372,6 @@ The Symfony Connect username in parenthesis allows to get more information - Pierre Minnieur (pminnieur) - Kyle - Dominique Bongiraud - - Romain Monteil (ker0x) - Hidde Wieringa (hiddewie) - Christopher Davis (chrisguitarguy) - Lukáš Holeczy (holicz) @@ -379,7 +380,6 @@ The Symfony Connect username in parenthesis allows to get more information - Emanuele Panzeri (thepanz) - Matthew Smeets - François Zaninotto (fzaninotto) - - Alexis Lefebvre - Dustin Whittle (dustinwhittle) - jeff - John Kary (johnkary) @@ -500,6 +500,7 @@ The Symfony Connect username in parenthesis allows to get more information - Thomas Schulz (king2500) - Benjamin Morel - Bernd Stellwag + - Philippe SEGATORI (tigitz) - Frank de Jonge - Chris Tanaskoski - julien57 @@ -563,6 +564,7 @@ The Symfony Connect username in parenthesis allows to get more information - Gabor Toth (tgabi333) - realmfoo - Thomas Tourlourat (armetiz) + - Gasan Guseynov (gassan) - Andrey Esaulov (andremaha) - Grégoire Passault (gregwar) - Jerzy Zawadzki (jzawadzki) @@ -607,7 +609,6 @@ The Symfony Connect username in parenthesis allows to get more information - Tri Pham (phamuyentri) - marie - Erkhembayar Gantulga (erheme318) - - Philippe SEGATORI (tigitz) - Fractal Zombie - Gunnstein Lye (glye) - Thomas Talbot (ioni) @@ -620,6 +621,7 @@ The Symfony Connect username in parenthesis allows to get more information - Jérôme Tamarelle (jtamarelle-prismamedia) - Emil Masiakowski - Alexandre Parent + - Angelov Dejan (angelov) - DT Inier (gam6itko) - Matthew Lewinski (lewinski) - Magnus Nordlander (magnusnordlander) @@ -671,6 +673,7 @@ The Symfony Connect username in parenthesis allows to get more information - mondrake (mondrake) - Yaroslav Kiliba - “Filip + - FORT Pierre-Louis (plfort) - Simon Watiau (simonwatiau) - Ruben Jacobs (rubenj) - Arkadius Stefanski (arkadius) @@ -861,7 +864,6 @@ The Symfony Connect username in parenthesis allows to get more information - Arturs Vonda - Xavier Briand (xavierbriand) - Daniel Badura - - Angelov Dejan (angelov) - vagrant - Asier Illarramendi (doup) - AKeeman (akeeman) @@ -869,10 +871,10 @@ The Symfony Connect username in parenthesis allows to get more information - Restless-ET - Vlad Gregurco (vgregurco) - Boris Vujicic (boris.vujicic) + - Vladimir Tsykun (vtsykun) - Chris Sedlmayr (catchamonkey) - Kamil Kokot (pamil) - Seb Koelen - - FORT Pierre-Louis (plfort) - Christoph Mewes (xrstf) - Vitaliy Tverdokhlib (vitaliytv) - Ariel Ferrandini (aferrandini) @@ -984,7 +986,6 @@ The Symfony Connect username in parenthesis allows to get more information - Rodrigo Borrego Bernabé (rodrigobb) - John Bafford (jbafford) - Emanuele Iannone - - Gasan Guseynov (gassan) - Ondrej Machulda (ondram) - Denis Gorbachev (starfall) - Martin Morávek (keeo) @@ -1075,6 +1076,7 @@ The Symfony Connect username in parenthesis allows to get more information - Arnaud Frézet - Nicolas Martin (cocorambo) - luffy1727 + - Allison Guilhem (a_guilhem) - LHommet Nicolas (nicolaslh) - Sebastian Blum - Amirreza Shafaat (amirrezashafaat) @@ -1140,10 +1142,10 @@ The Symfony Connect username in parenthesis allows to get more information - Javier López (loalf) - tamar peled - Reinier Kip + - Robert Meijers - Geoffrey Brier (geoffrey-brier) - Sofien Naas - Christophe Meneses (c77men) - - Vladimir Tsykun - Andrei O - Dustin Dobervich (dustin10) - Alejandro Diaz Torres @@ -1603,6 +1605,7 @@ The Symfony Connect username in parenthesis allows to get more information - Patrick Dawkins (pjcdawkins) - Paul Kamer (pkamer) - Rafał Wrzeszcz (rafalwrzeszcz) + - Reyo Stallenberg (reyostallenberg) - Rémi Faivre (rfv) - Nguyen Xuan Quynh - Reen Lokum @@ -2007,7 +2010,6 @@ The Symfony Connect username in parenthesis allows to get more information - Chris Jones (leek) - neghmurken - stefan.r - - Allison Guilhem (a_guilhem) - xaav - Jean-Christophe Cuvelier [Artack] - Mahmoud Mostafa (mahmoud) @@ -2090,6 +2092,7 @@ The Symfony Connect username in parenthesis allows to get more information - Ole Rößner (basster) - Faton (notaf) - Tom Houdmont + - mark burdett - Per Sandström (per) - Goran Juric - Laurent G. (laurentg) @@ -2116,6 +2119,7 @@ The Symfony Connect username in parenthesis allows to get more information - Norbert Schultheisz - Maximilian Berghoff (electricmaxxx) - SOEDJEDE Felix (fsoedjede) + - otsch - Piotr Antosik (antek88) - Nacho Martin (nacmartin) - Sergey Novikov (s12v) @@ -2125,6 +2129,7 @@ The Symfony Connect username in parenthesis allows to get more information - MARYNICH Mikhail (mmarynich-ext) - Viktor Novikov (nowiko) - Paul Mitchum (paul-m) + - Phil E. Taylor (philetaylor) - Angel Koilov (po_taka) - Dan Finnie - Ken Marfilla (marfillaster) @@ -2140,6 +2145,7 @@ The Symfony Connect username in parenthesis allows to get more information - Martijn Evers - Benjamin Paap (benjaminpaap) - Christian + - ju1ius - Denis Golubovskiy (bukashk0zzz) - Serge (nfx) - Mikkel Paulson @@ -2288,6 +2294,7 @@ The Symfony Connect username in parenthesis allows to get more information - Jay Klehr - Sergey Yuferev - Monet Emilien + - voodooism - Tobias Stöckler - Mario Young - martkop26 @@ -2296,7 +2303,7 @@ The Symfony Connect username in parenthesis allows to get more information - cilefen (cilefen) - Mo Di (modi) - Pablo Schläpfer - - Robert Meijers + - Nikos Charalampidis - Xavier RENAUDIN - Christian Wahler (christian) - Jelte Steijaert (jelte) @@ -2413,6 +2420,7 @@ The Symfony Connect username in parenthesis allows to get more information - Ilya Biryukov (ibiryukov) - Roma (memphys) - Giorgio Premi + - Matthias Bilger - Krzysztof Pyrkosz - ncou - Ian Carroll @@ -2458,6 +2466,7 @@ The Symfony Connect username in parenthesis allows to get more information - Nicolas Eeckeloo (neeckeloo) - Andriy Prokopenko (sleepyboy) - Dariusz Ruminski + - Thomas Hanke - Daniel Tschinder - Arnaud CHASSEUX - Wojciech Gorczyca @@ -2469,6 +2478,7 @@ The Symfony Connect username in parenthesis allows to get more information - Mara Blaga - Rick Prent - skalpa + - Pierre Foresi - Pieter Jordaan - Tournoud (damientournoud) - Michael Dowling (mtdowling) @@ -2543,6 +2553,7 @@ The Symfony Connect username in parenthesis allows to get more information - Cédric Anne - LubenZA - Flavian Sierk + - Rik van der Heijden - Michael Bessolov - Zdeněk Drahoš - Dan Harper @@ -2621,7 +2632,6 @@ The Symfony Connect username in parenthesis allows to get more information - Jakub Janata (janatjak) - Jibé Barth (jibbarth) - Matthew Foster (mfoster) - - Reyo Stallenberg (reyostallenberg) - Paul Seiffert (seiffert) - Vasily Khayrulin (sirian) - Stas Soroka (stasyan) @@ -2685,6 +2695,7 @@ The Symfony Connect username in parenthesis allows to get more information - Radek Wionczek (rwionczek) - Nick Stemerdink - David Stone + - Vincent Bouzeran - Grayson Koonce - Wissame MEKHILEF - Romain Dorgueil @@ -2792,6 +2803,7 @@ The Symfony Connect username in parenthesis allows to get more information - Adam - Ivo - Sören Bernstein + - michael.kubovic - devel - taiiiraaa - gedrox @@ -2982,6 +2994,7 @@ The Symfony Connect username in parenthesis allows to get more information - Pablo Monterde Perez (plebs) - Jimmy Leger (redpanda) - Mokhtar Tlili (sf-djuba) + - Gregor Nathanael Meyer (spackmat) - Marcin Szepczynski (szepczynski) - Simone Di Maulo (toretto460) - Cyrille Jouineau (tuxosaurus) @@ -3100,6 +3113,7 @@ The Symfony Connect username in parenthesis allows to get more information - Alexis BOYER - Kaipi Yann - adam-mospan + - nerdgod - Sam Williams - Guillaume Aveline - Adrian Philipp @@ -3184,6 +3198,7 @@ The Symfony Connect username in parenthesis allows to get more information - Sam Anthony - Christian Stocker - Oussama Elgoumri + - Gert de Pagter - David Lima - Dawid Nowak - Lesnykh Ilia From 8ae97daf60c596f6723729d3d451c17e1752cbdb Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 24 Jan 2023 14:37:42 +0100 Subject: [PATCH 34/34] Update VERSION for 5.4.19 --- 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 8f12b88e8102..d354205eb14a 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -78,12 +78,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ private static $freshCache = []; - public const VERSION = '5.4.19-DEV'; + public const VERSION = '5.4.19'; public const VERSION_ID = 50419; public const MAJOR_VERSION = 5; public const MINOR_VERSION = 4; public const RELEASE_VERSION = 19; - public const EXTRA_VERSION = 'DEV'; + public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '11/2024'; public const END_OF_LIFE = '11/2025';