From ab5ac9a02dd6e6526dfc569f646a2ca08d16fe10 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 12 Jun 2020 12:56:53 +0200 Subject: [PATCH 01/28] updated CHANGELOG for 3.4.42 --- CHANGELOG-3.4.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index dfd39c33e3..a2da20414f 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,16 @@ in 3.4 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.4.0...v3.4.1 +* 3.4.42 (2020-06-12) + + * bug #37103 [Form] switch the context when validating nested forms (xabbuh) + * bug #37182 [HttpKernel] Fix regression where Store does not return response body correctly (mpdude) + * bug #36913 [FrameworkBundle] fix type annotation on ControllerTrait::addFlash() (ThomasLandauer) + * bug #37169 [Cache] fix forward compatibility with Doctrine DBAL 3 (xabbuh) + * bug #37085 [Form] properly cascade validation to child forms (xabbuh) + * bug #37095 [PhpUnitBridge] Fix undefined index when output of "composer show" cannot be parsed (nicolas-grekas) + * bug #37092 [PhpUnitBridge] fix undefined var on version 3.4 (nicolas-grekas) + * 3.4.41 (2020-05-31) * bug #36894 [Validator] never directly validate Existence (Required/Optional) constraints (xabbuh) From 4a02bde238fa0d4b18512452ace4a12315886326 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 12 Jun 2020 12:57:05 +0200 Subject: [PATCH 02/28] update CONTRIBUTORS for 3.4.42 --- CONTRIBUTORS.md | 53 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index baf025cfe0..cd95879aaa 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -65,18 +65,18 @@ Symfony is the result of the work of many people who made the code better - Kevin Bond (kbond) - Saša Stamenković (umpirsky) - Peter Rehm (rpet) + - Gábor Egyed (1ed) - Gabriel Ostrolucký (gadelat) - Henrik Bjørnskov (henrikbjorn) - - Gábor Egyed (1ed) - Miha Vrhovnik - David Maicher (dmaicher) + - Titouan Galopin (tgalopin) - Diego Saint Esteben (dii3g0) - Jan Schädlich (jschaedl) - - Titouan Galopin (tgalopin) - Konstantin Kudryashov (everzet) + - Vladimir Reznichenko (kalessil) - Bilal Amarni (bamarni) - Mathieu Piot (mpiot) - - Vladimir Reznichenko (kalessil) - Florin Patan (florinpatan) - Jáchym Toušek (enumag) - Andrej Hudec (pulzarraider) @@ -91,12 +91,12 @@ Symfony is the result of the work of many people who made the code better - Henrik Westphal (snc) - Dariusz Górecki (canni) - David Buchmann (dbu) + - Jérôme Tamarelle (gromnan) - Graham Campbell (graham) - Dariusz Ruminski - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) - - Jérôme Tamarelle (gromnan) - Daniel Holmes (dholmes) - Toni Uebernickel (havvg) - Fran Moreno (franmomu) @@ -106,11 +106,11 @@ Symfony is the result of the work of many people who made the code better - Antoine Hérault (herzult) - Paráda József (paradajozsef) - Arnaud Le Blanc (arnaud-lb) + - Sebastiaan Stok (sstok) - Maxime STEINHAUSSER - Baptiste Clavié (talus) - Michal Piotrowski (eventhorizon) - Tim Nagel (merk) - - Sebastiaan Stok (sstok) - Chris Wilkinson (thewilkybarkid) - Brice BERNARD (brikou) - marc.weistroff @@ -170,6 +170,7 @@ Symfony is the result of the work of many people who made the code better - Philipp Wahala (hifi) - Rafael Dohms (rdohms) - jwdeitch + - Ahmed TAILOULOUTE (ahmedtai) - Mikael Pajunen - Arman Hosseini (arman) - Niels Keurentjes (curry684) @@ -177,7 +178,6 @@ Symfony is the result of the work of many people who made the code better - Richard van Laak (rvanlaak) - Richard Shank (iampersistent) - Thomas Rabaix (rande) - - Ahmed TAILOULOUTE (ahmedtai) - Vincent Touzet (vincenttouzet) - jeremyFreeAgent (jeremyfreeagent) - Rouven Weßling (realityking) @@ -198,6 +198,7 @@ Symfony is the result of the work of many people who made the code better - GDIBass - Samuel NELA (snela) - Saif (╯°□°)╯ (azjezz) + - Gary PEGEOT (gary-p) - James Halsall (jaitsu) - Matthieu Napoli (mnapoli) - Florent Mata (fmata) @@ -220,7 +221,6 @@ Symfony is the result of the work of many people who made the code better - DQNEO - Andre Rømcke (andrerom) - mcfedr (mcfedr) - - Gary PEGEOT (gary-p) - Ruben Gonzalez (rubenrua) - Benjamin Dulau (dbenjamin) - Jan Rosier (rosier) @@ -244,6 +244,7 @@ Symfony is the result of the work of many people who made the code better - Matthieu Bontemps (mbontemps) - apetitpa - Pierre Minnieur (pminnieur) + - David Prévot - fivestar - Dominique Bongiraud - Jeremy Livingston (jeremylivingston) @@ -277,7 +278,6 @@ Symfony is the result of the work of many people who made the code better - Ruud Kamphuis (ruudk) - Pavel Batanov (scaytrase) - Mantis Development - - David Prévot - Loïc Faugeron - Hidde Wieringa (hiddewie) - dFayet @@ -371,6 +371,7 @@ Symfony is the result of the work of many people who made the code better - Chris Smith (cs278) - Thomas Bisignani (toma) - Florian Klein (docteurklein) + - Benjamin Leveque (benji07) - Manuel Kiessling (manuelkiessling) - Atsuhiro KUBO (iteman) - rudy onfroy (ronfroy) @@ -407,6 +408,7 @@ Symfony is the result of the work of many people who made the code better - Dariusz Rumiński - Berny Cantos (xphere81) - Thierry Thuon (lepiaf) + - Guilhem N (guilhemn) - Ricard Clau (ricardclau) - Mark Challoner (markchalloner) - Philippe Segatori @@ -432,6 +434,7 @@ Symfony is the result of the work of many people who made the code better - Tomasz Kowalczyk (thunderer) - Artur Eshenbrener - Timo Bakx (timobakx) + - Harm van Tilborg (hvt) - Thomas Perez (scullwm) - Felix Labrecque - Yaroslav Kiliba @@ -471,7 +474,6 @@ Symfony is the result of the work of many people who made the code better - Michele Locati - Pavel Volokitin (pvolok) - Valentine Boineau (valentineboineau) - - Benjamin Leveque (benji07) - Arthur de Moulins (4rthem) - Matthias Althaus (althaus) - Nicolas Dewez (nicolas_dewez) @@ -516,10 +518,11 @@ Symfony is the result of the work of many people who made the code better - Steffen Roßkamp - Alexandru Furculita (afurculita) - Valentin Jonovs (valentins-jonovs) - - Guilhem N (guilhemn) + - Sebastien Morel (plopix) - Jeanmonod David (jeanmonod) - Christopher Davis (chrisguitarguy) - Webnet team (webnet) + - Joe Bennett (kralos) - Farhad Safarov - Jan Schumann - Niklas Fiekas @@ -556,6 +559,7 @@ Symfony is the result of the work of many people who made the code better - Ariel Ferrandini (aferrandini) - Dirk Pahl (dirkaholic) - cedric lombardot (cedriclombardot) + - Arkadius Stefanski (arkadius) - Tim Goudriaan (codedmonkey) - Jonas Flodén (flojon) - Tobias Weichart @@ -621,6 +625,7 @@ Symfony is the result of the work of many people who made the code better - Maks Slesarenko - Filip Procházka (fprochazka) - mmoreram + - Jeroen Thora (bolle) - Markus Lanthaler (lanthaler) - Remi Collet - Vicent Soria Durá (vicentgodella) @@ -688,6 +693,7 @@ Symfony is the result of the work of many people who made the code better - Pavel Campr (pcampr) - Andrii Dembitskyi - Johnny Robeson (johnny) + - Thomas Landauer (thomas-landauer) - Guilliam Xavier - Disquedur - Michiel Boeckaert (milio) @@ -701,13 +707,11 @@ Symfony is the result of the work of many people who made the code better - Piotr Stankowski - Baptiste Leduc (bleduc) - Julien Maulny - - Sebastien Morel (plopix) - Jean-Christophe Cuvelier [Artack] - Julien Montel (julienmgel) - Simon DELICATA - Artem Henvald (artemgenvald) - Dmitry Simushev - - Joe Bennett (kralos) - alcaeus - Thomas Talbot (ioni) - Fred Cox @@ -722,10 +726,12 @@ Symfony is the result of the work of many people who made the code better - Marvin Butkereit - Renan - Ricky Su (ricky) + - Marcin Szepczynski (czepol) - Kyle Evans (kevans91) - Charles-Henri Bruyand - Max Rath (drak3) - Stéphane Escandell (sescandell) + - Baptiste Leduc (korbeil) - Konstantin S. M. Möllers (ksmmoellers) - James Johnston - Noémi Salaün (noemi-salaun) @@ -776,7 +782,6 @@ Symfony is the result of the work of many people who made the code better - maxime.steinhausser - adev - Stefan Warman - - Arkadius Stefanski (arkadius) - Tristan Maindron (tmaindron) - Behnoush Norouzali (behnoush) - Wesley Lancel @@ -949,12 +954,10 @@ Symfony is the result of the work of many people who made the code better - Jayson Xu (superjavason) - Hubert Lenoir (hubert_lenoir) - fago - - Harm van Tilborg - Jan Prieser - GDIBass - Antoine Lamirault - Adrien Lucas (adrienlucas) - - Jeroen Thora (bolle) - Zhuravlev Alexander (scif) - Stefano Degenkamp (steef) - James Michael DuPont @@ -1038,7 +1041,6 @@ Symfony is the result of the work of many people who made the code better - Don Pinkster - Maksim Muruev - Emil Einarsson - - Thomas Landauer - 243083df - Thibault Duplessis - Rimas Kudelis @@ -1060,6 +1062,7 @@ Symfony is the result of the work of many people who made the code better - Hugo Alliaume (kocal) - Marcos Gómez Vilches (markitosgv) - Matthew Davis (mdavis1982) + - Paulo Ribeiro (paulo) - Markus S. (staabm) - Benjamin Morel - Maks @@ -1118,7 +1121,6 @@ Symfony is the result of the work of many people who made the code better - xaav - Mahmoud Mostafa (mahmoud) - Antonio Jose Cerezo (ajcerezo) - - Baptiste Leduc (korbeil) - Ahmed Abdou - Daniel Iwaniec - Thomas Ferney @@ -1157,6 +1159,8 @@ Symfony is the result of the work of many people who made the code better - zairig imad (zairigimad) - Anton Babenko (antonbabenko) - Irmantas Šiupšinskas (irmantas) + - Benoit Mallo + - Lescot Edouard (idetox) - Danilo Silva - Giuseppe Campanelli - Arnaud PETITPAS (apetitpa) @@ -1226,11 +1230,13 @@ Symfony is the result of the work of many people who made the code better - gr1ev0us - mlazovla - Alejandro Diaz Torres + - quentin neyrat (qneyrat) - Max Beutel - Jan Vernieuwe (vernija) - Antanas Arvasevicius - Pierre Dudoret - Thomas + - j.schmitt - Maximilian Berghoff (electricmaxxx) - nacho - Piotr Antosik (antek88) @@ -1326,7 +1332,9 @@ Symfony is the result of the work of many people who made the code better - Carlos Ortega Huetos - rpg600 - Péter Buri (burci) + - John VanDeWeghe - kaiwa + - Claude Khedhiri (ck-developer) - Charles Sanquer (csanquer) - Albert Ganiev (helios-ag) - Neil Katin @@ -1363,6 +1371,7 @@ Symfony is the result of the work of many people who made the code better - arnaud (arnooo999) - Gilles Doge (gido) - Oscar Esteve (oesteve) + - Sobhan Sharifi (50bhan) - abulford - Philipp Kretzschmar - antograssiot @@ -1412,6 +1421,7 @@ Symfony is the result of the work of many people who made the code better - Marc Torres - Mark Spink - Alberto Aldegheri + - Sagrario Meneses - Dmitri Petmanson - heccjj - Alexandre Melard @@ -1731,7 +1741,9 @@ Symfony is the result of the work of many people who made the code better - Przemysław Piechota (kibao) - Leonid Terentyev (li0n) - Martynas Sudintas (martiis) + - Douglas Hammond (wizhippo) - ryunosuke + - Bruno BOUTAREL - victoria - Francisco Facioni (fran6co) - Stanislav Gamayunov (happyproff) @@ -1864,6 +1876,7 @@ Symfony is the result of the work of many people who made the code better - Pavel.Batanov - avi123 - Pavel Prischepa + - Sami Mussbach - alsar - downace - Aarón Nieves Fernández @@ -1891,6 +1904,7 @@ Symfony is the result of the work of many people who made the code better - Brian Graham (incognito) - Kevin Vergauwen (innocenzo) - Alessio Baglio (ioalessio) + - Jeroen Noten (jeroennoten) - Johannes Müller (johmue) - Jordi Llonch (jordillonch) - Nicholas Ruunu (nicholasruunu) @@ -1911,6 +1925,7 @@ Symfony is the result of the work of many people who made the code better - Alexey Popkov - Gijs Kunze - Artyom Protaskin + - Steven Dubois - Nathanael d. Noblet - helmer - ged15 @@ -1983,6 +1998,7 @@ Symfony is the result of the work of many people who made the code better - Andrew Marcinkevičius (ifdattic) - Ioana Hazsda (ioana-hazsda) - Jan Marek (janmarek) + - Dmitriy Mamontov (mamontovdmitriy) - Mark de Haan (markdehaan) - Dan Patrick (mdpatrick) - naitsirch (naitsirch) @@ -2343,6 +2359,7 @@ Symfony is the result of the work of many people who made the code better - Ben Miller - Peter Gribanov - Matteo Galli + - Loenix - kwiateusz - jspee - Ilya Bulakh @@ -2466,7 +2483,6 @@ Symfony is the result of the work of many people who made the code better - Marco Petersen (ocrampete16) - ollie harridge (ollietb) - Paul Andrieux (paulandrieux) - - Paulo Ribeiro (paulo) - Paweł Szczepanek (pauluz) - Philippe Degeeter (pdegeeter) - Christian López Espínola (penyaskito) @@ -2521,6 +2537,7 @@ Symfony is the result of the work of many people who made the code better - MaPePeR - Andreas Streichardt - Alexandre Segura + - Marco Pfeiffer - Vivien - Pascal Hofmann - david-binda From 4d48338b6c1643c78fa2eb52c298b1914fd99476 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 12 Jun 2020 12:57:07 +0200 Subject: [PATCH 03/28] updated VERSION for 3.4.42 --- 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 a0eb026f60..1f0e29b97c 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.42-DEV'; + const VERSION = '3.4.42'; const VERSION_ID = 30442; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; const RELEASE_VERSION = 42; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From b30f4c1537147cc592374b6ef635a337fe476be5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 12 Jun 2020 13:14:22 +0200 Subject: [PATCH 04/28] bumped Symfony version to 3.4.43 --- 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 1f0e29b97c..7fad1ee281 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.42'; - const VERSION_ID = 30442; + const VERSION = '3.4.43-DEV'; + const VERSION_ID = 30443; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; - const RELEASE_VERSION = 42; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 43; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From 992205a759a339e81615b19d759c5bab89c387ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 13 Jun 2020 16:49:13 +0200 Subject: [PATCH 05/28] Fix precendence in 4.4 --- .../Tests/Transport/Doctrine/ConnectionTest.php | 10 +++++----- .../Messenger/Transport/Doctrine/Connection.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php index b4348d4958..c0204cdf4b 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php @@ -209,7 +209,7 @@ class ConnectionTest extends TestCase 'expectedAutoSetup' => false, ]; - yield 'options from options array wins over options from dsn' => [ + yield 'options from dsn array wins over options from options' => [ 'dsn' => 'doctrine://default?table_name=name_from_dsn&redeliver_timeout=1200&queue_name=normal&auto_setup=true', 'options' => [ 'table_name' => 'name_from_options', @@ -218,10 +218,10 @@ class ConnectionTest extends TestCase 'auto_setup' => false, ], 'expectedConnection' => 'default', - 'expectedTableName' => 'name_from_options', - 'expectedRedeliverTimeout' => 1800, - 'expectedQueue' => 'important', - 'expectedAutoSetup' => false, + 'expectedTableName' => 'name_from_dsn', + 'expectedRedeliverTimeout' => 1200, + 'expectedQueue' => 'normal', + 'expectedAutoSetup' => true, ]; yield 'options from dsn with falsey boolean' => [ diff --git a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php index 19141bd8d9..de6d144e45 100644 --- a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php @@ -85,7 +85,7 @@ class Connection } $configuration = ['connection' => $components['host']]; - $configuration += $options + $query + self::DEFAULT_OPTIONS; + $configuration += $query + $options + self::DEFAULT_OPTIONS; $configuration['auto_setup'] = filter_var($configuration['auto_setup'], FILTER_VALIDATE_BOOLEAN); From fcc0e2c143caba8cf5ff0dda363af7e60d1be92f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 13 Jun 2020 17:55:52 +0200 Subject: [PATCH 06/28] [FrameworkBundle] preserve dots in query-string when redirecting --- .../Controller/RedirectController.php | 3 +- .../Controller/RedirectControllerTest.php | 41 ++++++++----------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php index 244e8a0f35..05e39a27a0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php @@ -128,8 +128,7 @@ class RedirectController implements ContainerAwareInterface $scheme = $request->getScheme(); } - $qs = $request->getQueryString(); - if ($qs) { + if ($qs = $request->server->get('QUERY_STRING') ?: $request->getQueryString()) { if (false === strpos($path, '?')) { $qs = '?'.$qs; } else { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php index 4bd0212e69..78d41a2f2b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php @@ -220,9 +220,9 @@ class RedirectControllerTest extends TestCase return [ ['http://www.example.com/base/redirect-path', '/redirect-path', ''], ['http://www.example.com/base/redirect-path?foo=bar', '/redirect-path?foo=bar', ''], - ['http://www.example.com/base/redirect-path?foo=bar', '/redirect-path', 'foo=bar'], - ['http://www.example.com/base/redirect-path?foo=bar&abc=example', '/redirect-path?foo=bar', 'abc=example'], - ['http://www.example.com/base/redirect-path?foo=bar&abc=example&baz=def', '/redirect-path?foo=bar', 'abc=example&baz=def'], + ['http://www.example.com/base/redirect-path?f.o=bar', '/redirect-path', 'f.o=bar'], + ['http://www.example.com/base/redirect-path?f.o=bar&a.c=example', '/redirect-path?f.o=bar', 'a.c=example'], + ['http://www.example.com/base/redirect-path?f.o=bar&a.c=example&b.z=def', '/redirect-path?f.o=bar', 'a.c=example&b.z=def'], ]; } @@ -246,29 +246,20 @@ class RedirectControllerTest extends TestCase private function createRequestObject($scheme, $host, $port, $baseUrl, $queryString = '') { - $request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock(); - $request - ->expects($this->any()) - ->method('getScheme') - ->willReturn($scheme); - $request - ->expects($this->any()) - ->method('getHost') - ->willReturn($host); - $request - ->expects($this->any()) - ->method('getPort') - ->willReturn($port); - $request - ->expects($this->any()) - ->method('getBaseUrl') - ->willReturn($baseUrl); - $request - ->expects($this->any()) - ->method('getQueryString') - ->willReturn($queryString); + if ('' !== $queryString) { + parse_str($queryString, $query); + } else { + $query = []; + } - return $request; + return new Request($query, [], [], [], [], [ + 'HTTPS' => 'https' === $scheme, + 'HTTP_HOST' => $host.($port ? ':'.$port : ''), + 'SERVER_PORT' => $port, + 'SCRIPT_FILENAME' => $baseUrl, + 'REQUEST_URI' => $baseUrl, + 'QUERY_STRING' => $queryString, + ]); } private function createRedirectController($httpPort = null, $httpsPort = null) From b746dd900cf50a545064e51f5178be8e0b2aab4c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 14 Jun 2020 14:27:25 +0200 Subject: [PATCH 07/28] [DI] tighten detection of local dirs to prevent false positives --- .../Component/DependencyInjection/Dumper/PhpDumper.php | 7 ++++--- .../DependencyInjection/Tests/Dumper/PhpDumperTest.php | 2 +- .../DependencyInjection/Tests/Fixtures/php/services12.php | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 3bfa0c3188..c66c3bcf7c 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -191,7 +191,7 @@ class PhpDumper extends Dumper $regex = preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#').$regex; } while (0 < --$i); - $this->targetDirRegex = '#'.preg_quote($dir[0], '#').$regex.'#'; + $this->targetDirRegex = '#(^|file://|[:;, \|\r\n])'.preg_quote($dir[0], '#').$regex.'#'; } } @@ -1993,11 +1993,12 @@ EOF; private function export($value) { if (null !== $this->targetDirRegex && \is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { - $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : ''; $suffix = $matches[0][1] + \strlen($matches[0][0]); + $matches[0][1] += \strlen($matches[1][0]); + $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : ''; $suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix), true) : ''; $dirname = $this->asFiles ? '$this->containerDir' : '__DIR__'; - $offset = 1 + $this->targetDirMaxMatches - \count($matches); + $offset = 2 + $this->targetDirMaxMatches - \count($matches); if ($this->asFiles || 0 < $offset) { $dirname = sprintf('$this->targetDirs[%d]', $offset); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index b2cbb3caf6..946d09c748 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -98,7 +98,7 @@ class PhpDumperTest extends TestCase $container = new ContainerBuilder(); $container->setDefinition('test', $definition); - $container->setParameter('foo', 'wiz'.\dirname(__DIR__)); + $container->setParameter('foo', 'file://'.\dirname(__DIR__)); $container->setParameter('bar', __DIR__); $container->setParameter('baz', '%bar%/PhpDumperTest.php'); $container->setParameter('buz', \dirname(\dirname(__DIR__))); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php index 0e8f581e8a..eb21559686 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services12.php @@ -67,7 +67,7 @@ class ProjectServiceContainer extends Container */ protected function getTestService() { - return $this->services['test'] = new \stdClass(('wiz'.$this->targetDirs[1]), [('wiz'.$this->targetDirs[1]) => ($this->targetDirs[2].'/')]); + return $this->services['test'] = new \stdClass(('file://'.$this->targetDirs[1]), [('file://'.$this->targetDirs[1]) => ($this->targetDirs[2].'/')]); } public function getParameter($name) @@ -131,7 +131,7 @@ class ProjectServiceContainer extends Container private function getDynamicParameter($name) { switch ($name) { - case 'foo': $value = ('wiz'.$this->targetDirs[1]); break; + case 'foo': $value = ('file://'.$this->targetDirs[1]); break; case 'buz': $value = $this->targetDirs[2]; break; default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); } From 7af34697715018bc7c6510289907e003d129e19c Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Tue, 24 Mar 2020 21:48:50 +0100 Subject: [PATCH 08/28] [VarDumper] Fix CliDumper coloration When using AbstractDumper::DUMP_LIGHT_ARRAY --- .../Component/VarDumper/Dumper/CliDumper.php | 3 +- .../VarDumper/Tests/Dumper/CliDumperTest.php | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php index 946df78257..881241ab3e 100644 --- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php @@ -268,7 +268,8 @@ class CliDumper extends AbstractDumper } elseif (Cursor::HASH_RESOURCE === $type) { $prefix = $this->style('note', $class.' resource').($hasChild ? ' {' : ' '); } else { - $prefix = $class && !(self::DUMP_LIGHT_ARRAY & $this->flags) ? $this->style('note', 'array:'.$class).' [' : '['; + $unstyledPrefix = $class && !(self::DUMP_LIGHT_ARRAY & $this->flags) ? 'array:'.$class : ''; + $prefix = $this->style('note', $unstyledPrefix).($unstyledPrefix ? ' [' : '['); } if ($cursor->softRefCount || 0 < $cursor->softRefHandle) { diff --git a/src/Symfony/Component/VarDumper/Tests/Dumper/CliDumperTest.php b/src/Symfony/Component/VarDumper/Tests/Dumper/CliDumperTest.php index 7656e09259..e7efaae95c 100644 --- a/src/Symfony/Component/VarDumper/Tests/Dumper/CliDumperTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Dumper/CliDumperTest.php @@ -13,6 +13,7 @@ namespace Symfony\Component\VarDumper\Tests\Dumper; use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\AbstractDumper; use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\Test\VarDumperTestTrait; use Twig\Environment; @@ -572,6 +573,57 @@ EOTXT ); } + public function provideDumpArrayWithColor() + { + yield [ + ['foo' => 'bar'], + 0, +<< "\e[1;38;5;113mbar\e[0;38;5;208m"\e[m +\e[0;38;5;208m]\e[m + +EOTXT + ]; + + yield [[], AbstractDumper::DUMP_LIGHT_ARRAY, "\e[0;38;5;208m\e[38;5;38m\e[0;38;5;208m[]\e[m\n"]; + + yield [ + ['foo' => 'bar'], + AbstractDumper::DUMP_LIGHT_ARRAY, + << "\e[1;38;5;113mbar\e[0;38;5;208m"\e[m +\e[0;38;5;208m]\e[m + +EOTXT + ]; + + yield [[], 0, "\e[0;38;5;208m\e[38;5;38m\e[0;38;5;208m[]\e[m\n"]; + } + + /** + * @dataProvider provideDumpArrayWithColor + */ + public function testDumpArrayWithColor($value, $flags, $expectedOut) + { + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Windows console does not support coloration'); + } + + $out = ''; + $dumper = new CliDumper(function ($line, $depth) use (&$out) { + if ($depth >= 0) { + $out .= str_repeat(' ', $depth).$line."\n"; + } + }, null, $flags); + $dumper->setColors(true); + $cloner = new VarCloner(); + $dumper->dump($cloner->cloneVar($value)); + + $this->assertSame($expectedOut, $out); + } + private function getSpecialVars() { foreach (array_keys($GLOBALS) as $var) { From ee8d11451b075f1fd3138ce402f9cd8784017679 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 15 Jun 2020 15:51:15 +0200 Subject: [PATCH 09/28] updated CHANGELOG for 5.1.2 --- CHANGELOG-5.1.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG-5.1.md b/CHANGELOG-5.1.md index 4f34853bc8..54abc070fa 100644 --- a/CHANGELOG-5.1.md +++ b/CHANGELOG-5.1.md @@ -7,6 +7,16 @@ in 5.1 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.1.0...v5.1.1 +* 5.1.2 (2020-06-15) + + * bug #37265 [HttpFoundation] use InputBag for Request::$request only if data is coming from a form (nicolas-grekas) + * bug #37283 [SecurityBundle] Fix CookieClearingLogoutListener DI configuration (wouterj) + * bug #37160 Reset question validator attempts only for actual stdin (ostrolucky) + * bug #36975 [PropertyInfo] Make PhpDocExtractor compatible with phpDocumentor v5 (DerManoMann) + * bug #37279 [Form] Fixed prototype block prefixes hierarchy of the CollectionType (yceruto) + * bug #37276 [Form] Fixed block prefixes hierarchy of the CollectionType (yceruto) + * bug #37261 Fix register csrf protection listener (Ne-Lexa) + * 5.1.1 (2020-06-12) * bug #37227 [DependencyInjection][CheckTypeDeclarationsPass] Handle unresolved parameters pointing to environment variables (fancyweb) From 04f054e44c697a2fc90900048423872959ab4c1c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 15 Jun 2020 15:51:38 +0200 Subject: [PATCH 10/28] updated VERSION for 5.1.2 --- 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 8190103082..178585762d 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -73,12 +73,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '5.1.2-DEV'; + const VERSION = '5.1.2'; const VERSION_ID = 50102; const MAJOR_VERSION = 5; const MINOR_VERSION = 1; const RELEASE_VERSION = 2; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '01/2021'; const END_OF_LIFE = '01/2021'; From bf2fb938be7ef03339976b12db76aa1b1e59aa97 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 15 Jun 2020 16:01:03 +0200 Subject: [PATCH 11/28] bumped Symfony version to 5.1.3 --- 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 178585762d..4f7e6e0408 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -73,12 +73,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '5.1.2'; - const VERSION_ID = 50102; + const VERSION = '5.1.3-DEV'; + const VERSION_ID = 50103; const MAJOR_VERSION = 5; const MINOR_VERSION = 1; - const RELEASE_VERSION = 2; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 3; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '01/2021'; const END_OF_LIFE = '01/2021'; From 7a932222597665a10cee58f32d826da1c7a2108a Mon Sep 17 00:00:00 2001 From: Antoine M Date: Tue, 16 Jun 2020 18:25:20 +0100 Subject: [PATCH 12/28] Fix package rename when releasing --- .../Notifier/Exception/UnsupportedSchemeException.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php b/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php index 0d45a7d065..70854ef099 100644 --- a/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php +++ b/src/Symfony/Component/Notifier/Exception/UnsupportedSchemeException.php @@ -50,9 +50,9 @@ class UnsupportedSchemeException extends LogicException 'class' => Bridge\Firebase\FirebaseTransportFactory::class, 'package' => 'symfony/firebase-notifier', ], - 'freemobile' => [ + 'free-mobile' => [ 'class' => Bridge\FreeMobile\FreeMobileTransportFactory::class, - 'package' => 'symfony/freemobile-notifier', + 'package' => 'symfony/free-mobile-notifier', ], 'ovhcloud' => [ 'class' => Bridge\OvhCloud\OvhCloudTransportFactory::class, From 9497972500413b05db33d6c0a5a85b0c107240c4 Mon Sep 17 00:00:00 2001 From: Mikko Pesari Date: Wed, 17 Jun 2020 11:19:44 +0300 Subject: [PATCH 13/28] [HttpClient] Convert CurlHttpClient::handlePush() to instance method Fix #37252 --- .../Component/HttpClient/CurlHttpClient.php | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 2fcba7902e..0fda8c604c 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -13,7 +13,6 @@ namespace Symfony\Component\HttpClient; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; -use Psr\Log\LoggerInterface; use Symfony\Component\HttpClient\Exception\InvalidArgumentException; use Symfony\Component\HttpClient\Exception\TransportException; use Symfony\Component\HttpClient\Internal\CurlClientState; @@ -71,7 +70,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, [, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions); } - $this->multi = $multi = new CurlClientState(); + $this->multi = new CurlClientState(); self::$curlVersion = self::$curlVersion ?? curl_version(); // Don't enable HTTP/1.1 pipelining: it forces responses to be sent in order @@ -95,10 +94,8 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, return; } - $logger = &$this->logger; - - curl_multi_setopt($this->multi->handle, CURLMOPT_PUSHFUNCTION, static function ($parent, $pushed, array $requestHeaders) use ($multi, $maxPendingPushes, &$logger) { - return self::handlePush($parent, $pushed, $requestHeaders, $multi, $maxPendingPushes, $logger); + curl_multi_setopt($this->multi->handle, CURLMOPT_PUSHFUNCTION, function ($parent, $pushed, array $requestHeaders) use ($maxPendingPushes) { + return $this->handlePush($parent, $pushed, $requestHeaders, $maxPendingPushes); }); } @@ -361,7 +358,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, $this->reset(); } - private static function handlePush($parent, $pushed, array $requestHeaders, CurlClientState $multi, int $maxPendingPushes, ?LoggerInterface $logger): int + private function handlePush($parent, $pushed, array $requestHeaders, int $maxPendingPushes): int { $headers = []; $origin = curl_getinfo($parent, CURLINFO_EFFECTIVE_URL); @@ -373,7 +370,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, } if (!isset($headers[':method']) || !isset($headers[':scheme']) || !isset($headers[':authority']) || !isset($headers[':path'])) { - $logger && $logger->debug(sprintf('Rejecting pushed response from "%s": pushed headers are invalid', $origin)); + $this->logger && $this->logger->debug(sprintf('Rejecting pushed response from "%s": pushed headers are invalid', $origin)); return CURL_PUSH_DENY; } @@ -384,21 +381,21 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, // but this is a MUST in the HTTP/2 RFC; let's restrict pushes to the original host, // ignoring domains mentioned as alt-name in the certificate for now (same as curl). if (0 !== strpos($origin, $url.'/')) { - $logger && $logger->debug(sprintf('Rejecting pushed response from "%s": server is not authoritative for "%s"', $origin, $url)); + $this->logger && $this->logger->debug(sprintf('Rejecting pushed response from "%s": server is not authoritative for "%s"', $origin, $url)); return CURL_PUSH_DENY; } - if ($maxPendingPushes <= \count($multi->pushedResponses)) { - $fifoUrl = key($multi->pushedResponses); - unset($multi->pushedResponses[$fifoUrl]); - $logger && $logger->debug(sprintf('Evicting oldest pushed response: "%s"', $fifoUrl)); + if ($maxPendingPushes <= \count($this->multi->pushedResponses)) { + $fifoUrl = key($this->multi->pushedResponses); + unset($this->multi->pushedResponses[$fifoUrl]); + $this->logger && $this->logger->debug(sprintf('Evicting oldest pushed response: "%s"', $fifoUrl)); } $url .= $headers[':path'][0]; - $logger && $logger->debug(sprintf('Queueing pushed response: "%s"', $url)); + $this->logger && $this->logger->debug(sprintf('Queueing pushed response: "%s"', $url)); - $multi->pushedResponses[$url] = new PushedResponse(new CurlResponse($multi, $pushed), $headers, $multi->openHandles[(int) $parent][1] ?? [], $pushed); + $this->multi->pushedResponses[$url] = new PushedResponse(new CurlResponse($this->multi, $pushed), $headers, $this->multi->openHandles[(int) $parent][1] ?? [], $pushed); return CURL_PUSH_OK; } From 14ec6a76599cde6771e932a7ff7900ead3ede146 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Wed, 17 Jun 2020 14:47:49 -0500 Subject: [PATCH 14/28] [HttpFoundation] Allow `null` in InputBag@set --- src/Symfony/Component/HttpFoundation/InputBag.php | 6 +++--- src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/InputBag.php b/src/Symfony/Component/HttpFoundation/InputBag.php index b2aff595c4..c83d63d6d5 100644 --- a/src/Symfony/Component/HttpFoundation/InputBag.php +++ b/src/Symfony/Component/HttpFoundation/InputBag.php @@ -72,12 +72,12 @@ final class InputBag extends ParameterBag /** * Sets an input by name. * - * @param string|array $value + * @param string|array|null $value */ public function set(string $key, $value) { - if (!is_scalar($value) && !\is_array($value) && !method_exists($value, '__toString')) { - trigger_deprecation('symfony/http-foundation', '5.1', 'Passing "%s" as a 2nd Argument to "%s()" is deprecated, pass a string or an array instead.', get_debug_type($value), __METHOD__); + if (null !== $value && !is_scalar($value) && !\is_array($value) && !method_exists($value, '__toString')) { + trigger_deprecation('symfony/http-foundation', '5.1', 'Passing "%s" as a 2nd Argument to "%s()" is deprecated, pass a string, array, or null instead.', get_debug_type($value), __METHOD__); } $this->parameters[$key] = $value; diff --git a/src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php index bd6f3114d7..870057e41b 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php @@ -51,7 +51,7 @@ class InputBagTest extends TestCase public function testSetWithNonStringishOrArrayIsDeprecated() { $bag = new InputBag(); - $this->expectDeprecation('Since symfony/http-foundation 5.1: Passing "Symfony\Component\HttpFoundation\InputBag" as a 2nd Argument to "Symfony\Component\HttpFoundation\InputBag::set()" is deprecated, pass a string or an array instead.'); + $this->expectDeprecation('Since symfony/http-foundation 5.1: Passing "Symfony\Component\HttpFoundation\InputBag" as a 2nd Argument to "Symfony\Component\HttpFoundation\InputBag::set()" is deprecated, pass a string, array, or null instead.'); $bag->set('foo', new InputBag()); } From a74a50688326502d5ef64859bd587d428b6d7be4 Mon Sep 17 00:00:00 2001 From: Christian Scheb Date: Thu, 18 Jun 2020 16:08:44 +0200 Subject: [PATCH 15/28] Remove unnecessary null check --- .../Security/Http/Authentication/AuthenticatorManager.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php b/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php index 4585741c15..a9bdf8a36f 100644 --- a/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php +++ b/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php @@ -171,9 +171,7 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent $authenticatedToken->eraseCredentials(); } - if (null !== $this->eventDispatcher) { - $this->eventDispatcher->dispatch(new AuthenticationSuccessEvent($authenticatedToken), AuthenticationEvents::AUTHENTICATION_SUCCESS); - } + $this->eventDispatcher->dispatch(new AuthenticationSuccessEvent($authenticatedToken), AuthenticationEvents::AUTHENTICATION_SUCCESS); if (null !== $this->logger) { $this->logger->info('Authenticator successful!', ['token' => $authenticatedToken, 'authenticator' => \get_class($authenticator)]); From 8c4b49613ac32c238a794f987dc474ded1df4809 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 18 Jun 2020 17:42:01 +0200 Subject: [PATCH 16/28] [Cache] fix compat with DBAL v3 --- .../Component/Cache/Traits/PdoTrait.php | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Cache/Traits/PdoTrait.php b/src/Symfony/Component/Cache/Traits/PdoTrait.php index 1aa87cd3f1..d453904d44 100644 --- a/src/Symfony/Component/Cache/Traits/PdoTrait.php +++ b/src/Symfony/Component/Cache/Traits/PdoTrait.php @@ -366,25 +366,31 @@ trait PdoTrait if ($this->conn instanceof \PDO) { $this->driver = $this->conn->getAttribute(\PDO::ATTR_DRIVER_NAME); } else { - switch ($this->driver = $this->conn->getDriver()->getName()) { - case 'mysqli': - case 'pdo_mysql': - case 'drizzle_pdo_mysql': + $driver = $this->conn->getDriver(); + + switch (true) { + case $driver instanceof \Doctrine\DBAL\Driver\AbstractMySQLDriver: + case $driver instanceof \Doctrine\DBAL\Driver\DrizzlePDOMySql\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\Mysqli\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDOMySql\Driver: $this->driver = 'mysql'; break; - case 'pdo_sqlite': + case $driver instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver: $this->driver = 'sqlite'; break; - case 'pdo_pgsql': + case $driver instanceof \Doctrine\DBAL\Driver\PDOPgSql\Driver: $this->driver = 'pgsql'; break; - case 'oci8': - case 'pdo_oracle': + case $driver instanceof \Doctrine\DBAL\Driver\OCI8\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDOOracle\Driver: $this->driver = 'oci'; break; - case 'pdo_sqlsrv': + case $driver instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver: $this->driver = 'sqlsrv'; break; + default: + $this->driver = \get_class($driver); + break; } } } From c143aacd811d0cab4e3351cb77d7d3e37c031c16 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sat, 13 Jun 2020 10:25:25 +0200 Subject: [PATCH 17/28] [3.4] Small update in our internal terminology --- .../Handler/FingersCrossed/NotFoundActivationStrategy.php | 6 +++--- .../DependencyInjection/AddAnnotatedClassesToCachePass.php | 4 ++-- .../Component/Intl/Data/Generator/CurrencyDataGenerator.php | 4 ++-- .../Component/Intl/Data/Generator/RegionDataGenerator.php | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php index ed41929a2c..e5ccf1afc5 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php +++ b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php @@ -23,7 +23,7 @@ use Symfony\Component\HttpKernel\Exception\HttpException; */ class NotFoundActivationStrategy extends ErrorLevelActivationStrategy { - private $blacklist; + private $exclude; private $requestStack; public function __construct(RequestStack $requestStack, array $excludedUrls, $actionLevel) @@ -31,7 +31,7 @@ class NotFoundActivationStrategy extends ErrorLevelActivationStrategy parent::__construct($actionLevel); $this->requestStack = $requestStack; - $this->blacklist = '{('.implode('|', $excludedUrls).')}i'; + $this->exclude = '{('.implode('|', $excludedUrls).')}i'; } public function isHandlerActivated(array $record) @@ -45,7 +45,7 @@ class NotFoundActivationStrategy extends ErrorLevelActivationStrategy && 404 == $record['context']['exception']->getStatusCode() && ($request = $this->requestStack->getMasterRequest()) ) { - return !preg_match($this->blacklist, $request->getPathInfo()); + return !preg_match($this->exclude, $request->getPathInfo()); } return $isActivated; diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/AddAnnotatedClassesToCachePass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/AddAnnotatedClassesToCachePass.php index 8bb03bd0c7..b59949379d 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/AddAnnotatedClassesToCachePass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/AddAnnotatedClassesToCachePass.php @@ -136,10 +136,10 @@ class AddAnnotatedClassesToCachePass implements CompilerPassInterface private function matchAnyRegexps($class, $regexps) { - $blacklisted = false !== strpos($class, 'Test'); + $isTest = false !== strpos($class, 'Test'); foreach ($regexps as $regex) { - if ($blacklisted && false === strpos($regex, 'Test')) { + if ($isTest && false === strpos($regex, 'Test')) { continue; } diff --git a/src/Symfony/Component/Intl/Data/Generator/CurrencyDataGenerator.php b/src/Symfony/Component/Intl/Data/Generator/CurrencyDataGenerator.php index b4543428eb..a5ed6d1026 100644 --- a/src/Symfony/Component/Intl/Data/Generator/CurrencyDataGenerator.php +++ b/src/Symfony/Component/Intl/Data/Generator/CurrencyDataGenerator.php @@ -25,7 +25,7 @@ use Symfony\Component\Intl\Data\Util\LocaleScanner; */ class CurrencyDataGenerator extends AbstractDataGenerator { - private static $blacklist = [ + private static $denylist = [ 'XBA' => true, // European Composite Unit 'XBB' => true, // European Monetary Unit 'XBC' => true, // European Unit of Account (XBC) @@ -136,7 +136,7 @@ class CurrencyDataGenerator extends AbstractDataGenerator $symbolNamePairs = iterator_to_array($rootBundle['Currencies']); // Remove unwanted currencies - $symbolNamePairs = array_diff_key($symbolNamePairs, self::$blacklist); + $symbolNamePairs = array_diff_key($symbolNamePairs, self::$denylist); return $symbolNamePairs; } diff --git a/src/Symfony/Component/Intl/Data/Generator/RegionDataGenerator.php b/src/Symfony/Component/Intl/Data/Generator/RegionDataGenerator.php index bab85b11b1..b50a585de6 100644 --- a/src/Symfony/Component/Intl/Data/Generator/RegionDataGenerator.php +++ b/src/Symfony/Component/Intl/Data/Generator/RegionDataGenerator.php @@ -27,7 +27,7 @@ use Symfony\Component\Intl\Data\Util\LocaleScanner; */ class RegionDataGenerator extends AbstractDataGenerator { - private static $blacklist = [ + private static $denylist = [ // Look like countries, but are sub-continents 'QO' => true, // Outlying Oceania 'EU' => true, // European Union @@ -50,7 +50,7 @@ class RegionDataGenerator extends AbstractDataGenerator public static function isValidCountryCode($region) { - if (isset(self::$blacklist[$region])) { + if (isset(self::$denylist[$region])) { return false; } From 968d6c4276bb1540786bc4ba6ef2a49f913f8b10 Mon Sep 17 00:00:00 2001 From: kick-the-bucket Date: Thu, 4 Jun 2020 11:26:35 +0300 Subject: [PATCH 18/28] [PhpUnitBridge] Streamline ansi/no-ansi of composer according to phpunit --colors option --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index eae4cc3125..90efc97658 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -106,15 +106,21 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ } } + if (in_array('--colors=never', $argv, true) || (isset($argv[$i = array_search('never', $argv, true) - 1]) && '--colors' === $argv[$i])) { + $COMPOSER .= ' --no-ansi'; + } else { + $COMPOSER .= ' --ansi'; + } + $info += array( 'versions' => array(), 'requires' => array('php' => '*'), ); if (1 === \count($info['versions'])) { - $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi -s dev phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); + $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress -s dev phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); } else { - $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); + $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); } @copy("phpunit-$PHPUNIT_VERSION/phpunit.xsd", 'phpunit.xsd'); @@ -144,7 +150,7 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ putenv("COMPOSER_ROOT_VERSION=$PHPUNIT_VERSION.99"); $q = '\\' === DIRECTORY_SEPARATOR ? '"' : ''; // --no-suggest is not in the list to keep compat with composer 1.0, which is shipped with Ubuntu 16.04LTS - $exit = proc_close(proc_open("$q$COMPOSER install --no-dev --prefer-dist --no-progress --ansi$q", array(), $p, getcwd())); + $exit = proc_close(proc_open("$q$COMPOSER install --no-dev --prefer-dist --no-progress$q", array(), $p, getcwd())); putenv('COMPOSER_ROOT_VERSION'.(false !== $prevRoot ? '='.$prevRoot : '')); if ($exit) { exit($exit); From e09372bcbf3de62acf139c203f4492b6c8e41d07 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 15 Jun 2020 16:43:28 +0200 Subject: [PATCH 19/28] [3.4] Fix support for PHP8 union types --- .../Resource/ReflectionClassResource.php | 6 ++- .../LazyProxy/ProxyHelper.php | 44 ++++++++++++------- .../OptionsResolver/OptionsResolver.php | 2 +- .../PropertyAccess/PropertyAccessor.php | 3 +- .../Extractor/ReflectionExtractor.php | 42 ++++++++++-------- .../Normalizer/AbstractNormalizer.php | 2 +- .../VarDumper/Caster/ReflectionCaster.php | 6 +-- 7 files changed, 61 insertions(+), 44 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index cfab1f6c10..294da3e10c 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -177,6 +177,7 @@ class ReflectionClassResource implements SelfCheckingResourceInterface, \Seriali if (!$parametersWithUndefinedConstants) { yield preg_replace('/^ @@.*/m', '', $m); } else { + $t = \PHP_VERSION_ID >= 70000 ? $m->getReturnType() : ''; $stack = [ $m->getDocComment(), $m->getName(), @@ -187,15 +188,16 @@ class ReflectionClassResource implements SelfCheckingResourceInterface, \Seriali $m->isPrivate(), $m->isProtected(), $m->returnsReference(), - \PHP_VERSION_ID >= 70000 && $m->hasReturnType() ? (\PHP_VERSION_ID >= 70100 ? $m->getReturnType()->getName() : (string) $m->getReturnType()) : '', + $t instanceof \ReflectionNamedType ? ((string) $t->allowsNull()).$t->getName() : (string) $t, ]; foreach ($m->getParameters() as $p) { if (!isset($parametersWithUndefinedConstants[$p->name])) { $stack[] = (string) $p; } else { + $t = \PHP_VERSION_ID >= 70000 ? $p->getType() : ''; $stack[] = $p->isOptional(); - $stack[] = \PHP_VERSION_ID >= 70000 && $p->hasType() ? (\PHP_VERSION_ID >= 70100 ? $p->getType()->getName() : (string) $p->getType()) : ''; + $stack[] = $t instanceof \ReflectionNamedType ? $t->getName() : (string) $t; $stack[] = $p->isPassedByReference(); $stack[] = \PHP_VERSION_ID >= 50600 ? $p->isVariadic() : ''; $stack[] = $p->getName(); diff --git a/src/Symfony/Component/DependencyInjection/LazyProxy/ProxyHelper.php b/src/Symfony/Component/DependencyInjection/LazyProxy/ProxyHelper.php index cb19c729c1..bfa65f56f0 100644 --- a/src/Symfony/Component/DependencyInjection/LazyProxy/ProxyHelper.php +++ b/src/Symfony/Component/DependencyInjection/LazyProxy/ProxyHelper.php @@ -39,26 +39,36 @@ class ProxyHelper if (!$type) { return null; } - if (!\is_string($type)) { - $name = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString(); - if ($type->isBuiltin()) { - return $noBuiltin ? null : $name; + $types = []; + + foreach ($type instanceof \ReflectionUnionType ? $type->getTypes() : [$type] as $type) { + $name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type; + + if (!\is_string($type) && $type->isBuiltin()) { + if (!$noBuiltin) { + $types[] = $name; + } + continue; + } + + $lcName = strtolower($name); + $prefix = $noBuiltin ? '' : '\\'; + + if ('self' !== $lcName && 'parent' !== $lcName) { + $types[] = '' !== $prefix ? $prefix.$name : $name; + continue; + } + if (!$r instanceof \ReflectionMethod) { + continue; + } + if ('self' === $lcName) { + $types[] = $prefix.$r->getDeclaringClass()->name; + } else { + $types[] = ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix.$parent->name : null; } } - $lcName = strtolower($name); - $prefix = $noBuiltin ? '' : '\\'; - if ('self' !== $lcName && 'parent' !== $lcName) { - return $prefix.$name; - } - if (!$r instanceof \ReflectionMethod) { - return null; - } - if ('self' === $lcName) { - return $prefix.$r->getDeclaringClass()->name; - } - - return ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix.$parent->name : null; + return $types ? implode('|', $types) : null; } } diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index 7354caf8a6..ffb101e512 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -1076,7 +1076,7 @@ class OptionsResolver implements Options return ($class = $parameter->getClass()) ? $class->name : null; } - if (!($type = $parameter->getType()) || $type->isBuiltin()) { + if (!($type = $parameter->getType()) instanceof \ReflectionNamedType || $type->isBuiltin()) { return null; } diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 99aa9a3ebc..07e0204cd2 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -519,8 +519,9 @@ class PropertyAccessor implements PropertyAccessorInterface // handle uninitialized properties in PHP >= 7.4 if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ([\w\\\]+)::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) { $r = new \ReflectionProperty($matches[1], $matches[2]); + $type = ($type = $r->getType()) instanceof \ReflectionNamedType ? $type->getName() : (string) $type; - throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getName(), $r->getType()->getName()), 0, $e); + throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getName(), $type), 0, $e); } throw $e; diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 3306946a9b..cbcb349d2e 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -187,26 +187,26 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp $type = $this->extractFromReflectionType($reflectionType, $reflectionMethod); // HHVM reports variadics with "array" but not builtin type hints - if (!$reflectionType->isBuiltin() && Type::BUILTIN_TYPE_ARRAY === $type->getBuiltinType()) { + if (1 === \count($type) && !$reflectionType->isBuiltin() && Type::BUILTIN_TYPE_ARRAY === $type[0]->getBuiltinType()) { return null; } } elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $reflectionParameter, $info)) { if (Type::BUILTIN_TYPE_ARRAY === $info[1]) { - $type = new Type(Type::BUILTIN_TYPE_ARRAY, $reflectionParameter->allowsNull(), null, true); + $type = [new Type(Type::BUILTIN_TYPE_ARRAY, $reflectionParameter->allowsNull(), null, true)]; } elseif (Type::BUILTIN_TYPE_CALLABLE === $info[1]) { - $type = new Type(Type::BUILTIN_TYPE_CALLABLE, $reflectionParameter->allowsNull()); + $type = [new Type(Type::BUILTIN_TYPE_CALLABLE, $reflectionParameter->allowsNull())]; } else { - $type = new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionParameter->allowsNull(), $this->resolveTypeName($info[1], $reflectionMethod)); + $type = [new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionParameter->allowsNull(), $this->resolveTypeName($info[1], $reflectionMethod))]; } } else { return null; } - if (\in_array($prefix, $this->arrayMutatorPrefixes)) { - $type = new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type); + if (1 === \count($type) && \in_array($prefix, $this->arrayMutatorPrefixes)) { + $type = [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type[0])]; } - return [$type]; + return $type; } /** @@ -225,7 +225,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp } if ($this->supportsParameterType && $reflectionType = $reflectionMethod->getReturnType()) { - return [$this->extractFromReflectionType($reflectionType, $reflectionMethod)]; + return $this->extractFromReflectionType($reflectionType, $reflectionMethod); } return \in_array($prefix, ['is', 'can']) ? [new Type(Type::BUILTIN_TYPE_BOOL)] : null; @@ -234,24 +234,28 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp /** * Extracts data from the PHP 7 reflection type. * - * @return Type + * @return Type[] */ private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionMethod $reflectionMethod) { - $phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : $reflectionType->__toString(); + $types = []; $nullable = $reflectionType->allowsNull(); - if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) { - $type = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true); - } elseif ('void' === $phpTypeOrClass) { - $type = new Type(Type::BUILTIN_TYPE_NULL, $nullable); - } elseif ($reflectionType->isBuiltin()) { - $type = new Type($phpTypeOrClass, $nullable); - } else { - $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod)); + foreach ($reflectionType instanceof \ReflectionUnionType ? $reflectionType->getTypes() : [$reflectionType] as $type) { + $phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : (string) $type; + + if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) { + $types[] = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true); + } elseif ('void' === $phpTypeOrClass || 'null' === $phpTypeOrClass) { + $types[] = new Type(Type::BUILTIN_TYPE_NULL, $nullable); + } elseif ($reflectionType->isBuiltin()) { + $types[] = new Type($phpTypeOrClass, $nullable); + } else { + $types[] = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod)); + } } - return $type; + return $types; } private function resolveTypeName($name, \ReflectionMethod $reflectionMethod) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 71b1e38d37..e88b5a2110 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -388,7 +388,7 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N try { if (\PHP_VERSION_ID < 70100 && null !== $parameterClass = $parameter->getClass()) { $parameterClass = $parameterClass->name; - } elseif (\PHP_VERSION_ID >= 70100 && ($parameterType = $parameter->getType()) && !$parameterType->isBuiltin()) { + } elseif (\PHP_VERSION_ID >= 70100 && ($parameterType = $parameter->getType()) instanceof \ReflectionNamedType && !$parameterType->isBuiltin()) { $parameterClass = $parameterType->getName(); new \ReflectionClass($parameterClass); // throws a \ReflectionException if the class doesn't exist } else { diff --git a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php index 067da6bbd3..31de78e961 100644 --- a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php @@ -91,7 +91,7 @@ class ReflectionCaster $prefix = Caster::PREFIX_VIRTUAL; $a += [ - $prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : $c->__toString(), + $prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : (string) $c, $prefix.'allowsNull' => $c->allowsNull(), $prefix.'isBuiltin' => $c->isBuiltin(), ]; @@ -178,7 +178,7 @@ class ReflectionCaster if (isset($a[$prefix.'returnType'])) { $v = $a[$prefix.'returnType']; - $v = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); + $v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v; $a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType']->allowsNull() ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']); } if (isset($a[$prefix.'class'])) { @@ -247,7 +247,7 @@ class ReflectionCaster if (method_exists($c, 'getType')) { if ($v = $c->getType()) { - $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); + $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v; } } elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $c, $v)) { $a[$prefix.'typeHint'] = $v[1]; From 3d0d59de20a5ee2cc2bb4d6038b26577072463cd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 13 Jun 2020 17:57:51 +0200 Subject: [PATCH 20/28] [FrameworkBundle] preserve dots in query-string when redirecting --- .../Controller/RedirectController.php | 57 ++++++++++++++++++- .../Controller/RedirectControllerTest.php | 22 ++++--- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php index 67be757db3..58f06d5df9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php @@ -62,7 +62,17 @@ class RedirectController $attributes = []; if (false === $ignoreAttributes || \is_array($ignoreAttributes)) { $attributes = $request->attributes->get('_route_params'); - $attributes = $keepQueryParams ? array_merge($request->query->all(), $attributes) : $attributes; + + if ($keepQueryParams) { + if ($query = $request->server->get('QUERY_STRING')) { + $query = self::parseQuery($query); + } else { + $query = $request->query->all(); + } + + $attributes = array_merge($query, $attributes); + } + unset($attributes['route'], $attributes['permanent'], $attributes['ignoreAttributes'], $attributes['keepRequestMethod'], $attributes['keepQueryParams']); if ($ignoreAttributes) { $attributes = array_diff_key($attributes, array_flip($ignoreAttributes)); @@ -175,4 +185,49 @@ class RedirectController throw new \RuntimeException(sprintf('The parameter "path" or "route" is required to configure the redirect action in "%s" routing configuration.', $request->attributes->get('_route'))); } + + private static function parseQuery(string $query) + { + $q = []; + + foreach (explode('&', $query) as $v) { + if (false !== $i = strpos($v, "\0")) { + $v = substr($v, 0, $i); + } + + if (false === $i = strpos($v, '=')) { + $k = urldecode($v); + $v = ''; + } else { + $k = urldecode(substr($v, 0, $i)); + $v = substr($v, $i); + } + + if (false !== $i = strpos($k, "\0")) { + $k = substr($k, 0, $i); + } + + $k = ltrim($k, ' '); + + if (false === $i = strpos($k, '[')) { + $q[] = bin2hex($k).$v; + } else { + $q[] = substr_replace($k, bin2hex(substr($k, 0, $i)), 0, $i).$v; + } + } + + parse_str(implode('&', $q), $q); + + $query = []; + + foreach ($q as $k => $v) { + if (false !== $i = strpos($k, '_')) { + $query[substr_replace($k, hex2bin(substr($k, 0, $i)).'[', 0, 1 + $i)] = $v; + } else { + $query[hex2bin($k)] = $v; + } + } + + return $query; + } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php index 5920cfc37a..732ac3e2d6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php @@ -302,17 +302,16 @@ class RedirectControllerTest extends TestCase $baseUrl = '/base'; $port = 80; - $request = $this->createRequestObject($scheme, $host, $port, $baseUrl, 'base=zaza'); - $request->query = new ParameterBag(['base' => 'zaza']); + $request = $this->createRequestObject($scheme, $host, $port, $baseUrl, 'b.se=zaza'); $request->attributes = new ParameterBag(['_route_params' => ['base2' => 'zaza']]); $urlGenerator = $this->getMockBuilder(UrlGeneratorInterface::class)->getMock(); - $urlGenerator->expects($this->exactly(2))->method('generate')->willReturn('/test?base=zaza&base2=zaza')->with('/test', ['base' => 'zaza', 'base2' => 'zaza'], UrlGeneratorInterface::ABSOLUTE_URL); + $urlGenerator->expects($this->exactly(2))->method('generate')->willReturn('/test?b.se=zaza&base2=zaza')->with('/test', ['b.se' => 'zaza', 'base2' => 'zaza'], UrlGeneratorInterface::ABSOLUTE_URL); $controller = new RedirectController($urlGenerator); - $this->assertRedirectUrl($controller->redirectAction($request, '/test', false, false, false, true), '/test?base=zaza&base2=zaza'); + $this->assertRedirectUrl($controller->redirectAction($request, '/test', false, false, false, true), '/test?b.se=zaza&base2=zaza'); $request->attributes->set('_route_params', ['base2' => 'zaza', 'route' => '/test', 'ignoreAttributes' => false, 'keepRequestMethod' => false, 'keepQueryParams' => true]); - $this->assertRedirectUrl($controller($request), '/test?base=zaza&base2=zaza'); + $this->assertRedirectUrl($controller($request), '/test?b.se=zaza&base2=zaza'); } public function testRedirectWithQueryWithRouteParamsOveriding() @@ -322,17 +321,16 @@ class RedirectControllerTest extends TestCase $baseUrl = '/base'; $port = 80; - $request = $this->createRequestObject($scheme, $host, $port, $baseUrl, 'base=zaza'); - $request->query = new ParameterBag(['base' => 'zaza']); - $request->attributes = new ParameterBag(['_route_params' => ['base' => 'zouzou']]); + $request = $this->createRequestObject($scheme, $host, $port, $baseUrl, 'b.se=zaza'); + $request->attributes = new ParameterBag(['_route_params' => ['b.se' => 'zouzou']]); $urlGenerator = $this->getMockBuilder(UrlGeneratorInterface::class)->getMock(); - $urlGenerator->expects($this->exactly(2))->method('generate')->willReturn('/test?base=zouzou')->with('/test', ['base' => 'zouzou'], UrlGeneratorInterface::ABSOLUTE_URL); + $urlGenerator->expects($this->exactly(2))->method('generate')->willReturn('/test?b.se=zouzou')->with('/test', ['b.se' => 'zouzou'], UrlGeneratorInterface::ABSOLUTE_URL); $controller = new RedirectController($urlGenerator); - $this->assertRedirectUrl($controller->redirectAction($request, '/test', false, false, false, true), '/test?base=zouzou'); + $this->assertRedirectUrl($controller->redirectAction($request, '/test', false, false, false, true), '/test?b.se=zouzou'); - $request->attributes->set('_route_params', ['base' => 'zouzou', 'route' => '/test', 'ignoreAttributes' => false, 'keepRequestMethod' => false, 'keepQueryParams' => true]); - $this->assertRedirectUrl($controller($request), '/test?base=zouzou'); + $request->attributes->set('_route_params', ['b.se' => 'zouzou', 'route' => '/test', 'ignoreAttributes' => false, 'keepRequestMethod' => false, 'keepQueryParams' => true]); + $this->assertRedirectUrl($controller($request), '/test?b.se=zouzou'); } public function testMissingPathOrRouteParameter() From da68e66a9913cd0bef7cbf98bdd01ebf13220457 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 15 Jun 2020 16:43:28 +0200 Subject: [PATCH 21/28] Fix support for PHP8 union types --- .../Compiler/CheckTypeDeclarationsPass.php | 23 +++++++++++++--- .../DependencyInjection/Dumper/Preloader.php | 27 ++++++++++++------- .../InvalidParameterTypeException.php | 5 +++- .../RegisterListenersPass.php | 2 +- .../ArgumentMetadataFactory.php | 2 +- .../EventListener/ErrorListener.php | 2 +- .../DependencyInjection/MessengerPass.php | 15 ++++++++++- .../OptionsResolver/OptionsResolver.php | 2 +- .../Contracts/Service/ServiceLocatorTrait.php | 2 +- .../Service/ServiceSubscriberTrait.php | 2 +- 10 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php index cf255640c2..ae1a2ec204 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php @@ -153,9 +153,26 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass /** * @throws InvalidParameterTypeException When a parameter is not compatible with the declared type */ - private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix): void + private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix, string $type = null): void { - $type = $parameter->getType()->getName(); + if (null === $type) { + $type = $parameter->getType(); + + if ($type instanceof \ReflectionUnionType) { + foreach ($type->getTypes() as $type) { + try { + $this->checkType($checkedDefinition, $value, $parameter, $envPlaceholderUniquePrefix, $type); + + return; + } catch (InvalidParameterTypeException $e) { + } + } + + throw new InvalidParameterTypeException($this->currentId, $e->getCode(), $parameter); + } + + $type = $type->getName(); + } if ($value instanceof Reference) { if (!$this->container->has($value = (string) $value)) { @@ -266,7 +283,7 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass return; } - $checkFunction = sprintf('is_%s', $parameter->getType()->getName()); + $checkFunction = sprintf('is_%s', $type); if (!$parameter->getType()->isBuiltin() || !$checkFunction($value)) { throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? $class : \gettype($value), $parameter); diff --git a/src/Symfony/Component/DependencyInjection/Dumper/Preloader.php b/src/Symfony/Component/DependencyInjection/Dumper/Preloader.php index abb7d90ff5..f9d2716e7d 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/Preloader.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/Preloader.php @@ -48,7 +48,7 @@ class Preloader } } - private static function doPreload(string $class, array &$preloaded) + private static function doPreload(string $class, array &$preloaded): void { if (isset($preloaded[$class]) || \in_array($class, ['self', 'static', 'parent'], true)) { return; @@ -68,9 +68,7 @@ class Preloader if (\PHP_VERSION_ID >= 70400) { foreach ($r->getProperties(\ReflectionProperty::IS_PUBLIC) as $p) { - if (($t = $p->getType()) && !$t->isBuiltin()) { - self::doPreload($t->getName(), $preloaded); - } + self::preloadType($p->getType(), $preloaded); } } @@ -84,17 +82,26 @@ class Preloader } } - if (($t = $p->getType()) && !$t->isBuiltin()) { - self::doPreload($t->getName(), $preloaded); - } + self::preloadType($p->getType(), $preloaded); } - if (($t = $m->getReturnType()) && !$t->isBuiltin()) { - self::doPreload($t->getName(), $preloaded); - } + self::preloadType($p->getReturnType(), $preloaded); } } catch (\ReflectionException $e) { // ignore missing classes } } + + private static function preloadType(?\ReflectionType $t, array &$preloaded): void + { + if (!$t || $t->isBuiltin()) { + return; + } + + foreach ($t instanceof \ReflectionUnionType ? $t->getTypes() : [$t] as $t) { + if (!$t->isBuiltin()) { + self::doPreload($t instanceof \ReflectionNamedType ? $t->getName() : $t, $preloaded); + } + } + } } diff --git a/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php b/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php index 206561fa95..05fdb4a779 100644 --- a/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php +++ b/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php @@ -21,6 +21,9 @@ class InvalidParameterTypeException extends InvalidArgumentException { public function __construct(string $serviceId, string $type, \ReflectionParameter $parameter) { - parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $parameter->getType()->getName(), $type)); + $acceptedType = $parameter->getType(); + $acceptedType = $acceptedType instanceof \ReflectionNamedType ? $acceptedType->getName() : (string) $acceptedType; + + parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $acceptedType, $type), $type); } } diff --git a/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php b/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php index 3ae1136c4c..4b27d3b23a 100644 --- a/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php +++ b/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php @@ -138,7 +138,7 @@ class RegisterListenersPass implements CompilerPassInterface || !($r = $container->getReflectionClass($class, false)) || !$r->hasMethod($method) || 1 > ($m = $r->getMethod($method))->getNumberOfParameters() - || !($type = $m->getParameters()[0]->getType()) + || !($type = $m->getParameters()[0]->getType()) instanceof \ReflectionNamedType || $type->isBuiltin() || Event::class === ($name = $type->getName()) || LegacyEvent::class === $name diff --git a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php index 9370174c25..6c192a6f5f 100644 --- a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php +++ b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php @@ -45,7 +45,7 @@ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface */ private function getType(\ReflectionParameter $parameter, \ReflectionFunctionAbstract $function): ?string { - if (!$type = $parameter->getType()) { + if (!($type = $parameter->getType()) instanceof \ReflectionNamedType) { return null; } $name = $type->getName(); diff --git a/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php b/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php index 26c361f754..1ca6c9b458 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php @@ -99,7 +99,7 @@ class ErrorListener implements EventSubscriberInterface $r = new \ReflectionFunction(\Closure::fromCallable($event->getController())); $r = $r->getParameters()[$k] ?? null; - if ($r && (!$r->hasType() || \in_array($r->getType()->getName(), [FlattenException::class, LegacyFlattenException::class], true))) { + if ($r && (!($r = $r->getType()) instanceof \ReflectionNamedType || \in_array($r->getName(), [FlattenException::class, LegacyFlattenException::class], true))) { $arguments = $event->getArguments(); $arguments[$k] = FlattenException::createFromThrowable($e); $event->setArguments($arguments); diff --git a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php index bf62b4c87e..888155dea9 100644 --- a/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php +++ b/src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php @@ -228,11 +228,24 @@ class MessengerPass implements CompilerPassInterface throw new RuntimeException(sprintf('Invalid handler service "%s": argument "$%s" of method "%s::__invoke()" must have a type-hint corresponding to the message class it handles.', $serviceId, $parameters[0]->getName(), $handlerClass->getName())); } + if ($type instanceof \ReflectionUnionType) { + $types = []; + foreach ($type->getTypes() as $type) { + if (!$type->isBuiltin()) { + $types[] = (string) $type; + } + } + + if ($types) { + return $types; + } + } + if ($type->isBuiltin()) { throw new RuntimeException(sprintf('Invalid handler service "%s": type-hint of argument "$%s" in method "%s::__invoke()" must be a class , "%s" given.', $serviceId, $parameters[0]->getName(), $handlerClass->getName(), $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type)); } - return [$parameters[0]->getType()->getName()]; + return [$type->getName()]; } private function registerReceivers(ContainerBuilder $container, array $busIds) diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index e40583dd5f..3fb3c06f92 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -201,7 +201,7 @@ class OptionsResolver implements Options return $this; } - if (isset($params[0]) && null !== ($type = $params[0]->getType()) && self::class === $type->getName() && (!isset($params[1]) || (null !== ($type = $params[1]->getType()) && Options::class === $type->getName()))) { + if (isset($params[0]) && null !== ($type = $params[0]->getType()) && self::class === $type->getName() && (!isset($params[1]) || (($type = $params[1]->getType()) instanceof \ReflectionNamedType && Options::class === $type->getName()))) { // Store closure for later evaluation $this->nested[$option][] = $value; $this->defaults[$option] = []; diff --git a/src/Symfony/Contracts/Service/ServiceLocatorTrait.php b/src/Symfony/Contracts/Service/ServiceLocatorTrait.php index 0b4d60affa..1737f50e99 100644 --- a/src/Symfony/Contracts/Service/ServiceLocatorTrait.php +++ b/src/Symfony/Contracts/Service/ServiceLocatorTrait.php @@ -87,7 +87,7 @@ trait ServiceLocatorTrait } else { $type = (new \ReflectionFunction($factory))->getReturnType(); - $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').$type->getName() : '?'; + $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?'; } } } diff --git a/src/Symfony/Contracts/Service/ServiceSubscriberTrait.php b/src/Symfony/Contracts/Service/ServiceSubscriberTrait.php index 5d9d456d0c..82fb5ab361 100644 --- a/src/Symfony/Contracts/Service/ServiceSubscriberTrait.php +++ b/src/Symfony/Contracts/Service/ServiceSubscriberTrait.php @@ -40,7 +40,7 @@ trait ServiceSubscriberTrait } if (self::class === $method->getDeclaringClass()->name && ($returnType = $method->getReturnType()) && !$returnType->isBuiltin()) { - $services[self::class.'::'.$method->name] = '?'.$returnType->getName(); + $services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $type); } } From 9670e9ff06c5faaa62f85c078a6ae227a41058e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 13 Jun 2020 17:29:14 +0200 Subject: [PATCH 22/28] [Lock][Messenger] Fix precedence of DSN options for 5.1 --- .../Component/Lock/Store/MongoDbStore.php | 4 ++-- .../Lock/Tests/Store/MongoDbStoreTest.php | 13 +++++++++++++ .../Tests/Transport/ConnectionTest.php | 9 +++++++++ .../Bridge/AmazonSqs/Transport/Connection.php | 18 +++++++++--------- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Lock/Store/MongoDbStore.php b/src/Symfony/Component/Lock/Store/MongoDbStore.php index 34c740a668..8828bb8c3a 100644 --- a/src/Symfony/Component/Lock/Store/MongoDbStore.php +++ b/src/Symfony/Component/Lock/Store/MongoDbStore.php @@ -120,8 +120,8 @@ class MongoDbStore implements BlockingStoreInterface if (isset($parsedUrl['query'])) { parse_str($parsedUrl['query'], $query); } - $this->options['collection'] = $this->options['collection'] ?? $query['collection'] ?? null; - $this->options['database'] = $this->options['database'] ?? ltrim($parsedUrl['path'] ?? '', '/') ?: null; + $this->options['collection'] = $query['collection'] ?? $this->options['collection'] ?? null; + $this->options['database'] = ltrim($parsedUrl['path'] ?? '', '/') ?: $this->options['database'] ?? null; if (null === $this->options['database']) { throw new InvalidArgumentException(sprintf('"%s()" requires the "database" in the URI path or option when constructing with a URI.', __METHOD__)); } diff --git a/src/Symfony/Component/Lock/Tests/Store/MongoDbStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/MongoDbStoreTest.php index 5e4985e352..34dd1182c9 100644 --- a/src/Symfony/Component/Lock/Tests/Store/MongoDbStoreTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/MongoDbStoreTest.php @@ -121,6 +121,19 @@ class MongoDbStoreTest extends AbstractStoreTest yield ['mongodb://localhost/', ['database' => 'test', 'collection' => 'lock']]; } + public function testDsnPrecedence() + { + $client = self::getMongoClient(); + + $store = new MongoDbStore('mongodb://localhost/test_dsn?collection=lock_dns', ['collection' => 'lock_option', 'database' => 'test_option']); + $r = new \ReflectionObject($store); + $p = $r->getProperty('options'); + $p->setAccessible(true); + $options = $p->getValue($store); + $this->assertSame('lock_dns', $options['collection']); + $this->assertSame('test_dsn', $options['database']); + } + /** * @dataProvider provideInvalidConstructorArgs */ diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/ConnectionTest.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/ConnectionTest.php index b82f6333de..1c2cc479f5 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/ConnectionTest.php @@ -70,6 +70,15 @@ class ConnectionTest extends TestCase ); } + public function testDsnPrecedence() + { + $httpClient = $this->getMockBuilder(HttpClientInterface::class)->getMock(); + $this->assertEquals( + new Connection(['queue_name' => 'queue_dsn'], new SqsClient(['region' => 'us-east-2', 'accessKeyId' => 'key_dsn', 'accessKeySecret' => 'secret_dsn'], null, $httpClient)), + Connection::fromDsn('sqs://key_dsn:secret_dsn@default/queue_dsn?region=us-east-2', ['region' => 'eu-west-3', 'queue_name' => 'queue_options', 'access_key' => 'key_option', 'secret_key' => 'secret_option'], $httpClient) + ); + } + public function testFromDsnWithRegion() { $httpClient = $this->getMockBuilder(HttpClientInterface::class)->getMock(); diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php index 1ae2b46321..ce1b3413ed 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php @@ -94,19 +94,19 @@ class Connection if (isset($parsedUrl['query'])) { parse_str($parsedUrl['query'], $query); } - + $options = $query + $options + self::DEFAULT_OPTIONS; $configuration = [ - 'buffer_size' => $options['buffer_size'] ?? (int) ($query['buffer_size'] ?? self::DEFAULT_OPTIONS['buffer_size']), - 'wait_time' => $options['wait_time'] ?? (int) ($query['wait_time'] ?? self::DEFAULT_OPTIONS['wait_time']), - 'poll_timeout' => $options['poll_timeout'] ?? ($query['poll_timeout'] ?? self::DEFAULT_OPTIONS['poll_timeout']), - 'visibility_timeout' => $options['visibility_timeout'] ?? ($query['visibility_timeout'] ?? self::DEFAULT_OPTIONS['visibility_timeout']), - 'auto_setup' => $options['auto_setup'] ?? (bool) ($query['auto_setup'] ?? self::DEFAULT_OPTIONS['auto_setup']), + 'buffer_size' => (int) $options['buffer_size'], + 'wait_time' => (int) $options['wait_time'], + 'poll_timeout' => $options['poll_timeout'], + 'visibility_timeout' => $options['visibility_timeout'], + 'auto_setup' => (bool) $options['auto_setup'], ]; $clientConfiguration = [ - 'region' => $options['region'] ?? ($query['region'] ?? self::DEFAULT_OPTIONS['region']), - 'accessKeyId' => $options['access_key'] ?? (urldecode($parsedUrl['user'] ?? '') ?: self::DEFAULT_OPTIONS['access_key']), - 'accessKeySecret' => $options['secret_key'] ?? (urldecode($parsedUrl['pass'] ?? '') ?: self::DEFAULT_OPTIONS['secret_key']), + 'region' => $options['region'], + 'accessKeyId' => urldecode($parsedUrl['user'] ?? '') ?: $options['access_key'] ?? self::DEFAULT_OPTIONS['access_key'], + 'accessKeySecret' => urldecode($parsedUrl['pass'] ?? '') ?: $options['secret_key'] ?? self::DEFAULT_OPTIONS['secret_key'], ]; unset($query['region']); From 2eb3c0eb7fcc6e732f2451c0367afa5625f153fb Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 18 Jun 2020 20:15:32 +0200 Subject: [PATCH 23/28] [VarDumper] fix typo --- src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php index c0e9e5c03b..81a2da7298 100644 --- a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php @@ -326,7 +326,7 @@ class ReflectionCaster if (!$param->isOptional() && $param->allowsNull()) { $signature .= '?'; } - $signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1); + $signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' '; } } $signature .= $k; From dd1b61703fae220004b476f58fa380a31e8386c5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 15 Jun 2020 16:43:28 +0200 Subject: [PATCH 24/28] Fix support for PHP8 union types --- .../Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php | 2 +- .../Compiler/AutowireRequiredPropertiesPass.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php b/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php index abb220b4aa..efd99784e4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php @@ -112,7 +112,7 @@ trait MicroKernelTrait throw new \LogicException(sprintf('"%s" uses "%s", but does not implement the required method "protected function configureContainer(ContainerConfigurator $c): void".', get_debug_type($this), MicroKernelTrait::class), 0, $e); } - $configuratorClass = $configureContainer->getNumberOfParameters() > 0 && ($type = $configureContainer->getParameters()[0]->getType()) && !$type->isBuiltin() ? $type->getName() : null; + $configuratorClass = $configureContainer->getNumberOfParameters() > 0 && ($type = $configureContainer->getParameters()[0]->getType()) instanceof \ReflectionNamedType && !$type->isBuiltin() ? $type->getName() : null; if ($configuratorClass && !is_a(ContainerConfigurator::class, $configuratorClass, true)) { $this->configureContainer($container, $loader); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredPropertiesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredPropertiesPass.php index 945b8c9e01..24f9c41d2b 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredPropertiesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredPropertiesPass.php @@ -42,7 +42,7 @@ class AutowireRequiredPropertiesPass extends AbstractRecursivePass $properties = $value->getProperties(); foreach ($reflectionClass->getProperties() as $reflectionProperty) { - if (!$reflectionProperty->hasType()) { + if (!($type = $reflectionProperty->getType()) instanceof \ReflectionNamedType) { continue; } if (false === $doc = $reflectionProperty->getDocComment()) { @@ -55,7 +55,7 @@ class AutowireRequiredPropertiesPass extends AbstractRecursivePass continue; } - $type = $reflectionProperty->getType()->getName(); + $type = $type->getName(); $value->setProperty($name, new TypedReference($type, $type, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name)); } From 00682acdea2e7e9b37caa732f93672ca1a73d65c Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 7 Jun 2020 14:29:13 +0200 Subject: [PATCH 25/28] Small update in our internal terminology --- .../Component/HttpClient/NoPrivateNetworkHttpClient.php | 2 +- .../HttpClient/Tests/NoPrivateNetworkHttpClientTest.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpClient/NoPrivateNetworkHttpClient.php b/src/Symfony/Component/HttpClient/NoPrivateNetworkHttpClient.php index 3d86f09e76..d4c69cabce 100644 --- a/src/Symfony/Component/HttpClient/NoPrivateNetworkHttpClient.php +++ b/src/Symfony/Component/HttpClient/NoPrivateNetworkHttpClient.php @@ -81,7 +81,7 @@ final class NoPrivateNetworkHttpClient implements HttpClientInterface, LoggerAwa $options['on_progress'] = function (int $dlNow, int $dlSize, array $info) use ($onProgress, $subnets, &$lastPrimaryIp): void { if ($info['primary_ip'] !== $lastPrimaryIp) { if (IpUtils::checkIp($info['primary_ip'], $subnets ?? self::PRIVATE_SUBNETS)) { - throw new TransportException(sprintf('IP "%s" is blacklisted for "%s".', $info['primary_ip'], $info['url'])); + throw new TransportException(sprintf('IP "%s" is blocked for "%s".', $info['primary_ip'], $info['url'])); } $lastPrimaryIp = $info['primary_ip']; diff --git a/src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php index 1e099689b1..aabfe38c01 100755 --- a/src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php @@ -22,7 +22,7 @@ use Symfony\Contracts\HttpClient\ResponseInterface; class NoPrivateNetworkHttpClientTest extends TestCase { - public function getBlacklistData(): array + public function getExcludeData(): array { return [ // private @@ -63,16 +63,16 @@ class NoPrivateNetworkHttpClientTest extends TestCase } /** - * @dataProvider getBlacklistData + * @dataProvider getExcludeData */ - public function testBlacklist(string $ipAddr, $subnets, bool $mustThrow) + public function testExclude(string $ipAddr, $subnets, bool $mustThrow) { $content = 'foo'; $url = sprintf('http://%s/', 0 < substr_count($ipAddr, ':') ? sprintf('[%s]', $ipAddr) : $ipAddr); if ($mustThrow) { $this->expectException(TransportException::class); - $this->expectExceptionMessage(sprintf('IP "%s" is blacklisted for "%s".', $ipAddr, $url)); + $this->expectExceptionMessage(sprintf('IP "%s" is blocked for "%s".', $ipAddr, $url)); } $previousHttpClient = $this->getHttpClientMock($url, $ipAddr, $content); From 8bbbdbe74576639224d7019d90d80f4f2a4b5737 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 18 Jun 2020 21:30:53 +0200 Subject: [PATCH 26/28] Fix --- .../Component/Config/Resource/ReflectionClassResource.php | 2 +- .../DependencyInjection/Compiler/FactoryReturnTypePass.php | 2 +- .../HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php | 2 +- src/Symfony/Component/OptionsResolver/OptionsResolver.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index 294da3e10c..79b21fbf4c 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -197,7 +197,7 @@ class ReflectionClassResource implements SelfCheckingResourceInterface, \Seriali } else { $t = \PHP_VERSION_ID >= 70000 ? $p->getType() : ''; $stack[] = $p->isOptional(); - $stack[] = $t instanceof \ReflectionNamedType ? $t->getName() : (string) $t; + $stack[] = $t instanceof \ReflectionNamedType ? ((string) $t->allowsNull()).$t->getName() : (string) $t; $stack[] = $p->isPassedByReference(); $stack[] = \PHP_VERSION_ID >= 50600 ? $p->isVariadic() : ''; $stack[] = $p->getName(); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php b/src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php index d688fb59fd..6b1277e26a 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php @@ -93,7 +93,7 @@ class FactoryReturnTypePass implements CompilerPassInterface $returnType = $m->getReturnType(); if (null !== $returnType && !$returnType->isBuiltin()) { - $returnType = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType->__toString(); + $returnType = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; if (null !== $class) { $declaringClass = $m->getDeclaringClass()->getName(); if ('self' === strtolower($returnType)) { diff --git a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php index 2548a2a083..14e7ca3d11 100644 --- a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php +++ b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php @@ -105,7 +105,7 @@ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface if (!$type = $parameter->getType()) { return null; } - $name = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString(); + $name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type; if ('array' === $name && !$type->isBuiltin()) { // Special case for HHVM with variadics return null; diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index ffb101e512..7354caf8a6 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -1076,7 +1076,7 @@ class OptionsResolver implements Options return ($class = $parameter->getClass()) ? $class->name : null; } - if (!($type = $parameter->getType()) instanceof \ReflectionNamedType || $type->isBuiltin()) { + if (!($type = $parameter->getType()) || $type->isBuiltin()) { return null; } From 03b9ff177d84258a959a8fa5ec113289f0b1e982 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 18 Jun 2020 21:44:11 +0200 Subject: [PATCH 27/28] Use "composer/package-versions-deprecated" when possible --- composer.json | 1 + src/Symfony/Bridge/Doctrine/composer.json | 1 + src/Symfony/Component/Messenger/composer.json | 2 +- src/Symfony/Contracts/composer.json | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 84692253ea..3c75a0e70e 100644 --- a/composer.json +++ b/composer.json @@ -100,6 +100,7 @@ }, "require-dev": { "cache/integration-tests": "dev-master", + "composer/package-versions-deprecated": "^1.8", "doctrine/annotations": "~1.0", "doctrine/cache": "~1.6", "doctrine/collections": "~1.0", diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index fde197dedb..82848c2ad6 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -24,6 +24,7 @@ "symfony/service-contracts": "^1.1|^2" }, "require-dev": { + "composer/package-versions-deprecated": "^1.8", "symfony/stopwatch": "^3.4|^4.0|^5.0", "symfony/config": "^4.2|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", diff --git a/src/Symfony/Component/Messenger/composer.json b/src/Symfony/Component/Messenger/composer.json index bbc5e5e3ff..3537c7d317 100644 --- a/src/Symfony/Component/Messenger/composer.json +++ b/src/Symfony/Component/Messenger/composer.json @@ -22,8 +22,8 @@ }, "require-dev": { "doctrine/dbal": "^2.6|^3.0", - "psr/cache": "~1.0", "doctrine/persistence": "^1.3", + "psr/cache": "~1.0", "symfony/console": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^3.4.19|^4.1.8|^5.0", "symfony/event-dispatcher": "^4.3|^5.0", diff --git a/src/Symfony/Contracts/composer.json b/src/Symfony/Contracts/composer.json index 4ac096ed11..f823bf30d6 100644 --- a/src/Symfony/Contracts/composer.json +++ b/src/Symfony/Contracts/composer.json @@ -45,6 +45,7 @@ ] }, "minimum-stability": "dev", + "version": "1.99", "extra": { "branch-alias": { "dev-master": "1.1-dev" From d2efe50eee1e125cdaf88c88e37ad084c1ccb0e2 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 18 Jun 2020 21:50:30 +0200 Subject: [PATCH 28/28] [DI] fix --- .../Exception/InvalidParameterTypeException.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php b/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php index 05fdb4a779..f6f12ad604 100644 --- a/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php +++ b/src/Symfony/Component/DependencyInjection/Exception/InvalidParameterTypeException.php @@ -23,7 +23,8 @@ class InvalidParameterTypeException extends InvalidArgumentException { $acceptedType = $parameter->getType(); $acceptedType = $acceptedType instanceof \ReflectionNamedType ? $acceptedType->getName() : (string) $acceptedType; + $this->code = $type; - parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $acceptedType, $type), $type); + parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $acceptedType, $type)); } }