From dfa23034c3885f0d6e63eb43648027f262b9a0fe Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Mon, 7 Oct 2019 15:00:46 +0200 Subject: [PATCH 01/72] [Form][DateTimeImmutableToDateTimeTransformer] Preserve microseconds and use \DateTime::createFromImmutable() when available --- ...DateTimeImmutableToDateTimeTransformer.php | 6 +++- ...TimeImmutableToDateTimeTransformerTest.php | 34 ++++++++++++++----- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformer.php index b0737393e4e3f..167ea57faebbf 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformer.php @@ -40,7 +40,11 @@ public function transform($value) throw new TransformationFailedException('Expected a \DateTimeImmutable.'); } - return \DateTime::createFromFormat(\DateTime::RFC3339, $value->format(\DateTime::RFC3339)); + if (\PHP_VERSION_ID >= 70300) { + return \DateTime::createFromImmutable($value); + } + + return \DateTime::createFromFormat('U.u', $value->format('U.u'))->setTimezone($value->getTimezone()); } /** diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php index 9313e4f1785cf..c8b6549778cce 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeImmutableToDateTimeTransformerTest.php @@ -16,16 +16,33 @@ class DateTimeImmutableToDateTimeTransformerTest extends TestCase { - public function testTransform() + /** + * @dataProvider provider + */ + public function testTransform(\DateTime $expectedOutput, \DateTimeImmutable $input) { $transformer = new DateTimeImmutableToDateTimeTransformer(); - $input = new \DateTimeImmutable('2010-02-03 04:05:06 UTC'); - $expectedOutput = new \DateTime('2010-02-03 04:05:06 UTC'); $actualOutput = $transformer->transform($input); - $this->assertInstanceOf(\DateTime::class, $actualOutput); $this->assertEquals($expectedOutput, $actualOutput); + $this->assertEquals($expectedOutput->getTimezone(), $actualOutput->getTimezone()); + } + + public function provider() + { + return [ + [ + new \DateTime('2010-02-03 04:05:06 UTC'), + new \DateTimeImmutable('2010-02-03 04:05:06 UTC'), + ], + [ + (new \DateTime('2019-10-07 +11:00')) + ->setTime(14, 27, 11, 10042), + (new \DateTimeImmutable('2019-10-07 +11:00')) + ->setTime(14, 27, 11, 10042), + ], + ]; } public function testTransformEmpty() @@ -43,16 +60,17 @@ public function testTransformFail() $transformer->transform(new \DateTime()); } - public function testReverseTransform() + /** + * @dataProvider provider + */ + public function testReverseTransform(\DateTime $input, \DateTimeImmutable $expectedOutput) { $transformer = new DateTimeImmutableToDateTimeTransformer(); - $input = new \DateTime('2010-02-03 04:05:06 UTC'); - $expectedOutput = new \DateTimeImmutable('2010-02-03 04:05:06 UTC'); $actualOutput = $transformer->reverseTransform($input); - $this->assertInstanceOf(\DateTimeImmutable::class, $actualOutput); $this->assertEquals($expectedOutput, $actualOutput); + $this->assertEquals($expectedOutput->getTimezone(), $actualOutput->getTimezone()); } public function testReverseTransformEmpty() From ed01f3c51167f8063b000112162e5ab991123158 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 7 Oct 2019 16:41:35 +0200 Subject: [PATCH 02/72] updated CHANGELOG for 3.4.32 --- CHANGELOG-3.4.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index f92c85dd9c425..015ca124b1815 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,46 @@ 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.32 (2019-10-07) + + * bug #33834 [Validator] Fix ValidValidator group cascading usage (fancyweb) + * bug #33841 [VarDumper] fix dumping uninitialized SplFileInfo (nicolas-grekas) + * bug #33799 [Security]: Don't let falsy usernames slip through impersonation (j4nr6n) + * bug #33814 [HttpFoundation] Check if data passed to SessionBagProxy::initialize is an array (mynameisbogdan) + * bug #33805 [FrameworkBundle] Fix wrong returned status code in ConfigDebugCommand (jschaedl) + * bug #33781 [AnnotationCacheWarmer] add RedirectController to annotation cache (jenschude) + * bug #33777 Fix the :only-of-type pseudo class selector (jakzal) + * bug #32051 [Serializer] Add CsvEncoder tests for PHP 7.4 (ro0NL) + * feature #33776 Copy phpunit.xsd to a predictable path (julienfalque) + * bug #33759 [Security/Http] fix parsing X509 emailAddress (nicolas-grekas) + * bug #33733 [Serializer] fix denormalization of string-arrays with only one element (mkrauser) + * bug #33754 [Cache] fix known tag versions ttl check (SwenVanZanten) + * bug #33646 [HttpFoundation] allow additinal characters in not raw cookies (marie) + * bug #33748 [Console] Do not include hidden commands in suggested alternatives (m-vo) + * bug #33625 [DependencyInjection] Fix wrong exception when service is synthetic (k0d3r1s) + * bug #32522 [Validator] Accept underscores in the URL validator, as the URL will load (battye) + * bug #32437 Fix toolbar load when GET params are present in "_wdt" route (Molkobain) + * bug #32925 [Translation] Collect original locale in case of fallback translation (digilist) + * bug #31198 [FrameworkBundle] Fix framework bundle lock configuration not working as expected (HypeMC) + * bug #33719 [Cache] dont override native Memcached options (nicolas-grekas) + * bug #33675 [PhpUnit] Fix usleep mock return value (fabpot) + * bug #33618 fix tests depending on other components' tests (xabbuh) + * bug #33626 [PropertyInfo] ensure compatibility with type resolver 0.5 (xabbuh) + * bug #33620 [Twig] Fix Twig config extra keys (fabpot) + * bug #33571 [Inflector] add support 'see' to 'ee' for singularize 'fees' to 'fee' (maxhelias) + * bug #32763 [Console] Get dimensions from stty on windows if possible (rtek) + * bug #33518 [Yaml] don't dump a scalar tag value on its own line (xabbuh) + * bug #32818 [HttpKernel] Fix getFileLinkFormat() to avoid returning the wrong URL in Profiler (Arman-Hosseini) + * bug #33487 [HttpKernel] Fix Apache mod_expires Session Cache-Control issue (pbowyer) + * bug #33439 [Validator] Sync string to date behavior and throw a better exception (fancyweb) + * bug #32903 [PHPUnit Bridge] Avoid registering listener twice (alexpott) + * bug #33402 [Finder] Prevent unintentional file locks in Windows (jspringe) + * bug #33396 Fix #33395 PHP 5.3 compatibility (kylekatarnls) + * bug #33385 [Console] allow Command::getName() to return null (nicolas-grekas) + * bug #33353 Return null as Expire header if it was set to null (danrot) + * bug #33382 [ProxyManager] remove ProxiedMethodReturnExpression polyfill (nicolas-grekas) + * bug #33377 [Yaml] fix dumping not inlined scalar tag values (xabbuh) + * 3.4.31 (2019-08-26) * bug #33335 [DependencyInjection] Fixed the `getServiceIds` implementation to always return aliases (pdommelen) From fd683f05ea6ba923a760efb29d60ec65ef2dd812 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 7 Oct 2019 16:41:46 +0200 Subject: [PATCH 03/72] update CONTRIBUTORS for 3.4.32 --- CONTRIBUTORS.md | 110 ++++++++++++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 963f9e960293c..2cf905be32e88 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -6,36 +6,36 @@ Symfony is the result of the work of many people who made the code better - Fabien Potencier (fabpot) - Nicolas Grekas (nicolas-grekas) - - Bernhard Schussek (bschussek) - Christian Flothmann (xabbuh) + - Bernhard Schussek (bschussek) - Tobias Schultze (tobion) - Christophe Coevoet (stof) - Robin Chalas (chalas_r) - Jordi Boggiano (seldaek) - - Victor Berchet (victor) - Kévin Dunglas (dunglas) + - Victor Berchet (victor) - Maxime Steinhausser (ogizanagi) - Ryan Weaver (weaverryan) - Javier Eguiluz (javier.eguiluz) - - Jakub Zalas (jakubzalas) - Roland Franssen (ro0) + - Jakub Zalas (jakubzalas) - Johannes S (johannes) - - Kris Wallsmith (kriswallsmith) - Grégoire Pineau (lyrixx) + - Kris Wallsmith (kriswallsmith) - Hugo Hamon (hhamon) + - Yonel Ceruto (yonelceruto) - Abdellatif Ait boudad (aitboudad) - Samuel ROZE (sroze) - - Yonel Ceruto (yonelceruto) - Romain Neutron (romain) - Pascal Borreli (pborreli) - Wouter De Jong (wouterj) - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - Lukas Kahwe Smith (lsmith) + - Alexander M. Turek (derrabus) - Martin Hasoň (hason) - Hamza Amrouche (simperfit) - Jeremy Mikola (jmikola) - - Alexander M. Turek (derrabus) - Jean-François Simon (jfsimon) - Jules Pietri (heah) - Benjamin Eberlei (beberlei) @@ -44,21 +44,21 @@ Symfony is the result of the work of many people who made the code better - Eriksen Costa (eriksencosta) - Guilhem Niot (energetick) - Sarah Khalil (saro0h) + - Thomas Calvet (fancyweb) - Tobias Nyholm (tobias) - Jonathan Wage (jwage) - Lynn van der Berg (kjarli) - Diego Saint Esteben (dosten) - - Thomas Calvet (fancyweb) - Alexandre Salomé (alexandresalome) - William Durand (couac) - ornicar + - Pierre du Plessis (pierredup) - Dany Maillard (maidmaid) - Francis Besset (francisbesset) - stealth35 ‏ (stealth35) - Alexander Mols (asm89) - - Pierre du Plessis (pierredup) - - Matthias Pigulla (mpdude) - Konstantin Myakshin (koc) + - Matthias Pigulla (mpdude) - Bulat Shakirzyanov (avalanche123) - Grégoire Paris (greg0ire) - Saša Stamenković (umpirsky) @@ -69,13 +69,13 @@ Symfony is the result of the work of many people who made the code better - Miha Vrhovnik - Diego Saint Esteben (dii3g0) - Gábor Egyed (1ed) - - Konstantin Kudryashov (everzet) - Titouan Galopin (tgalopin) + - Konstantin Kudryashov (everzet) + - David Maicher (dmaicher) - Bilal Amarni (bamarni) - Mathieu Piot (mpiot) - - David Maicher (dmaicher) - - Florin Patan (florinpatan) - Gabriel Ostrolucký (gadelat) + - Florin Patan (florinpatan) - Vladimir Reznichenko (kalessil) - Jáchym Toušek (enumag) - Michel Weimerskirch (mweimerskirch) @@ -83,6 +83,7 @@ Symfony is the result of the work of many people who made the code better - Issei Murasawa (issei_m) - Eric Clemmons (ericclemmons) - Charles Sarrazin (csarrazi) + - Jan Schädlich (jschaedl) - Christian Raue - Arnout Boks (aboks) - Deni @@ -90,7 +91,6 @@ Symfony is the result of the work of many people who made the code better - Dariusz Górecki (canni) - Douglas Greenshields (shieldo) - David Buchmann (dbu) - - Jan Schädlich (jschaedl) - Dariusz Ruminski - Lee McDermott - Brandon Turner @@ -114,30 +114,30 @@ Symfony is the result of the work of many people who made the code better - Baptiste Clavié (talus) - marc.weistroff - Tomáš Votruba (tomas_votruba) + - Jérôme Vasseur (jvasseur) - lenar - Alexander Schwenn (xelaris) - Włodzimierz Gajda (gajdaw) - - Jérôme Vasseur (jvasseur) + - Sebastiaan Stok (sstok) + - Adrien Brault (adrienbrault) - Peter Kokot (maastermedia) - Jacob Dreesen (jdreesen) - Florian Voutzinos (florianv) - - Sebastiaan Stok (sstok) - Colin Frei - Javier Spagnoletti (phansys) - - Adrien Brault (adrienbrault) - Joshua Thijssen - Daniel Wehner (dawehner) - excelwebzone - Gordon Franke (gimler) + - Teoh Han Hui (teohhanhui) - Oskar Stark (oskarstark) + - Alex Pott - Fabien Pennequin (fabienpennequin) - Théo FIDRY (theofidry) - - Teoh Han Hui (teohhanhui) - Eric GELOEN (gelo) - Joel Wurtz (brouznouf) - Lars Strojny (lstrojny) - Tugdual Saunier (tucksaun) - - Alex Pott - Jannik Zschiesche (apfelbox) - Robert Schönthal (digitalkaoz) - Florian Lonqueu-Brochard (florianlb) @@ -152,6 +152,7 @@ Symfony is the result of the work of many people who made the code better - Daniel Gomes (danielcsgomes) - Hidenori Goto (hidenorigoto) - Andréia Bohner (andreia) + - Julien Falque (julienfalque) - Arnaud Kleinpeter (nanocom) - Guilherme Blanco (guilhermeblanco) - SpacePossum @@ -160,7 +161,6 @@ Symfony is the result of the work of many people who made the code better - François-Xavier de Guillebon (de-gui_f) - Oleg Voronkovich - Philipp Wahala (hifi) - - Julien Falque (julienfalque) - Rafael Dohms (rdohms) - jwdeitch - Mikael Pajunen @@ -172,6 +172,7 @@ Symfony is the result of the work of many people who made the code better - Richard Shank (iampersistent) - Thomas Rabaix (rande) - Vincent Touzet (vincenttouzet) + - Gregor Harlan (gharlan) - jeremyFreeAgent (jeremyfreeagent) - Rouven Weßling (realityking) - Alexander Schranz (alexander-schranz) @@ -193,6 +194,7 @@ Symfony is the result of the work of many people who made the code better - James Halsall (jaitsu) - Matthieu Napoli (mnapoli) - Florent Mata (fmata) + - Arman Hosseini - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) @@ -206,11 +208,11 @@ Symfony is the result of the work of many people who made the code better - Mario A. Alvarez Garcia (nomack84) - Dennis Benkert (denderello) - DQNEO - - Gregor Harlan (gharlan) + - mcfedr (mcfedr) - Gary PEGEOT (gary-p) - Ruben Gonzalez (rubenrua) - Benjamin Dulau (dbenjamin) - - Arman Hosseini + - Andreas Braun - Mathieu Lemoine (lemoinem) - Christian Schmidt - Andreas Hucks (meandmymonkey) @@ -241,7 +243,6 @@ Symfony is the result of the work of many people who made the code better - jeff - John Kary (johnkary) - Andreas Schempp (aschempp) - - Andreas Braun - Justin Hileman (bobthecow) - Blanchon Vincent (blanchonvincent) - Michele Orselli (orso) @@ -265,7 +266,6 @@ Symfony is the result of the work of many people who made the code better - julien pauli (jpauli) - Lorenz Schori - Sébastien Lavoie (lavoiesl) - - mcfedr (mcfedr) - Dariusz - Michael Babker (mbabker) - Francois Zaninotto @@ -314,12 +314,14 @@ Symfony is the result of the work of many people who made the code better - Jhonny Lidfors (jhonne) - Diego Agulló (aeoris) - jdhoek + - Maxime Helias (maxhelias) - David Prévot - Bob den Otter (bopp) - Thomas Schulz (king2500) - Frank de Jonge (frenkynet) - Nikita Konstantinov - Wodor Wodorski + - dFayet - Thomas Lallement (raziel057) - Colin O'Dell (colinodell) - Giorgio Premi @@ -343,6 +345,7 @@ Symfony is the result of the work of many people who made the code better - Christian Schmidt - Patrick Landolt (scube) - MatTheCat + - David Badura (davidbadura) - Chad Sikorra (chadsikorra) - Chris Smith (cs278) - Florian Klein (docteurklein) @@ -361,6 +364,7 @@ Symfony is the result of the work of many people who made the code better - Jerzy Zawadzki (jzawadzki) - Wouter J - Ismael Ambrosi (iambrosi) + - Ruud Kamphuis (ruudk) - Emmanuel BORGES (eborges78) - Aurelijus Valeiša (aurelijus) - Jan Decavele (jandc) @@ -374,7 +378,6 @@ Symfony is the result of the work of many people who made the code better - Francesc Rosàs (frosas) - Romain Pierre (romain-pierre) - Julien Galenski (ruian) - - Maxime Helias - Bongiraud Dominique - janschoenherr - Emanuele Gaspari (inmarelibero) @@ -382,7 +385,6 @@ Symfony is the result of the work of many people who made the code better - Berny Cantos (xphere81) - Thierry Thuon (lepiaf) - Ricard Clau (ricardclau) - - dFayet - Mark Challoner (markchalloner) - Gennady Telegin (gtelegin) - Erin Millard @@ -410,10 +412,10 @@ Symfony is the result of the work of many people who made the code better - Robbert Klarenbeek (robbertkl) - Eric Masoero (eric-masoero) - JhonnyL - - David Badura (davidbadura) - hossein zolfi (ocean) - Clément Gautier (clementgautier) - Thomas Bisignani (toma) + - Dāvis Zālītis (k0d3r1s) - Sanpi - Eduardo Gulias (egulias) - giulio de donato (liuggio) @@ -436,6 +438,7 @@ Symfony is the result of the work of many people who made the code better - Tamas Szijarto - Michele Locati - Pavel Volokitin (pvolok) + - Valentine Boineau (valentineboineau) - Arthur de Moulins (4rthem) - Matthias Althaus (althaus) - Nicolas Dewez (nicolas_dewez) @@ -447,13 +450,13 @@ Symfony is the result of the work of many people who made the code better - Joe Lencioni - Daniel Tschinder - vladimir.reznichenko - - Ruud Kamphuis (ruudk) - Kai - Lee Rowlands - Krzysztof Piasecki (krzysztek) - Maximilian Reichel (phramz) - Loick Piera (pyrech) - Alain Hippolyte (aloneh) + - Grenier Kévin (mcsky_biig) - Karoly Negyesi (chx) - Ivan Kurnosov - Xavier HAUSHERR @@ -481,9 +484,11 @@ Symfony is the result of the work of many people who made the code better - Jeanmonod David (jeanmonod) - Christopher Davis (chrisguitarguy) - Webnet team (webnet) + - Farhad Safarov - Jan Schumann - Niklas Fiekas - Markus Bachmann (baachi) + - Kévin THERAGE (kevin_therage) - lancergr - Mihai Stancu - Ivan Nikolaev (destillat) @@ -499,6 +504,7 @@ Symfony is the result of the work of many people who made the code better - EdgarPE - Florian Pfitzer (marmelatze) - Asier Illarramendi (doup) + - Sylvain Fabre (sylfabre) - Martijn Cuppens - Vlad Gregurco (vgregurco) - Maciej Malarz (malarzm) @@ -517,6 +523,7 @@ Symfony is the result of the work of many people who made the code better - Tobias Weichart - Gonzalo Vilaseca (gonzalovilaseca) - Marcin Sikoń (marphi) + - Tien Vo (tienvx) - Denis Brumann (dbrumann) - Dominik Zogg (dominik.zogg) - Marek Pietrzak @@ -533,6 +540,7 @@ Symfony is the result of the work of many people who made the code better - Anton Bakai - Martin Auswöger - Rhodri Pugh (rodnaph) + - battye - Sam Fleming (sam_fleming) - Alex Bakhturin - Patrick Reimers (preimers) @@ -606,7 +614,6 @@ Symfony is the result of the work of many people who made the code better - Nate (frickenate) - Timothée Barray (tyx) - jhonnyL - - Grenier Kévin (mcsky_biig) - sasezaki - Dawid Pakuła (zulusx) - Florian Rey (nervo) @@ -621,6 +628,7 @@ Symfony is the result of the work of many people who made the code better - Kevin Saliou (kbsali) - Shawn Iwinski - Gawain Lynch (gawain) + - mmokhi - NothingWeAre - Ryan - Alexander Deruwe (aderuwe) @@ -643,9 +651,11 @@ Symfony is the result of the work of many people who made the code better - Disquedur - Michiel Boeckaert (milio) - Geoffrey Tran (geoff) + - Kyle - Jan Behrens - Mantas Var (mvar) - Chris Tanaskoski + - Terje Bråten - Sebastian Krebs - Piotr Stankowski - Baptiste Leduc (bleduc) @@ -669,6 +679,7 @@ Symfony is the result of the work of many people who made the code better - Kyle Evans (kevans91) - Charles-Henri Bruyand - Max Rath (drak3) + - Oleg Andreyev - Stéphane Escandell (sescandell) - Konstantin S. M. Möllers (ksmmoellers) - James Johnston @@ -676,7 +687,6 @@ Symfony is the result of the work of many people who made the code better - Alexandre Dupuy (satchette) - Malte Blättermann - Desjardins Jérôme (jewome62) - - Kévin THERAGE (kevin_therage) - Simeon Kolev (simeon_kolev9) - Joost van Driel (j92) - Jonas Elfering @@ -693,7 +703,6 @@ Symfony is the result of the work of many people who made the code better - Gunnstein Lye (glye) - Maxime Douailin - Jean Pasdeloup (pasdeloup) - - Sylvain Fabre (sylfabre) - Benjamin Cremer (bcremer) - Javier López (loalf) - Reinier Kip @@ -712,6 +721,7 @@ Symfony is the result of the work of many people who made the code better - DerManoMann - Rostyslav Kinash - Dennis Fridrich (dfridrich) + - Mardari Dorel (dorumd) - Daisuke Ohata - Vincent Simonin - Alex Bogomazov (alebo) @@ -730,6 +740,7 @@ Symfony is the result of the work of many people who made the code better - Miquel Rodríguez Telep (mrtorrent) - Sergey Kolodyazhnyy (skolodyazhnyy) - umpirski + - M. Vondano - Quentin de Longraye (quentinus95) - Chris Heng (gigablah) - Shaun Simmons (simshaun) @@ -750,7 +761,7 @@ Symfony is the result of the work of many people who made the code better - Kristijan Kanalas - Stephan Vock - Benjamin Zikarsky (bzikarsky) - - battye + - Ruben Jacobs (rubenj) - Simon Schick (simonsimcity) - redstar504 - Tristan Roussel @@ -799,6 +810,7 @@ Symfony is the result of the work of many people who made the code better - Indra Gunawan (guind) - Peter Ward - Davide Borsatto (davide.borsatto) + - Markus Fasselt (digilist) - Julien DIDIER (juliendidier) - Dominik Ritter (dritter) - Sebastian Grodzicki (sgrodzicki) @@ -935,7 +947,6 @@ Symfony is the result of the work of many people who made the code better - Benoît Bourgeois - mantulo - Stefan Kruppa - - mmokhi - corphi - JoppeDC - grizlik @@ -1005,10 +1016,8 @@ Symfony is the result of the work of many people who made the code better - Pablo Lozano (arkadis) - Erik Saunier (snickers) - Rootie - - Kyle - Daniel Alejandro Castro Arellano (lexcast) - sensio - - Terje Bråten - Thomas Jarrand - Antoine Bluchet (soyuka) - Sebastien Morel (plopix) @@ -1031,7 +1040,6 @@ Symfony is the result of the work of many people who made the code better - The Whole Life to Learn - Mikkel Paulson - ergiegonzaga - - Farhad Safarov - Liverbool (liverbool) - Sam Malone - Phan Thanh Ha (haphan) @@ -1039,7 +1047,9 @@ Symfony is the result of the work of many people who made the code better - neghmurken - xaav - Mahmoud Mostafa (mahmoud) + - Julien Turby - Ahmed Abdou + - Daniel Iwaniec - Pieter - Michael Tibben - Billie Thompson @@ -1115,6 +1125,7 @@ Symfony is the result of the work of many people who made the code better - Chris Tiearney - Oliver Hoff - Ole Rößner (basster) + - rtek - Faton (notaf) - Tom Houdmont - Per Sandström (per) @@ -1133,6 +1144,7 @@ Symfony is the result of the work of many people who made the code better - ilyes kooli - gr1ev0us - mlazovla + - Alejandro Diaz Torres - Max Beutel - Antanas Arvasevicius - Pierre Dudoret @@ -1152,6 +1164,7 @@ Symfony is the result of the work of many people who made the code better - Ken Marfilla (marfillaster) - benatespina (benatespina) - Denis Kop + - HypeMC - Jean-Guilhem Rouel (jean-gui) - jfcixmedia - Dominic Tubach @@ -1167,6 +1180,7 @@ Symfony is the result of the work of many people who made the code better - Soner Sayakci - hugofonseca (fonsecas72) - Marc Duboc (icemad) + - Matthias Krauser (mkrauser) - Martynas Narbutas - Toon Verwerft (veewee) - Bailey Parker @@ -1216,6 +1230,7 @@ Symfony is the result of the work of many people who made the code better - Mathias STRASSER (roukmoute) - Thomason, James - Gordienko Vladislav + - marie - Viacheslav Sychov - Alexandre Quercia (alquerci) - Helmut Hummel (helhum) @@ -1307,8 +1322,8 @@ Symfony is the result of the work of many people who made the code better - Ilia (aliance) - Chris McCafferty (cilefen) - Mo Di (modi) - - Tien Vo (tienvx) - Pablo Schläpfer + - SuRiKmAn - Gert de Pagter - Jelte Steijaert (jelte) - David Négrier (moufmouf) @@ -1319,11 +1334,13 @@ Symfony is the result of the work of many people who made the code better - Alex Vasilchenko - sez-open - Xavier Coureau + - fruty - ConneXNL - Aharon Perkel - matze - Rubén Calvo (rubencm) - Abdul.Mohsen B. A. A + - Swen van Zanten - Benoît Burnichon - pthompson - Malaney J. Hill @@ -1360,6 +1377,7 @@ Symfony is the result of the work of many people who made the code better - sl_toto (sl_toto) - Walter Dal Mut (wdalmut) - abluchet + - Ruud Arentsen - Matthieu - Albin Kerouaton - Sébastien HOUZÉ @@ -1385,11 +1403,11 @@ Symfony is the result of the work of many people who made the code better - Constantine Shtompel - Jules Lamur - Renato Mendes Figueiredo + - pdommelen - Eric Stern - ShiraNai7 - Cedrick Oka - Antal Áron (antalaron) - - Markus Fasselt (digilist) - Vašek Purchart (vasek-purchart) - Janusz Jabłoński (yanoosh) - Fleuv @@ -1408,6 +1426,7 @@ Symfony is the result of the work of many people who made the code better - Andreas Frömer - Philip Frank - Lance McNearney + - Jeroen Spee (jeroens) - Giorgio Premi - ncou - Ian Carroll @@ -1420,6 +1439,7 @@ Symfony is the result of the work of many people who made the code better - Luis Galeas - Martin Pärtel - Bastien Jaillot (bastnic) + - Daniel Rotter (danrot) - Frédéric Bouchery (fbouchery) - Patrick Daley (padrig) - Xavier Briand (xavierbriand) @@ -1440,7 +1460,6 @@ Symfony is the result of the work of many people who made the code better - Daniel González Zaballos (dem3trio) - Emmanuel Vella (emmanuel.vella) - Guillaume BRETOU (guiguiboy) - - Dāvis Zālītis (k0d3r1s) - Carsten Nielsen (phreaknerd) - Roger Guasch (rogerguasch) - Jay Severson @@ -1559,6 +1578,7 @@ Symfony is the result of the work of many people who made the code better - povilas - Gavin Staniforth - Alessandro Tagliapietra (alex88) + - Andy Palmer (andyexeter) - Biji (biji) - Jérôme Tanghe (deuchnord) - Alex Teterin (errogaht) @@ -1606,7 +1626,6 @@ Symfony is the result of the work of many people who made the code better - Jibé Barth (jibbarth) - Matthew Foster (mfoster) - Reyo Stallenberg (reyostallenberg) - - Ruben Jacobs (rubenj) - Paul Seiffert (seiffert) - Vasily Khayrulin (sirian) - Stefan Koopmanschap (skoop) @@ -1648,6 +1667,7 @@ Symfony is the result of the work of many people who made the code better - Peter Bex - Manatsawin Hanmongkolchai - Gunther Konig + - Joe Springe - Mickael GOETZ - Maciej Schmidt - Dennis Væversted @@ -1677,12 +1697,12 @@ Symfony is the result of the work of many people who made the code better - me_shaon - 蝦米 - Grayson Koonce (breerly) - - Mardari Dorel (dorumd) - Andrey Helldar (helldar) - Karim Cassam Chenaï (ka) - Maksym Slesarenko (maksym_slesarenko) - Michal Kurzeja (mkurzeja) - Nicolas Bastien (nicolas_bastien) + - Peter Bowyer (pbowyer) - Nikola Svitlica (thecelavi) - Denis (yethee) - Andrew Zhilin (zhil) @@ -1760,7 +1780,6 @@ Symfony is the result of the work of many people who made the code better - Yannick Warnier (ywarnier) - Kevin Decherf - Jason Woods - - Oleg Andreyev - klemens - dened - Dmitry Korotovsky @@ -1777,6 +1796,7 @@ Symfony is the result of the work of many people who made the code better - taiiiraaa - Trevor Suarez - gedrox + - Bohan Yang - Alan Bondarchuk - Joe Bennett - dropfen @@ -1810,6 +1830,7 @@ Symfony is the result of the work of many people who made the code better - Jan Marek (janmarek) - Mark de Haan (markdehaan) - Dan Patrick (mdpatrick) + - Geoffrey Monte (numerogeek) - Pedro Magalhães (pmmaga) - Rares Vlaseanu (raresvla) - tante kinast (tante) @@ -1907,6 +1928,7 @@ Symfony is the result of the work of many people who made the code better - hainey - Juan M Martínez - Gilles Gauthier + - Pavinthan - ddebree - Kuba Werłos - Gyula Szucs @@ -2032,11 +2054,13 @@ Symfony is the result of the work of many people who made the code better - jc - BenjaminBeck - Aurelijus Rožėnas + - Beno!t POLASZEK - Jordan Hoff - znerol - Christian Eikermann - Kai Eichinger - Antonio Angelino + - Jens Schulze - Matt Fields - Niklas Keller - Andras Debreczeni @@ -2115,6 +2139,7 @@ Symfony is the result of the work of many people who made the code better - Lebnik - nsbx - Shude + - Richard Hodgson - Ondřej Führer - Sema - Elan Ruusamäe @@ -2134,6 +2159,7 @@ Symfony is the result of the work of many people who made the code better - Benjamin Long - Ben Miller - Peter Gribanov + - Matteo Galli - kwiateusz - jspee - Ilya Bulakh @@ -2172,6 +2198,7 @@ Symfony is the result of the work of many people who made the code better - Lin Lu - arduanov - sualko + - Molkobain - Bilge - ADmad - Nicolas Roudaire @@ -2282,6 +2309,7 @@ Symfony is the result of the work of many people who made the code better - Wouter Sioen (wouter_sioen) - Xavier Amado (xamado) - Jesper Søndergaard Pedersen (zerrvox) + - Alexander Menshchikov (zmey_kk) - Florent Cailhol - szymek - Kovacs Nicolas From 83b90c2e003c460db7407829484a0c85f28f8043 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 7 Oct 2019 16:41:56 +0200 Subject: [PATCH 04/72] updated VERSION for 3.4.32 --- 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 8ad08b9c7de77..2f6a6e4612e68 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.32-DEV'; + const VERSION = '3.4.32'; const VERSION_ID = 30432; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; const RELEASE_VERSION = 32; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From e3624e7086ba300c5043bd5cec981a00975b4129 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 7 Oct 2019 16:51:28 +0200 Subject: [PATCH 05/72] bumped Symfony version to 3.4.33 --- 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 2f6a6e4612e68..325ef4d443c61 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.32'; - const VERSION_ID = 30432; + const VERSION = '3.4.33-DEV'; + const VERSION_ID = 30433; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; - const RELEASE_VERSION = 32; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 33; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From a4f90e8258e285dbca3b2122ef059000ec5ca8d8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 7 Oct 2019 17:19:44 +0200 Subject: [PATCH 06/72] bumped Symfony version to 4.3.6 --- 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 7d18d221d5c18..cf789426e37ee 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 $requestStackSize = 0; private $resetServices = false; - const VERSION = '4.3.5'; - const VERSION_ID = 40305; + const VERSION = '4.3.6-DEV'; + const VERSION_ID = 40306; const MAJOR_VERSION = 4; const MINOR_VERSION = 3; - const RELEASE_VERSION = 5; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 6; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '01/2020'; const END_OF_LIFE = '07/2020'; From 0db883888c8ad1a17a0141b307f546fff5541328 Mon Sep 17 00:00:00 2001 From: Ogbemudia Terry Osayawe Date: Mon, 7 Oct 2019 17:36:51 +0200 Subject: [PATCH 07/72] Add the missing translations for the Swedish ("sv") locale --- .../Resources/translations/validators.sv.xlf | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.sv.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.sv.xlf index b3e8f0f42f124..bf7da2f06c907 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.sv.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.sv.xlf @@ -334,6 +334,38 @@ This value should be valid JSON. Detta värde ska vara giltig JSON. + + This collection should contain only unique elements. + Denna samling bör endast innehålla unika element. + + + This value should be positive. + Detta värde bör vara positivt. + + + This value should be either positive or zero. + Detta värde bör vara antingen positivt eller noll. + + + This value should be negative. + Detta värde bör vara negativt. + + + This value should be either negative or zero. + Detta värde bör vara antingen negativt eller noll. + + + This value is not a valid timezone. + Detta värde är inte en giltig tidszon. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Det här lösenordet har läckt ut vid ett dataintrång, det får inte användas. Använd ett annat lösenord. + + + This value should be between {{ min }} and {{ max }}. + Detta värde bör ligga mellan {{ min }} och {{ max }}. + From ca3fb258bf9665cbac08c635e3f8619a03f64226 Mon Sep 17 00:00:00 2001 From: bogdan Date: Tue, 8 Oct 2019 04:19:00 +0300 Subject: [PATCH 08/72] [HttpKernel] fix $dotenvVars in data collector --- .../HttpKernel/DataCollector/RequestDataCollector.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index 32624c963fa07..3f6150ba9fddf 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -80,9 +80,9 @@ public function collect(Request $request, Response $response, \Exception $except } $dotenvVars = []; - foreach (explode(',', getenv('SYMFONY_DOTENV_VARS')) as $name) { - if ('' !== $name && false !== $value = getenv($name)) { - $dotenvVars[$name] = $value; + foreach (explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? $_ENV['SYMFONY_DOTENV_VARS'] ?? '') as $name) { + if ('' !== $name && isset($_ENV[$name])) { + $dotenvVars[$name] = $_ENV[$name]; } } From 5baa3ea8d4e6ec99d9813df3dfd47cca8e598726 Mon Sep 17 00:00:00 2001 From: Harald Tollefsen Date: Tue, 8 Oct 2019 11:13:14 +0200 Subject: [PATCH 09/72] Adds missing translations for no nb --- .../Resources/translations/validators.nb.xlf | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf index db534528d1d99..bfa9b1284e8d9 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.nb.xlf @@ -334,6 +334,38 @@ This value should be valid JSON. Verdien er ikke gyldig JSON. + + This collection should contain only unique elements. + Samlingen kan kun inneholde unike elementer. + + + This value should be positive. + Denne verdien må være positiv. + + + This value should be either positive or zero. + Denne verdien må være positiv eller null. + + + This value should be negative. + Denne verdien må være negativ. + + + This value should be either negative or zero. + Denne verdien må være negativ eller null. + + + This value is not a valid timezone. + Verdien er ikke en gyldig tidssone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Dette passordet er lekket i et datainnbrudd, det må ikke tas i bruk. Vennligst bruk et annet passord. + + + This value should be between {{ min }} and {{ max }}. + Verdien må være mellom {{ min }} og {{ max }}. + From 1f20f35f74df7c657ca648efb87755416427da82 Mon Sep 17 00:00:00 2001 From: zcodes Date: Wed, 9 Oct 2019 10:12:52 +0800 Subject: [PATCH 10/72] [VarDumper] fix array key error for class SymfonyCaster --- src/Symfony/Component/VarDumper/Caster/SymfonyCaster.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Caster/SymfonyCaster.php b/src/Symfony/Component/VarDumper/Caster/SymfonyCaster.php index 78acb90b66a68..bd8b595a3dc02 100644 --- a/src/Symfony/Component/VarDumper/Caster/SymfonyCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/SymfonyCaster.php @@ -30,7 +30,8 @@ public static function castRequest(Request $request, array $a, Stub $stub, $isNe $clone = null; foreach (self::$requestGetters as $prop => $getter) { - if (null === $a[Caster::PREFIX_PROTECTED.$prop]) { + $key = Caster::PREFIX_PROTECTED.$prop; + if (\array_key_exists($key, $a) && null === $a[$key]) { if (null === $clone) { $clone = clone $request; } @@ -44,7 +45,9 @@ public static function castRequest(Request $request, array $a, Stub $stub, $isNe public static function castHttpClient($client, array $a, Stub $stub, $isNested) { $multiKey = sprintf("\0%s\0multi", \get_class($client)); - $a[$multiKey] = new CutStub($a[$multiKey]); + if (isset($a[$multiKey])) { + $a[$multiKey] = new CutStub($a[$multiKey]); + } return $a; } From eec7e8cc61f3a9adec9ce6741d6ff94a78b94691 Mon Sep 17 00:00:00 2001 From: Yannick Ihmels Date: Wed, 9 Oct 2019 11:59:43 +0200 Subject: [PATCH 11/72] Allow to set cookie_samesite to 'none' --- .../FrameworkBundle/DependencyInjection/Configuration.php | 2 +- .../DependencyInjection/Security/Factory/RememberMeFactory.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 6d6195bbc9956..497fb08424712 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -542,7 +542,7 @@ private function addSessionSection(ArrayNodeDefinition $rootNode) ->scalarNode('cookie_domain')->end() ->enumNode('cookie_secure')->values([true, false, 'auto'])->end() ->booleanNode('cookie_httponly')->defaultTrue()->end() - ->enumNode('cookie_samesite')->values([null, Cookie::SAMESITE_LAX, Cookie::SAMESITE_STRICT])->defaultNull()->end() + ->enumNode('cookie_samesite')->values([null, Cookie::SAMESITE_LAX, Cookie::SAMESITE_STRICT, Cookie::SAMESITE_NONE])->defaultNull()->end() ->booleanNode('use_cookies')->end() ->scalarNode('gc_divisor')->end() ->scalarNode('gc_probability')->defaultValue(1)->end() diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php index f7500f05e3b9f..28103a3522542 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php @@ -144,7 +144,7 @@ public function addConfiguration(NodeDefinition $node) if ('secure' === $name) { $builder->enumNode($name)->values([true, false, 'auto'])->defaultValue('auto' === $value ? null : $value); } elseif ('samesite' === $name) { - $builder->enumNode($name)->values([null, Cookie::SAMESITE_LAX, Cookie::SAMESITE_STRICT])->defaultValue($value); + $builder->enumNode($name)->values([null, Cookie::SAMESITE_LAX, Cookie::SAMESITE_STRICT, Cookie::SAMESITE_NONE])->defaultValue($value); } elseif (\is_bool($value)) { $builder->booleanNode($name)->defaultValue($value); } else { From 85f27f270e5b113b84fa7476444e4a5c8149253f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 9 Oct 2019 11:02:41 +0200 Subject: [PATCH 12/72] [Cache] remove implicit dependency on symfony/filesystem --- .../Adapter/FilesystemTagAwareAdapter.php | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php index 0dd81a99704ed..899e570ef6a36 100644 --- a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php @@ -16,7 +16,6 @@ use Symfony\Component\Cache\Marshaller\MarshallerInterface; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\Traits\FilesystemTrait; -use Symfony\Component\Filesystem\Filesystem; /** * Stores tag id <> cache id relationship as a symlink, and lookup on invalidation calls. @@ -29,8 +28,8 @@ class FilesystemTagAwareAdapter extends AbstractTagAwareAdapter implements PruneableInterface { use FilesystemTrait { - doSave as doSaveCache; - doDelete as doDeleteCache; + doSave as private doSaveCache; + doDelete as private doDeleteCache; } /** @@ -38,11 +37,6 @@ class FilesystemTagAwareAdapter extends AbstractTagAwareAdapter implements Prune */ private const TAG_FOLDER = 'tags'; - /** - * @var Filesystem|null - */ - private $fs; - public function __construct(string $namespace = '', int $defaultLifetime = 0, string $directory = null, MarshallerInterface $marshaller = null) { $this->marshaller = $marshaller ?? new DefaultMarshaller(); @@ -57,7 +51,6 @@ protected function doSave(array $values, ?int $lifetime, array $addTagData = [], { $failed = $this->doSaveCache($values, $lifetime); - $fs = $this->getFilesystem(); // Add Tags as symlinks foreach ($addTagData as $tagId => $ids) { $tagFolder = $this->getTagFolder($tagId); @@ -67,12 +60,15 @@ protected function doSave(array $values, ?int $lifetime, array $addTagData = [], } $file = $this->getFile($id); - $fs->symlink($file, $this->getFile($id, true, $tagFolder)); + + if (!@symlink($file, $this->getFile($id, true, $tagFolder))) { + @unlink($file); + $failed[] = $id; + } } } // Unlink removed Tags - $files = []; foreach ($removeTagData as $tagId => $ids) { $tagFolder = $this->getTagFolder($tagId); foreach ($ids as $id) { @@ -80,10 +76,9 @@ protected function doSave(array $values, ?int $lifetime, array $addTagData = [], continue; } - $files[] = $this->getFile($id, false, $tagFolder); + @unlink($this->getFile($id, false, $tagFolder)); } } - $fs->remove($files); return $failed; } @@ -96,15 +91,12 @@ protected function doDelete(array $ids, array $tagData = []): bool $ok = $this->doDeleteCache($ids); // Remove tags - $files = []; - $fs = $this->getFilesystem(); foreach ($tagData as $tagId => $idMap) { $tagFolder = $this->getTagFolder($tagId); foreach ($idMap as $id) { - $files[] = $this->getFile($id, false, $tagFolder); + @unlink($this->getFile($id, false, $tagFolder)); } } - $fs->remove($files); return $ok; } @@ -137,11 +129,6 @@ protected function doInvalidate(array $tagIds): bool return true; } - private function getFilesystem(): Filesystem - { - return $this->fs ?? $this->fs = new Filesystem(); - } - private function getTagFolder(string $tagId): string { return $this->getFile($tagId, false, $this->directory.self::TAG_FOLDER.\DIRECTORY_SEPARATOR).\DIRECTORY_SEPARATOR; From b377e41a2c7c11d2bf4e2a077b78b781d542af71 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 9 Oct 2019 14:17:28 +0200 Subject: [PATCH 13/72] [Cache] clean tags folder on invalidation --- .../Adapter/FilesystemTagAwareAdapter.php | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php index 0dd81a99704ed..077f754aa5ba7 100644 --- a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Cache\Adapter; -use Symfony\Component\Cache\Exception\LogicException; use Symfony\Component\Cache\Marshaller\DefaultMarshaller; use Symfony\Component\Cache\Marshaller\MarshallerInterface; use Symfony\Component\Cache\PruneableInterface; @@ -115,22 +114,39 @@ protected function doDelete(array $ids, array $tagData = []): bool protected function doInvalidate(array $tagIds): bool { foreach ($tagIds as $tagId) { - $tagsFolder = $this->getTagFolder($tagId); - if (!file_exists($tagsFolder)) { + if (!file_exists($tagsFolder = $this->getTagFolder($tagId))) { continue; } - foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($tagsFolder, \FilesystemIterator::SKIP_DOTS)) as $itemLink) { - if (!$itemLink->isLink()) { - throw new LogicException('Expected a (sym)link when iterating over tag folder, non link found: '.$itemLink); + set_error_handler(static function () {}); + + try { + if (rename($tagsFolder, $renamed = substr_replace($tagsFolder, bin2hex(random_bytes(4)), -1))) { + $tagsFolder = $renamed.\DIRECTORY_SEPARATOR; + } else { + $renamed = null; + } + + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($tagsFolder, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_PATHNAME)) as $itemLink) { + unlink(realpath($itemLink) ?: $itemLink); + unlink($itemLink); } - $valueFile = $itemLink->getRealPath(); - if ($valueFile && file_exists($valueFile)) { - @unlink($valueFile); + if (null === $renamed) { + continue; } - @unlink((string) $itemLink); + $chars = '+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + + for ($i = 0; $i < 38; ++$i) { + for ($j = 0; $j < 38; ++$j) { + rmdir($tagsFolder.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j]); + } + rmdir($tagsFolder.$chars[$i]); + } + rmdir($renamed); + } finally { + restore_error_handler(); } } From 20fd92571e4002449967563122dbe98415da4381 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 9 Oct 2019 15:27:34 +0200 Subject: [PATCH 14/72] [Cache] cs fix --- .../Cache/Adapter/FilesystemTagAwareAdapter.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php index 23f507bfde905..67801e8ab9cc7 100644 --- a/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/FilesystemTagAwareAdapter.php @@ -106,20 +106,20 @@ protected function doDelete(array $ids, array $tagData = []): bool protected function doInvalidate(array $tagIds): bool { foreach ($tagIds as $tagId) { - if (!file_exists($tagsFolder = $this->getTagFolder($tagId))) { + if (!file_exists($tagFolder = $this->getTagFolder($tagId))) { continue; } set_error_handler(static function () {}); try { - if (rename($tagsFolder, $renamed = substr_replace($tagsFolder, bin2hex(random_bytes(4)), -1))) { - $tagsFolder = $renamed.\DIRECTORY_SEPARATOR; + if (rename($tagFolder, $renamed = substr_replace($tagFolder, bin2hex(random_bytes(4)), -1))) { + $tagFolder = $renamed.\DIRECTORY_SEPARATOR; } else { $renamed = null; } - foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($tagsFolder, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_PATHNAME)) as $itemLink) { + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($tagFolder, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_PATHNAME)) as $itemLink) { unlink(realpath($itemLink) ?: $itemLink); unlink($itemLink); } @@ -132,9 +132,9 @@ protected function doInvalidate(array $tagIds): bool for ($i = 0; $i < 38; ++$i) { for ($j = 0; $j < 38; ++$j) { - rmdir($tagsFolder.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j]); + rmdir($tagFolder.$chars[$i].\DIRECTORY_SEPARATOR.$chars[$j]); } - rmdir($tagsFolder.$chars[$i]); + rmdir($tagFolder.$chars[$i]); } rmdir($renamed); } finally { From 31fcf93253168df12d325e95598656158722209f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 9 Oct 2019 16:33:48 +0200 Subject: [PATCH 15/72] [Validator] sync NO and NB translations --- .../Resources/translations/validators.no.xlf | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.no.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.no.xlf index db534528d1d99..bfa9b1284e8d9 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.no.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.no.xlf @@ -334,6 +334,38 @@ This value should be valid JSON. Verdien er ikke gyldig JSON. + + This collection should contain only unique elements. + Samlingen kan kun inneholde unike elementer. + + + This value should be positive. + Denne verdien må være positiv. + + + This value should be either positive or zero. + Denne verdien må være positiv eller null. + + + This value should be negative. + Denne verdien må være negativ. + + + This value should be either negative or zero. + Denne verdien må være negativ eller null. + + + This value is not a valid timezone. + Verdien er ikke en gyldig tidssone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Dette passordet er lekket i et datainnbrudd, det må ikke tas i bruk. Vennligst bruk et annet passord. + + + This value should be between {{ min }} and {{ max }}. + Verdien må være mellom {{ min }} og {{ max }}. + From aff4e56fc5458ee13a2baffc422597552e916c4a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 9 Oct 2019 18:19:03 +0200 Subject: [PATCH 16/72] [HttpClient] send `Accept: */*` by default, fix removing it when needed --- .../Component/HttpClient/CurlHttpClient.php | 4 +-- .../Component/HttpClient/HttpClientTrait.php | 2 +- .../HttpClient/Tests/HttpClientTestCase.php | 28 +++++++++++++++++++ .../HttpClient/Tests/HttpClientTraitTest.php | 2 +- .../HttpClient/Tests/MockHttpClientTest.php | 7 +++++ 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 83413a23edf45..471f694b4e89f 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -220,7 +220,7 @@ public function request(string $method, string $url, array $options = []): Respo // Prevent curl from sending its default Accept and Expect headers foreach (['accept', 'expect'] as $header) { - if (!isset($options['normalized_headers'][$header])) { + if (!isset($options['normalized_headers'][$header][0])) { $curlopts[CURLOPT_HTTPHEADER][] = $header.':'; } } @@ -413,7 +413,7 @@ private static function createRedirectResolver(array $options, string $host): \C return 0 !== stripos($h, 'Host:'); }); - if (isset($options['normalized_headers']['authorization']) || isset($options['normalized_headers']['cookie'])) { + if (isset($options['normalized_headers']['authorization'][0]) || isset($options['normalized_headers']['cookie'][0])) { $redirectHeaders['no_auth'] = array_filter($options['headers'], static function ($h) { return 0 !== stripos($h, 'Authorization:') && 0 !== stripos($h, 'Cookie:'); }); diff --git a/src/Symfony/Component/HttpClient/HttpClientTrait.php b/src/Symfony/Component/HttpClient/HttpClientTrait.php index 3fd9814df68f0..ab5f3502f7c00 100644 --- a/src/Symfony/Component/HttpClient/HttpClientTrait.php +++ b/src/Symfony/Component/HttpClient/HttpClientTrait.php @@ -57,7 +57,7 @@ private static function prepareRequest(?string $method, ?string $url, array $opt } if (!isset($options['normalized_headers']['accept'])) { - $options['normalized_headers']['accept'] = [$options['headers'][] = 'Accept: *']; + $options['normalized_headers']['accept'] = [$options['headers'][] = 'Accept: */*']; } if (isset($options['body'])) { diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php index 3d5a70a0a96e5..bc836a7fade1b 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php +++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php @@ -19,4 +19,32 @@ public function testMaxDuration() { $this->markTestSkipped('Implemented as of version 4.4'); } + + public function testAcceptHeader() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://localhost:8057'); + $requestHeaders = $response->toArray(); + + $this->assertSame('*/*', $requestHeaders['HTTP_ACCEPT']); + + $response = $client->request('GET', 'http://localhost:8057', [ + 'headers' => [ + 'Accept' => 'foo/bar', + ], + ]); + $requestHeaders = $response->toArray(); + + $this->assertSame('foo/bar', $requestHeaders['HTTP_ACCEPT']); + + $response = $client->request('GET', 'http://localhost:8057', [ + 'headers' => [ + 'Accept' => null, + ], + ]); + $requestHeaders = $response->toArray(); + + $this->assertArrayNotHasKey('HTTP_ACCEPT', $requestHeaders); + } } diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php index 559f2b62270df..e1636a5d5f84d 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php +++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php @@ -172,7 +172,7 @@ public function provideRemoveDotSegments() public function testAuthBearerOption() { [, $options] = self::prepareRequest('POST', 'http://example.com', ['auth_bearer' => 'foobar'], HttpClientInterface::OPTIONS_DEFAULTS); - $this->assertSame(['Accept: *', 'Authorization: Bearer foobar'], $options['headers']); + $this->assertSame(['Accept: */*', 'Authorization: Bearer foobar'], $options['headers']); $this->assertSame(['Authorization: Bearer foobar'], $options['normalized_headers']['authorization']); } diff --git a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php index 8a3936b442f7a..32b4ebe4485a1 100644 --- a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php @@ -36,6 +36,7 @@ protected function getHttpClient(string $testCase): HttpClientInterface "SERVER_NAME": "127.0.0.1", "REQUEST_URI": "/", "REQUEST_METHOD": "GET", + "HTTP_ACCEPT": "*/*", "HTTP_FOO": "baR", "HTTP_HOST": "localhost:8057" }'; @@ -113,6 +114,12 @@ protected function getHttpClient(string $testCase): HttpClientInterface $responses[] = $mock; break; + case 'testAcceptHeader': + $responses[] = new MockResponse($body, ['response_headers' => $headers]); + $responses[] = new MockResponse(str_replace('*/*', 'foo/bar', $body), ['response_headers' => $headers]); + $responses[] = new MockResponse(str_replace('"HTTP_ACCEPT": "*/*",', '', $body), ['response_headers' => $headers]); + break; + case 'testResolve': $responses[] = new MockResponse($body, ['response_headers' => $headers]); $responses[] = new MockResponse($body, ['response_headers' => $headers]); From a1f334c1b7160f9aac070abef1ead8910f2946ba Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 9 Oct 2019 19:31:25 +0200 Subject: [PATCH 17/72] [Cache] ignore unserialization failures in AbstractTagAwareAdapter::doDelete() --- .../Cache/Adapter/AbstractTagAwareAdapter.php | 10 +++++++--- .../Component/Cache/Adapter/RedisTagAwareAdapter.php | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php index 5e535e51fcb4b..13a4968ac596d 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractTagAwareAdapter.php @@ -229,10 +229,14 @@ public function deleteItems(array $keys) unset($this->deferred[$key]); } - foreach ($this->doFetch($ids) as $id => $value) { - foreach ($value['tags'] ?? [] as $tag) { - $tagData[$this->getId(self::TAGS_PREFIX.$tag)][] = $id; + try { + foreach ($this->doFetch($ids) as $id => $value) { + foreach ($value['tags'] ?? [] as $tag) { + $tagData[$this->getId(self::TAGS_PREFIX.$tag)][] = $id; + } } + } catch (\Exception $e) { + // ignore unserialization failures } try { diff --git a/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php index 3bc5d84b62eab..b83b09b013dee 100644 --- a/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php @@ -97,7 +97,7 @@ protected function doSave(array $values, ?int $lifetime, array $addTagData = [], } // While pipeline isn't supported on RedisCluster, other setups will at least benefit from doing this in one op - $results = $this->pipeline(static function () use ($serialized, $lifetime, $addTagData, $delTagData) { + $results = $this->pipeline(static function () use ($serialized, $lifetime, $addTagData, $delTagData, $failed) { // Store cache items, force a ttl if none is set, as there is no MSETEX we need to set each one foreach ($serialized as $id => $value) { yield 'setEx' => [ @@ -109,11 +109,15 @@ protected function doSave(array $values, ?int $lifetime, array $addTagData = [], // Add and Remove Tags foreach ($addTagData as $tagId => $ids) { - yield 'sAdd' => array_merge([$tagId], $ids); + if (!$failed || $ids = array_diff($ids, $failed)) { + yield 'sAdd' => array_merge([$tagId], $ids); + } } foreach ($delTagData as $tagId => $ids) { - yield 'sRem' => array_merge([$tagId], $ids); + if (!$failed || $ids = array_diff($ids, $failed)) { + yield 'sRem' => array_merge([$tagId], $ids); + } } }); From 6af04bbac6f65739c00f8e16f4ec975f29f924de Mon Sep 17 00:00:00 2001 From: Vladimir Reznichenko Date: Wed, 9 Oct 2019 21:00:06 +0200 Subject: [PATCH 18/72] SCA: added missing break in a loop --- src/Symfony/Component/Cache/Traits/MemcachedTrait.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php index 999687de99fd4..28046e475bb9d 100644 --- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php +++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php @@ -249,6 +249,7 @@ protected function doDelete(array $ids) foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) { if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) { $ok = false; + break; } } From d2a8e94c79b4d05b18c7ee0c246647647c1d8e2b Mon Sep 17 00:00:00 2001 From: detinkin <48881722+detinkin@users.noreply.github.com> Date: Wed, 9 Oct 2019 20:18:55 +0300 Subject: [PATCH 19/72] Missing argument in method_exists --- src/Symfony/Component/HttpClient/HttpClientTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpClient/HttpClientTrait.php b/src/Symfony/Component/HttpClient/HttpClientTrait.php index ab5f3502f7c00..2914ab20b6022 100644 --- a/src/Symfony/Component/HttpClient/HttpClientTrait.php +++ b/src/Symfony/Component/HttpClient/HttpClientTrait.php @@ -196,7 +196,7 @@ private static function normalizeHeaders(array $headers): array $normalizedHeaders = []; foreach ($headers as $name => $values) { - if (\is_object($values) && method_exists('__toString')) { + if (\is_object($values) && method_exists($values, '__toString')) { $values = (string) $values; } From 21645a5b96dda40070c1555496ede2cb7bd0e213 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 Oct 2019 13:03:19 +0200 Subject: [PATCH 20/72] [VarDumper] fix resetting the "bold" state in CliDumper --- src/Symfony/Component/VarDumper/Dumper/CliDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php index 2bd347d96a53e..946df78257bae 100644 --- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php @@ -28,7 +28,7 @@ class CliDumper extends AbstractDumper protected $maxStringWidth = 0; protected $styles = [ // See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics - 'default' => '38;5;208', + 'default' => '0;38;5;208', 'num' => '1;38;5;38', 'const' => '1;38;5;208', 'str' => '1;38;5;113', From 843bb76f8ac02756932038255c7794b3a59058ce Mon Sep 17 00:00:00 2001 From: Anto Date: Fri, 11 Oct 2019 06:08:52 +0200 Subject: [PATCH 21/72] [PropertyInfo] Respect property name case when guessing from public method name --- .../Extractor/ReflectionExtractor.php | 4 ++-- .../Extractor/ReflectionExtractorTest.php | 2 ++ .../PropertyInfo/Tests/Fixtures/Dummy.php | 24 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index bb8138dc1a88d..dcb06ee192249 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -103,8 +103,8 @@ public function getProperties($class, array $context = []) if (!$propertyName || isset($properties[$propertyName])) { continue; } - if (!$reflectionClass->hasProperty($propertyName) && !preg_match('/^[A-Z]{2,}/', $propertyName)) { - $propertyName = lcfirst($propertyName); + if ($reflectionClass->hasProperty($lowerCasedPropertyName = lcfirst($propertyName)) || (!$reflectionClass->hasProperty($propertyName) && !preg_match('/^[A-Z]{2,}/', $propertyName))) { + $propertyName = $lowerCasedPropertyName; } $properties[$propertyName] = $propertyName; } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 0ed5390bb5882..5a5c0c7b62c6a 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -59,6 +59,8 @@ public function testGetProperties() '123', 'self', 'realParent', + 'xTotals', + 'YT', 'c', 'd', 'e', diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php index 5b82209e1d417..663fef84c7760 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php @@ -93,6 +93,16 @@ class Dummy extends ParentDummy */ public $j; + /** + * @var array + */ + private $xTotals; + + /** + * @var string + */ + private $YT; + /** * This should not be removed. * @@ -166,4 +176,18 @@ public function setSelf(self $self) public function setRealParent(parent $realParent) { } + + /** + * @return array + */ + public function getXTotals() + { + } + + /** + * @return string + */ + public function getYT() + { + } } From 30180417823e5f41c69cbb1fd6eee07e71c13c6c Mon Sep 17 00:00:00 2001 From: soufianZantar Date: Mon, 5 Aug 2019 10:42:16 +0200 Subject: [PATCH 22/72] [Dotenv] search variable values in ENV first then env file --- src/Symfony/Component/Dotenv/Dotenv.php | 38 ++++++++++++------- .../Component/Dotenv/Tests/DotenvTest.php | 17 +++++++++ src/Symfony/Component/Dotenv/composer.json | 2 +- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index c6fc3cbda9ea5..78bc83334e7ae 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -183,6 +183,8 @@ private function lexValue() throw $this->createFormatException('Whitespace are not supported before the value'); } + $loadedVars = array_flip(explode(',', isset($_SERVER['SYMFONY_DOTENV_VARS']) ? $_SERVER['SYMFONY_DOTENV_VARS'] : (isset($_ENV['SYMFONY_DOTENV_VARS']) ? $_ENV['SYMFONY_DOTENV_VARS'] : ''))); + unset($loadedVars['']); $v = ''; do { @@ -224,8 +226,8 @@ private function lexValue() ++$this->cursor; $value = str_replace(['\\"', '\r', '\n'], ['"', "\r", "\n"], $value); $resolvedValue = $value; - $resolvedValue = $this->resolveVariables($resolvedValue); - $resolvedValue = $this->resolveCommands($resolvedValue); + $resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars); + $resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars); $resolvedValue = str_replace('\\\\', '\\', $resolvedValue); $v .= $resolvedValue; } else { @@ -247,8 +249,8 @@ private function lexValue() } $value = rtrim($value); $resolvedValue = $value; - $resolvedValue = $this->resolveVariables($resolvedValue); - $resolvedValue = $this->resolveCommands($resolvedValue); + $resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars); + $resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars); $resolvedValue = str_replace('\\\\', '\\', $resolvedValue); if ($resolvedValue === $value && preg_match('/\s+/', $value)) { @@ -301,7 +303,7 @@ private function skipEmptyLines() } } - private function resolveCommands($value) + private function resolveCommands($value, $loadedVars) { if (false === strpos($value, '$')) { return $value; @@ -317,7 +319,7 @@ private function resolveCommands($value) ) /x'; - return preg_replace_callback($regex, function ($matches) { + return preg_replace_callback($regex, function ($matches) use ($loadedVars) { if ('\\' === $matches[1]) { return substr($matches[0], 1); } @@ -332,7 +334,15 @@ private function resolveCommands($value) $process = new Process('echo '.$matches[0]); $process->inheritEnvironmentVariables(true); - $process->setEnv($this->values); + + $env = []; + foreach ($this->values as $name => $value) { + if (isset($loadedVars[$name]) || (!isset($_ENV[$name]) && !(isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')))) { + $env[$name] = $value; + } + } + $process->setEnv($env); + try { $process->mustRun(); } catch (ProcessException $e) { @@ -343,7 +353,7 @@ private function resolveCommands($value) }, $value); } - private function resolveVariables($value) + private function resolveVariables($value, array $loadedVars) { if (false === strpos($value, '$')) { return $value; @@ -359,7 +369,7 @@ private function resolveVariables($value) (?P\})? # optional closing brace /x'; - $value = preg_replace_callback($regex, function ($matches) { + $value = preg_replace_callback($regex, function ($matches) use ($loadedVars) { // odd number of backslashes means the $ character is escaped if (1 === \strlen($matches['backslashes']) % 2) { return substr($matches[0], 1); @@ -375,14 +385,16 @@ private function resolveVariables($value) } $name = $matches['name']; - if (isset($this->values[$name])) { + if (isset($loadedVars[$name]) && isset($this->values[$name])) { $value = $this->values[$name]; - } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { - $value = $_SERVER[$name]; } elseif (isset($_ENV[$name])) { $value = $_ENV[$name]; + } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { + $value = $_SERVER[$name]; + } elseif (isset($this->values[$name])) { + $value = $this->values[$name]; } else { - $value = (string) getenv($name); + $value = ''; } if (!$matches['opening_brace'] && isset($matches['closing_brace'])) { diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php index b920270da9d7d..dc7c4c1715450 100644 --- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php +++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php @@ -63,6 +63,7 @@ public function testParse($data, $expected) public function getEnvData() { putenv('LOCAL=local'); + $_ENV['LOCAL'] = 'local'; $_ENV['REMOTE'] = 'remote'; $tests = [ @@ -295,4 +296,20 @@ public function testOverridingEnvVarsWithNamesMemorizedInSpecialVar() $this->assertSame('baz1', getenv('BAZ')); $this->assertSame('/var/www', getenv('DOCUMENT_ROOT')); } + + public function testGetVariablesValueFromEnvFirst() + { + $_ENV['APP_ENV'] = 'prod'; + $dotenv = new Dotenv(true); + + $test = "APP_ENV=dev\nTEST1=foo1_\${APP_ENV}"; + $values = $dotenv->parse($test); + $this->assertSame('foo1_prod', $values['TEST1']); + + if ('\\' !== \DIRECTORY_SEPARATOR) { + $test = "APP_ENV=dev\nTEST2=foo2_\$(php -r 'echo \$_SERVER[\"APP_ENV\"];')"; + $values = $dotenv->parse($test); + $this->assertSame('foo2_prod', $values['TEST2']); + } + } } diff --git a/src/Symfony/Component/Dotenv/composer.json b/src/Symfony/Component/Dotenv/composer.json index 3bcfd89c8d350..e35339c98e111 100644 --- a/src/Symfony/Component/Dotenv/composer.json +++ b/src/Symfony/Component/Dotenv/composer.json @@ -19,7 +19,7 @@ "php": "^5.5.9|>=7.0.8" }, "require-dev": { - "symfony/process": "~3.2|~4.0" + "symfony/process": "^3.4.2|^4.0" }, "autoload": { "psr-4": { "Symfony\\Component\\Dotenv\\": "" }, From b17ebdf081047649334291d93bc4227e2496e07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gildas=20Qu=C3=A9m=C3=A9ner?= Date: Fri, 11 Oct 2019 18:56:51 +0200 Subject: [PATCH 23/72] bug #33942 [DI] Add extra type check to php dumper --- src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 64dfee8573763..e7534ea321a68 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1889,7 +1889,7 @@ private function isSingleUsePrivateNode(ServiceReferenceGraphNode $node): bool if (!$value = $edge->getSourceNode()->getValue()) { continue; } - if ($edge->isLazy() || !$value->isShared()) { + if ($edge->isLazy() || !$value instanceof Definition || !$value->isShared()) { return false; } $ids[$edge->getSourceNode()->getId()] = true; From c2dd804a24fffd10da659b36e65ec8cff7baa51f Mon Sep 17 00:00:00 2001 From: Reedy Date: Sat, 12 Oct 2019 01:38:35 +0100 Subject: [PATCH 24/72] Make Symfony\Contracts\Service\Test\ServiceLocatorTest abstract Also make getServiceLocator protected As per https://github.com/symfony/symfony/issues/33946#issuecomment-541100439 --- src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php b/src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php index 408c017c3ee40..5ed9149529655 100644 --- a/src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php +++ b/src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php @@ -15,9 +15,9 @@ use Psr\Container\ContainerInterface; use Symfony\Contracts\Service\ServiceLocatorTrait; -class ServiceLocatorTest extends TestCase +abstract class ServiceLocatorTest extends TestCase { - public function getServiceLocator(array $factories) + protected function getServiceLocator(array $factories) { return new class($factories) implements ContainerInterface { use ServiceLocatorTrait; From 56895f12b92cc17baa978606cec56165ce56057a Mon Sep 17 00:00:00 2001 From: Ilia Lazarev Date: Sat, 12 Oct 2019 10:36:35 +0300 Subject: [PATCH 25/72] Add plus character `+` to legal mime subtype For example, the following mime type (used for epub) is not recognized given the current regexp: `application/epub+zip` --- .../HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php index b75242afd0d61..cfa76843cc4f7 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php @@ -89,7 +89,7 @@ public function guess($path) $type = trim(ob_get_clean()); - if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) { + if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\+\.]+)#i', $type, $match)) { // it's not a type, but an error message return null; } From 946f0a1e11e5182364d42b323fa82df3212be591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vedran=20Miho=C4=8Dinec?= Date: Sat, 12 Oct 2019 09:41:19 +0200 Subject: [PATCH 26/72] [Cache] fixed TagAwareAdapter returning invalid cache --- .../Cache/Adapter/TagAwareAdapter.php | 12 ++- .../Tests/Adapter/TagAwareAdapterTest.php | 78 +++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index cac8a0ea18509..fd038bc612706 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -156,7 +156,12 @@ public function hasItem($key) if (!$this->pool->hasItem($key)) { return false; } - if (!$itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key)->get()) { + + if (!($itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key))->isHit()) { + return false; + } + + if (!$itemTags = $itemTags->get()) { return true; } @@ -296,7 +301,10 @@ private function generateItems($items, array $tagKeys) } unset($tagKeys[$key]); - $itemTags[$key] = $item->get() ?: []; + + if ($item->isHit()) { + $itemTags[$key] = $item->get() ?: []; + } if (!$tagKeys) { $tagVersions = $this->getTagVersions($itemTags); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php index c8677d5e28319..0108b9250b79a 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php @@ -194,6 +194,84 @@ public function testKnownTagVersionsTtl() $this->assertTrue($pool->getItem('foo')->isHit()); } + public function testTagEntryIsCreatedForItemWithoutTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $adapter = new FilesystemAdapter(); + $this->assertTrue($adapter->hasItem(TagAwareAdapter::TAGS_PREFIX.$itemKey)); + } + + public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair + + $this->assertFalse($anotherPool->hasItem($itemKey)); + } + + public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair + + $item = $anotherPool->getItem($itemKey); + $this->assertFalse($item->isHit()); + } + + public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemAndOnlyHasTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem($itemKey); //simulate losing item but keeping tags + + $this->assertFalse($anotherPool->hasItem($itemKey)); + } + + public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem($itemKey); //simulate losing item but keeping tags + + $item = $anotherPool->getItem($itemKey); + $this->assertFalse($item->isHit()); + } + /** * @return MockObject|PruneableCacheInterface */ From 8a04886f2631284984beda8184ebb520281bcd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Sun, 13 Oct 2019 14:02:04 +0200 Subject: [PATCH 27/72] Increase limits for flakey appveyor tests --- src/Symfony/Component/VarDumper/Tests/Server/ConnectionTest.php | 2 +- src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Tests/Server/ConnectionTest.php b/src/Symfony/Component/VarDumper/Tests/Server/ConnectionTest.php index 21902b5cf1aa4..a67cb76bf11be 100644 --- a/src/Symfony/Component/VarDumper/Tests/Server/ConnectionTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Server/ConnectionTest.php @@ -72,7 +72,7 @@ public function testNoServer() $connection = new Connection(self::VAR_DUMPER_SERVER); $start = microtime(true); $this->assertFalse($connection->write($data)); - $this->assertLessThan(1, microtime(true) - $start); + $this->assertLessThan(4, microtime(true) - $start); } private function getServerProcess(): Process diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index 0547c752ac9d5..20ac77ff37187 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -669,7 +669,7 @@ public function testDestruct() $duration = microtime(true) - $start; $this->assertGreaterThan(1, $duration); - $this->assertLessThan(3, $duration); + $this->assertLessThan(4, $duration); } public function testProxy() From 5c82d301a7cbfa1969adca52658e53f841d70b7a Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 13 Oct 2019 20:43:12 +0200 Subject: [PATCH 28/72] fix PHP 5.6 compatibility --- src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index fd038bc612706..ff4fc9a29cdd5 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -157,7 +157,9 @@ public function hasItem($key) return false; } - if (!($itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key))->isHit()) { + $itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key); + + if (!$itemTags->isHit()) { return false; } From b7b694225165100b08edac6f6611cc7868e3c990 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 15 Oct 2019 09:35:54 +0200 Subject: [PATCH 29/72] [CI] fix building local packages --- .appveyor.yml | 2 ++ .github/build-packages.php | 2 +- .travis.yml | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 5146a65ae6cab..188dfe78a2493 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -54,6 +54,8 @@ install: - php composer.phar self-update - copy /Y .github\composer-config.json %APPDATA%\Composer\config.json - php composer.phar global require --no-progress --no-scripts --no-plugins symfony/flex dev-master + - git config --global user.email "" + - git config --global user.name "Symfony" - php .github/build-packages.php "HEAD^" src\Symfony\Bridge\PhpUnit - IF %APPVEYOR_REPO_BRANCH%==master (SET COMPOSER_ROOT_VERSION=dev-master) ELSE (SET COMPOSER_ROOT_VERSION=%APPVEYOR_REPO_BRANCH%.x-dev) - php composer.phar config platform.php 5.5.9 diff --git a/.github/build-packages.php b/.github/build-packages.php index d859e3ec808a1..81a309911135c 100644 --- a/.github/build-packages.php +++ b/.github/build-packages.php @@ -47,7 +47,7 @@ if (isset($preferredInstall[$package->name]) && 'source' === $preferredInstall[$package->name]) { passthru("cd $dir && tar -cf package.tar --exclude='package.tar' *"); } else { - passthru("cd $dir && git init && git add . && git commit --author \"Symfony <>\" -m - && git archive -o package.tar HEAD && rm .git/ -Rf"); + passthru("cd $dir && git init && git add . && git commit -q -m - && git archive -o package.tar HEAD && rm .git/ -Rf"); } if (!isset($package->extra->{'branch-alias'}->{'dev-master'})) { diff --git a/.travis.yml b/.travis.yml index 682b50b1558da..99595ca5f89b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -212,6 +212,9 @@ install: - | # Create local composer packages for each patched components and reference them in composer.json files when cross-testing components + git config --global user.email "" + git config --global user.name "Symfony" + if [[ ! $deps ]]; then php .github/build-packages.php HEAD^ src/Symfony/Bridge/PhpUnit else From e635491c96ed7e3cc4efa15f1930009f1fe38905 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 15 Oct 2019 09:35:54 +0200 Subject: [PATCH 30/72] [HttpClient] workaround curl_multi_select() issue --- .appveyor.yml | 1 - src/Symfony/Component/HttpClient/Response/CurlResponse.php | 5 +++++ src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 30cc82fb5ba0c..648c9a9849e6e 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -48,7 +48,6 @@ install: - php composer.phar global require --no-progress --no-scripts --no-plugins symfony/flex dev-master - git config --global user.email "" - git config --global user.name "Symfony" - - php .github/build-packages.php "HEAD^" src\Symfony\Bridge\PhpUnit - php .github/build-packages.php "HEAD^" src\Symfony\Bridge\PhpUnit src\Symfony\Contracts - IF %APPVEYOR_REPO_BRANCH%==master (SET COMPOSER_ROOT_VERSION=dev-master) ELSE (SET COMPOSER_ROOT_VERSION=%APPVEYOR_REPO_BRANCH%.x-dev) - php composer.phar update --no-progress --no-suggest --ansi diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 532f4130860f3..6f4ebf554ff92 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -274,6 +274,11 @@ private static function perform(CurlClientState $multi, array &$responses = null */ private static function select(CurlClientState $multi, float $timeout): int { + if (\PHP_VERSION_ID < 70123 || (70200 <= \PHP_VERSION_ID && \PHP_VERSION_ID < 70211)) { + // workaround https://bugs.php.net/76480 + $timeout = min($timeout, 0.01); + } + return curl_multi_select($multi->handle, $timeout); } diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index 20ac77ff37187..485712c6888aa 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -597,9 +597,9 @@ public function testNotATimeout() { $client = $this->getHttpClient(__FUNCTION__); $response = $client->request('GET', 'http://localhost:8057/timeout-header', [ - 'timeout' => 0.5, + 'timeout' => 0.9, ]); - usleep(510000); + sleep(1); $this->assertSame(200, $response->getStatusCode()); } From 6dbac13a07c23f321b04489b6a9773f72c93a621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Perrin?= Date: Tue, 15 Oct 2019 14:55:21 -0500 Subject: [PATCH 31/72] [Mailer] Fix Mandrill Transport API payload with named addresses --- .../Mailchimp/Http/Api/MandrillTransport.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/Api/MandrillTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/Api/MandrillTransport.php index 9217eaa49f46b..c8e313e7b7391 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/Api/MandrillTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/Api/MandrillTransport.php @@ -17,6 +17,7 @@ use Symfony\Component\Mailer\SmtpEnvelope; use Symfony\Component\Mailer\Transport\Http\Api\AbstractApiTransport; use Symfony\Component\Mime\Email; +use Symfony\Component\Mime\NamedAddress; use Symfony\Contracts\HttpClient\HttpClientInterface; /** @@ -60,11 +61,15 @@ private function getPayload(Email $email, SmtpEnvelope $envelope): array 'html' => $email->getHtmlBody(), 'text' => $email->getTextBody(), 'subject' => $email->getSubject(), - 'from_email' => $envelope->getSender()->toString(), + 'from_email' => $envelope->getSender()->getAddress(), 'to' => $this->getRecipients($email, $envelope), ], ]; + if ($envelope->getSender() instanceof NamedAddress) { + $payload['message']['from_name'] = $envelope->getSender()->getName(); + } + foreach ($email->getAttachments() as $attachment) { $headers = $attachment->getPreparedHeaders(); $disposition = $headers->getHeaderBody('Content-Disposition'); @@ -104,10 +109,16 @@ protected function getRecipients(Email $email, SmtpEnvelope $envelope): array $type = 'cc'; } - $recipients[] = [ - 'email' => $recipient->toString(), + $recipientPayload = [ + 'email' => $recipient->getAddress(), 'type' => $type, ]; + + if ($recipient instanceof NamedAddress) { + $recipientPayload['name'] = $recipient->getName(); + } + + $recipients[] = $recipientPayload; } return $recipients; From bed479c56105ccf0821f1c39521b5fe63ccbe8e2 Mon Sep 17 00:00:00 2001 From: Gregor Harlan Date: Wed, 16 Oct 2019 00:08:58 +0200 Subject: [PATCH 32/72] [Yaml] Throw exception for tagged invalid inline elements --- src/Symfony/Component/Yaml/Inline.php | 8 ++++---- src/Symfony/Component/Yaml/Tests/InlineTest.php | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index 10fa2702e851c..7d3218a35e187 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -126,15 +126,15 @@ public static function parse($value, $flags = 0, $references = []) $result = self::parseScalar($value, $flags, null, $i, null === $tag, $references); } - if (null !== $tag) { - return new TaggedValue($tag, $result); - } - // some comments are allowed at the end if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) { throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename); } + if (null !== $tag) { + return new TaggedValue($tag, $result); + } + return $result; } finally { if (isset($mbEncoding)) { diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index 3b3dabf56d1d4..014a12a706723 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -201,6 +201,12 @@ public function testParseInvalidSequenceShouldThrowException() Inline::parse('{ foo: bar } bar'); } + public function testParseInvalidTaggedSequenceShouldThrowException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + Inline::parse('!foo { bar: baz } qux', Yaml::PARSE_CUSTOM_TAGS); + } + public function testParseScalarWithCorrectlyQuotedStringShouldReturnString() { $value = "'don''t do somthin'' like that'"; From c83ff94c37cb1e4f1aa2fc382bd50898eea76cc4 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Thu, 17 Oct 2019 19:56:35 +0200 Subject: [PATCH 33/72] [Messenger] Fix ignored options in redis transport --- .../Transport/RedisExt/ConnectionTest.php | 25 +++++++++++++------ .../Transport/RedisExt/Connection.php | 11 ++++---- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php index 4e525702aa5f8..81baaac8d96a2 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/RedisExt/ConnectionTest.php @@ -57,13 +57,8 @@ public function testFromDsn() public function testFromDsnWithOptions() { $this->assertEquals( - new Connection(['stream' => 'queue', 'group' => 'group1', 'consumer' => 'consumer1', 'auto_setup' => false], [ - 'host' => 'localhost', - 'port' => 6379, - ], [ - 'serializer' => 2, - ]), - Connection::fromDsn('redis://localhost/queue/group1/consumer1', ['serializer' => 2, 'auto_setup' => false]) + Connection::fromDsn('redis://localhost', ['stream' => 'queue', 'group' => 'group1', 'consumer' => 'consumer1', 'auto_setup' => false, 'serializer' => 2]), + Connection::fromDsn('redis://localhost/queue/group1/consumer1?serializer=2&auto_setup=0') ); } @@ -99,7 +94,21 @@ public function testAuth() $redis = $this->getMockBuilder(\Redis::class)->disableOriginalConstructor()->getMock(); $redis->expects($this->exactly(1))->method('auth') - ->with('password'); + ->with('password') + ->willReturn(true); + + Connection::fromDsn('redis://password@localhost/queue', [], $redis); + } + + public function testFailedAuth() + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Redis connection failed'); + $redis = $this->getMockBuilder(\Redis::class)->disableOriginalConstructor()->getMock(); + + $redis->expects($this->exactly(1))->method('auth') + ->with('password') + ->willReturn(false); Connection::fromDsn('redis://password@localhost/queue', [], $redis); } diff --git a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php index 59ec9f029d6a4..6864cd1b9c459 100644 --- a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php @@ -20,6 +20,7 @@ * * @author Alexander Schranz * @author Antoine Bluchet + * @author Robin Chalas * * @internal * @final @@ -52,8 +53,8 @@ public function __construct(array $configuration, array $connectionCredentials = $this->connection->connect($connectionCredentials['host'] ?? '127.0.0.1', $connectionCredentials['port'] ?? 6379); $this->connection->setOption(\Redis::OPT_SERIALIZER, $redisOptions['serializer'] ?? \Redis::SERIALIZER_PHP); - if (isset($connectionCredentials['auth'])) { - $this->connection->auth($connectionCredentials['auth']); + if (isset($connectionCredentials['auth']) && !$this->connection->auth($connectionCredentials['auth'])) { + throw new InvalidArgumentException(sprintf('Redis connection failed: %s', $redis->getLastError())); } $this->stream = $configuration['stream'] ?? self::DEFAULT_OPTIONS['stream']; @@ -70,9 +71,9 @@ public static function fromDsn(string $dsn, array $redisOptions = [], \Redis $re $pathParts = explode('/', $parsedUrl['path'] ?? ''); - $stream = $pathParts[1] ?? null; - $group = $pathParts[2] ?? null; - $consumer = $pathParts[3] ?? null; + $stream = $pathParts[1] ?? $redisOptions['stream'] ?? null; + $group = $pathParts[2] ?? $redisOptions['group'] ?? null; + $consumer = $pathParts[3] ?? $redisOptions['consumer'] ?? null; $connectionCredentials = [ 'host' => $parsedUrl['host'] ?? '127.0.0.1', From 9eddea97d8bbc90697ddcf31ba90022466e6dcb1 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 18 Oct 2019 10:33:13 +0200 Subject: [PATCH 34/72] do not render errors for checkboxes twice --- .../Resources/views/Form/bootstrap_4_horizontal_layout.html.twig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig index e23e6f8a29d09..5673cf212730c 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig @@ -71,7 +71,6 @@ col-sm-10
{#--#}
{{- form_widget(form) -}} - {{- form_errors(form) -}}
{#--#} {%- endblock checkbox_row %} From 4d79116a0dd5c952d4fbc7fd883f539be80e12c5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 18 Oct 2019 12:00:34 +0200 Subject: [PATCH 35/72] [Dotenv] allow LF in single-quoted strings --- src/Symfony/Component/Dotenv/Dotenv.php | 23 +++++++------------ .../Component/Dotenv/Tests/DotenvTest.php | 2 ++ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index 78bc83334e7ae..c2475f204a8bb 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -189,25 +189,18 @@ private function lexValue() do { if ("'" === $this->data[$this->cursor]) { - $value = ''; - ++$this->cursor; + $len = 0; - while ("\n" !== $this->data[$this->cursor]) { - if ("'" === $this->data[$this->cursor]) { - break; - } - $value .= $this->data[$this->cursor]; - ++$this->cursor; + do { + if ($this->cursor + ++$len === $this->end) { + $this->cursor += $len; - if ($this->cursor === $this->end) { throw $this->createFormatException('Missing quote to end the value'); } - } - if ("\n" === $this->data[$this->cursor]) { - throw $this->createFormatException('Missing quote to end the value'); - } - ++$this->cursor; - $v .= $value; + } while ("'" !== $this->data[$this->cursor + $len]); + + $v .= substr($this->data, 1 + $this->cursor, $len - 1); + $this->cursor += 1 + $len; } elseif ('"' === $this->data[$this->cursor]) { $value = ''; ++$this->cursor; diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php index dc7c4c1715450..1e493f24bdb5b 100644 --- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php +++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php @@ -40,6 +40,7 @@ public function getEnvDataWithFormatErrors() ['FOO', "Missing = in the environment variable declaration in \".env\" at line 1.\n...FOO...\n ^ line 1 offset 3"], ['FOO="foo', "Missing quote to end the value in \".env\" at line 1.\n...FOO=\"foo...\n ^ line 1 offset 8"], ['FOO=\'foo', "Missing quote to end the value in \".env\" at line 1.\n...FOO='foo...\n ^ line 1 offset 8"], + ['FOO=\'foo'."\n", "Missing quote to end the value in \".env\" at line 1.\n...FOO='foo\\n...\n ^ line 1 offset 9"], ['export FOO', "Unable to unset an environment variable in \".env\" at line 1.\n...export FOO...\n ^ line 1 offset 10"], ['FOO=${FOO', "Unclosed braces on variable expansion in \".env\" at line 1.\n...FOO=\${FOO...\n ^ line 1 offset 9"], ]; @@ -105,6 +106,7 @@ public function getEnvData() ['FOO="bar\rfoo"', ['FOO' => "bar\rfoo"]], ['FOO=\'bar\nfoo\'', ['FOO' => 'bar\nfoo']], ['FOO=\'bar\rfoo\'', ['FOO' => 'bar\rfoo']], + ["FOO='bar\nfoo'", ['FOO' => "bar\nfoo"]], ['FOO=" FOO "', ['FOO' => ' FOO ']], ['FOO=" "', ['FOO' => ' ']], ['PATH="c:\\\\"', ['PATH' => 'c:\\']], From 18cc561754fca7c68219681d8e7a57d10ed66a3e Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 19 Oct 2019 10:14:32 +0200 Subject: [PATCH 36/72] execute all compatible tests across versions --- .../Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php | 2 +- src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php | 2 +- src/Symfony/Component/Form/Tests/VersionAwareTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php index e5d4303911105..d7d7cae5ecda9 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php @@ -30,7 +30,7 @@ class EntityTypePerformanceTest extends FormPerformanceTestCase */ private $em; - protected static $supportedFeatureSetVersion = 304; + protected static $supportedFeatureSetVersion = 403; protected function getExtensions() { diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index 0f530d37d62a4..ebffc57c1d045 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -58,7 +58,7 @@ class EntityTypeTest extends BaseTypeTest */ private $emRegistry; - protected static $supportedFeatureSetVersion = 304; + protected static $supportedFeatureSetVersion = 403; protected function setUp(): void { diff --git a/src/Symfony/Component/Form/Tests/VersionAwareTest.php b/src/Symfony/Component/Form/Tests/VersionAwareTest.php index 2b8489a6a27cf..578bebcb0800f 100644 --- a/src/Symfony/Component/Form/Tests/VersionAwareTest.php +++ b/src/Symfony/Component/Form/Tests/VersionAwareTest.php @@ -13,7 +13,7 @@ trait VersionAwareTest { - protected static $supportedFeatureSetVersion = 304; + protected static $supportedFeatureSetVersion = 403; /** * @param int $requiredFeatureSetVersion From 217058b47561f2b7457a695ca61fc5c419383e46 Mon Sep 17 00:00:00 2001 From: Gerhard Seidel Date: Fri, 18 Oct 2019 13:11:49 +0200 Subject: [PATCH 37/72] [Routing] fix route loading with wildcard, but dir or file is empty --- .../Routing/Loader/Configurator/RoutingConfigurator.php | 3 ++- src/Symfony/Component/Routing/Loader/XmlFileLoader.php | 2 +- src/Symfony/Component/Routing/Loader/YamlFileLoader.php | 2 +- .../Tests/Fixtures/controller/empty_wildcard/.gitignore | 0 .../Tests/Fixtures/import_with_name_prefix/routing.yml | 4 ++++ 5 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Component/Routing/Tests/Fixtures/controller/empty_wildcard/.gitignore diff --git a/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php b/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php index a315cfb4ad07e..849db56759d60 100644 --- a/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php +++ b/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php @@ -39,7 +39,8 @@ public function __construct(RouteCollection $collection, PhpFileLoader $loader, final public function import($resource, $type = null, $ignoreErrors = false) { $this->loader->setCurrentDir(\dirname($this->path)); - $imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file); + $imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file) ?? []; + if (!\is_array($imported)) { return new ImportConfigurator($this->collection, $imported); } diff --git a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php index ed4faf3915b72..7b5998bd20277 100644 --- a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -169,7 +169,7 @@ protected function parseImport(RouteCollection $collection, \DOMElement $node, $ $this->setCurrentDir(\dirname($path)); /** @var RouteCollection[] $imported */ - $imported = $this->import($resource, ('' !== $type ? $type : null), false, $file); + $imported = $this->import($resource, ('' !== $type ? $type : null), false, $file) ?? []; if (!\is_array($imported)) { $imported = [$imported]; diff --git a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php index 15c223ecadcf4..339776c13f921 100644 --- a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php @@ -187,7 +187,7 @@ protected function parseImport(RouteCollection $collection, array $config, $path $this->setCurrentDir(\dirname($path)); - $imported = $this->import($config['resource'], $type, false, $file); + $imported = $this->import($config['resource'], $type, false, $file) ?? []; if (!\is_array($imported)) { $imported = [$imported]; diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/controller/empty_wildcard/.gitignore b/src/Symfony/Component/Routing/Tests/Fixtures/controller/empty_wildcard/.gitignore new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/import_with_name_prefix/routing.yml b/src/Symfony/Component/Routing/Tests/Fixtures/import_with_name_prefix/routing.yml index 90dce0ea1bfc4..057b7b2d6b9ce 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/import_with_name_prefix/routing.yml +++ b/src/Symfony/Component/Routing/Tests/Fixtures/import_with_name_prefix/routing.yml @@ -5,3 +5,7 @@ api: resource: ../controller/routing.yml name_prefix: api_ prefix: /api + +empty_wildcard: + resource: ../controller/empty_wildcard/* + prefix: /empty_wildcard From a54ecb0fae7ea9fbbf9bc9c6f5715d0ec235a9e5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 19 Oct 2019 15:04:41 +0200 Subject: [PATCH 38/72] bug #34024 [Routing] fix route loading with wildcard, but dir or file is empty (gseidel) This PR was merged into the 4.3 branch. Discussion ---------- [Routing] fix route loading with wildcard, but dir or file is empty | Q | A | ------------- | --- | Branch? | 4.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | no ticket i see so far | License | MIT In my route config i have something like: ```yaml empty_wildcard: resource: ../controller/empty_wildcard/* prefix: /empty_wildcard ``` But ``empty_wildcard`` is empty or has no route configured. So i had this error: ``Call to a member function addPrefix() on null`` This PR take care if no route is configured, there will be no error. Commits ------- 217058b475 [Routing] fix route loading with wildcard, but dir or file is empty --- .../Routing/Loader/Configurator/RoutingConfigurator.php | 3 ++- src/Symfony/Component/Routing/Loader/XmlFileLoader.php | 3 ++- src/Symfony/Component/Routing/Loader/YamlFileLoader.php | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php b/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php index 7614caea3dc40..d0cc02d1c3fba 100644 --- a/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php +++ b/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php @@ -39,7 +39,8 @@ public function __construct(RouteCollection $collection, PhpFileLoader $loader, final public function import($resource, $type = null, $ignoreErrors = false) { $this->loader->setCurrentDir(\dirname($this->path)); - $imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file); + $imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file) ?: []; + if (!\is_array($imported)) { return new ImportConfigurator($this->collection, $imported); } diff --git a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php index c114310fc3232..29dfdb1665b56 100644 --- a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -146,7 +146,8 @@ protected function parseImport(RouteCollection $collection, \DOMElement $node, $ $this->setCurrentDir(\dirname($path)); - $imported = $this->import($resource, ('' !== $type ? $type : null), false, $file); + /** @var RouteCollection[] $imported */ + $imported = $this->import($resource, ('' !== $type ? $type : null), false, $file) ?: []; if (!\is_array($imported)) { $imported = [$imported]; diff --git a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php index bc21e9cb4db7c..568827695bbea 100644 --- a/src/Symfony/Component/Routing/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/YamlFileLoader.php @@ -158,7 +158,7 @@ protected function parseImport(RouteCollection $collection, array $config, $path $this->setCurrentDir(\dirname($path)); - $imported = $this->import($config['resource'], $type, false, $file); + $imported = $this->import($config['resource'], $type, false, $file) ?: []; if (!\is_array($imported)) { $imported = [$imported]; From 4ad09ebafb1570878264aa49a73aab63c52a5aa2 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 20 Oct 2019 11:47:57 +0200 Subject: [PATCH 39/72] [HttpKernel] fix wrong removal of the just generated container dir --- src/Symfony/Component/HttpKernel/Kernel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 325ef4d443c61..b05e877d7ba50 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -868,7 +868,7 @@ protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container $fs->dumpFile($dir.$file, $code); @chmod($dir.$file, 0666 & ~umask()); } - $legacyFile = \dirname($dir.$file).'.legacy'; + $legacyFile = \dirname($dir.key($content)).'.legacy'; if (file_exists($legacyFile)) { @unlink($legacyFile); } From 7c2b974e26230a507a66c07e3648b73a12d3a395 Mon Sep 17 00:00:00 2001 From: Menno Holtkamp Date: Mon, 21 Oct 2019 17:20:49 +0200 Subject: [PATCH 40/72] Fix small typo in Exception message --- .../Component/Workflow/Validator/StateMachineValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php b/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php index 7dbe694940518..6330cabec99c0 100644 --- a/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php +++ b/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php @@ -37,7 +37,7 @@ public function validate(Definition $definition, $name) // Enforcing uniqueness of the names of transitions starting at each node $from = reset($froms); if (isset($transitionFromNames[$from][$transition->getName()])) { - throw new InvalidDefinitionException(sprintf('A transition from a place/state must have an unique name. Multiple transitions named "%s" from place/state "%s" where found on StateMachine "%s". ', $transition->getName(), $from, $name)); + throw new InvalidDefinitionException(sprintf('A transition from a place/state must have an unique name. Multiple transitions named "%s" from place/state "%s" were found on StateMachine "%s".', $transition->getName(), $from, $name)); } $transitionFromNames[$from][$transition->getName()] = true; From ae86ab18fa3fdb8237142641ae7003c4cfdecc08 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 21 Oct 2019 18:09:12 +0200 Subject: [PATCH 41/72] [HttpClient] skip tests implemented in 4.4 --- .../HttpClient/Tests/HttpClientTestCase.php | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php index bc836a7fade1b..2acf01fd0a642 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php +++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php @@ -15,11 +15,6 @@ abstract class HttpClientTestCase extends BaseHttpClientTestCase { - public function testMaxDuration() - { - $this->markTestSkipped('Implemented as of version 4.4'); - } - public function testAcceptHeader() { $client = $this->getHttpClient(__FUNCTION__); @@ -47,4 +42,34 @@ public function testAcceptHeader() $this->assertArrayNotHasKey('HTTP_ACCEPT', $requestHeaders); } + + public function testInfoOnCanceledResponse() + { + $this->markTestSkipped('Implemented as of version 4.4'); + } + + public function testBufferSink() + { + $this->markTestSkipped('Implemented as of version 4.4'); + } + + public function testConditionalBuffering() + { + $this->markTestSkipped('Implemented as of version 4.4'); + } + + public function testReentrantBufferCallback() + { + $this->markTestSkipped('Implemented as of version 4.4'); + } + + public function testThrowingBufferCallback() + { + $this->markTestSkipped('Implemented as of version 4.4'); + } + + public function testMaxDuration() + { + $this->markTestSkipped('Implemented as of version 4.4'); + } } From 6b7044fc0112b49a866ff94debc866384fe90ba0 Mon Sep 17 00:00:00 2001 From: Douglas Greenshields Date: Wed, 23 Oct 2019 10:40:35 +0100 Subject: [PATCH 42/72] [SecurityBundle] correct types for default arguments for firewall configs --- .../Bundle/SecurityBundle/Resources/config/security.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index 4a2b936c716ce..98b7f3bee099b 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -150,15 +150,15 @@ - - + false + false - + null From 3dbe924f477d307d8dd15a42a4e1ddcdc3e3afb3 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Wed, 23 Oct 2019 13:26:24 +0200 Subject: [PATCH 43/72] Revert "[Messenger] Fix exception message of failed message is dropped on retry" This reverts commit 8f9f44eb21d5cd29ce41277080b9e986a9da822a. --- .../FailedMessagesRetryCommandTest.php | 53 +++---------------- src/Symfony/Component/Messenger/Worker.php | 16 +----- 2 files changed, 8 insertions(+), 61 deletions(-) diff --git a/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRetryCommandTest.php b/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRetryCommandTest.php index bc69a1c2e8a2e..bcc67f79d566b 100644 --- a/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRetryCommandTest.php +++ b/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesRetryCommandTest.php @@ -13,15 +13,12 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; -use Symfony\Component\Debug\Exception\FlattenException; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Messenger\Command\FailedMessagesRetryCommand; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\MessageBusInterface; -use Symfony\Component\Messenger\Retry\RetryStrategyInterface; -use Symfony\Component\Messenger\Stamp\ReceivedStamp; -use Symfony\Component\Messenger\Stamp\RedeliveryStamp; use Symfony\Component\Messenger\Transport\Receiver\ListableReceiverInterface; +use Symfony\Component\Messenger\Worker; class FailedMessagesRetryCommandTest extends TestCase { @@ -37,52 +34,16 @@ public function testBasicRun() // the bus should be called in the worker $bus->expects($this->exactly(2))->method('dispatch')->willReturn(new Envelope(new \stdClass())); - $command = new FailedMessagesRetryCommand('failure_receiver', $receiver, $bus, $dispatcher); + $command = new FailedMessagesRetryCommand( + 'failure_receiver', + $receiver, + $bus, + $dispatcher + ); $tester = new CommandTester($command); $tester->execute(['id' => [10, 12]]); $this->assertStringContainsString('[OK]', $tester->getDisplay()); } - - public function testExceptionOnRetry() - { - $receiver = $this->createMock(ListableReceiverInterface::class); - $receiver->expects($this->once())->method('find')->with(10)->willReturn(new Envelope(new \stdClass())); - // message will eventually be ack'ed in Worker - $receiver->expects($this->once())->method('ack'); - - $dispatcher = $this->createMock(EventDispatcherInterface::class); - $bus = $this->createMock(MessageBusInterface::class); - // the bus should be called in the worker - $bus->expects($this->at(0)) - ->method('dispatch') - ->with($this->callback(function (Envelope $envelope) { - $lastReceivedStamp = $envelope->last(ReceivedStamp::class); - - return $lastReceivedStamp instanceof ReceivedStamp && \is_string($lastReceivedStamp->getTransportName()); - })) - ->will($this->throwException(new \Exception('Mock test exception'))); - - $bus->expects($this->at(1)) - ->method('dispatch') - ->with($this->callback(function (Envelope $envelope) { - $lastRedeliveryStamp = $envelope->last(RedeliveryStamp::class); - - return $lastRedeliveryStamp instanceof RedeliveryStamp && - \is_string($lastRedeliveryStamp->getExceptionMessage()) && - $lastRedeliveryStamp->getFlattenException() instanceof FlattenException; - })) - ->willReturn(new Envelope(new \stdClass())); - - $retryStrategy = $this->createMock(RetryStrategyInterface::class); - $retryStrategy->expects($this->once())->method('isRetryable')->with($this->isInstanceOf(Envelope::class))->willReturn(true); - - $command = new FailedMessagesRetryCommand('failure_receiver', $receiver, $bus, $dispatcher, $retryStrategy); - - $tester = new CommandTester($command); - $tester->execute(['id' => [10]]); - - $this->assertStringContainsString('[OK]', $tester->getDisplay()); - } } diff --git a/src/Symfony/Component/Messenger/Worker.php b/src/Symfony/Component/Messenger/Worker.php index 3ce1bd79e5857..398124e99491f 100644 --- a/src/Symfony/Component/Messenger/Worker.php +++ b/src/Symfony/Component/Messenger/Worker.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Messenger; use Psr\Log\LoggerInterface; -use Symfony\Component\Debug\Exception\FlattenException; use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy; use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent; use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent; @@ -154,7 +153,7 @@ private function handleMessage(Envelope $envelope, ReceiverInterface $receiver, // add the delay and retry stamp info + remove ReceivedStamp $retryEnvelope = $envelope->with(new DelayStamp($delay)) - ->with(new RedeliveryStamp($retryCount, $transportName, $throwable->getMessage(), $this->flattenedException($throwable))) + ->with(new RedeliveryStamp($retryCount, $transportName)) ->withoutAll(ReceivedStamp::class); // re-send the message @@ -217,17 +216,4 @@ private function shouldRetry(\Throwable $e, Envelope $envelope, RetryStrategyInt return $retryStrategy->isRetryable($envelope); } - - private function flattenedException(\Throwable $throwable): ?FlattenException - { - if (!class_exists(FlattenException::class)) { - return null; - } - - if ($throwable instanceof HandlerFailedException) { - $throwable = $throwable->getNestedExceptions()[0]; - } - - return FlattenException::createFromThrowable($throwable); - } } From 598bd923139d733806841bbded6651780defc091 Mon Sep 17 00:00:00 2001 From: Timo Bakx Date: Wed, 3 Jul 2019 15:24:14 +0200 Subject: [PATCH 44/72] [Messenger] Show exceptions on after empty fails --- .../Command/AbstractFailedMessagesCommand.php | 21 ++++++++--- .../Command/FailedMessagesShowCommand.php | 8 ++--- .../Command/FailedMessagesShowCommandTest.php | 36 +++++++++++++++++++ 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Messenger/Command/AbstractFailedMessagesCommand.php b/src/Symfony/Component/Messenger/Command/AbstractFailedMessagesCommand.php index 194d42c109ac4..291ed85aeba57 100644 --- a/src/Symfony/Component/Messenger/Command/AbstractFailedMessagesCommand.php +++ b/src/Symfony/Component/Messenger/Command/AbstractFailedMessagesCommand.php @@ -62,8 +62,7 @@ protected function displaySingleMessage(Envelope $envelope, SymfonyStyle $io) /** @var SentToFailureTransportStamp|null $sentToFailureTransportStamp */ $sentToFailureTransportStamp = $envelope->last(SentToFailureTransportStamp::class); - /** @var RedeliveryStamp|null $lastRedeliveryStamp */ - $lastRedeliveryStamp = $envelope->last(RedeliveryStamp::class); + $lastRedeliveryStampWithException = $this->getLastRedeliveryStampWithException($envelope); $rows = [ ['Class', \get_class($envelope->getMessage())], @@ -73,13 +72,13 @@ protected function displaySingleMessage(Envelope $envelope, SymfonyStyle $io) $rows[] = ['Message Id', $id]; } - $flattenException = null === $lastRedeliveryStamp ? null : $lastRedeliveryStamp->getFlattenException(); + $flattenException = null === $lastRedeliveryStampWithException ? null : $lastRedeliveryStampWithException->getFlattenException(); if (null === $sentToFailureTransportStamp) { $io->warning('Message does not appear to have been sent to this transport after failing'); } else { $rows = array_merge($rows, [ - ['Failed at', null === $lastRedeliveryStamp ? '' : $lastRedeliveryStamp->getRedeliveredAt()->format('Y-m-d H:i:s')], - ['Error', null === $lastRedeliveryStamp ? '' : $lastRedeliveryStamp->getExceptionMessage()], + ['Failed at', null === $lastRedeliveryStampWithException ? '' : $lastRedeliveryStampWithException->getRedeliveredAt()->format('Y-m-d H:i:s')], + ['Error', null === $lastRedeliveryStampWithException ? '' : $lastRedeliveryStampWithException->getExceptionMessage()], ['Error Class', null === $flattenException ? '(unknown)' : $flattenException->getClass()], ['Transport', $sentToFailureTransportStamp->getOriginalReceiverName()], ]); @@ -121,4 +120,16 @@ protected function getReceiver(): ReceiverInterface { return $this->receiver; } + + protected function getLastRedeliveryStampWithException(Envelope $envelope): ?RedeliveryStamp + { + /** @var RedeliveryStamp $stamp */ + foreach (array_reverse($envelope->all(RedeliveryStamp::class)) as $stamp) { + if (null !== $stamp->getExceptionMessage()) { + return $stamp; + } + } + + return null; + } } diff --git a/src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php b/src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php index 0444d79f447ff..b0f16b704e3d8 100644 --- a/src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php +++ b/src/Symfony/Component/Messenger/Command/FailedMessagesShowCommand.php @@ -18,7 +18,6 @@ use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Messenger\Stamp\RedeliveryStamp; use Symfony\Component\Messenger\Transport\Receiver\ListableReceiverInterface; /** @@ -83,14 +82,13 @@ private function listMessages(SymfonyStyle $io, int $max) $rows = []; foreach ($envelopes as $envelope) { - /** @var RedeliveryStamp|null $lastRedeliveryStamp */ - $lastRedeliveryStamp = $envelope->last(RedeliveryStamp::class); + $lastRedeliveryStampWithException = $this->getLastRedeliveryStampWithException($envelope); $rows[] = [ $this->getMessageId($envelope), \get_class($envelope->getMessage()), - null === $lastRedeliveryStamp ? '' : $lastRedeliveryStamp->getRedeliveredAt()->format('Y-m-d H:i:s'), - null === $lastRedeliveryStamp ? '' : $lastRedeliveryStamp->getExceptionMessage(), + null === $lastRedeliveryStampWithException ? '' : $lastRedeliveryStampWithException->getRedeliveredAt()->format('Y-m-d H:i:s'), + null === $lastRedeliveryStampWithException ? '' : $lastRedeliveryStampWithException->getExceptionMessage(), ]; } diff --git a/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesShowCommandTest.php b/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesShowCommandTest.php index 48c34fcaea9ba..8b437d7c76db9 100644 --- a/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesShowCommandTest.php +++ b/src/Symfony/Component/Messenger/Tests/Command/FailedMessagesShowCommandTest.php @@ -58,4 +58,40 @@ public function testBasicRun() $redeliveryStamp->getRedeliveredAt()->format('Y-m-d H:i:s')), $tester->getDisplay(true)); } + + public function testMultipleRedeliveryFails() + { + $sentToFailureStamp = new SentToFailureTransportStamp('async'); + $redeliveryStamp1 = new RedeliveryStamp(0, 'failure_receiver', 'Things are bad!'); + $redeliveryStamp2 = new RedeliveryStamp(0, 'failure_receiver'); + $envelope = new Envelope(new \stdClass(), [ + new TransportMessageIdStamp(15), + $sentToFailureStamp, + $redeliveryStamp1, + $redeliveryStamp2, + ]); + $receiver = $this->createMock(ListableReceiverInterface::class); + $receiver->expects($this->once())->method('find')->with(15)->willReturn($envelope); + + $command = new FailedMessagesShowCommand( + 'failure_receiver', + $receiver + ); + + $tester = new CommandTester($command); + $tester->execute(['id' => 15]); + + $this->assertStringContainsString(sprintf(<<getRedeliveredAt()->format('Y-m-d H:i:s')), + $tester->getDisplay(true)); + } } From 402fed02e7bd628c470bc02fb6d50988d9192f2b Mon Sep 17 00:00:00 2001 From: Anto Date: Wed, 23 Oct 2019 19:52:52 +0200 Subject: [PATCH 45/72] [WebProfilerBundle] Improve display in Email panel for dark theme --- .../Resources/views/Profiler/profiler.css.twig | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig index d737ab0e063ad..e5a731cf19ca8 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig @@ -46,6 +46,8 @@ --base-4: #666; --base-5: #444; --base-6: #222; + --card-label-background: #eee; + --card-label-color: var(--base-6); } .theme-dark { @@ -85,6 +87,8 @@ --base-4: #666; --base-5: #e0e0e0; --base-6: #f5f5f5; + --card-label-background: var(--tab-active-background); + --card-label-color: var(--tab-active-color); } {# Basic styles @@ -436,8 +440,8 @@ table tbody td.num-col { margin-top: 0; } .card .label { - background-color: #EEE; - color: var(--base-6); + background-color: var(--card-label-background); + color: var(--card-label-color); } {# Status From 50efc1a9234e56a7a3cbb7056178b37068a9e668 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Wed, 16 Oct 2019 09:16:00 -0400 Subject: [PATCH 46/72] Make sure to collect child forms created on *_SET_DATA events --- .../DataCollector/FormDataCollector.php | 3 +- .../DataCollector/FormDataCollectorTest.php | 66 ++++++++++++++++++- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php index 88fa453a62580..e8545232bf2fb 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php @@ -128,7 +128,8 @@ public function collectDefaultData(FormInterface $form) $hash = spl_object_hash($form); if (!isset($this->dataByForm[$hash])) { - $this->dataByForm[$hash] = []; + // field was created by form event + $this->collectConfiguration($form); } $this->dataByForm[$hash] = array_replace( diff --git a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php index 16aea8dfc4d5c..5cbc37b0a7628 100644 --- a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php @@ -13,10 +13,20 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\Form\Extension\Core\CoreExtension; +use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; +use Symfony\Component\Form\Extension\Core\Type\CollectionType; +use Symfony\Component\Form\Extension\Core\Type\FormType; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\DataCollector\FormDataCollector; use Symfony\Component\Form\Form; use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormFactory; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormRegistry; use Symfony\Component\Form\FormView; +use Symfony\Component\Form\ResolvedFormTypeFactory; class FormDataCollectorTest extends TestCase { @@ -69,9 +79,9 @@ protected function setUp() { $this->dataExtractor = $this->getMockBuilder('Symfony\Component\Form\Extension\DataCollector\FormDataExtractorInterface')->getMock(); $this->dataCollector = new FormDataCollector($this->dataExtractor); - $this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); - $this->factory = $this->getMockBuilder('Symfony\Component\Form\FormFactoryInterface')->getMock(); - $this->dataMapper = $this->getMockBuilder('Symfony\Component\Form\DataMapperInterface')->getMock(); + $this->dispatcher = new EventDispatcher(); + $this->factory = new FormFactory(new FormRegistry([new CoreExtension()], new ResolvedFormTypeFactory())); + $this->dataMapper = new PropertyPathMapper(); $this->form = $this->createForm('name'); $this->childForm = $this->createForm('child'); $this->view = new FormView(); @@ -726,6 +736,56 @@ public function testReset() ); } + public function testCollectMissingDataFromChildFormAddedOnFormEvents() + { + $form = $this->factory->createNamedBuilder('root', FormType::class, ['items' => null]) + ->add('items', CollectionType::class, [ + 'entry_type' => TextType::class, + 'allow_add' => true, + // data is locked and modelData (null) is different to the + // configured data, so modifications of the configured data + // won't be allowed at this point. It also means *_SET_DATA + // events won't dispatched either. Therefore, no child form + // is created during the mapping of data to the form. + 'data' => ['foo'], + ]) + ->getForm() + ; + $this->dataExtractor->expects($extractConfiguration = $this->exactly(4)) + ->method('extractConfiguration') + ->willReturn([]) + ; + $this->dataExtractor->expects($extractDefaultData = $this->exactly(4)) + ->method('extractDefaultData') + ->willReturnCallback(static function (FormInterface $form) { + // this simulate the call in extractDefaultData() method + // where (if defaultDataSet is false) it fires *_SET_DATA + // events, adding the form related to the configured data + $form->getNormData(); + + return []; + }) + ; + $this->dataExtractor->expects($this->exactly(4)) + ->method('extractSubmittedData') + ->willReturn([]) + ; + + $this->dataCollector->collectConfiguration($form); + $this->assertSame(2, $extractConfiguration->getInvocationCount(), 'only "root" and "items" forms were collected, the "items" children do not exist yet.'); + + $this->dataCollector->collectDefaultData($form); + $this->assertSame(3, $extractConfiguration->getInvocationCount(), 'extracted missing configuration of the "items" children ["0" => foo].'); + $this->assertSame(3, $extractDefaultData->getInvocationCount()); + $this->assertSame(['foo'], $form->get('items')->getData()); + + $form->submit(['items' => ['foo', 'bar']]); + $this->dataCollector->collectSubmittedData($form); + $this->assertSame(4, $extractConfiguration->getInvocationCount(), 'extracted missing configuration of the "items" children ["1" => bar].'); + $this->assertSame(4, $extractDefaultData->getInvocationCount(), 'extracted missing default data of the "items" children ["1" => bar].'); + $this->assertSame(['foo', 'bar'], $form->get('items')->getData()); + } + private function createForm($name) { $builder = new FormBuilder($name, null, $this->dispatcher, $this->factory); From 49acc164249e0409f3886267ebb63ebc936eeff7 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Thu, 24 Oct 2019 11:57:16 +0200 Subject: [PATCH 47/72] [Yaml][Parser] Remove the getLastLineNumberBeforeDeprecation() internal unused method --- src/Symfony/Component/Yaml/Parser.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index ef53f2a5e6e8c..d4e94a5ee3174 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -108,14 +108,6 @@ public function parse(string $value, int $flags = 0) return $data; } - /** - * @internal - */ - public function getLastLineNumberBeforeDeprecation(): int - { - return $this->getRealCurrentLineNb(); - } - private function doParse(string $value, int $flags) { $this->currentLineNb = -1; From c07cee8f61065d7fca0777fa6babb4aa73dcedc0 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Thu, 24 Oct 2019 14:44:17 +0200 Subject: [PATCH 48/72] Remove unused local variables in tests --- .../Tests/Form/Type/EntityTypeTest.php | 2 +- .../Twig/Node/SearchAndRenderBlockNode.php | 1 - .../Bridge/Twig/Tests/AppVariableTest.php | 4 ++-- .../Twig/Tests/Command/LintCommandTest.php | 2 +- .../Extension/StopwatchExtensionTest.php | 2 +- .../Extension/TranslationExtensionTest.php | 6 ++--- .../Console/Descriptor/TextDescriptor.php | 1 - .../FrameworkExtension.php | 2 -- .../Tests/Controller/ControllerTraitTest.php | 3 +-- .../AddConstraintValidatorsPassTest.php | 2 +- .../FrameworkExtensionTest.php | 2 +- .../DependencyInjection/TestExtension.php | 2 +- .../Tests/Functional/SessionTest.php | 2 +- .../Tests/Translation/TranslatorTest.php | 2 +- .../Security/Factory/AbstractFactoryTest.php | 4 ++-- .../GuardAuthenticationFactoryTest.php | 4 ++-- .../Component/BrowserKit/Tests/CookieTest.php | 2 +- .../Tests/Adapter/MaxIdLengthAdapterTest.php | 2 +- .../Tests/Loader/DelegatingLoaderTest.php | 2 +- .../Resource/ClassExistenceResourceTest.php | 2 +- .../Tests/Resource/DirectoryResourceTest.php | 4 ++-- .../Tests/Resource/FileResourceTest.php | 4 ++-- .../Console/Tests/ApplicationTest.php | 2 +- .../Tests/Helper/ProgressIndicatorTest.php | 2 +- .../Component/Debug/DebugClassLoader.php | 4 ++-- .../Tests/Exception/FlattenExceptionTest.php | 2 +- .../DependencyInjection/Dumper/PhpDumper.php | 2 +- .../AnalyzeServiceReferencesPassTest.php | 10 ++++---- .../Tests/Compiler/IntegrationTest.php | 2 +- .../ResolveChildDefinitionsPassTest.php | 2 +- .../Tests/Compiler/ResolveClassPassTest.php | 4 ++-- .../Tests/ContainerBuilderTest.php | 6 ++--- .../Tests/Dumper/PhpDumperTest.php | 3 +-- .../Tests/Loader/XmlFileLoaderTest.php | 1 - .../Tests/Field/ChoiceFormFieldTest.php | 4 ++-- .../Tests/Field/FileFormFieldTest.php | 4 ++-- .../Tests/Field/InputFormFieldTest.php | 6 ++--- .../Tests/Field/TextareaFormFieldTest.php | 2 +- .../Component/DomCrawler/Tests/FormTest.php | 24 +++++++++++++------ .../RegisterListenersPassTest.php | 4 ---- .../Tests/ExpressionLanguageTest.php | 4 ++-- .../ParserCache/ParserCacheAdapterTest.php | 2 +- ...teTimeToLocalizedStringTransformerTest.php | 4 ++-- .../Tests/File/UploadedFileTest.php | 2 +- .../HttpFoundation/Tests/HeaderBagTest.php | 2 +- .../Tests/RedirectResponseTest.php | 4 ++-- .../Handler/NativeFileSessionHandlerTest.php | 6 ++--- .../Handler/NullSessionHandlerTest.php | 2 +- .../Storage/Handler/PdoSessionHandlerTest.php | 2 +- .../Storage/NativeSessionStorageTest.php | 4 ++-- .../DataCollector/RequestDataCollector.php | 2 -- .../HttpCache/ResponseCacheStrategy.php | 1 - ...sterControllerArgumentLocatorsPassTest.php | 2 +- .../HttpKernel/Tests/HttpCache/StoreTest.php | 8 +++---- .../Process/Tests/ExecutableFinderTest.php | 3 --- .../Routing/Tests/Annotation/RouteTest.php | 2 +- .../Fixtures/AnnotatedClasses/FooTrait.php | 2 +- .../Dumper/PhpGeneratorDumperTest.php | 2 +- .../Tests/Loader/AnnotationFileLoaderTest.php | 3 --- .../Routing/Tests/RouteCompilerTest.php | 8 +++---- .../Core/Tests/Encoder/EncoderFactoryTest.php | 2 +- .../GuardAuthenticationProviderTest.php | 2 +- .../Tests/Firewall/LogoutListenerTest.php | 6 ++--- .../Tests/Firewall/RememberMeListenerTest.php | 4 ++-- .../RemoteUserAuthenticationListenerTest.php | 2 +- .../X509AuthenticationListenerTest.php | 2 +- .../Security/Http/Tests/FirewallTest.php | 2 -- .../Tests/RememberMe/ResponseListenerTest.php | 2 -- .../Tests/Loader/FilesystemLoaderTest.php | 1 - .../Validator/Constraints/FileValidator.php | 2 +- .../Tests/Constraints/FileValidatorTest.php | 2 +- .../Workflow/Tests/DefinitionBuilderTest.php | 2 +- .../Workflow/Tests/DefinitionTest.php | 4 ++-- .../Workflow/Tests/TransitionTest.php | 2 +- .../Component/Workflow/Tests/WorkflowTest.php | 6 ++--- .../Yaml/Tests/Command/LintCommandTest.php | 2 +- .../Component/Yaml/Tests/ParserTest.php | 2 +- 77 files changed, 118 insertions(+), 133 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index 1feabd1a451ca..147be98b90ce1 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -187,7 +187,7 @@ public function testSetDataToUninitializedEntityWithNonRequiredQueryBuilder() public function testConfigureQueryBuilderWithNonQueryBuilderAndNonClosure() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $field = $this->factory->createNamed('name', static::TESTED_TYPE, null, [ + $this->factory->createNamed('name', static::TESTED_TYPE, null, [ 'em' => 'default', 'class' => self::SINGLE_IDENT_CLASS, 'query_builder' => new \stdClass(), diff --git a/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php b/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php index 612bec14e5329..8925d588772a8 100644 --- a/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php +++ b/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php @@ -28,7 +28,6 @@ public function compile(Compiler $compiler) preg_match('/_([^_]+)$/', $this->getAttribute('name'), $matches); - $label = null; $arguments = iterator_to_array($this->getNode('arguments')); $blockNameSuffix = $matches[1]; diff --git a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php index 4a3f04fddef18..eb132e72022ba 100644 --- a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php +++ b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php @@ -180,10 +180,10 @@ public function testGetFlashes() $flashMessages = $this->setFlashMessages(); $this->assertEquals($flashMessages, $this->appVariable->getFlashes([])); - $flashMessages = $this->setFlashMessages(); + $this->setFlashMessages(); $this->assertEquals([], $this->appVariable->getFlashes('this-does-not-exist')); - $flashMessages = $this->setFlashMessages(); + $this->setFlashMessages(); $this->assertEquals( ['this-does-not-exist' => []], $this->appVariable->getFlashes(['this-does-not-exist']) diff --git a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php index db10ccb6c0904..84154512be15c 100644 --- a/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php @@ -52,7 +52,7 @@ public function testLintFileNotReadable() $filename = $this->createFile(''); unlink($filename); - $ret = $tester->execute(['filename' => [$filename]], ['decorated' => false]); + $tester->execute(['filename' => [$filename]], ['decorated' => false]); } public function testLintFileCompileTimeException() diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/StopwatchExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/StopwatchExtensionTest.php index 2b38122e56410..35f3baa1b9b99 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/StopwatchExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/StopwatchExtensionTest.php @@ -34,7 +34,7 @@ public function testTiming($template, $events) $twig->addExtension(new StopwatchExtension($this->getStopwatch($events))); try { - $nodes = $twig->render('template'); + $twig->render('template'); } catch (RuntimeError $e) { throw $e->getPrevious(); } diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php index aeb109fd250d3..206cda6783d3d 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php @@ -49,21 +49,21 @@ public function testTransUnknownKeyword() { $this->expectException('Twig\Error\SyntaxError'); $this->expectExceptionMessage('Unexpected token. Twig was looking for the "with", "from", or "into" keyword in "index" at line 3.'); - $output = $this->getTemplate("{% trans \n\nfoo %}{% endtrans %}")->render(); + $this->getTemplate("{% trans \n\nfoo %}{% endtrans %}")->render(); } public function testTransComplexBody() { $this->expectException('Twig\Error\SyntaxError'); $this->expectExceptionMessage('A message inside a trans tag must be a simple text in "index" at line 2.'); - $output = $this->getTemplate("{% trans %}\n{{ 1 + 2 }}{% endtrans %}")->render(); + $this->getTemplate("{% trans %}\n{{ 1 + 2 }}{% endtrans %}")->render(); } public function testTransChoiceComplexBody() { $this->expectException('Twig\Error\SyntaxError'); $this->expectExceptionMessage('A message inside a transchoice tag must be a simple text in "index" at line 2.'); - $output = $this->getTemplate("{% transchoice count %}\n{{ 1 + 2 }}{% endtranschoice %}")->render(); + $this->getTemplate("{% transchoice count %}\n{{ 1 + 2 }}{% endtranschoice %}")->render(); } public function getTransTests() diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index 43a811b92dba7..f17a1bba21218 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -425,7 +425,6 @@ private function renderEventListenerTable(EventDispatcherInterface $eventDispatc $tableHeaders = ['Order', 'Callable', 'Priority']; $tableRows = []; - $order = 1; foreach ($eventListeners as $order => $listener) { $tableRows[] = [sprintf('#%d', $order + 1), $this->formatCallable($listener), $eventDispatcher->getListenerPriority($event, $listener)]; } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index a190dba908a01..3e28e52ad3d0a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1043,8 +1043,6 @@ private function registerAssetsConfiguration(array $config, ContainerBuilder $co $container->getDefinition('assets.url_package')->setPrivate(true); $container->getDefinition('assets.static_version_strategy')->setPrivate(true); - $defaultVersion = null; - if ($config['version_strategy']) { $defaultVersion = new Reference($config['version_strategy']); } else { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php index 169dba0e29f8d..c039345653fd2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php @@ -277,8 +277,7 @@ public function testFileWhichDoesNotExist() $this->expectException('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException'); $controller = $this->createController(); - /* @var BinaryFileResponse $response */ - $response = $controller->file('some-file.txt', 'test.php'); + $controller->file('some-file.txt', 'test.php'); } public function testIsGranted() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php index 81a8512858d89..1d998395e2e0d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php @@ -51,7 +51,7 @@ public function testAbstractConstraintValidator() $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('The service "my_abstract_constraint_validator" tagged "validator.constraint_validator" must not be abstract.'); $container = new ContainerBuilder(); - $validatorFactory = $container->register('validator.validator_factory') + $container->register('validator.validator_factory') ->addArgument([]); $container->register('my_abstract_constraint_validator') diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 431cc0c084a73..556fd9afd48e5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -251,7 +251,7 @@ public function testWorkflows() */ public function testDeprecatedWorkflowMissingType() { - $container = $this->createContainerFromFile('workflows_without_type'); + $this->createContainerFromFile('workflows_without_type'); } public function testWorkflowCannotHaveBothTypeAndService() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/DependencyInjection/TestExtension.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/DependencyInjection/TestExtension.php index 59670fdd19a24..0ae7669ce803a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/DependencyInjection/TestExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/DependencyInjection/TestExtension.php @@ -26,7 +26,7 @@ class TestExtension extends Extension implements PrependExtensionInterface public function load(array $configs, ContainerBuilder $container) { $configuration = $this->getConfiguration($configs, $container); - $config = $this->processConfiguration($configuration, $configs); + $this->processConfiguration($configuration, $configs); $container->setAlias('test.annotation_reader', new Alias('annotation_reader', true)); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php index c99b5e073e49a..3a87f7e4e6e0a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SessionTest.php @@ -59,7 +59,7 @@ public function testFlash($config, $insulate) } // set flash - $crawler = $client->request('GET', '/session_setflash/Hello%20world.'); + $client->request('GET', '/session_setflash/Hello%20world.'); // check flash displays on redirect $this->assertStringContainsString('Hello world.', $client->followRedirect()->text()); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index c9396624f0bac..e38e11601b66e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -162,7 +162,7 @@ public function testGetDefaultLocaleOmittingLocaleWithPsrContainer() $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('Missing third $defaultLocale argument.'); $container = $this->getMockBuilder(ContainerInterface::class)->getMock(); - $translator = new Translator($container, new MessageFormatter()); + new Translator($container, new MessageFormatter()); } /** diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php index 9eb9a08177700..01e03b0312bd9 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php @@ -61,7 +61,7 @@ public function testDefaultFailureHandler($serviceId, $defaultHandlerInjection) $options['failure_handler'] = $serviceId; } - list($container, $authProviderId, $listenerId, $entryPointId) = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); + list($container) = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); $definition = $container->getDefinition('abstract_listener.foo'); $arguments = $definition->getArguments(); @@ -99,7 +99,7 @@ public function testDefaultSuccessHandler($serviceId, $defaultHandlerInjection) $options['success_handler'] = $serviceId; } - list($container, $authProviderId, $listenerId, $entryPointId) = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); + list($container) = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); $definition = $container->getDefinition('abstract_listener.foo'); $arguments = $definition->getArguments(); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php index f327eece8f99c..fd812c13ae04c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php @@ -159,7 +159,7 @@ public function testCreateWithEntryPoint() 'authenticators' => ['authenticator123', 'authenticatorABC'], 'entry_point' => 'authenticatorABC', ]; - list($container, $entryPointId) = $this->executeCreate($config, null); + list(, $entryPointId) = $this->executeCreate($config, null); $this->assertEquals('authenticatorABC', $entryPointId); } @@ -172,7 +172,7 @@ private function executeCreate(array $config, $defaultEntryPointId) $userProviderId = 'my_user_provider'; $factory = new GuardAuthenticationFactory(); - list($providerId, $listenerId, $entryPointId) = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId); + list(, , $entryPointId) = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId); return [$container, $entryPointId]; } diff --git a/src/Symfony/Component/BrowserKit/Tests/CookieTest.php b/src/Symfony/Component/BrowserKit/Tests/CookieTest.php index 1404da9a1c089..84c4a0c2e0fb1 100644 --- a/src/Symfony/Component/BrowserKit/Tests/CookieTest.php +++ b/src/Symfony/Component/BrowserKit/Tests/CookieTest.php @@ -198,6 +198,6 @@ public function testConstructException() { $this->expectException('UnexpectedValueException'); $this->expectExceptionMessage('The cookie expiration time "string" is not valid.'); - $cookie = new Cookie('foo', 'bar', 'string'); + new Cookie('foo', 'bar', 'string'); } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/MaxIdLengthAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/MaxIdLengthAdapterTest.php index 909191960f179..536e2c2d4d0bc 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/MaxIdLengthAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/MaxIdLengthAdapterTest.php @@ -70,7 +70,7 @@ public function testTooLongNamespace() { $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); $this->expectExceptionMessage('Namespace must be 26 chars max, 40 given ("----------------------------------------")'); - $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) + $this->getMockBuilder(MaxIdLengthAdapter::class) ->setConstructorArgs([str_repeat('-', 40)]) ->getMock(); } diff --git a/src/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php b/src/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php index 438af9f286eae..38ae6ff7b8529 100644 --- a/src/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php +++ b/src/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php @@ -19,7 +19,7 @@ class DelegatingLoaderTest extends TestCase { public function testConstructor() { - $loader = new DelegatingLoader($resolver = new LoaderResolver()); + new DelegatingLoader($resolver = new LoaderResolver()); $this->assertTrue(true, '__construct() takes a loader resolver as its first argument'); } diff --git a/src/Symfony/Component/Config/Tests/Resource/ClassExistenceResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ClassExistenceResourceTest.php index 6b38e33baf4a2..ad331240debaf 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ClassExistenceResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ClassExistenceResourceTest.php @@ -67,7 +67,7 @@ public function testExistsKo() $loadedClass = 123; - $res = new ClassExistenceResource('MissingFooClass', false); + new ClassExistenceResource('MissingFooClass', false); $this->assertSame(123, $loadedClass); } finally { diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index 69f781c2e980e..40b179010196d 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -67,7 +67,7 @@ public function testResourceDoesNotExist() { $this->expectException('InvalidArgumentException'); $this->expectExceptionMessageRegExp('/The directory ".*" does not exist./'); - $resource = new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999)); + new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999)); } public function testIsFresh() @@ -165,7 +165,7 @@ public function testSerializeUnserialize() { $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); - $unserialized = unserialize(serialize($resource)); + unserialize(serialize($resource)); $this->assertSame(realpath($this->directory), $resource->getResource()); $this->assertSame('/\.(foo|xml)$/', $resource->getPattern()); diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php index bf9e6f3155b73..968c7e9266169 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -57,7 +57,7 @@ public function testResourceDoesNotExist() { $this->expectException('InvalidArgumentException'); $this->expectExceptionMessageRegExp('/The file ".*" does not exist./'); - $resource = new FileResource('/____foo/foobar'.mt_rand(1, 999999)); + new FileResource('/____foo/foobar'.mt_rand(1, 999999)); } public function testIsFresh() @@ -76,7 +76,7 @@ public function testIsFreshForDeletedResources() public function testSerializeUnserialize() { - $unserialized = unserialize(serialize($this->resource)); + unserialize(serialize($this->resource)); $this->assertSame(realpath($this->file), $this->resource->getResource()); } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index d61418f37ba47..1ef2ed3d78d7a 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -521,7 +521,7 @@ public function testFindAlternativeExceptionMessageMultiple() // Subnamespace + plural try { - $a = $application->find('foo3:'); + $application->find('foo3:'); $this->fail('->find() should throw an Symfony\Component\Console\Exception\CommandNotFoundException if a command is ambiguous because of a subnamespace, with alternatives'); } catch (\Exception $e) { $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e); diff --git a/src/Symfony/Component/Console/Tests/Helper/ProgressIndicatorTest.php b/src/Symfony/Component/Console/Tests/Helper/ProgressIndicatorTest.php index 6d803fc251efe..1428cf5e97a5f 100644 --- a/src/Symfony/Component/Console/Tests/Helper/ProgressIndicatorTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/ProgressIndicatorTest.php @@ -104,7 +104,7 @@ public function testCannotSetInvalidIndicatorCharacters() { $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('Must have at least 2 indicator value characters.'); - $bar = new ProgressIndicator($this->getOutputStream(), null, 100, ['1']); + new ProgressIndicator($this->getOutputStream(), null, 100, ['1']); } public function testCannotStartAlreadyStartedIndicator() diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index a3b7ac63234ea..b0174187afd06 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -404,7 +404,7 @@ private function darwinRealpath($real) } if (isset($dirFiles[$file])) { - return $real .= $dirFiles[$file]; + return $real.$dirFiles[$file]; } $kFile = strtolower($file); @@ -423,7 +423,7 @@ private function darwinRealpath($real) self::$darwinCache[$kDir][1] = $dirFiles; } - return $real .= $dirFiles[$kFile]; + return $real.$dirFiles[$kFile]; } /** diff --git a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php index bcb86b4e3f39f..0290b05bad484 100644 --- a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php +++ b/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php @@ -256,7 +256,7 @@ function () {}, // assertEquals() does not like NAN values. $this->assertEquals($array[$i][0], 'float'); - $this->assertNan($array[$i++][1]); + $this->assertNan($array[$i][1]); } public function testRecursionInArguments() diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index b6d0b03b2b24a..7596b9953bda4 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -219,7 +219,7 @@ public function dump(array $options = []) foreach ($ids as $id) { $c .= ' '.$this->doExport($id)." => true,\n"; } - $files['removed-ids.php'] = $c .= "];\n"; + $files['removed-ids.php'] = $c."];\n"; } foreach ($this->generateServiceFiles() as $file => $c) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php index 0bd94a3e609cb..66b6e19cc323a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php @@ -25,28 +25,28 @@ public function testProcess() { $container = new ContainerBuilder(); - $a = $container + $container ->register('a') ->addArgument($ref1 = new Reference('b')) ; - $b = $container + $container ->register('b') ->addMethodCall('setA', [$ref2 = new Reference('a')]) ; - $c = $container + $container ->register('c') ->addArgument($ref3 = new Reference('a')) ->addArgument($ref4 = new Reference('b')) ; - $d = $container + $container ->register('d') ->setProperty('foo', $ref5 = new Reference('b')) ; - $e = $container + $container ->register('e') ->setConfigurator([$ref6 = new Reference('b'), 'methodName']) ; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php index 10c34aa489d45..348d1d7f53584 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php @@ -43,7 +43,7 @@ public function testProcessRemovesAndInlinesRecursively() ->addArgument(new Reference('c')) ; - $b = $container + $container ->register('b', '\stdClass') ->addArgument(new Reference('c')) ->setPublic(false) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php index 27bb9157c8fc0..eee4cf730c881 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php @@ -390,7 +390,7 @@ public function testBindings() ->setBindings(['a' => '1', 'b' => '2']) ; - $child = $container->setDefinition('child', new ChildDefinition('parent')) + $container->setDefinition('child', new ChildDefinition('parent')) ->setBindings(['b' => 'B', 'c' => 'C']) ; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php index 0ab6303164688..81e05fb284bf2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php @@ -87,8 +87,8 @@ public function testAmbiguousChildDefinition() $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); $this->expectExceptionMessage('Service definition "App\Foo\Child" has a parent but no class, and its name looks like a FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.'); $container = new ContainerBuilder(); - $parent = $container->register('App\Foo', null); - $child = $container->setDefinition('App\Foo\Child', new ChildDefinition('App\Foo')); + $container->register('App\Foo', null); + $container->setDefinition('App\Foo\Child', new ChildDefinition('App\Foo')); (new ResolveClassPass())->process($container); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 199179c9b4998..f2666ef9629b3 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1265,7 +1265,7 @@ public function testNoClassFromGlobalNamespaceClassId() $this->expectExceptionMessage('The definition for "DateTime" has no class attribute, and appears to reference a class or interface in the global namespace.'); $container = new ContainerBuilder(); - $definition = $container->register(\DateTime::class); + $container->register(\DateTime::class); $container->compile(); } @@ -1295,7 +1295,7 @@ public function testNoClassFromNonClassId() $this->expectExceptionMessage('The definition for "123_abc" has no class.'); $container = new ContainerBuilder(); - $definition = $container->register('123_abc'); + $container->register('123_abc'); $container->compile(); } @@ -1305,7 +1305,7 @@ public function testNoClassFromNsSeparatorId() $this->expectExceptionMessage('The definition for "\foo" has no class.'); $container = new ContainerBuilder(); - $definition = $container->register('\\foo'); + $container->register('\\foo'); $container->compile(); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 4e6083d99814f..b2cbb3caf6283 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -886,7 +886,7 @@ public function testInlineSelfRef() ->setPublic(true) ->addArgument($baz); - $passConfig = $container->getCompiler()->getPassConfig(); + $container->getCompiler()->getPassConfig(); $container->compile(); $dumper = new PhpDumper($container); @@ -978,7 +978,6 @@ public function testAdawsonContainer() $container->compile(); $dumper = new PhpDumper($container); - $dump = $dumper->dump(); $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_adawson.php', $dumper->dump()); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 1b6e51c56757e..2b963968d8411 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -808,7 +808,6 @@ public function testTsantosContainer() $container->compile(); $dumper = new PhpDumper($container); - $dump = $dumper->dump(); $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_tsantos.php', $dumper->dump()); } diff --git a/src/Symfony/Component/DomCrawler/Tests/Field/ChoiceFormFieldTest.php b/src/Symfony/Component/DomCrawler/Tests/Field/ChoiceFormFieldTest.php index 61e776736a4b5..176ea5927fe1c 100644 --- a/src/Symfony/Component/DomCrawler/Tests/Field/ChoiceFormFieldTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/Field/ChoiceFormFieldTest.php @@ -19,7 +19,7 @@ public function testInitialize() { $node = $this->createNode('textarea', ''); try { - $field = new ChoiceFormField($node); + new ChoiceFormField($node); $this->fail('->initialize() throws a \LogicException if the node is not an input or a select'); } catch (\LogicException $e) { $this->assertTrue(true, '->initialize() throws a \LogicException if the node is not an input or a select'); @@ -27,7 +27,7 @@ public function testInitialize() $node = $this->createNode('input', '', ['type' => 'text']); try { - $field = new ChoiceFormField($node); + new ChoiceFormField($node); $this->fail('->initialize() throws a \LogicException if the node is an input with a type different from checkbox or radio'); } catch (\LogicException $e) { $this->assertTrue(true, '->initialize() throws a \LogicException if the node is an input with a type different from checkbox or radio'); diff --git a/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php b/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php index 9b359d69785b3..b14bcc855e2ab 100644 --- a/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php @@ -24,7 +24,7 @@ public function testInitialize() $node = $this->createNode('textarea', ''); try { - $field = new FileFormField($node); + new FileFormField($node); $this->fail('->initialize() throws a \LogicException if the node is not an input field'); } catch (\LogicException $e) { $this->assertTrue(true, '->initialize() throws a \LogicException if the node is not an input field'); @@ -32,7 +32,7 @@ public function testInitialize() $node = $this->createNode('input', '', ['type' => 'text']); try { - $field = new FileFormField($node); + new FileFormField($node); $this->fail('->initialize() throws a \LogicException if the node is not a file input field'); } catch (\LogicException $e) { $this->assertTrue(true, '->initialize() throws a \LogicException if the node is not a file input field'); diff --git a/src/Symfony/Component/DomCrawler/Tests/Field/InputFormFieldTest.php b/src/Symfony/Component/DomCrawler/Tests/Field/InputFormFieldTest.php index 5758f1b7bb3fe..a1f327bbc2f81 100644 --- a/src/Symfony/Component/DomCrawler/Tests/Field/InputFormFieldTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/Field/InputFormFieldTest.php @@ -24,7 +24,7 @@ public function testInitialize() $node = $this->createNode('textarea', ''); try { - $field = new InputFormField($node); + new InputFormField($node); $this->fail('->initialize() throws a \LogicException if the node is not an input'); } catch (\LogicException $e) { $this->assertTrue(true, '->initialize() throws a \LogicException if the node is not an input'); @@ -32,7 +32,7 @@ public function testInitialize() $node = $this->createNode('input', '', ['type' => 'checkbox']); try { - $field = new InputFormField($node); + new InputFormField($node); $this->fail('->initialize() throws a \LogicException if the node is a checkbox'); } catch (\LogicException $e) { $this->assertTrue(true, '->initialize() throws a \LogicException if the node is a checkbox'); @@ -40,7 +40,7 @@ public function testInitialize() $node = $this->createNode('input', '', ['type' => 'file']); try { - $field = new InputFormField($node); + new InputFormField($node); $this->fail('->initialize() throws a \LogicException if the node is a file'); } catch (\LogicException $e) { $this->assertTrue(true, '->initialize() throws a \LogicException if the node is a file'); diff --git a/src/Symfony/Component/DomCrawler/Tests/Field/TextareaFormFieldTest.php b/src/Symfony/Component/DomCrawler/Tests/Field/TextareaFormFieldTest.php index 5d4d0038260db..192984ce29c2f 100644 --- a/src/Symfony/Component/DomCrawler/Tests/Field/TextareaFormFieldTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/Field/TextareaFormFieldTest.php @@ -24,7 +24,7 @@ public function testInitialize() $node = $this->createNode('input', ''); try { - $field = new TextareaFormField($node); + new TextareaFormField($node); $this->fail('->initialize() throws a \LogicException if the node is not a textarea'); } catch (\LogicException $e) { $this->assertTrue(true, '->initialize() throws a \LogicException if the node is not a textarea'); diff --git a/src/Symfony/Component/DomCrawler/Tests/FormTest.php b/src/Symfony/Component/DomCrawler/Tests/FormTest.php index 504a9bd4251d9..45d964b08c8d3 100644 --- a/src/Symfony/Component/DomCrawler/Tests/FormTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/FormTest.php @@ -39,14 +39,14 @@ public function testConstructorThrowsExceptionIfTheNodeHasNoFormAncestor() $nodes = $dom->getElementsByTagName('input'); try { - $form = new Form($nodes->item(0), 'http://example.com'); + new Form($nodes->item(0), 'http://example.com'); $this->fail('__construct() throws a \\LogicException if the node has no form ancestor'); } catch (\LogicException $e) { $this->assertTrue(true, '__construct() throws a \\LogicException if the node has no form ancestor'); } try { - $form = new Form($nodes->item(1), 'http://example.com'); + new Form($nodes->item(1), 'http://example.com'); $this->fail('__construct() throws a \\LogicException if the input type is not submit, button, or image'); } catch (\LogicException $e) { $this->assertTrue(true, '__construct() throws a \\LogicException if the input type is not submit, button, or image'); @@ -55,7 +55,7 @@ public function testConstructorThrowsExceptionIfTheNodeHasNoFormAncestor() $nodes = $dom->getElementsByTagName('button'); try { - $form = new Form($nodes->item(0), 'http://example.com'); + new Form($nodes->item(0), 'http://example.com'); $this->fail('__construct() throws a \\LogicException if the node has no form ancestor'); } catch (\LogicException $e) { $this->assertTrue(true, '__construct() throws a \\LogicException if the node has no form ancestor'); @@ -63,11 +63,19 @@ public function testConstructorThrowsExceptionIfTheNodeHasNoFormAncestor() } /** - * __construct() should throw \\LogicException if the form attribute is invalid. + * @dataProvider constructorThrowsExceptionIfNoRelatedFormProvider + * + * __construct() should throw a \LogicException if the form attribute is invalid. */ - public function testConstructorThrowsExceptionIfNoRelatedForm() + public function testConstructorThrowsExceptionIfNoRelatedForm(\DOMElement $node) { $this->expectException('LogicException'); + + new Form($node, 'http://example.com'); + } + + public function constructorThrowsExceptionIfNoRelatedFormProvider() + { $dom = new \DOMDocument(); $dom->loadHTML(' @@ -81,8 +89,10 @@ public function testConstructorThrowsExceptionIfNoRelatedForm() $nodes = $dom->getElementsByTagName('input'); - $form = new Form($nodes->item(0), 'http://example.com'); - $form = new Form($nodes->item(1), 'http://example.com'); + return [ + [$nodes->item(0)], + [$nodes->item(1)], + ]; } public function testConstructorLoadsOnlyFieldsOfTheRightForm() diff --git a/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php b/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php index 34e28bcbb21fc..61c047af39c46 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php @@ -37,10 +37,6 @@ public function testEventSubscriberWithoutInterface() public function testValidEventSubscriber() { - $services = [ - 'my_event_subscriber' => [0 => []], - ]; - $builder = new ContainerBuilder(); $eventDispatcherDefinition = $builder->register('event_dispatcher'); $builder->register('my_event_subscriber', 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService') diff --git a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php index 22d1d1649da12..f69ee57982e8a 100644 --- a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php +++ b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php @@ -98,7 +98,7 @@ public function testWrongCacheImplementation() $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('Cache argument has to implement Psr\Cache\CacheItemPoolInterface.'); $cacheMock = $this->getMockBuilder('Psr\Cache\CacheItemSpoolInterface')->getMock(); - $expressionLanguage = new ExpressionLanguage($cacheMock); + new ExpressionLanguage($cacheMock); } public function testConstantFunction() @@ -196,7 +196,7 @@ public function testCachingWithDifferentNamesOrder() $cacheMock = $this->getMockBuilder('Psr\Cache\CacheItemPoolInterface')->getMock(); $cacheItemMock = $this->getMockBuilder('Psr\Cache\CacheItemInterface')->getMock(); $expressionLanguage = new ExpressionLanguage($cacheMock); - $savedParsedExpressions = []; + $savedParsedExpression = null; $cacheMock ->expects($this->exactly(2)) diff --git a/src/Symfony/Component/ExpressionLanguage/Tests/ParserCache/ParserCacheAdapterTest.php b/src/Symfony/Component/ExpressionLanguage/Tests/ParserCache/ParserCacheAdapterTest.php index 28e9ef5725043..2e9263307f0dd 100644 --- a/src/Symfony/Component/ExpressionLanguage/Tests/ParserCache/ParserCacheAdapterTest.php +++ b/src/Symfony/Component/ExpressionLanguage/Tests/ParserCache/ParserCacheAdapterTest.php @@ -68,7 +68,7 @@ public function testSave() ->willReturn($value) ; - $cacheItem = $parserCacheAdapter->save($cacheItemMock); + $parserCacheAdapter->save($cacheItemMock); } public function testGetItems() diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php index d4602b88fd66a..ce91d05ff4b6c 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php @@ -181,10 +181,10 @@ public function testTransformRequiresValidDateTime() public function testTransformWrapsIntlErrors() { - $transformer = new DateTimeToLocalizedStringTransformer(); - $this->markTestIncomplete('Checking for intl errors needs to be reimplemented'); + $transformer = new DateTimeToLocalizedStringTransformer(); + // HOW TO REPRODUCE? //$this->expectException('Symfony\Component\Form\Extension\Core\DataTransformer\TransformationFailedException'); diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php b/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php index 4186c72a62c2f..2ea924bac2a4d 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php @@ -153,7 +153,7 @@ public function testMoveLocalFileIsNotAllowed() UPLOAD_ERR_OK ); - $movedFile = $file->move(__DIR__.'/Fixtures/directory'); + $file->move(__DIR__.'/Fixtures/directory'); } public function testMoveLocalFileIsAllowedInTestMode() diff --git a/src/Symfony/Component/HttpFoundation/Tests/HeaderBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/HeaderBagTest.php index dcc266f69c41a..cabe038bdf00b 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/HeaderBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/HeaderBagTest.php @@ -59,7 +59,7 @@ public function testGetDateException() { $this->expectException('RuntimeException'); $bag = new HeaderBag(['foo' => 'Tue']); - $headerDate = $bag->getDate('foo'); + $bag->getDate('foo'); } public function testGetCacheControlHeader() diff --git a/src/Symfony/Component/HttpFoundation/Tests/RedirectResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/RedirectResponseTest.php index 92f4876da4ff1..e1ff3bf2bdb98 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RedirectResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RedirectResponseTest.php @@ -29,13 +29,13 @@ public function testGenerateMetaRedirect() public function testRedirectResponseConstructorNullUrl() { $this->expectException('InvalidArgumentException'); - $response = new RedirectResponse(null); + new RedirectResponse(null); } public function testRedirectResponseConstructorWrongStatusCode() { $this->expectException('InvalidArgumentException'); - $response = new RedirectResponse('foo.bar', 404); + new RedirectResponse('foo.bar', 404); } public function testGenerateLocationHeader() diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php index 9daf1a0eeee7a..7de55798a6413 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php @@ -41,7 +41,7 @@ public function testConstruct() */ public function testConstructSavePath($savePath, $expectedSavePath, $path) { - $handler = new NativeFileSessionHandler($savePath); + new NativeFileSessionHandler($savePath); $this->assertEquals($expectedSavePath, ini_get('session.save_path')); $this->assertDirectoryExists(realpath($path)); @@ -62,13 +62,13 @@ public function savePathDataProvider() public function testConstructException() { $this->expectException('InvalidArgumentException'); - $handler = new NativeFileSessionHandler('something;invalid;with;too-many-args'); + new NativeFileSessionHandler('something;invalid;with;too-many-args'); } public function testConstructDefault() { $path = ini_get('session.save_path'); - $storage = new NativeSessionStorage(['name' => 'TESTING'], new NativeFileSessionHandler()); + new NativeSessionStorage(['name' => 'TESTING'], new NativeFileSessionHandler()); $this->assertEquals($path, ini_get('session.save_path')); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php index 0d246e1aa560b..f793db144c6ac 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php @@ -28,7 +28,7 @@ class NullSessionHandlerTest extends TestCase { public function testSaveHandlers() { - $storage = $this->getStorage(); + $this->getStorage(); $this->assertEquals('user', ini_get('session.save_handler')); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php index 123b605d28600..e710dca92cf8c 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php @@ -54,7 +54,7 @@ public function testWrongPdoErrMode() $pdo = $this->getMemorySqlitePdo(); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_SILENT); - $storage = new PdoSessionHandler($pdo); + new PdoSessionHandler($pdo); } public function testInexistentTable() diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php index fa170d17d3b32..9ce8108dacc61 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php @@ -145,7 +145,7 @@ public function testDefaultSessionCacheLimiter() { $this->iniSet('session.cache_limiter', 'nocache'); - $storage = new NativeSessionStorage(); + new NativeSessionStorage(); $this->assertEquals('', ini_get('session.cache_limiter')); } @@ -153,7 +153,7 @@ public function testExplicitSessionCacheLimiter() { $this->iniSet('session.cache_limiter', 'nocache'); - $storage = new NativeSessionStorage(['cache_limiter' => 'public']); + new NativeSessionStorage(['cache_limiter' => 'public']); $this->assertEquals('public', ini_get('session.cache_limiter')); } diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index 671865aa16b17..246c0c7f6f2ee 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -49,7 +49,6 @@ public function collect(Request $request, Response $response, \Exception $except } } - $content = null; try { $content = $request->getContent(); } catch (\LogicException $e) { @@ -59,7 +58,6 @@ public function collect(Request $request, Response $response, \Exception $except $sessionMetadata = []; $sessionAttributes = []; - $session = null; $flashes = []; if ($request->hasSession()) { $session = $request->getSession(); diff --git a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php index 25c071c335a02..3bdf0f5199891 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/ResponseCacheStrategy.php @@ -130,7 +130,6 @@ public function update(Response $response) $response->headers->set('Cache-Control', implode(', ', array_keys($flags))); $maxAge = null; - $sMaxage = null; if (is_numeric($this->ageDirectives['max-age'])) { $maxAge = $this->ageDirectives['max-age'] + $this->age; diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php index 32cfcb8604a84..ef4c8b2172f67 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php @@ -256,7 +256,7 @@ public function testArgumentWithNoTypeHintIsOk() public function testControllersAreMadePublic() { $container = new ContainerBuilder(); - $resolver = $container->register('argument_resolver.service')->addArgument([]); + $container->register('argument_resolver.service')->addArgument([]); $container->register('foo', ArgumentWithoutTypeController::class) ->setPublic(false) diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php index fc47ff2c88c56..77cb34cfa5556 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php @@ -52,7 +52,7 @@ public function testReadsAnEmptyArrayWithReadWhenNothingCachedAtKey() public function testUnlockFileThatDoesExist() { - $cacheKey = $this->storeSimpleEntry(); + $this->storeSimpleEntry(); $this->store->lock($this->request); $this->assertTrue($this->store->unlock($this->request)); @@ -92,7 +92,7 @@ public function testSetsTheXContentDigestResponseHeaderBeforeStoring() { $cacheKey = $this->storeSimpleEntry(); $entries = $this->getStoreMetadata($cacheKey); - list($req, $res) = $entries[0]; + list(, $res) = $entries[0]; $this->assertEquals('en9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', $res['x-content-digest'][0]); } @@ -208,7 +208,7 @@ public function testOverwritesNonVaryingResponseWithStore() { $req1 = Request::create('/test', 'get', [], [], [], ['HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bar']); $res1 = new Response('test 1', 200, ['Vary' => 'Foo Bar']); - $key = $this->store->write($req1, $res1); + $this->store->write($req1, $res1); $this->assertEquals($this->getStorePath('en'.hash('sha256', 'test 1')), $this->store->lookup($req1)->getContent()); $req2 = Request::create('/test', 'get', [], [], [], ['HTTP_FOO' => 'Bling', 'HTTP_BAR' => 'Bam']); @@ -229,7 +229,7 @@ public function testLocking() $req = Request::create('/test', 'get', [], [], [], ['HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bar']); $this->assertTrue($this->store->lock($req)); - $path = $this->store->lock($req); + $this->store->lock($req); $this->assertTrue($this->store->isLocked($req)); $this->store->unlock($req); diff --git a/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php b/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php index a437f2bb6f771..2942695af37e4 100644 --- a/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php +++ b/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php @@ -132,9 +132,6 @@ public function testFindProcessInOpenBasedir() $this->assertSamePath(PHP_BINARY, $result); } - /** - * @requires PHP 5.4 - */ public function testFindBatchExecutableOnWindows() { if (ini_get('open_basedir')) { diff --git a/src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php b/src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php index 08eed456aaa7a..b698be8f667dc 100644 --- a/src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php +++ b/src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php @@ -19,7 +19,7 @@ class RouteTest extends TestCase public function testInvalidRouteParameter() { $this->expectException('BadMethodCallException'); - $route = new Route(['foo' => 'bar']); + new Route(['foo' => 'bar']); } /** diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php b/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php index ee8f4b071a368..c06fb43f6887e 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php @@ -6,7 +6,7 @@ trait FooTrait { public function doBar() { - $baz = self::class; + self::class; if (true) { } } diff --git a/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php b/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php index d3ddb9f3b1838..4e725fa8bb510 100644 --- a/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php +++ b/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php @@ -135,7 +135,7 @@ public function testGenerateNonExistingRoute() include $this->testTmpFilepath; $projectUrlGenerator = new \NonExistingRoutesUrlGenerator(new RequestContext()); - $url = $projectUrlGenerator->generate('NonExisting', []); + $projectUrlGenerator->generate('NonExisting', []); } public function testDumpForRouteWithDefaults() diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php index 8af8e2e14ff2d..0b1175f605eec 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationFileLoaderTest.php @@ -35,9 +35,6 @@ public function testLoad() $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php'); } - /** - * @requires PHP 5.4 - */ public function testLoadTraitWithClassConstant() { $this->reader->expects($this->never())->method('getClassAnnotation'); diff --git a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php index a460c6651cc65..b398b2f35e90f 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -248,7 +248,7 @@ public function testRouteWithSameVariableTwice() $this->expectException('LogicException'); $route = new Route('/{name}/{name}'); - $compiled = $route->compile(); + $route->compile(); } public function testRouteCharsetMismatch() @@ -256,7 +256,7 @@ public function testRouteCharsetMismatch() $this->expectException('LogicException'); $route = new Route("/\xE9/{bar}", [], ['bar' => '.'], ['utf8' => true]); - $compiled = $route->compile(); + $route->compile(); } public function testRequirementCharsetMismatch() @@ -264,7 +264,7 @@ public function testRequirementCharsetMismatch() $this->expectException('LogicException'); $route = new Route('/foo/{bar}', [], ['bar' => "\xE9"], ['utf8' => true]); - $compiled = $route->compile(); + $route->compile(); } public function testRouteWithFragmentAsPathParameter() @@ -272,7 +272,7 @@ public function testRouteWithFragmentAsPathParameter() $this->expectException('InvalidArgumentException'); $route = new Route('/{_fragment}'); - $compiled = $route->compile(); + $route->compile(); } /** diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php index 0b2c36c72de4a..48b7ebcbb269f 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php @@ -117,7 +117,7 @@ public function testGetInvalidNamedEncoderForEncoderAware() $user = new EncAwareUser('user', 'pass'); $user->encoderName = 'invalid_encoder_name'; - $encoder = $factory->getEncoder($user); + $factory->getEncoder($user); } public function testGetEncoderForEncoderAwareWithClassName() diff --git a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php index 2c4faaa31a90b..c2c1dde623b93 100644 --- a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php @@ -192,7 +192,7 @@ public function testGuardWithNoLongerAuthenticatedTriggersLogout() $token->setAuthenticated(false); $provider = new GuardAuthenticationProvider([], $this->userProvider, $providerKey, $this->userChecker); - $actualToken = $provider->authenticate($token); + $provider->authenticate($token); } public function testSupportsChecksGuardAuthenticatorsTokenOrigin() diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php index 2b6e662700da3..fd49b54ccc2b2 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php @@ -20,7 +20,7 @@ class LogoutListenerTest extends TestCase { public function testHandleUnmatchedPath() { - list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener(); + list($listener, , $httpUtils, $options) = $this->getListener(); list($event, $request) = $this->getGetResponseEvent(); @@ -130,7 +130,7 @@ public function testSuccessHandlerReturnsNonResponse() $this->expectException('RuntimeException'); $successHandler = $this->getSuccessHandler(); - list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler); + list($listener, , $httpUtils, $options) = $this->getListener($successHandler); list($event, $request) = $this->getGetResponseEvent(); @@ -152,7 +152,7 @@ public function testCsrfValidationFails() $this->expectException('Symfony\Component\Security\Core\Exception\LogoutException'); $tokenManager = $this->getTokenManager(); - list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener(null, $tokenManager); + list($listener, , $httpUtils, $options) = $this->getListener(null, $tokenManager); list($event, $request) = $this->getGetResponseEvent(); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php index 4478a1a4d8b89..0770872968c5b 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php @@ -221,7 +221,7 @@ public function testOnCoreSecurity() public function testSessionStrategy() { - list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, true); + list($listener, $tokenStorage, $service, $manager, , , $sessionStrategy) = $this->getListener(false, true, true); $tokenStorage ->expects($this->once()) @@ -286,7 +286,7 @@ public function testSessionStrategy() public function testSessionIsMigratedByDefault() { - list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, false); + list($listener, $tokenStorage, $service, $manager) = $this->getListener(false, true, false); $tokenStorage ->expects($this->once()) diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php index 02d1ba03ce441..fd29297a5778e 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php @@ -60,7 +60,7 @@ public function testGetPreAuthenticatedDataNoUser() $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); $method->setAccessible(true); - $result = $method->invokeArgs($listener, [$request]); + $method->invokeArgs($listener, [$request]); } public function testGetPreAuthenticatedDataWithDifferentKeys() diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/X509AuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/X509AuthenticationListenerTest.php index e35e685d5bf88..c81b2d589ed06 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/X509AuthenticationListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/X509AuthenticationListenerTest.php @@ -98,7 +98,7 @@ public function testGetPreAuthenticatedDataNoData() $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); $method->setAccessible(true); - $result = $method->invokeArgs($listener, [$request]); + $method->invokeArgs($listener, [$request]); } public function testGetPreAuthenticatedDataWithDifferentKeys() diff --git a/src/Symfony/Component/Security/Http/Tests/FirewallTest.php b/src/Symfony/Component/Security/Http/Tests/FirewallTest.php index 673a8be7139d0..774db6128f379 100644 --- a/src/Symfony/Component/Security/Http/Tests/FirewallTest.php +++ b/src/Symfony/Component/Security/Http/Tests/FirewallTest.php @@ -48,8 +48,6 @@ public function testOnKernelRequestRegistersExceptionListener() public function testOnKernelRequestStopsWhenThereIsAResponse() { - $response = new Response(); - $first = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock(); $first ->expects($this->once()) diff --git a/src/Symfony/Component/Security/Http/Tests/RememberMe/ResponseListenerTest.php b/src/Symfony/Component/Security/Http/Tests/RememberMe/ResponseListenerTest.php index 465636eb9f77e..0a97ea7b8a9d2 100644 --- a/src/Symfony/Component/Security/Http/Tests/RememberMe/ResponseListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/RememberMe/ResponseListenerTest.php @@ -65,8 +65,6 @@ public function testRememberMeCookieIsNotSendWithResponse() public function testItSubscribesToTheOnKernelResponseEvent() { - $listener = new ResponseListener(); - $this->assertSame([KernelEvents::RESPONSE => 'onKernelResponse'], ResponseListener::getSubscribedEvents()); } diff --git a/src/Symfony/Component/Templating/Tests/Loader/FilesystemLoaderTest.php b/src/Symfony/Component/Templating/Tests/Loader/FilesystemLoaderTest.php index c6dcdefc95f51..781e19d935a71 100644 --- a/src/Symfony/Component/Templating/Tests/Loader/FilesystemLoaderTest.php +++ b/src/Symfony/Component/Templating/Tests/Loader/FilesystemLoaderTest.php @@ -27,7 +27,6 @@ public static function setUpBeforeClass() public function testConstructor() { $pathPattern = self::$fixturesPath.'/templates/%name%.%engine%'; - $path = self::$fixturesPath.'/templates'; $loader = new ProjectTemplateLoader2($pathPattern); $this->assertEquals([$pathPattern], $loader->getTemplatePathPatterns(), '__construct() takes a path as its second argument'); $loader = new ProjectTemplateLoader2([$pathPattern]); diff --git a/src/Symfony/Component/Validator/Constraints/FileValidator.php b/src/Symfony/Component/Validator/Constraints/FileValidator.php index d3e3833ab72c0..0a58cd2d687a0 100644 --- a/src/Symfony/Component/Validator/Constraints/FileValidator.php +++ b/src/Symfony/Component/Validator/Constraints/FileValidator.php @@ -60,7 +60,7 @@ public function validate($value, Constraint $constraint) $binaryFormat = null === $constraint->binaryFormat ? true : $constraint->binaryFormat; } - list($sizeAsString, $limitAsString, $suffix) = $this->factorizeSizes(0, $limitInBytes, $binaryFormat); + list(, $limitAsString, $suffix) = $this->factorizeSizes(0, $limitInBytes, $binaryFormat); $this->context->buildViolation($constraint->uploadIniSizeErrorMessage) ->setParameter('{{ limit }}', $limitAsString) ->setParameter('{{ suffix }}', $suffix) diff --git a/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php index 67b5a8c7b98b5..c0c89398ce466 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php @@ -450,7 +450,7 @@ public function uploadedFileErrorProvider() $reflection = new \ReflectionClass(\get_class(new FileValidator())); $method = $reflection->getMethod('factorizeSizes'); $method->setAccessible(true); - list($sizeAsString, $limit, $suffix) = $method->invokeArgs(new FileValidator(), [0, UploadedFile::getMaxFilesize(), false]); + list(, $limit, $suffix) = $method->invokeArgs(new FileValidator(), [0, UploadedFile::getMaxFilesize(), false]); // it correctly parses the maxSize option and not only uses simple string comparison // 1000M should be bigger than the ini value diff --git a/src/Symfony/Component/Workflow/Tests/DefinitionBuilderTest.php b/src/Symfony/Component/Workflow/Tests/DefinitionBuilderTest.php index 7e96c8875e74f..b7ffdec96e59c 100644 --- a/src/Symfony/Component/Workflow/Tests/DefinitionBuilderTest.php +++ b/src/Symfony/Component/Workflow/Tests/DefinitionBuilderTest.php @@ -11,7 +11,7 @@ class DefinitionBuilderTest extends TestCase public function testAddPlaceInvalidName() { $this->expectException('Symfony\Component\Workflow\Exception\InvalidArgumentException'); - $builder = new DefinitionBuilder(['a"', 'b']); + new DefinitionBuilder(['a"', 'b']); } public function testSetInitialPlace() diff --git a/src/Symfony/Component/Workflow/Tests/DefinitionTest.php b/src/Symfony/Component/Workflow/Tests/DefinitionTest.php index 185d4fd6c9ef4..8df6494a1edc9 100644 --- a/src/Symfony/Component/Workflow/Tests/DefinitionTest.php +++ b/src/Symfony/Component/Workflow/Tests/DefinitionTest.php @@ -22,7 +22,7 @@ public function testAddPlacesInvalidArgument() { $this->expectException('Symfony\Component\Workflow\Exception\InvalidArgumentException'); $places = ['a"', 'e"']; - $definition = new Definition($places, []); + new Definition($places, []); } public function testSetInitialPlace() @@ -37,7 +37,7 @@ public function testSetInitialPlaceAndPlaceIsNotDefined() { $this->expectException('Symfony\Component\Workflow\Exception\LogicException'); $this->expectExceptionMessage('Place "d" cannot be the initial place as it does not exist.'); - $definition = new Definition([], [], 'd'); + new Definition([], [], 'd'); } public function testAddTransition() diff --git a/src/Symfony/Component/Workflow/Tests/TransitionTest.php b/src/Symfony/Component/Workflow/Tests/TransitionTest.php index 009f19acfad29..0e049158f77b4 100644 --- a/src/Symfony/Component/Workflow/Tests/TransitionTest.php +++ b/src/Symfony/Component/Workflow/Tests/TransitionTest.php @@ -11,7 +11,7 @@ public function testValidateName() { $this->expectException('Symfony\Component\Workflow\Exception\InvalidArgumentException'); $this->expectExceptionMessage('The transition "foo.bar" contains invalid characters.'); - $transition = new Transition('foo.bar', 'a', 'b'); + new Transition('foo.bar', 'a', 'b'); } public function testConstructor() diff --git a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php index 6a1d092a0760c..90990d8cbbd79 100644 --- a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php +++ b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php @@ -219,7 +219,7 @@ public function testApplyWithSameNameTransition() $this->assertFalse($marking->has('b')); $this->assertFalse($marking->has('c')); - $marking = $workflow->apply($subject, 'a_to_bc'); + $workflow->apply($subject, 'a_to_bc'); $marking = $workflow->apply($subject, 'b_to_c'); $this->assertFalse($marking->has('a')); @@ -291,7 +291,7 @@ public function testApplyWithEventDispatcher() 'workflow.workflow_name.announce.t2', ]; - $marking = $workflow->apply($subject, 't1'); + $workflow->apply($subject, 't1'); $this->assertSame($eventNameExpected, $eventDispatcher->dispatchedEvents); } @@ -330,7 +330,7 @@ public function testApplyDoesNotTriggerExtraGuardWithEventDispatcher() 'workflow.workflow_name.announce', ]; - $marking = $workflow->apply($subject, 'a-b'); + $workflow->apply($subject, 'a-b'); $this->assertSame($eventNameExpected, $eventDispatcher->dispatchedEvents); } diff --git a/src/Symfony/Component/Yaml/Tests/Command/LintCommandTest.php b/src/Symfony/Component/Yaml/Tests/Command/LintCommandTest.php index b1306f043cdba..349897859f53f 100644 --- a/src/Symfony/Component/Yaml/Tests/Command/LintCommandTest.php +++ b/src/Symfony/Component/Yaml/Tests/Command/LintCommandTest.php @@ -85,7 +85,7 @@ public function testLintFileNotReadable() $filename = $this->createFile(''); unlink($filename); - $ret = $tester->execute(['filename' => $filename], ['decorated' => false]); + $tester->execute(['filename' => $filename], ['decorated' => false]); } /** diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index c48f0b4f4546b..dc7c122d592c2 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -110,7 +110,7 @@ public function testTabsInYaml() foreach ($yamls as $yaml) { try { - $content = $this->parser->parse($yaml); + $this->parser->parse($yaml); $this->fail('YAML files must not contain tabs'); } catch (\Exception $e) { From d211904c8e635cd4e3bc631d2b9817ffab7f0750 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Thu, 24 Oct 2019 17:19:11 +0200 Subject: [PATCH 49/72] [Messenger] prevent infinite redelivery loops and blocked queues by republishing the redelivered messages as retries with a retry limit and potential delay --- .../FrameworkExtension.php | 1 + .../Resources/config/messenger.xml | 2 + .../FrameworkExtensionTest.php | 2 + .../Bundle/FrameworkBundle/composer.json | 4 +- .../RejectRedeliveredMessageException.php | 21 ++++++++ .../RejectRedeliveredMessageMiddleware.php | 50 +++++++++++++++++++ .../Component/Messenger/Tests/WorkerTest.php | 4 +- src/Symfony/Component/Messenger/Worker.php | 14 ++++-- 8 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 src/Symfony/Component/Messenger/Exception/RejectRedeliveredMessageException.php create mode 100644 src/Symfony/Component/Messenger/Middleware/RejectRedeliveredMessageMiddleware.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 8cb3fdd242cde..3fd5ff90286b1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1649,6 +1649,7 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder $defaultMiddleware = [ 'before' => [ ['id' => 'add_bus_name_stamp_middleware'], + ['id' => 'reject_redelivered_message_middleware'], ['id' => 'dispatch_after_current_bus'], ['id' => 'failed_message_processing_middleware'], ], diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml index 5ef47e751efd0..f50b613dc7856 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml @@ -48,6 +48,8 @@ + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index c1824ecafead5..5f2e007ddbcd4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -739,6 +739,7 @@ public function testMessengerWithMultipleBuses() $this->assertSame([], $container->getDefinition('messenger.bus.commands')->getArgument(0)); $this->assertEquals([ ['id' => 'add_bus_name_stamp_middleware', 'arguments' => ['messenger.bus.commands']], + ['id' => 'reject_redelivered_message_middleware'], ['id' => 'dispatch_after_current_bus'], ['id' => 'failed_message_processing_middleware'], ['id' => 'send_message'], @@ -748,6 +749,7 @@ public function testMessengerWithMultipleBuses() $this->assertSame([], $container->getDefinition('messenger.bus.events')->getArgument(0)); $this->assertEquals([ ['id' => 'add_bus_name_stamp_middleware', 'arguments' => ['messenger.bus.events']], + ['id' => 'reject_redelivered_message_middleware'], ['id' => 'dispatch_after_current_bus'], ['id' => 'failed_message_processing_middleware'], ['id' => 'with_factory', 'arguments' => ['foo', true, ['bar' => 'baz']]], diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 8854a78d14194..57c344f68f22e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -42,7 +42,7 @@ "symfony/expression-language": "~3.4|~4.0", "symfony/http-client": "^4.3", "symfony/mailer": "^4.3", - "symfony/messenger": "^4.3", + "symfony/messenger": "^4.3.6", "symfony/mime": "^4.3", "symfony/process": "~3.4|~4.0", "symfony/security-csrf": "~3.4|~4.0", @@ -73,7 +73,7 @@ "symfony/dotenv": "<4.2", "symfony/dom-crawler": "<4.3", "symfony/form": "<4.3", - "symfony/messenger": "<4.3", + "symfony/messenger": "<4.3.6", "symfony/property-info": "<3.4", "symfony/serializer": "<4.2", "symfony/stopwatch": "<3.4", diff --git a/src/Symfony/Component/Messenger/Exception/RejectRedeliveredMessageException.php b/src/Symfony/Component/Messenger/Exception/RejectRedeliveredMessageException.php new file mode 100644 index 0000000000000..79b94fa2656f2 --- /dev/null +++ b/src/Symfony/Component/Messenger/Exception/RejectRedeliveredMessageException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Exception; + +/** + * @author Tobias Schultze + * + * @experimental in 4.3 + */ +class RejectRedeliveredMessageException extends RuntimeException +{ +} diff --git a/src/Symfony/Component/Messenger/Middleware/RejectRedeliveredMessageMiddleware.php b/src/Symfony/Component/Messenger/Middleware/RejectRedeliveredMessageMiddleware.php new file mode 100644 index 0000000000000..2c6e6b6ff718f --- /dev/null +++ b/src/Symfony/Component/Messenger/Middleware/RejectRedeliveredMessageMiddleware.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Messenger\Middleware; + +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\Exception\RejectRedeliveredMessageException; +use Symfony\Component\Messenger\Stamp\ReceivedStamp; +use Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceivedStamp; + +/** + * Middleware that throws a RejectRedeliveredMessageException when a message is detected that has been redelivered by AMQP. + * + * The middleware runs before the HandleMessageMiddleware and prevents redelivered messages from being handled directly. + * The thrown exception is caught by the worker and will trigger the retry logic according to the retry strategy. + * + * AMQP redelivers messages when they do not get acknowledged or rejected. This can happen when the connection times out + * or an exception is thrown before acknowledging or rejecting. When such errors happen again while handling the + * redelivered message, the message would get redelivered again and again. The purpose of this middleware is to prevent + * infinite redelivery loops and to unblock the queue by republishing the redelivered messages as retries with a retry + * limit and potential delay. + * + * @experimental in 4.3 + * + * @author Tobias Schultze + */ +class RejectRedeliveredMessageMiddleware implements MiddlewareInterface +{ + public function handle(Envelope $envelope, StackInterface $stack): Envelope + { + // ignore the dispatched messages for retry + if (null !== $envelope->last(ReceivedStamp::class)) { + $amqpReceivedStamp = $envelope->last(AmqpReceivedStamp::class); + + if ($amqpReceivedStamp instanceof AmqpReceivedStamp && $amqpReceivedStamp->getAmqpEnvelope()->isRedelivery()) { + throw new RejectRedeliveredMessageException('Redelivered message from AMQP detected that will be rejected and trigger the retry logic.'); + } + } + + return $stack->next()->handle($envelope, $stack); + } +} diff --git a/src/Symfony/Component/Messenger/Tests/WorkerTest.php b/src/Symfony/Component/Messenger/Tests/WorkerTest.php index ad7477253e86b..9a09c0a04a333 100644 --- a/src/Symfony/Component/Messenger/Tests/WorkerTest.php +++ b/src/Symfony/Component/Messenger/Tests/WorkerTest.php @@ -118,8 +118,8 @@ public function testDispatchCausesRetry() } }); - // old message acknowledged - $this->assertSame(1, $receiver->getAcknowledgeCount()); + // old message rejected + $this->assertSame(1, $receiver->getRejectCount()); } public function testUnrecoverableMessageHandlingExceptionPreventsRetries() diff --git a/src/Symfony/Component/Messenger/Worker.php b/src/Symfony/Component/Messenger/Worker.php index 398124e99491f..6205baefd43bd 100644 --- a/src/Symfony/Component/Messenger/Worker.php +++ b/src/Symfony/Component/Messenger/Worker.php @@ -18,6 +18,7 @@ use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent; use Symfony\Component\Messenger\Event\WorkerStoppedEvent; use Symfony\Component\Messenger\Exception\HandlerFailedException; +use Symfony\Component\Messenger\Exception\RejectRedeliveredMessageException; use Symfony\Component\Messenger\Exception\UnrecoverableExceptionInterface; use Symfony\Component\Messenger\Retry\RetryStrategyInterface; use Symfony\Component\Messenger\Stamp\DelayStamp; @@ -135,6 +136,13 @@ private function handleMessage(Envelope $envelope, ReceiverInterface $receiver, try { $envelope = $this->bus->dispatch($envelope->with(new ReceivedStamp($transportName))); } catch (\Throwable $throwable) { + $rejectFirst = $throwable instanceof RejectRedeliveredMessageException; + if ($rejectFirst) { + // redelivered messages are rejected first so that continuous failures in an event listener or while + // publishing for retry does not cause infinite redelivery loops + $receiver->reject($envelope); + } + if ($throwable instanceof HandlerFailedException) { $envelope = $throwable->getEnvelope(); } @@ -156,15 +164,15 @@ private function handleMessage(Envelope $envelope, ReceiverInterface $receiver, ->with(new RedeliveryStamp($retryCount, $transportName)) ->withoutAll(ReceivedStamp::class); - // re-send the message + // re-send the message for retry $this->bus->dispatch($retryEnvelope); - // acknowledge the previous message has received - $receiver->ack($envelope); } else { if (null !== $this->logger) { $this->logger->critical('Error thrown while handling message {class}. Removing from transport after {retryCount} retries. Error: "{error}"', $context + ['retryCount' => $retryCount, 'error' => $throwable->getMessage(), 'exception' => $throwable]); } + } + if (!$rejectFirst) { $receiver->reject($envelope); } From cfa11561d17c89649d9cbcde0f9562bdf5502c42 Mon Sep 17 00:00:00 2001 From: Mathias STRASSER Date: Tue, 9 Jul 2019 11:05:42 +0200 Subject: [PATCH 50/72] Format DateTime depending on database platform --- .../Transport/Doctrine/ConnectionTest.php | 20 ++++++-- .../Doctrine/DoctrineIntegrationTest.php | 47 ++++++++++--------- .../Transport/Doctrine/Connection.php | 45 +++++++++--------- 3 files changed, 64 insertions(+), 48 deletions(-) diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php index 6e7724d506927..b7ac30bee1c8a 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/ConnectionTest.php @@ -44,8 +44,11 @@ public function testGetAMessageWillChangeItsStatus() $queryBuilder ->method('getParameters') ->willReturn([]); + $queryBuilder + ->method('getParameterTypes') + ->willReturn([]); $driverConnection - ->method('prepare') + ->method('executeQuery') ->willReturn($stmt); $connection = new Connection([], $driverConnection, $schemaSynchronizer); @@ -65,13 +68,17 @@ public function testGetWithNoPendingMessageWillReturnNull() $queryBuilder ->method('getParameters') ->willReturn([]); + $queryBuilder + ->method('getParameterTypes') + ->willReturn([]); $driverConnection->expects($this->once()) ->method('createQueryBuilder') ->willReturn($queryBuilder); - $driverConnection->method('prepare') - ->willReturn($stmt); $driverConnection->expects($this->never()) ->method('update'); + $driverConnection + ->method('executeQuery') + ->willReturn($stmt); $connection = new Connection([], $driverConnection, $schemaSynchronizer); $doctrineEnvelope = $connection->get(); @@ -273,7 +280,7 @@ public function testFind() ->method('getParameters') ->willReturn([]); $driverConnection - ->method('prepare') + ->method('executeQuery') ->willReturn($stmt); $connection = new Connection([], $driverConnection, $schemaSynchronizer); @@ -316,8 +323,11 @@ public function testFindAll() $queryBuilder ->method('getParameters') ->willReturn([]); + $queryBuilder + ->method('getParameterTypes') + ->willReturn([]); $driverConnection - ->method('prepare') + ->method('executeQuery') ->willReturn($stmt); $connection = new Connection([], $driverConnection, $schemaSynchronizer); diff --git a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineIntegrationTest.php b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineIntegrationTest.php index fa05a43b0b66b..a01e68db39e2a 100644 --- a/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineIntegrationTest.php +++ b/src/Symfony/Component/Messenger/Tests/Transport/Doctrine/DoctrineIntegrationTest.php @@ -80,25 +80,25 @@ public function testItRetrieveTheFirstAvailableMessage() 'body' => '{"message": "Hi handled"}', 'headers' => json_encode(['type' => DummyMessage::class]), 'queue_name' => 'default', - 'created_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'available_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'delivered_at' => Connection::formatDateTime(new \DateTime()), + 'created_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'available_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'delivered_at' => $this->formatDateTime(new \DateTime()), ]); // one available later $this->driverConnection->insert('messenger_messages', [ 'body' => '{"message": "Hi delayed"}', 'headers' => json_encode(['type' => DummyMessage::class]), 'queue_name' => 'default', - 'created_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'available_at' => Connection::formatDateTime(new \DateTime('2019-03-15 13:00:00')), + 'created_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'available_at' => $this->formatDateTime(new \DateTime('2019-03-15 13:00:00')), ]); // one available $this->driverConnection->insert('messenger_messages', [ 'body' => '{"message": "Hi available"}', 'headers' => json_encode(['type' => DummyMessage::class]), 'queue_name' => 'default', - 'created_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'available_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:30:00')), + 'created_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'available_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:30:00')), ]); $encoded = $this->connection->get(); @@ -114,33 +114,33 @@ public function testItCountMessages() 'body' => '{"message": "Hi handled"}', 'headers' => json_encode(['type' => DummyMessage::class]), 'queue_name' => 'default', - 'created_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'available_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'delivered_at' => Connection::formatDateTime(new \DateTime()), + 'created_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'available_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'delivered_at' => $this->formatDateTime(new \DateTime()), ]); // one available later $this->driverConnection->insert('messenger_messages', [ 'body' => '{"message": "Hi delayed"}', 'headers' => json_encode(['type' => DummyMessage::class]), 'queue_name' => 'default', - 'created_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'available_at' => Connection::formatDateTime((new \DateTime())->modify('+1 minute')), + 'created_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'available_at' => $this->formatDateTime((new \DateTime())->modify('+1 minute')), ]); // one available $this->driverConnection->insert('messenger_messages', [ 'body' => '{"message": "Hi available"}', 'headers' => json_encode(['type' => DummyMessage::class]), 'queue_name' => 'default', - 'created_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'available_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:30:00')), + 'created_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'available_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:30:00')), ]); // another available $this->driverConnection->insert('messenger_messages', [ 'body' => '{"message": "Hi available"}', 'headers' => json_encode(['type' => DummyMessage::class]), 'queue_name' => 'default', - 'created_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'available_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:30:00')), + 'created_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'available_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:30:00')), ]); $this->assertSame(2, $this->connection->getMessageCount()); @@ -155,16 +155,16 @@ public function testItRetrieveTheMessageThatIsOlderThanRedeliverTimeout() 'body' => '{"message": "Hi requeued"}', 'headers' => json_encode(['type' => DummyMessage::class]), 'queue_name' => 'default', - 'created_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'available_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'delivered_at' => Connection::formatDateTime($twoHoursAgo), + 'created_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'available_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'delivered_at' => $this->formatDateTime($twoHoursAgo), ]); $this->driverConnection->insert('messenger_messages', [ 'body' => '{"message": "Hi available"}', 'headers' => json_encode(['type' => DummyMessage::class]), 'queue_name' => 'default', - 'created_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:00:00')), - 'available_at' => Connection::formatDateTime(new \DateTime('2019-03-15 12:30:00')), + 'created_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:00:00')), + 'available_at' => $this->formatDateTime(new \DateTime('2019-03-15 12:30:00')), ]); $next = $this->connection->get(); @@ -181,4 +181,9 @@ public function testTheTransportIsSetupOnGet() $envelope = $this->connection->get(); $this->assertEquals('the body', $envelope['body']); } + + private function formatDateTime(\DateTime $dateTime) + { + return $dateTime->format($this->driverConnection->getDatabasePlatform()->getDateTimeFormatString()); + } } diff --git a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php index 2c8bcd35cc459..f665e8b31c492 100644 --- a/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php @@ -124,8 +124,14 @@ public function send(string $body, array $headers, int $delay = 0): string $body, json_encode($headers), $this->configuration['queue_name'], - self::formatDateTime($now), - self::formatDateTime($availableAt), + $now, + $availableAt, + ], [ + null, + null, + null, + Type::DATETIME, + Type::DATETIME, ]); return $this->driverConnection->lastInsertId(); @@ -143,7 +149,8 @@ public function get(): ?array // use SELECT ... FOR UPDATE to lock table $doctrineEnvelope = $this->executeQuery( $query->getSQL().' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL(), - $query->getParameters() + $query->getParameters(), + $query->getParameterTypes() )->fetch(); if (false === $doctrineEnvelope) { @@ -160,8 +167,10 @@ public function get(): ?array ->where('id = ?'); $now = new \DateTime(); $this->executeQuery($queryBuilder->getSQL(), [ - self::formatDateTime($now), + $now, $doctrineEnvelope['id'], + ], [ + Type::DATETIME, ]); $this->driverConnection->commit(); @@ -228,7 +237,7 @@ public function getMessageCount(): int ->select('COUNT(m.id) as message_count') ->setMaxResults(1); - return $this->executeQuery($queryBuilder->getSQL(), $queryBuilder->getParameters())->fetchColumn(); + return $this->executeQuery($queryBuilder->getSQL(), $queryBuilder->getParameters(), $queryBuilder->getParameterTypes())->fetchColumn(); } public function findAll(int $limit = null): array @@ -238,7 +247,7 @@ public function findAll(int $limit = null): array $queryBuilder->setMaxResults($limit); } - $data = $this->executeQuery($queryBuilder->getSQL(), $queryBuilder->getParameters())->fetchAll(); + $data = $this->executeQuery($queryBuilder->getSQL(), $queryBuilder->getParameters(), $queryBuilder->getParameterTypes())->fetchAll(); return array_map(function ($doctrineEnvelope) { return $this->decodeEnvelopeHeaders($doctrineEnvelope); @@ -267,9 +276,12 @@ private function createAvailableMessagesQueryBuilder(): QueryBuilder ->andWhere('m.available_at <= ?') ->andWhere('m.queue_name = ?') ->setParameters([ - self::formatDateTime($redeliverLimit), - self::formatDateTime($now), + $redeliverLimit, + $now, $this->configuration['queue_name'], + ], [ + Type::DATETIME, + Type::DATETIME, ]); } @@ -280,12 +292,10 @@ private function createQueryBuilder(): QueryBuilder ->from($this->configuration['table_name'], 'm'); } - private function executeQuery(string $sql, array $parameters = []) + private function executeQuery(string $sql, array $parameters = [], array $types = []) { - $stmt = null; try { - $stmt = $this->driverConnection->prepare($sql); - $stmt->execute($parameters); + $stmt = $this->driverConnection->executeQuery($sql, $parameters, $types); } catch (TableNotFoundException $e) { if ($this->driverConnection->isTransactionActive()) { throw $e; @@ -295,11 +305,7 @@ private function executeQuery(string $sql, array $parameters = []) if ($this->autoSetup) { $this->setup(); } - // statement not prepared ? SQLite throw on exception on prepare if the table does not exist - if (null === $stmt) { - $stmt = $this->driverConnection->prepare($sql); - } - $stmt->execute($parameters); + $stmt = $this->driverConnection->executeQuery($sql, $parameters, $types); } return $stmt; @@ -332,11 +338,6 @@ private function getSchema(): Schema return $schema; } - public static function formatDateTime(\DateTimeInterface $dateTime) - { - return $dateTime->format('Y-m-d\TH:i:s'); - } - private function decodeEnvelopeHeaders(array $doctrineEnvelope): array { $doctrineEnvelope['headers'] = json_decode($doctrineEnvelope['headers'], true); From 8e56f46150cae79f73f655258ea5789c72e51a53 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 25 Oct 2019 05:36:17 +0200 Subject: [PATCH 51/72] [SecurityBundle] Fix wrong assertion --- .../Tests/Functional/MissingUserProviderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php index d795980b3ef38..6c8ba6482e45b 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php @@ -24,7 +24,7 @@ public function testUserProviderIsNeeded() $response = $client->getResponse(); $this->assertSame(500, $response->getStatusCode()); - $this->stringContains('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException', $response->getContent()); - $this->stringContains('"default" firewall requires a user provider but none was defined.', $response->getContent()); + $this->assertStringContainsString('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException', $response->getContent()); + $this->assertStringContainsString('"default" firewall requires a user provider but none was defined', html_entity_decode($response->getContent())); } } From 6244a1ec47034820f3dc0feb52ac4d3d8b13a8b6 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Thu, 24 Oct 2019 10:11:33 +0100 Subject: [PATCH 52/72] [Validator] Ensure numeric subpaths do not cause errors on PHP 7.4 --- .../Component/Validator/Tests/Util/PropertyPathTest.php | 1 + src/Symfony/Component/Validator/Util/PropertyPath.php | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Validator/Tests/Util/PropertyPathTest.php b/src/Symfony/Component/Validator/Tests/Util/PropertyPathTest.php index f796463bbc320..99bf9e6eb2ebe 100644 --- a/src/Symfony/Component/Validator/Tests/Util/PropertyPathTest.php +++ b/src/Symfony/Component/Validator/Tests/Util/PropertyPathTest.php @@ -32,6 +32,7 @@ public function provideAppendPaths() ['foo', 'bar', 'foo.bar', 'It append the subPath to the basePath'], ['foo', '[bar]', 'foo[bar]', 'It does not include the dot separator if subPath uses the array notation'], ['0', 'bar', '0.bar', 'Leading zeros are kept.'], + ['0', 1, '0.1', 'Numeric subpaths do not cause PHP 7.4 errors.'], ]; } } diff --git a/src/Symfony/Component/Validator/Util/PropertyPath.php b/src/Symfony/Component/Validator/Util/PropertyPath.php index 4108a02c24f25..5d062356772c0 100644 --- a/src/Symfony/Component/Validator/Util/PropertyPath.php +++ b/src/Symfony/Component/Validator/Util/PropertyPath.php @@ -36,12 +36,13 @@ class PropertyPath */ public static function append($basePath, $subPath) { - if ('' !== (string) $subPath) { + $subPath = (string) $subPath; + if ('' !== $subPath) { if ('[' === $subPath[0]) { return $basePath.$subPath; } - return '' !== (string) $basePath ? $basePath.'.'.$subPath : $subPath; + return '' !== $basePath ? $basePath.'.'.$subPath : $subPath; } return $basePath; From 0fc371e7df60be9a820081b414469ddedf93a3c6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 25 Oct 2019 08:37:36 +0200 Subject: [PATCH 53/72] [HttpClient] ignore the body of responses to HEAD requests --- .../Component/HttpClient/CurlHttpClient.php | 2 ++ .../HttpClient/Response/MockResponse.php | 2 +- .../HttpClient/Response/NativeResponse.php | 10 ++++++- .../HttpClient/Test/HttpClientTestCase.php | 27 +++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpClient/CurlHttpClient.php b/src/Symfony/Component/HttpClient/CurlHttpClient.php index 471f694b4e89f..56a129783d481 100644 --- a/src/Symfony/Component/HttpClient/CurlHttpClient.php +++ b/src/Symfony/Component/HttpClient/CurlHttpClient.php @@ -197,6 +197,8 @@ public function request(string $method, string $url, array $options = []): Respo if ('POST' === $method) { // Use CURLOPT_POST to have browser-like POST-to-GET redirects for 301, 302 and 303 $curlopts[CURLOPT_POST] = true; + } elseif ('HEAD' === $method) { + $curlopts[CURLOPT_NOBODY] = true; } else { $curlopts[CURLOPT_CUSTOMREQUEST] = $method; } diff --git a/src/Symfony/Component/HttpClient/Response/MockResponse.php b/src/Symfony/Component/HttpClient/Response/MockResponse.php index fa8abebea447b..3b961db4d13f3 100644 --- a/src/Symfony/Component/HttpClient/Response/MockResponse.php +++ b/src/Symfony/Component/HttpClient/Response/MockResponse.php @@ -176,7 +176,7 @@ protected static function perform(ClientState $multi, array &$responses): void try { $offset = 0; $chunk[1]->getStatusCode(); - $response->headers = $chunk[1]->getHeaders(false); + $chunk[1]->getHeaders(false); self::readResponse($response, $chunk[0], $chunk[1], $offset); $multi->handlesActivity[$id][] = new FirstChunk(); } catch (\Throwable $e) { diff --git a/src/Symfony/Component/HttpClient/Response/NativeResponse.php b/src/Symfony/Component/HttpClient/Response/NativeResponse.php index 2f414e3ba2d17..3115bade504d9 100644 --- a/src/Symfony/Component/HttpClient/Response/NativeResponse.php +++ b/src/Symfony/Component/HttpClient/Response/NativeResponse.php @@ -174,8 +174,16 @@ private function open(): void $this->inflate = null; } - $this->multi->openHandles[$this->id] = [$h, $this->buffer, $this->inflate, $this->content, $this->onProgress, &$this->remaining, &$this->info]; $this->multi->handlesActivity[$this->id] = [new FirstChunk()]; + + if ('HEAD' === $context['http']['method']) { + $this->multi->handlesActivity[$this->id][] = null; + $this->multi->handlesActivity[$this->id][] = null; + + return; + } + + $this->multi->openHandles[$this->id] = [$h, $this->buffer, $this->inflate, $this->content, $this->onProgress, &$this->remaining, &$this->info]; } /** diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index 485712c6888aa..78d0f1b39c25a 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -72,6 +72,33 @@ public function testGetRequest() $response->getContent(); } + public function testHeadRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('HEAD', 'http://localhost:8057', [ + 'headers' => ['Foo' => 'baR'], + 'user_data' => $data = new \stdClass(), + ]); + + $this->assertSame([], $response->getInfo('response_headers')); + $this->assertSame($data, $response->getInfo()['user_data']); + $this->assertSame(200, $response->getStatusCode()); + + $info = $response->getInfo(); + $this->assertNull($info['error']); + $this->assertSame(0, $info['redirect_count']); + $this->assertSame('HTTP/1.1 200 OK', $info['response_headers'][0]); + $this->assertSame('Host: localhost:8057', $info['response_headers'][1]); + $this->assertSame('http://localhost:8057/', $info['url']); + + $headers = $response->getHeaders(); + + $this->assertSame('localhost:8057', $headers['host'][0]); + $this->assertSame(['application/json'], $headers['content-type']); + + $this->assertSame('', $response->getContent()); + } + public function testNonBufferedGetRequest() { $client = $this->getHttpClient(__FUNCTION__); From cb7523d595f987b4d19f1e560e17ac1677d75697 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 26 Oct 2019 10:25:32 +0200 Subject: [PATCH 54/72] fix paths to detect code owners --- .github/CODEOWNERS | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e459d1e55f616..9e23ca5c1ea74 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,7 +4,7 @@ /src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @dunglas # Form /src/Symfony/Bridge/Twig/Extension/FormExtension.php @xabbuh -/src/Symfony/Bridge/Twig/Form/* @xabbuh +/src/Symfony/Bridge/Twig/Form/ @xabbuh /src/Symfony/Bridge/Twig/Node/FormThemeNode.php @xabbuh /src/Symfony/Bridge/Twig/Node/RenderBlockNode.php @xabbuh /src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php @xabbuh @@ -13,34 +13,34 @@ /src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php @xabbuh /src/Symfony/Bridge/Twig/TokenParser/FormThemeTokenParser.php @xabbuh /src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php @xabbuh -/src/Symfony/Bundle/FrameworkBundle/Resources/views/* @xabbuh +/src/Symfony/Bundle/FrameworkBundle/Resources/views/ @xabbuh /src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php @xabbuh /src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FormPassTest.php @xabbuh /src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php @xabbuh /src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php @xabbuh -/src/Symfony/Component/Form/* @xabbuh +/src/Symfony/Component/Form/ @xabbuh # HttpKernel /src/Symfony/Component/HttpKernel/Log/Logger.php @dunglas # LDAP -/src/Symfony/Component/Ldap/* @csarrazi +/src/Symfony/Component/Ldap/ @csarrazi # Lock -/src/Symfony/Component/Lock/* @jderusse +/src/Symfony/Component/Lock/ @jderusse # Messenger -/src/Symfony/Bridge/Doctrine/Messenger/* @sroze -/src/Symfony/Component/Messenger/* @sroze +/src/Symfony/Bridge/Doctrine/Messenger/ @sroze +/src/Symfony/Component/Messenger/ @sroze # PropertyInfo -/src/Symfony/Component/PropertyInfo/* @dunglas -/src/Symfony/Bridge/Doctrine/PropertyInfo/* @dunglas +/src/Symfony/Component/PropertyInfo/ @dunglas +/src/Symfony/Bridge/Doctrine/PropertyInfo/ @dunglas # Serializer -/src/Symfony/Component/Serializer/* @dunglas +/src/Symfony/Component/Serializer/ @dunglas # WebLink -/src/Symfony/Component/WebLink/* @dunglas +/src/Symfony/Component/WebLink/ @dunglas # Workflow /src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php @lyrixx /src/Symfony/Bridge/Twig/Tests/Extension/WorkflowExtensionTest.php @lyrixx /src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php @lyrixx /src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ValidateWorkflowsPass.php @lyrixx /src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php @lyrixx -/src/Symfony/Component/Workflow/* @lyrixx +/src/Symfony/Component/Workflow/ @lyrixx # Yaml -/src/Symfony/Component/Yaml/* @xabbuh +/src/Symfony/Component/Yaml/ @xabbuh From 7fa2fc2b96ff7a4055ee842652aa5c7273045b8a Mon Sep 17 00:00:00 2001 From: Dmytro Date: Mon, 11 Mar 2019 12:49:04 +0200 Subject: [PATCH 55/72] #30432 fix an error message --- .../OptionsResolver/OptionsResolver.php | 40 ++++++++++--------- .../Tests/OptionsResolverTest.php | 25 +++++++----- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index 8ed03c2af20a7..fd8a603fe24c6 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -734,7 +734,7 @@ public function offsetGet($option) // Validate the type of the resolved option if (isset($this->allowedTypes[$option])) { - $valid = false; + $valid = true; $invalidTypes = []; foreach ($this->allowedTypes[$option] as $type) { @@ -746,13 +746,22 @@ public function offsetGet($option) } if (!$valid) { - $keys = array_keys($invalidTypes); + $fmtActualValue = $this->formatValue($value); + $fmtAllowedTypes = implode('" or "', $this->allowedTypes[$option]); + $fmtProvidedTypes = implode('|', array_keys($invalidTypes)); + + $allowedContainsArrayType = \count(array_filter( + $this->allowedTypes[$option], + function ($item) { + return '[]' === substr(isset(self::$typeAliases[$item]) ? self::$typeAliases[$item] : $item, -2); + } + )) > 0; - if (1 === \count($keys) && '[]' === substr($keys[0], -2)) { - throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), $keys[0])); + if (\is_array($value) && $allowedContainsArrayType) { + throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes)); } - throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), implode('|', array_keys($invalidTypes)))); + throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes)); } } @@ -858,21 +867,14 @@ private function verifyArrayType($type, array $value, array &$invalidTypes, $lev { $type = substr($type, 0, -2); - $suffix = '[]'; - while (\strlen($suffix) <= $level * 2) { - $suffix .= '[]'; - } - if ('[]' === substr($type, -2)) { $success = true; foreach ($value as $item) { if (!\is_array($item)) { - $invalidTypes[$this->formatTypeOf($item, null).$suffix] = true; + $invalidTypes[$this->formatTypeOf($item, null)] = true; - return false; - } - - if (!$this->verifyArrayType($type, $item, $invalidTypes, $level + 1)) { + $success = false; + } elseif (!$this->verifyArrayType($type, $item, $invalidTypes, $level + 1)) { $success = false; } } @@ -880,15 +882,17 @@ private function verifyArrayType($type, array $value, array &$invalidTypes, $lev return $success; } + $valid = true; + foreach ($value as $item) { if (!self::isValueValidType($type, $item)) { - $invalidTypes[$this->formatTypeOf($item, $type).$suffix] = $value; + $invalidTypes[$this->formatTypeOf($item, $type)] = $value; - return false; + $valid = false; } } - return true; + return $valid; } /** diff --git a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php index cbdaaf024abae..ce90f93791edc 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php @@ -466,7 +466,7 @@ public function testFailIfSetAllowedTypesFromLazyOption() public function testResolveFailsIfInvalidTypedArray() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime[]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[]'); @@ -486,9 +486,10 @@ public function testResolveFailsWithNonArray() public function testResolveFailsIfTypedArrayContainsInvalidTypes() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass[]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass|array|DateTime".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[]'); + $values = range(1, 5); $values[] = new \stdClass(); $values[] = []; @@ -501,7 +502,7 @@ public function testResolveFailsIfTypedArrayContainsInvalidTypes() public function testResolveFailsWithCorrectLevelsButWrongScalar() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double[][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[][]'); @@ -537,6 +538,11 @@ public function provideInvalidTypes() [42, 'string', 'The option "option" with value 42 is expected to be of type "string", but is of type "integer".'], [null, 'string', 'The option "option" with value null is expected to be of type "string", but is of type "NULL".'], ['bar', '\stdClass', 'The option "option" with value "bar" is expected to be of type "\stdClass", but is of type "string".'], + [['foo', 12], 'string[]', 'The option "option" with value array is expected to be of type "string[]", but one of the elements is of type "integer".'], + [123, ['string[]', 'string'], 'The option "option" with value 123 is expected to be of type "string[]" or "string", but is of type "integer".'], + [[null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'], + [['string', null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'], + [[\stdClass::class], ['string'], 'The option "option" with value array is expected to be of type "string", but is of type "array".'], ]; } @@ -585,6 +591,7 @@ public function testResolveSucceedsIfTypedArray() new \DateTime(), ], ]; + $result = $this->resolver->resolve($data); $this->assertEquals($data, $result); } @@ -1535,7 +1542,7 @@ public function testNested2Arrays() public function testNestedArraysException() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer[][][][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'float[][][][]'); @@ -1553,7 +1560,7 @@ public function testNestedArraysException() public function testNestedArrayException1() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[][]'); $this->resolver->resolve([ @@ -1566,7 +1573,7 @@ public function testNestedArrayException1() public function testNestedArrayException2() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[][]'); $this->resolver->resolve([ @@ -1579,7 +1586,7 @@ public function testNestedArrayException2() public function testNestedArrayException3() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string[][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string|integer".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'string[][][]'); $this->resolver->resolve([ @@ -1592,7 +1599,7 @@ public function testNestedArrayException3() public function testNestedArrayException4() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer[][][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'string[][][]'); $this->resolver->resolve([ @@ -1606,7 +1613,7 @@ public function testNestedArrayException4() public function testNestedArrayException5() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array[]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'string[]'); $this->resolver->resolve([ From 799a2eae2d732d7b883f7ff7f30ec0aceb429b10 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 27 Oct 2019 12:35:02 +0100 Subject: [PATCH 56/72] [Security/Core] make NativePasswordEncoder use sodium to validate passwords when possible --- .../Core/Encoder/NativePasswordEncoder.php | 31 +++++++++++-------- .../Core/Encoder/SodiumPasswordEncoder.php | 2 +- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Encoder/NativePasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/NativePasswordEncoder.php index 1e09992afed4e..364cd19236ec2 100644 --- a/src/Symfony/Component/Security/Core/Encoder/NativePasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/NativePasswordEncoder.php @@ -45,7 +45,7 @@ public function __construct(int $opsLimit = null, int $memLimit = null, int $cos throw new \InvalidArgumentException('$cost must be in the range of 4-31.'); } - $this->algo = \defined('PASSWORD_ARGON2I') ? max(PASSWORD_DEFAULT, \defined('PASSWORD_ARGON2ID') ? PASSWORD_ARGON2ID : PASSWORD_ARGON2I) : PASSWORD_DEFAULT; + $this->algo = \defined('PASSWORD_ARGON2ID') ? PASSWORD_ARGON2ID : (\defined('PASSWORD_ARGON2I') ? PASSWORD_ARGON2I : PASSWORD_BCRYPT); $this->options = [ 'cost' => $cost, 'time_cost' => $opsLimit, @@ -59,20 +59,13 @@ public function __construct(int $opsLimit = null, int $memLimit = null, int $cos */ public function encodePassword($raw, $salt) { - if (\strlen($raw) > self::MAX_PASSWORD_LENGTH) { + if (\strlen($raw) > self::MAX_PASSWORD_LENGTH || (PASSWORD_BCRYPT === $this->algo && 72 < \strlen($raw))) { throw new BadCredentialsException('Invalid password.'); } // Ignore $salt, the auto-generated one is always the best - $encoded = password_hash($raw, $this->algo, $this->options); - - if (72 < \strlen($raw) && 0 === strpos($encoded, '$2')) { - // BCrypt encodes only the first 72 chars - throw new BadCredentialsException('Invalid password.'); - } - - return $encoded; + return password_hash($raw, $this->algo, $this->options); } /** @@ -80,11 +73,23 @@ public function encodePassword($raw, $salt) */ public function isPasswordValid($encoded, $raw, $salt) { - if (72 < \strlen($raw) && 0 === strpos($encoded, '$2')) { - // BCrypt encodes only the first 72 chars + if (\strlen($raw) > self::MAX_PASSWORD_LENGTH) { return false; } - return \strlen($raw) <= self::MAX_PASSWORD_LENGTH && password_verify($raw, $encoded); + if (0 === strpos($encoded, '$2')) { + // BCrypt encodes only the first 72 chars + return 72 >= \strlen($raw) && password_verify($raw, $encoded); + } + + if (\extension_loaded('sodium') && version_compare(\SODIUM_LIBRARY_VERSION, '1.0.14', '>=')) { + return sodium_crypto_pwhash_str_verify($encoded, $raw); + } + + if (\extension_loaded('libsodium') && version_compare(phpversion('libsodium'), '1.0.14', '>=')) { + return \Sodium\crypto_pwhash_str_verify($encoded, $raw); + } + + return password_verify($raw, $encoded); } } diff --git a/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php index 934a3fdfca528..9c794004111a6 100644 --- a/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/SodiumPasswordEncoder.php @@ -93,6 +93,6 @@ public function isPasswordValid($encoded, $raw, $salt) return \Sodium\crypto_pwhash_str_verify($encoded, $raw); } - throw new LogicException('Libsodium is not available. You should either install the sodium extension, upgrade to PHP 7.2+ or use a different encoder.'); + return false; } } From 0c31ff007e2ee19cc021bf5ee0e437c5e9a3d318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Mon, 28 Oct 2019 15:43:17 +0100 Subject: [PATCH 57/72] [Workflow] Made the configuration more robust for the 'property' key --- .../DependencyInjection/Configuration.php | 10 +++++++++- .../DependencyInjection/FrameworkExtension.php | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 497fb08424712..2b76352048c1c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -303,7 +303,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode) ->end() ->end() ->scalarNode('property') - ->defaultValue('marking') + ->defaultNull() // In Symfony 5.0, set "marking" as default property ->end() ->scalarNode('service') ->cannotBeEmpty() @@ -481,6 +481,14 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode) return $v; }) ->end() + ->validate() + ->ifTrue(function ($v) { + return isset($v['marking_store']['property']) + && (!isset($v['marking_store']['type']) || 'method' !== $v['marking_store']['type']) + ; + }) + ->thenInvalid('"property" option is only supported by the "method" marking store.') + ->end() ->end() ->end() ->end() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 3fd5ff90286b1..8b64507d0a21f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -666,7 +666,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ if ('method' === $workflow['marking_store']['type']) { $markingStoreDefinition->setArguments([ 'state_machine' === $type, //single state - $workflow['marking_store']['property'], + $workflow['marking_store']['property'] ?? 'marking', ]); } else { foreach ($workflow['marking_store']['arguments'] as $argument) { From 50a88c59f65c341a5993203d673cbf1ded551d4f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 28 Oct 2019 16:45:56 +0100 Subject: [PATCH 58/72] [HttpClient] fix handling of 3xx with no Location header - ignore Content-Length when no body is expected --- .../Component/HttpClient/Response/CurlResponse.php | 7 ++++--- .../Component/HttpClient/Response/MockResponse.php | 2 +- .../Component/HttpClient/Response/NativeResponse.php | 2 +- .../Contracts/HttpClient/Test/Fixtures/web/index.php | 5 +++++ .../Contracts/HttpClient/Test/HttpClientTestCase.php | 11 +++++++++++ 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 6f4ebf554ff92..4b25acf79565f 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -323,6 +323,7 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & if (200 > $statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE)) { $multi->handlesActivity[$id][] = new InformationalChunk($statusCode, $headers); + $location = null; return \strlen($data); } @@ -346,9 +347,7 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & } } - $location = null; - - if ($statusCode < 300 || 400 <= $statusCode || curl_getinfo($ch, CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { + if ($statusCode < 300 || 400 <= $statusCode || null === $location || curl_getinfo($ch, CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { // Headers and redirects completed, time to get the response's body $multi->handlesActivity[$id][] = new FirstChunk(); @@ -361,6 +360,8 @@ private static function parseHeaderLine($ch, string $data, array &$info, array & $logger->info(sprintf('Redirecting: "%s %s"', $info['http_code'], $info['redirect_url'])); } + $location = null; + return \strlen($data); } } diff --git a/src/Symfony/Component/HttpClient/Response/MockResponse.php b/src/Symfony/Component/HttpClient/Response/MockResponse.php index 3b961db4d13f3..3856112a09d39 100644 --- a/src/Symfony/Component/HttpClient/Response/MockResponse.php +++ b/src/Symfony/Component/HttpClient/Response/MockResponse.php @@ -257,7 +257,7 @@ private static function readResponse(self $response, array $options, ResponseInt $info = $mock->getInfo() ?: []; $response->info['http_code'] = ($info['http_code'] ?? 0) ?: $mock->getStatusCode() ?: 200; $response->addResponseHeaders($info['response_headers'] ?? [], $response->info, $response->headers); - $dlSize = isset($response->headers['content-encoding']) ? 0 : (int) ($response->headers['content-length'][0] ?? 0); + $dlSize = isset($response->headers['content-encoding']) || 'HEAD' === $response->info['http_method'] || \in_array($response->info['http_code'], [204, 304], true) ? 0 : (int) ($response->headers['content-length'][0] ?? 0); $response->info = [ 'start_time' => $response->info['start_time'], diff --git a/src/Symfony/Component/HttpClient/Response/NativeResponse.php b/src/Symfony/Component/HttpClient/Response/NativeResponse.php index 3115bade504d9..a9865ed09e494 100644 --- a/src/Symfony/Component/HttpClient/Response/NativeResponse.php +++ b/src/Symfony/Component/HttpClient/Response/NativeResponse.php @@ -176,7 +176,7 @@ private function open(): void $this->multi->handlesActivity[$this->id] = [new FirstChunk()]; - if ('HEAD' === $context['http']['method']) { + if ('HEAD' === $context['http']['method'] || \in_array($this->info['http_code'], [204, 304], true)) { $this->multi->handlesActivity[$this->id][] = null; $this->multi->handlesActivity[$this->id][] = null; diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index ec03bb61c2b84..10ed100ccc826 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -82,6 +82,11 @@ header('Location: ..', true, 302); break; + case '/304': + header('Content-Length: 10', true, 304); + echo '12345'; + return; + case '/307': header('Location: http://localhost:8057/post', true, 307); break; diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index 78d0f1b39c25a..df7a597590deb 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -260,6 +260,17 @@ public function testBadRequestBody() $response->getStatusCode(); } + public function test304() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/304', [ + 'headers' => ['If-Match' => '"abc"'], + ]); + + $this->assertSame(304, $response->getStatusCode()); + $this->assertSame('', $response->getContent(false)); + } + public function testRedirects() { $client = $this->getHttpClient(__FUNCTION__); From 15f08553be9801aa771a062545445f35941722b1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 28 Oct 2019 18:16:45 +0100 Subject: [PATCH 59/72] [OptionsResolve] Revert change in tests for a not-merged change in code --- .../Tests/OptionsResolverTest.php | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php index 2d0e28dd4118c..43ebf408e90b0 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php @@ -776,7 +776,7 @@ public function testFailIfSetAllowedTypesFromLazyOption() public function testResolveFailsIfInvalidTypedArray() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime[]".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[]'); @@ -796,10 +796,9 @@ public function testResolveFailsWithNonArray() public function testResolveFailsIfTypedArrayContainsInvalidTypes() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass|array|DateTime".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass[]".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[]'); - $values = range(1, 5); $values[] = new \stdClass(); $values[] = []; @@ -812,7 +811,7 @@ public function testResolveFailsIfTypedArrayContainsInvalidTypes() public function testResolveFailsWithCorrectLevelsButWrongScalar() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double[][]".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[][]'); @@ -848,11 +847,6 @@ public function provideInvalidTypes() [42, 'string', 'The option "option" with value 42 is expected to be of type "string", but is of type "integer".'], [null, 'string', 'The option "option" with value null is expected to be of type "string", but is of type "NULL".'], ['bar', '\stdClass', 'The option "option" with value "bar" is expected to be of type "\stdClass", but is of type "string".'], - [['foo', 12], 'string[]', 'The option "option" with value array is expected to be of type "string[]", but one of the elements is of type "integer".'], - [123, ['string[]', 'string'], 'The option "option" with value 123 is expected to be of type "string[]" or "string", but is of type "integer".'], - [[null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'], - [['string', null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'], - [[\stdClass::class], ['string'], 'The option "option" with value array is expected to be of type "string", but is of type "array".'], ]; } @@ -901,7 +895,6 @@ public function testResolveSucceedsIfTypedArray() new \DateTime(), ], ]; - $result = $this->resolver->resolve($data); $this->assertEquals($data, $result); } @@ -1905,7 +1898,7 @@ public function testNested2Arrays() public function testNestedArraysException() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer[][][][]".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'float[][][][]'); @@ -1923,7 +1916,7 @@ public function testNestedArraysException() public function testNestedArrayException1() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[][]'); $this->resolver->resolve([ @@ -1936,7 +1929,7 @@ public function testNestedArrayException1() public function testNestedArrayException2() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[][]'); $this->resolver->resolve([ @@ -1949,7 +1942,7 @@ public function testNestedArrayException2() public function testNestedArrayException3() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string|integer".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string[][]".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'string[][][]'); $this->resolver->resolve([ @@ -1962,7 +1955,7 @@ public function testNestedArrayException3() public function testNestedArrayException4() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer[][][]".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'string[][][]'); $this->resolver->resolve([ @@ -1976,7 +1969,7 @@ public function testNestedArrayException4() public function testNestedArrayException5() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array[]".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'string[]'); $this->resolver->resolve([ From 1be68a752a6bc9190c492a54cd996481b9d9367e Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Mon, 28 Oct 2019 15:33:22 -0400 Subject: [PATCH 60/72] Fix an error message to be more accurate --- .../OptionsResolver/OptionsResolver.php | 30 ++++++++++--------- .../Tests/OptionsResolverTest.php | 23 ++++++++------ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index f47aef128451a..e9de7800b6540 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -917,7 +917,7 @@ public function offsetGet($option/*, bool $triggerDeprecation = true*/) // Validate the type of the resolved option if (isset($this->allowedTypes[$option])) { - $valid = false; + $valid = true; $invalidTypes = []; foreach ($this->allowedTypes[$option] as $type) { @@ -929,13 +929,18 @@ public function offsetGet($option/*, bool $triggerDeprecation = true*/) } if (!$valid) { - $keys = array_keys($invalidTypes); - - if (1 === \count($keys) && '[]' === substr($keys[0], -2)) { - throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), $keys[0])); + $fmtActualValue = $this->formatValue($value); + $fmtAllowedTypes = implode('" or "', $this->allowedTypes[$option]); + $fmtProvidedTypes = implode('|', array_keys($invalidTypes)); + $allowedContainsArrayType = \count(array_filter($this->allowedTypes[$option], static function ($item) { + return '[]' === substr(self::$typeAliases[$item] ?? $item, -2); + })) > 0; + + if (\is_array($value) && $allowedContainsArrayType) { + throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $option, $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes)); } - throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $this->formatValue($value), implode('" or "', $this->allowedTypes[$option]), implode('|', array_keys($invalidTypes)))); + throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $option, $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes)); } } @@ -1040,26 +1045,23 @@ private function verifyTypes(string $type, $value, array &$invalidTypes, int $le { if (\is_array($value) && '[]' === substr($type, -2)) { $type = substr($type, 0, -2); + $valid = true; foreach ($value as $val) { if (!$this->verifyTypes($type, $val, $invalidTypes, $level + 1)) { - return false; + $valid = false; } } - return true; + return $valid; } if (('null' === $type && null === $value) || (\function_exists($func = 'is_'.$type) && $func($value)) || $value instanceof $type) { return true; } - if (!$invalidTypes) { - $suffix = ''; - while (\strlen($suffix) < $level * 2) { - $suffix .= '[]'; - } - $invalidTypes[$this->formatTypeOf($value).$suffix] = true; + if (!$invalidTypes || $level > 0) { + $invalidTypes[$this->formatTypeOf($value)] = true; } return false; diff --git a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php index 43ebf408e90b0..0211b22b26c00 100644 --- a/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php +++ b/src/Symfony/Component/OptionsResolver/Tests/OptionsResolverTest.php @@ -776,7 +776,7 @@ public function testFailIfSetAllowedTypesFromLazyOption() public function testResolveFailsIfInvalidTypedArray() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime[]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "DateTime".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[]'); @@ -796,7 +796,7 @@ public function testResolveFailsWithNonArray() public function testResolveFailsIfTypedArrayContainsInvalidTypes() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass[]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[]", but one of the elements is of type "stdClass|array|DateTime".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[]'); $values = range(1, 5); @@ -811,7 +811,7 @@ public function testResolveFailsIfTypedArrayContainsInvalidTypes() public function testResolveFailsWithCorrectLevelsButWrongScalar() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double[][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "double".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[][]'); @@ -847,6 +847,11 @@ public function provideInvalidTypes() [42, 'string', 'The option "option" with value 42 is expected to be of type "string", but is of type "integer".'], [null, 'string', 'The option "option" with value null is expected to be of type "string", but is of type "NULL".'], ['bar', '\stdClass', 'The option "option" with value "bar" is expected to be of type "\stdClass", but is of type "string".'], + [['foo', 12], 'string[]', 'The option "option" with value array is expected to be of type "string[]", but one of the elements is of type "integer".'], + [123, ['string[]', 'string'], 'The option "option" with value 123 is expected to be of type "string[]" or "string", but is of type "integer".'], + [[null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'], + [['string', null], ['string[]', 'string'], 'The option "option" with value array is expected to be of type "string[]" or "string", but one of the elements is of type "NULL".'], + [[\stdClass::class], ['string'], 'The option "option" with value array is expected to be of type "string", but is of type "array".'], ]; } @@ -1898,7 +1903,7 @@ public function testNested2Arrays() public function testNestedArraysException() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer[][][][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "float[][][][]", but one of the elements is of type "integer".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'float[][][][]'); @@ -1916,7 +1921,7 @@ public function testNestedArraysException() public function testNestedArrayException1() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[][]'); $this->resolver->resolve([ @@ -1929,7 +1934,7 @@ public function testNestedArrayException1() public function testNestedArrayException2() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean[][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "int[][]", but one of the elements is of type "boolean|string|array".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'int[][]'); $this->resolver->resolve([ @@ -1942,7 +1947,7 @@ public function testNestedArrayException2() public function testNestedArrayException3() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string[][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "string|integer".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'string[][][]'); $this->resolver->resolve([ @@ -1955,7 +1960,7 @@ public function testNestedArrayException3() public function testNestedArrayException4() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer[][][]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[][][]", but one of the elements is of type "integer".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'string[][][]'); $this->resolver->resolve([ @@ -1969,7 +1974,7 @@ public function testNestedArrayException4() public function testNestedArrayException5() { $this->expectException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException'); - $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array[]".'); + $this->expectExceptionMessage('The option "foo" with value array is expected to be of type "string[]", but one of the elements is of type "array".'); $this->resolver->setDefined('foo'); $this->resolver->setAllowedTypes('foo', 'string[]'); $this->resolver->resolve([ From 6c2253415f87ad759cfd5cd168cbec531a53062b Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Tue, 29 Oct 2019 02:54:26 +0100 Subject: [PATCH 61/72] drop wrong test (fix merge) --- .../ExpressionLanguage/Tests/ExpressionLanguageTest.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php index 6ecd38f4a4cc3..6e01b250caca5 100644 --- a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php +++ b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php @@ -63,14 +63,6 @@ public function testCachedParse() $this->assertSame($savedParsedExpression, $parsedExpression); } - public function testWrongCacheImplementation() - { - $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage('Cache argument has to implement Psr\Cache\CacheItemPoolInterface.'); - $cacheMock = $this->getMockBuilder('Psr\Cache\CacheItemSpoolInterface')->getMock(); - new ExpressionLanguage($cacheMock); - } - public function testConstantFunction() { $expressionLanguage = new ExpressionLanguage(); From f233259c6838b86155c216a0cfae1c169adf31b3 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Tue, 29 Oct 2019 03:10:02 +0100 Subject: [PATCH 62/72] remove outdated workflow test --- src/Symfony/Component/Workflow/Tests/TransitionTest.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Symfony/Component/Workflow/Tests/TransitionTest.php b/src/Symfony/Component/Workflow/Tests/TransitionTest.php index 0e049158f77b4..14a646d509927 100644 --- a/src/Symfony/Component/Workflow/Tests/TransitionTest.php +++ b/src/Symfony/Component/Workflow/Tests/TransitionTest.php @@ -7,13 +7,6 @@ class TransitionTest extends TestCase { - public function testValidateName() - { - $this->expectException('Symfony\Component\Workflow\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('The transition "foo.bar" contains invalid characters.'); - new Transition('foo.bar', 'a', 'b'); - } - public function testConstructor() { $transition = new Transition('name', 'a', 'b'); From 5ed7d6c759c63e512532fcc4a37019f3b7dd12c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 3 Oct 2019 11:47:46 +0200 Subject: [PATCH 63/72] [DoctrineBridge] Auto-validation must work if no regex are passed --- .../Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php | 2 +- src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php | 2 +- .../DependencyInjection/AddAutoMappingConfigurationPass.php | 4 ++++ .../AddAutoMappingConfigurationPassTest.php | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php index 2dcab2533d375..fbae0fbde2dac 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php @@ -173,7 +173,7 @@ public function testClassValidator(bool $expected, string $classValidatorRegexp public function regexpProvider() { return [ - [false, null], + [true, null], [true, '{^'.preg_quote(DoctrineLoaderEntity::class).'$|^'.preg_quote(Entity::class).'$}'], [false, '{^'.preg_quote(Entity::class).'$}'], ]; diff --git a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php index 76a2b4d8b0288..138b5d1cbbeee 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php +++ b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php @@ -43,7 +43,7 @@ public function __construct(EntityManagerInterface $entityManager, string $class public function loadClassMetadata(ClassMetadata $metadata): bool { $className = $metadata->getClassName(); - if (null === $this->classValidatorRegexp || !preg_match($this->classValidatorRegexp, $className)) { + if (null !== $this->classValidatorRegexp && !preg_match($this->classValidatorRegexp, $className)) { return false; } diff --git a/src/Symfony/Component/Validator/DependencyInjection/AddAutoMappingConfigurationPass.php b/src/Symfony/Component/Validator/DependencyInjection/AddAutoMappingConfigurationPass.php index 177f42e655d84..f28b78650ca0e 100644 --- a/src/Symfony/Component/Validator/DependencyInjection/AddAutoMappingConfigurationPass.php +++ b/src/Symfony/Component/Validator/DependencyInjection/AddAutoMappingConfigurationPass.php @@ -59,6 +59,10 @@ public function process(ContainerBuilder $container) $validatorBuilder = $container->getDefinition($this->validatorBuilderService); foreach ($container->findTaggedServiceIds($this->tag) as $id => $tags) { $regexp = $this->getRegexp(array_merge($globalNamespaces, $servicesToNamespaces[$id] ?? [])); + if (null === $regexp) { + $container->removeDefinition($id); + continue; + } $container->getDefinition($id)->setArgument('$classValidatorRegexp', $regexp); $validatorBuilder->addMethodCall('addLoader', [new Reference($id)]); diff --git a/src/Symfony/Component/Validator/Tests/DependencyInjection/AddAutoMappingConfigurationPassTest.php b/src/Symfony/Component/Validator/Tests/DependencyInjection/AddAutoMappingConfigurationPassTest.php index bce1101ef5cca..711bf8fc4f610 100644 --- a/src/Symfony/Component/Validator/Tests/DependencyInjection/AddAutoMappingConfigurationPassTest.php +++ b/src/Symfony/Component/Validator/Tests/DependencyInjection/AddAutoMappingConfigurationPassTest.php @@ -81,6 +81,6 @@ public function testDoNotMapAllClassesWhenConfigIsEmpty() (new AddAutoMappingConfigurationPass())->process($container); - $this->assertNull($container->getDefinition('loader')->getArgument('$classValidatorRegexp')); + $this->assertFalse($container->hasDefinition('loader')); } } From ad2ce276c7f276f391fc1ec095bc9dbc0ef47eb3 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Sun, 27 Oct 2019 17:07:41 +0100 Subject: [PATCH 64/72] [Serializer] Improve messages for unexpected resources values --- src/Symfony/Component/Serializer/Encoder/XmlEncoder.php | 2 +- src/Symfony/Component/Serializer/Serializer.php | 2 +- .../Serializer/Tests/Encoder/XmlEncoderTest.php | 9 +++++++++ .../Component/Serializer/Tests/SerializerTest.php | 9 +++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php index 3a76665a0bca1..c1e1109130479 100644 --- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php @@ -426,7 +426,7 @@ private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null) return $this->appendNode($parentNode, $data, 'data'); } - throw new NotEncodableValueException(sprintf('An unexpected value could not be serialized: %s', var_export($data, true))); + throw new NotEncodableValueException(sprintf('An unexpected value could not be serialized: %s', !\is_resource($data) ? var_export($data, true) : sprintf('%s resource', get_resource_type($data)))); } /** diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index fd6b7dd0598e8..a29a1482ddef8 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -164,7 +164,7 @@ public function normalize($data, $format = null, array $context = []) throw new NotNormalizableValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', \get_class($data))); } - throw new NotNormalizableValueException(sprintf('An unexpected value could not be normalized: %s', var_export($data, true))); + throw new NotNormalizableValueException(sprintf('An unexpected value could not be normalized: %s', !\is_resource($data) ? var_export($data, true) : sprintf('%s resource', get_resource_type($data)))); } /** diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php index 4f83bf3a58790..f1a8b6ab480e0 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php @@ -14,6 +14,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Encoder\XmlEncoder; +use Symfony\Component\Serializer\Exception\NotEncodableValueException; use Symfony\Component\Serializer\Normalizer\CustomNormalizer; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Serializer; @@ -679,6 +680,14 @@ public function testEncodeXmlWithDateTimeObjectField() $this->assertEquals($this->createXmlWithDateTimeField(), $actualXml); } + public function testNotEncodableValueExceptionMessageForAResource() + { + $this->expectException(NotEncodableValueException::class); + $this->expectExceptionMessage('An unexpected value could not be serialized: stream resource'); + + (new XmlEncoder())->encode(tmpfile(), 'xml'); + } + /** * @return XmlEncoder */ diff --git a/src/Symfony/Component/Serializer/Tests/SerializerTest.php b/src/Symfony/Component/Serializer/Tests/SerializerTest.php index c4814e364f53e..5652768fcab4f 100644 --- a/src/Symfony/Component/Serializer/Tests/SerializerTest.php +++ b/src/Symfony/Component/Serializer/Tests/SerializerTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Serializer\Encoder\JsonEncoder; +use Symfony\Component\Serializer\Exception\NotNormalizableValueException; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; use Symfony\Component\Serializer\Normalizer\CustomNormalizer; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; @@ -328,6 +329,14 @@ public function testDeserializeObjectConstructorWithObjectTypeHint() $this->assertEquals(new Foo(new Bar('baz')), $serializer->deserialize($jsonData, Foo::class, 'json')); } + + public function testNotNormalizableValueExceptionMessageForAResource() + { + $this->expectException(NotNormalizableValueException::class); + $this->expectExceptionMessage('An unexpected value could not be normalized: stream resource'); + + (new Serializer())->normalize(tmpfile()); + } } class Model From e819256ea03b1590d2d8c7a350f704bcf3304666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 29 Oct 2019 14:42:59 +0100 Subject: [PATCH 65/72] [HttpFoundation] Allow to not pass a parameter to Request::isMethodSafe() --- src/Symfony/Component/HttpFoundation/Request.php | 7 ++----- src/Symfony/Component/HttpFoundation/Tests/RequestTest.php | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index 9af2c28256fab..db82ffce815a6 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1447,14 +1447,11 @@ public function isMethod($method) * * @see https://tools.ietf.org/html/rfc7231#section-4.2.1 * - * @param bool $andCacheable Adds the additional condition that the method should be cacheable. True by default. - * * @return bool */ - public function isMethodSafe(/* $andCacheable = true */) + public function isMethodSafe() { - if (!\func_num_args() || func_get_arg(0)) { - // setting $andCacheable to false should be deprecated in 4.1 + if (\func_num_args() > 0 && func_get_arg(0)) { throw new \BadMethodCallException('Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is not supported.'); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index d56ef31476f59..03493b5327304 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -2132,7 +2132,7 @@ public function testMethodSafeChecksCacheable() $this->expectException('BadMethodCallException'); $request = new Request(); $request->setMethod('OPTIONS'); - $request->isMethodSafe(); + $request->isMethodSafe(true); } /** From 5f19501fc4d5b564d2e3ee8a5a1be83252893d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Tue, 29 Oct 2019 15:56:06 +0100 Subject: [PATCH 66/72] [TwigBundle][exception] Added missing css variable to highlight line in trace --- src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig index 8c1f9af2a0d18..b7eb560002f9b 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig @@ -28,6 +28,7 @@ --shadow: 0px 0px 1px rgba(128, 128, 128, .2); --border: 1px solid #e0e0e0; --background-error: var(--color-error); + --trace-selected-background: #F7E5A1; --highlight-comment: #969896; --highlight-default: #222222; --highlight-keyword: #a71d5d; From f78e14332e152b0bad504a9e20987bfc52f31e7a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 30 Oct 2019 12:53:18 +0100 Subject: [PATCH 67/72] [HttpClient] always return the empty string when the response cannot have a body --- .../Component/HttpClient/Response/ResponseTrait.php | 10 +++++++--- .../Component/HttpClient/Tests/MockHttpClientTest.php | 2 +- .../Contracts/HttpClient/Test/Fixtures/web/index.php | 10 ++++++++-- .../Contracts/HttpClient/Test/HttpClientTestCase.php | 9 ++++----- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/ResponseTrait.php b/src/Symfony/Component/HttpClient/Response/ResponseTrait.php index 8a1d9a9077ce1..5179a074183b5 100644 --- a/src/Symfony/Component/HttpClient/Response/ResponseTrait.php +++ b/src/Symfony/Component/HttpClient/Response/ResponseTrait.php @@ -112,11 +112,15 @@ public function getContent(bool $throw = true): string } } - if (null === $content) { - throw new TransportException('Cannot get the content of the response twice: the request was issued with option "buffer" set to false.'); + if (null !== $content) { + return $content; } - return $content; + if ('HEAD' === $this->info['http_method'] || \in_array($this->info['http_code'], [204, 304], true)) { + return ''; + } + + throw new TransportException('Cannot get the content of the response twice: the request was issued with option "buffer" set to false.'); } foreach (self::stream([$this]) as $chunk) { diff --git a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php index 32b4ebe4485a1..f8f2c3e18b1db 100644 --- a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php @@ -48,7 +48,7 @@ protected function getHttpClient(string $testCase): HttpClientInterface return new MockHttpClient(function (string $method, string $url, array $options) use ($client) { try { // force the request to be completed so that we don't test side effects of the transport - $response = $client->request($method, $url, $options); + $response = $client->request($method, $url, ['buffer' => false] + $options); $content = $response->getContent(false); return new MockResponse($content, $response->getInfo()); diff --git a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php index 10ed100ccc826..08dd1b6dcac7f 100644 --- a/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php +++ b/src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php @@ -29,15 +29,20 @@ } } +$json = json_encode($vars, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + switch ($vars['REQUEST_URI']) { default: exit; + case '/head': + header('Content-Length: '.strlen($json), true); + break; + case '/': case '/?a=a&b=b': case 'http://127.0.0.1:8057/': case 'http://localhost:8057/': - header('Content-Type: application/json'); ob_start('ob_gzhandler'); break; @@ -85,6 +90,7 @@ case '/304': header('Content-Length: 10', true, 304); echo '12345'; + return; case '/307': @@ -143,4 +149,4 @@ header('Content-Type: application/json', true); -echo json_encode($vars, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); +echo $json; diff --git a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php index df7a597590deb..e8d8b19eee9c6 100644 --- a/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php +++ b/src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php @@ -75,26 +75,24 @@ public function testGetRequest() public function testHeadRequest() { $client = $this->getHttpClient(__FUNCTION__); - $response = $client->request('HEAD', 'http://localhost:8057', [ + $response = $client->request('HEAD', 'http://localhost:8057/head', [ 'headers' => ['Foo' => 'baR'], 'user_data' => $data = new \stdClass(), + 'buffer' => false, ]); $this->assertSame([], $response->getInfo('response_headers')); - $this->assertSame($data, $response->getInfo()['user_data']); $this->assertSame(200, $response->getStatusCode()); $info = $response->getInfo(); - $this->assertNull($info['error']); - $this->assertSame(0, $info['redirect_count']); $this->assertSame('HTTP/1.1 200 OK', $info['response_headers'][0]); $this->assertSame('Host: localhost:8057', $info['response_headers'][1]); - $this->assertSame('http://localhost:8057/', $info['url']); $headers = $response->getHeaders(); $this->assertSame('localhost:8057', $headers['host'][0]); $this->assertSame(['application/json'], $headers['content-type']); + $this->assertTrue(0 < $headers['content-length'][0]); $this->assertSame('', $response->getContent()); } @@ -265,6 +263,7 @@ public function test304() $client = $this->getHttpClient(__FUNCTION__); $response = $client->request('GET', 'http://localhost:8057/304', [ 'headers' => ['If-Match' => '"abc"'], + 'buffer' => false, ]); $this->assertSame(304, $response->getStatusCode()); From 3bed0247c0b250c356ed9cc5b38c5fbaf23fa9a8 Mon Sep 17 00:00:00 2001 From: Denys Voronin Date: Wed, 16 Oct 2019 13:30:11 +0300 Subject: [PATCH 68/72] [Config] Disable default alphabet sorting in glob function due of unstable sort --- link | 2 +- src/Symfony/Component/Config/Resource/GlobResource.php | 4 +++- src/Symfony/Component/Finder/Finder.php | 3 ++- .../Translation/Resources/bin/translation-status.php | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/link b/link index 95a3142d2acda..7b7512f0c9d1f 100755 --- a/link +++ b/link @@ -64,6 +64,6 @@ foreach (glob("$pathToProject/vendor/symfony/*", GLOB_ONLYDIR | GLOB_NOSORT) as echo "\"$package\" has been linked to \"$sfPackages[$package]\".".PHP_EOL; } -foreach (glob("$pathToProject/var/cache/*") as $cacheDir) { +foreach (glob("$pathToProject/var/cache/*", GLOB_NOSORT) as $cacheDir) { $filesystem->remove($cacheDir); } diff --git a/src/Symfony/Component/Config/Resource/GlobResource.php b/src/Symfony/Component/Config/Resource/GlobResource.php index 28ba0a6112bd0..13d2ee7d703d7 100644 --- a/src/Symfony/Component/Config/Resource/GlobResource.php +++ b/src/Symfony/Component/Config/Resource/GlobResource.php @@ -100,7 +100,9 @@ public function getIterator() } if (0 !== strpos($this->prefix, 'phar://') && false === strpos($this->pattern, '/**/') && (\defined('GLOB_BRACE') || false === strpos($this->pattern, '{'))) { - foreach (glob($this->prefix.$this->pattern, \defined('GLOB_BRACE') ? GLOB_BRACE : 0) as $path) { + $paths = glob($this->prefix.$this->pattern, GLOB_NOSORT | (\defined('GLOB_BRACE') ? GLOB_BRACE : 0)); + sort($paths); + foreach ($paths as $path) { if ($this->recursive && is_dir($path)) { $files = iterator_to_array(new \RecursiveIteratorIterator( new \RecursiveCallbackFilterIterator( diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index e933f078416be..6624e840791fb 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -541,7 +541,8 @@ public function in($dirs) foreach ((array) $dirs as $dir) { if (is_dir($dir)) { $resolvedDirs[] = $this->normalizeDir($dir); - } elseif ($glob = glob($dir, (\defined('GLOB_BRACE') ? GLOB_BRACE : 0) | GLOB_ONLYDIR)) { + } elseif ($glob = glob($dir, (\defined('GLOB_BRACE') ? GLOB_BRACE : 0) | GLOB_ONLYDIR | GLOB_NOSORT)) { + sort($glob); $resolvedDirs = array_merge($resolvedDirs, array_map([$this, 'normalizeDir'], $glob)); } else { throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir)); diff --git a/src/Symfony/Component/Translation/Resources/bin/translation-status.php b/src/Symfony/Component/Translation/Resources/bin/translation-status.php index 669b8f2864730..44918c92ec527 100644 --- a/src/Symfony/Component/Translation/Resources/bin/translation-status.php +++ b/src/Symfony/Component/Translation/Resources/bin/translation-status.php @@ -89,7 +89,8 @@ function findTranslationFiles($originalFilePath, $localeToAnalyze) $originalFileName = basename($originalFilePath); $translationFileNamePattern = str_replace('.en.', '.*.', $originalFileName); - $translationFiles = glob($translationsDir.'/'.$translationFileNamePattern); + $translationFiles = glob($translationsDir.'/'.$translationFileNamePattern, GLOB_NOSORT); + sort($translationFiles); foreach ($translationFiles as $filePath) { $locale = extractLocaleFromFilePath($filePath); From 58161b8eec59d82c398c4afa0b999cd67a02199e Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Tue, 29 Oct 2019 19:32:45 +0100 Subject: [PATCH 69/72] [4.3] Remove unused local variables --- .../Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php | 3 --- src/Symfony/Bridge/Twig/Node/TransNode.php | 2 -- .../DependencyInjection/FrameworkExtension.php | 2 -- .../Bundle/FrameworkBundle/Routing/DelegatingLoader.php | 5 ----- .../FrameworkBundle/Tests/Functional/ContainerDumpTest.php | 4 ++-- .../Tests/DataCollector/SecurityDataCollectorTest.php | 1 - .../Component/Cache/Tests/Adapter/AdapterTestCase.php | 4 ++-- .../Component/Cache/Tests/Adapter/NullAdapterTest.php | 2 +- .../Component/Cache/Tests/Adapter/PdoDbalAdapterTest.php | 2 -- src/Symfony/Component/Config/ResourceCheckerConfigCache.php | 1 - .../Console/Tests/Output/ConsoleSectionOutputTest.php | 4 ++-- src/Symfony/Component/HttpClient/Response/ResponseTrait.php | 1 - .../Storage/Handler/NativeFileSessionHandlerTest.php | 2 +- .../RegisterControllerArgumentLocatorsPassTest.php | 2 +- src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php | 4 ++-- .../Component/Messenger/Transport/RedisExt/Connection.php | 1 - .../Messenger/Transport/Serialization/PhpSerializer.php | 1 - src/Symfony/Component/Mime/CharacterStream.php | 1 - src/Symfony/Component/Mime/Tests/EmailTest.php | 4 +--- src/Symfony/Component/Mime/Tests/Header/HeadersTest.php | 4 ---- .../Mime/Tests/Header/IdentificationHeaderTest.php | 6 +++--- src/Symfony/Component/Mime/Tests/Header/PathHeaderTest.php | 2 +- .../Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php | 2 +- .../Component/Routing/Tests/Annotation/RouteTest.php | 2 +- .../Generator/Dumper/CompiledUrlGeneratorDumperTest.php | 2 +- src/Symfony/Component/Security/Http/Tests/FirewallTest.php | 3 --- .../Component/Serializer/Normalizer/AbstractNormalizer.php | 1 - .../Component/Validator/Tests/ConstraintViolationTest.php | 5 ++--- src/Symfony/Component/Yaml/Parser.php | 1 - 29 files changed, 21 insertions(+), 53 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index 03696c69f0e4d..ed84eedf4a92a 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -257,14 +257,11 @@ public function endTest($test, $time) if (class_exists('PHPUnit_Util_Blacklist', false)) { $Test = 'PHPUnit_Util_Test'; $BaseTestRunner = 'PHPUnit_Runner_BaseTestRunner'; - $Warning = 'PHPUnit_Framework_Warning'; } else { $Test = 'PHPUnit\Util\Test'; $BaseTestRunner = 'PHPUnit\Runner\BaseTestRunner'; - $Warning = 'PHPUnit\Framework\Warning'; } $className = \get_class($test); - $classGroups = $Test::getGroups($className); $groups = $Test::getGroups($className, $test->getName(false)); if (null !== $this->reportUselessTests) { diff --git a/src/Symfony/Bridge/Twig/Node/TransNode.php b/src/Symfony/Bridge/Twig/Node/TransNode.php index cedc6b740e08d..e844801a5f0ce 100644 --- a/src/Symfony/Bridge/Twig/Node/TransNode.php +++ b/src/Symfony/Bridge/Twig/Node/TransNode.php @@ -57,8 +57,6 @@ public function compile(Compiler $compiler) } list($msg, $defaults) = $this->compileString($this->getNode('body'), $defaults, (bool) $vars); - $method = !$this->hasNode('count') ? 'trans' : 'transChoice'; - $compiler ->write('echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->trans(') ->subcompile($msg) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 8b64507d0a21f..a913f4f93db40 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -997,8 +997,6 @@ private function registerAssetsConfiguration(array $config, ContainerBuilder $co { $loader->load('assets.xml'); - $defaultVersion = null; - if ($config['version_strategy']) { $defaultVersion = new Reference($config['version_strategy']); } else { diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php index 1e6b90a9bf107..03b87fd6ebb8d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php @@ -98,11 +98,6 @@ public function load($resource, $type = null) } } - if (1 === substr_count($controller, ':')) { - $nonDeprecatedNotation = str_replace(':', '::', $controller); - // TODO deprecate this in 5.1 - } - $route->setDefault('_controller', $controller); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDumpTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDumpTest.php index 8f826714782a9..f543058440582 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDumpTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ContainerDumpTest.php @@ -18,14 +18,14 @@ class ContainerDumpTest extends AbstractWebTestCase { public function testContainerCompilationInDebug() { - $client = $this->createClient(['test_case' => 'ContainerDump', 'root_config' => 'config.yml']); + $this->createClient(['test_case' => 'ContainerDump', 'root_config' => 'config.yml']); $this->assertTrue(static::$container->has('serializer')); } public function testContainerCompilation() { - $client = $this->createClient(['test_case' => 'ContainerDump', 'root_config' => 'config.yml', 'debug' => false]); + $this->createClient(['test_case' => 'ContainerDump', 'root_config' => 'config.yml', 'debug' => false]); $this->assertTrue(static::$container->has('serializer')); } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php index 7e583facf7b09..450cb68ab119a 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php @@ -258,7 +258,6 @@ public function providerCollectDecisionLog(): \Generator $eventDispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMockForAbstractClass(); $decoratedVoter1 = new TraceableVoter($voter1, $eventDispatcher); - $decoratedVoter2 = new TraceableVoter($voter2, $eventDispatcher); yield [ AccessDecisionManager::STRATEGY_AFFIRMATIVE, diff --git a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php index 63a7f39e537c2..a6132ebca2fc9 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php @@ -87,8 +87,8 @@ public function testRecursiveGet() $cache = $this->createCachePool(0, __FUNCTION__); $v = $cache->get('k1', function () use (&$counter, $cache) { - $v = $cache->get('k2', function () use (&$counter) { return ++$counter; }); - $v = $cache->get('k2', function () use (&$counter) { return ++$counter; }); + $cache->get('k2', function () use (&$counter) { return ++$counter; }); + $v = $cache->get('k2', function () use (&$counter) { return ++$counter; }); // ensure the callback is called once return $v; }); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php index 6c5710a7e4e29..ae3de76dc135d 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php @@ -39,7 +39,7 @@ public function testGet() $adapter = $this->createCachePool(); $fetched = []; - $item = $adapter->get('myKey', function ($item) use (&$fetched) { $fetched[] = $item; }); + $adapter->get('myKey', function ($item) use (&$fetched) { $fetched[] = $item; }); $this->assertCount(1, $fetched); $item = $fetched[0]; $this->assertFalse($item->isHit()); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PdoDbalAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PdoDbalAdapterTest.php index 573a1b1d01394..d4071baedbc91 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PdoDbalAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PdoDbalAdapterTest.php @@ -31,8 +31,6 @@ public static function setUpBeforeClass(): void } self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - - $pool = new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile])); } public static function tearDownAfterClass(): void diff --git a/src/Symfony/Component/Config/ResourceCheckerConfigCache.php b/src/Symfony/Component/Config/ResourceCheckerConfigCache.php index 34dc35d5f51f8..c30686721a6cc 100644 --- a/src/Symfony/Component/Config/ResourceCheckerConfigCache.php +++ b/src/Symfony/Component/Config/ResourceCheckerConfigCache.php @@ -154,7 +154,6 @@ private function getMetaFile() private function safelyUnserialize($file) { - $e = null; $meta = false; $content = file_get_contents($file); $signalingException = new \UnexpectedValueException(); diff --git a/src/Symfony/Component/Console/Tests/Output/ConsoleSectionOutputTest.php b/src/Symfony/Component/Console/Tests/Output/ConsoleSectionOutputTest.php index e8d9a8b49253d..e8c65f9b21649 100644 --- a/src/Symfony/Component/Console/Tests/Output/ConsoleSectionOutputTest.php +++ b/src/Symfony/Component/Console/Tests/Output/ConsoleSectionOutputTest.php @@ -118,8 +118,8 @@ public function testOverwriteMultipleLines() public function testAddingMultipleSections() { $sections = []; - $output1 = new ConsoleSectionOutput($this->stream, $sections, OutputInterface::VERBOSITY_NORMAL, true, new OutputFormatter()); - $output2 = new ConsoleSectionOutput($this->stream, $sections, OutputInterface::VERBOSITY_NORMAL, true, new OutputFormatter()); + new ConsoleSectionOutput($this->stream, $sections, OutputInterface::VERBOSITY_NORMAL, true, new OutputFormatter()); + new ConsoleSectionOutput($this->stream, $sections, OutputInterface::VERBOSITY_NORMAL, true, new OutputFormatter()); $this->assertCount(2, $sections); } diff --git a/src/Symfony/Component/HttpClient/Response/ResponseTrait.php b/src/Symfony/Component/HttpClient/Response/ResponseTrait.php index 8a1d9a9077ce1..df511e90e57e8 100644 --- a/src/Symfony/Component/HttpClient/Response/ResponseTrait.php +++ b/src/Symfony/Component/HttpClient/Response/ResponseTrait.php @@ -104,7 +104,6 @@ public function getContent(bool $throw = true): string if (null === $this->content) { $content = null; - $chunk = null; foreach (self::stream([$this]) as $chunk) { if (!$chunk->isLast()) { diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php index 347619e96232e..368af6a3e3e10 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php @@ -27,7 +27,7 @@ class NativeFileSessionHandlerTest extends TestCase { public function testConstruct() { - $storage = new NativeSessionStorage(['name' => 'TESTING'], new NativeFileSessionHandler(sys_get_temp_dir())); + new NativeSessionStorage(['name' => 'TESTING'], new NativeFileSessionHandler(sys_get_temp_dir())); $this->assertEquals('user', ini_get('session.save_handler')); diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php index 1200472bb137c..624658f727cef 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php @@ -364,7 +364,7 @@ public function testBindingsOnChildDefinitions() public function testNotTaggedControllerServiceReceivesLocatorArgument() { $container = new ContainerBuilder(); - $resolver = $container->register('argument_resolver.not_tagged_controller')->addArgument([]); + $container->register('argument_resolver.not_tagged_controller')->addArgument([]); $pass = new RegisterControllerArgumentLocatorsPass(); $pass->process($container); diff --git a/src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php b/src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php index f963a5a0f4af4..edb8b97cabbf8 100644 --- a/src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php +++ b/src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php @@ -41,13 +41,13 @@ public function testConstructorWithAddressRecipients() public function testConstructorWithNoRecipients() { $this->expectException(\InvalidArgumentException::class); - $e = new SmtpEnvelope(new Address('fabien@symfony.com'), []); + new SmtpEnvelope(new Address('fabien@symfony.com'), []); } public function testConstructorWithWrongRecipients() { $this->expectException(\InvalidArgumentException::class); - $e = new SmtpEnvelope(new Address('fabien@symfony.com'), ['lucas@symfony.com']); + new SmtpEnvelope(new Address('fabien@symfony.com'), ['lucas@symfony.com']); } public function testSenderFromHeaders() diff --git a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php index 6864cd1b9c459..6ded724ca5bfa 100644 --- a/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php +++ b/src/Symfony/Component/Messenger/Transport/RedisExt/Connection.php @@ -106,7 +106,6 @@ public function get(): ?array $messageId = '0'; // will receive consumers pending messages } - $e = null; try { $messages = $this->connection->xreadgroup( $this->group, diff --git a/src/Symfony/Component/Messenger/Transport/Serialization/PhpSerializer.php b/src/Symfony/Component/Messenger/Transport/Serialization/PhpSerializer.php index 793da4a44802a..9a42bcc699bbf 100644 --- a/src/Symfony/Component/Messenger/Transport/Serialization/PhpSerializer.php +++ b/src/Symfony/Component/Messenger/Transport/Serialization/PhpSerializer.php @@ -52,7 +52,6 @@ public function encode(Envelope $envelope): array private function safelyUnserialize($contents) { - $e = null; $signalingException = new MessageDecodingFailedException(sprintf('Could not decode message using PHP serialization: %s.', $contents)); $prevUnserializeHandler = ini_set('unserialize_callback_func', self::class.'::handleUnserializeCallback'); $prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler, $signalingException) { diff --git a/src/Symfony/Component/Mime/CharacterStream.php b/src/Symfony/Component/Mime/CharacterStream.php index 9b80b2efa481a..045b477093c66 100644 --- a/src/Symfony/Component/Mime/CharacterStream.php +++ b/src/Symfony/Component/Mime/CharacterStream.php @@ -116,7 +116,6 @@ public function read(int $length): ?string if ($this->currentPos >= $this->charCount) { return null; } - $ret = null; $length = ($this->currentPos + $length > $this->charCount) ? $this->charCount - $this->currentPos : $length; if ($this->fixedWidth > 0) { $len = $length * $this->fixedWidth; diff --git a/src/Symfony/Component/Mime/Tests/EmailTest.php b/src/Symfony/Component/Mime/Tests/EmailTest.php index 764f66b079480..1822da12aaa45 100644 --- a/src/Symfony/Component/Mime/Tests/EmailTest.php +++ b/src/Symfony/Component/Mime/Tests/EmailTest.php @@ -320,8 +320,6 @@ public function testGenerateBody() $e->text('text content'); $e->attach($file); $e->attach($image, 'test.gif'); - $fullhtml = new TextPart($content, 'utf-8', 'html'); - $inlinedimg = (new DataPart($image, 'test.gif'))->asInline(); $body = $e->getBody(); $this->assertInstanceOf(MixedPart::class, $body); $this->assertCount(2, $related = $body->getParts()); @@ -378,7 +376,7 @@ public function testSerialize() $e->from('fabien@symfony.com'); $e->text($r); $e->html($r); - $contents = file_get_contents($name = __DIR__.'/Fixtures/mimetypes/test', 'r'); + $name = __DIR__.'/Fixtures/mimetypes/test'; $file = fopen($name, 'r'); $e->attach($file, 'test'); $expected = clone $e; diff --git a/src/Symfony/Component/Mime/Tests/Header/HeadersTest.php b/src/Symfony/Component/Mime/Tests/Header/HeadersTest.php index 3568c9a6e45d6..e2eb75a6977f3 100644 --- a/src/Symfony/Component/Mime/Tests/Header/HeadersTest.php +++ b/src/Symfony/Component/Mime/Tests/Header/HeadersTest.php @@ -173,8 +173,6 @@ public function testAllReturnsEmptyArrayIfNoneSet() public function testRemoveRemovesAllHeadersWithName() { - $header0 = new UnstructuredHeader('X-Test', 'some@id'); - $header1 = new UnstructuredHeader('X-Test', 'other@id'); $headers = new Headers(); $headers->addIdHeader('X-Test', 'some@id'); $headers->addIdHeader('X-Test', 'other@id'); @@ -185,7 +183,6 @@ public function testRemoveRemovesAllHeadersWithName() public function testHasIsNotCaseSensitive() { - $header = new IdentificationHeader('Message-ID', 'some@id'); $headers = new Headers(); $headers->addIdHeader('Message-ID', 'some@id'); $this->assertTrue($headers->has('message-id')); @@ -209,7 +206,6 @@ public function testAllIsNotCaseSensitive() public function testRemoveIsNotCaseSensitive() { - $header = new IdentificationHeader('Message-ID', 'some@id'); $headers = new Headers(); $headers->addIdHeader('Message-ID', 'some@id'); $headers->remove('message-id'); diff --git a/src/Symfony/Component/Mime/Tests/Header/IdentificationHeaderTest.php b/src/Symfony/Component/Mime/Tests/Header/IdentificationHeaderTest.php index b7f0095d3a164..7d274ab162d55 100644 --- a/src/Symfony/Component/Mime/Tests/Header/IdentificationHeaderTest.php +++ b/src/Symfony/Component/Mime/Tests/Header/IdentificationHeaderTest.php @@ -103,7 +103,7 @@ public function testInvalidIdLeftThrowsException() { $this->expectException('Exception'); $this->expectExceptionMessage('Email "a b c@d" does not comply with addr-spec of RFC 2822.'); - $header = new IdentificationHeader('References', 'a b c@d'); + new IdentificationHeader('References', 'a b c@d'); } public function testIdRightCanBeDotAtom() @@ -139,7 +139,7 @@ public function testInvalidIdRightThrowsException() { $this->expectException('Exception'); $this->expectExceptionMessage('Email "a@b c d" does not comply with addr-spec of RFC 2822.'); - $header = new IdentificationHeader('References', 'a@b c d'); + new IdentificationHeader('References', 'a@b c d'); } public function testMissingAtSignThrowsException() @@ -149,7 +149,7 @@ public function testMissingAtSignThrowsException() /* -- RFC 2822, 3.6.4. msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS] */ - $header = new IdentificationHeader('References', 'abc'); + new IdentificationHeader('References', 'abc'); } public function testSetBody() diff --git a/src/Symfony/Component/Mime/Tests/Header/PathHeaderTest.php b/src/Symfony/Component/Mime/Tests/Header/PathHeaderTest.php index 6bc029aee4cea..a8386f89462a9 100644 --- a/src/Symfony/Component/Mime/Tests/Header/PathHeaderTest.php +++ b/src/Symfony/Component/Mime/Tests/Header/PathHeaderTest.php @@ -26,7 +26,7 @@ public function testSingleAddressCanBeSetAndFetched() public function testAddressMustComplyWithRfc2822() { $this->expectException('Exception'); - $header = new PathHeader('Return-Path', new Address('chr is@swiftmailer.org')); + new PathHeader('Return-Path', new Address('chr is@swiftmailer.org')); } public function testValueIsAngleAddrWithValidAddress() diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php index ab67e6885ac92..b3a93886796b4 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/CompiledUrlMatcherDumper.php @@ -121,7 +121,7 @@ static function (\$condition, \$context, \$request) { // \$checkCondition } } EOF; - $compiledRoutes[4] = $forDump ? $checkConditionCode .= ",\n" : eval('return '.$checkConditionCode.';'); + $compiledRoutes[4] = $forDump ? $checkConditionCode.",\n" : eval('return '.$checkConditionCode.';'); } else { $compiledRoutes[4] = $forDump ? " null, // \$checkCondition\n" : null; } diff --git a/src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php b/src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php index c0a8589c984a2..2c193a8a09588 100644 --- a/src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php +++ b/src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php @@ -25,7 +25,7 @@ public function testInvalidRouteParameter() public function testTryingToSetLocalesDirectly() { $this->expectException('BadMethodCallException'); - $route = new Route(['locales' => ['nl' => 'bar']]); + new Route(['locales' => ['nl' => 'bar']]); } /** diff --git a/src/Symfony/Component/Routing/Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php b/src/Symfony/Component/Routing/Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php index 513e1c80e1e66..521f0f126cda7 100644 --- a/src/Symfony/Component/Routing/Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php +++ b/src/Symfony/Component/Routing/Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php @@ -194,7 +194,7 @@ public function testGenerateNonExistingRoute() file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump()); $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext()); - $url = $projectUrlGenerator->generate('NonExisting', []); + $projectUrlGenerator->generate('NonExisting', []); } public function testDumpForRouteWithDefaults() diff --git a/src/Symfony/Component/Security/Http/Tests/FirewallTest.php b/src/Symfony/Component/Security/Http/Tests/FirewallTest.php index bb81bc36a7086..e3e04d8f1573d 100644 --- a/src/Symfony/Component/Security/Http/Tests/FirewallTest.php +++ b/src/Symfony/Component/Security/Http/Tests/FirewallTest.php @@ -14,7 +14,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\Security\Http\Firewall; @@ -52,8 +51,6 @@ public function testOnKernelRequestRegistersExceptionListener() public function testOnKernelRequestStopsWhenThereIsAResponse() { - $response = new Response(); - $called = []; $first = function () use (&$called) { diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 5f165b56ac774..056744fa4b0f8 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -552,7 +552,6 @@ protected function createChildContext(array $parentContext, $attribute/*, ?strin { if (\func_num_args() < 3) { @trigger_error(sprintf('Method "%s::%s()" will have a third "?string $format" argument in version 5.0; not defining it is deprecated since Symfony 4.3.', \get_class($this), __FUNCTION__), E_USER_DEPRECATED); - $format = null; } if (isset($parentContext[self::ATTRIBUTES][$attribute])) { $parentContext[self::ATTRIBUTES] = $parentContext[self::ATTRIBUTES][$attribute]; diff --git a/src/Symfony/Component/Validator/Tests/ConstraintViolationTest.php b/src/Symfony/Component/Validator/Tests/ConstraintViolationTest.php index 698d95d91348d..f8dc69efc16bb 100644 --- a/src/Symfony/Component/Validator/Tests/ConstraintViolationTest.php +++ b/src/Symfony/Component/Validator/Tests/ConstraintViolationTest.php @@ -14,7 +14,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\Tests\Fixtures\CustomArrayObject; -use Symfony\Component\Validator\Tests\Fixtures\ToString; class ConstraintViolationTest extends TestCase { @@ -114,7 +113,7 @@ public function testToStringOmitsEmptyCodes() public function testMessageCannotBeArray() { $this->expectException(\TypeError::class); - $violation = new ConstraintViolation( + new ConstraintViolation( ['cannot be an array'], '', [], @@ -127,7 +126,7 @@ public function testMessageCannotBeArray() public function testMessageObjectMustBeStringable() { $this->expectException(\TypeError::class); - $violation = new ConstraintViolation( + new ConstraintViolation( new CustomArrayObject(), '', [], diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index d4e94a5ee3174..6ad165ad4e313 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -85,7 +85,6 @@ public function parse(string $value, int $flags = 0) $this->refs = []; $mbEncoding = null; - $data = null; if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { $mbEncoding = mb_internal_encoding(); From e388b739ed524d33254a2a6ce32141c784b4b7b6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 31 Oct 2019 08:19:16 +0100 Subject: [PATCH 70/72] [HttpClient] Fix perf issue when doing thousands of requests with curl --- src/Symfony/Component/HttpClient/Response/CurlResponse.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Symfony/Component/HttpClient/Response/CurlResponse.php b/src/Symfony/Component/HttpClient/Response/CurlResponse.php index 4b25acf79565f..6771dcb6f218a 100644 --- a/src/Symfony/Component/HttpClient/Response/CurlResponse.php +++ b/src/Symfony/Component/HttpClient/Response/CurlResponse.php @@ -142,7 +142,6 @@ public function __construct(CurlClientState $multi, $ch, array $options = null, // Schedule the request in a non-blocking way $multi->openHandles[$id] = [$ch, $options]; curl_multi_add_handle($multi->handle, $ch); - self::perform($multi); } /** From 48373ab261461db730ef84093a92a26827972167 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 1 Nov 2019 10:59:55 +0100 Subject: [PATCH 71/72] updated CHANGELOG for 4.3.6 --- CHANGELOG-4.3.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/CHANGELOG-4.3.md b/CHANGELOG-4.3.md index 0d1862231449a..5707e18c465a7 100644 --- a/CHANGELOG-4.3.md +++ b/CHANGELOG-4.3.md @@ -7,6 +7,49 @@ in 4.3 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.3.0...v4.3.1 +* 4.3.6 (2019-11-01) + + * bug #34198 [HttpClient] Fix perf issue when doing thousands of requests with curl (nicolas-grekas) + * bug #33998 [Config] Disable default alphabet sorting in glob function due of unstable sort (hurricane-voronin) + * bug #34144 [Serializer] Improve messages for unexpected resources values (fancyweb) + * bug #34186 [HttpClient] always return the empty string when the response cannot have a body (nicolas-grekas) + * bug #34167 [HttpFoundation] Allow to not pass a parameter to Request::isMethodSafe() (dunglas) + * bug #33828 [DoctrineBridge] Auto-validation must work if no regex are passed (dunglas) + * bug #34080 [SecurityBundle] correct types for default arguments for firewall configs (shieldo) + * bug #34152 [Workflow] Made the configuration more robust for the 'property' key (lyrixx) + * bug #34154 [HttpClient] fix handling of 3xx with no Location header - ignore Content-Length when no body is expected (nicolas-grekas) + * bug #34140 [Security/Core] make NativePasswordEncoder use sodium to validate passwords when possible (nicolas-grekas) + * bug #33999 [Form] Make sure to collect child forms created on *_SET_DATA events (yceruto) + * bug #34090 [WebProfilerBundle] Improve display in Email panel for dark theme (antograssiot) + * bug #34116 [HttpClient] ignore the body of responses to HEAD requests (nicolas-grekas) + * bug #32456 [Messenger] use database platform to convert correctly the DateTime (roukmoute) + * bug #34107 [Messenger] prevent infinite redelivery loops and blocked queues (Tobion) + * bug #32341 [Messenger] Show exceptions after multiple retries (TimoBakx) + * bug #34082 Revert "[Messenger] Fix exception message of failed message is dropped (Tobion) + * bug #34021 [TwigBridge] do not render errors for checkboxes twice (xabbuh) + * bug #34017 [Messenger] Fix ignored options in redis transport (chalasr) + * bug #34041 [HttpKernel] fix wrong removal of the just generated container dir (nicolas-grekas) + * bug #34024 [Routing] fix route loading with wildcard, but dir or file is empty (gseidel) + * bug #34023 [Dotenv] allow LF in single-quoted strings (nicolas-grekas) + * bug #33818 [Yaml] Throw exception for tagged invalid inline elements (gharlan) + * bug #33994 [Mailer] Fix Mandrill Transport API payload for named addresses (Michaël Perrin) + * bug #33985 [HttpClient] workaround curl_multi_select() issue (nicolas-grekas) + * bug #33948 [PropertyInfo] Respect property name case when guessing from public method name (antograssiot) + * bug #33962 [Cache] fixed TagAwareAdapter returning invalid cache (v-m-i) + * bug #33958 [DI] Add extra type check to php dumper (gquemener) + * bug #33965 [HttpFoundation] Add plus character `+` to legal mime subtype (ilzrv) + * bug #32943 [Dotenv] search variable values in ENV first then env file (soufianZantar) + * bug #33943 [VarDumper] fix resetting the "bold" state in CliDumper (nicolas-grekas) + * bug #33936 [HttpClient] Missing argument in method_exists (detinkin) + * bug #33937 [Cache] ignore unserialization failures in AbstractTagAwareAdapter::doDelete() (nicolas-grekas) + * bug #33935 [HttpClient] send `Accept: */*` by default, fix removing it when needed (nicolas-grekas) + * bug #33922 [Cache] remove implicit dependency on symfony/filesystem (nicolas-grekas) + * bug #33927 Allow to set SameSite config to 'none' (ihmels) + * bug #33930 [Cache] clean tags folder on invalidation (nicolas-grekas) + * bug #33919 [VarDumper] fix array key error for class SymfonyCaster (zcodes) + * bug #33885 [Form][DateTimeImmutableToDateTimeTransformer] Preserve microseconds and use \DateTime::createFromImmutable() when available (fancyweb) + * bug #33900 [HttpKernel] Fix to populate $dotenvVars in data collector when not using putenv() (mynameisbogdan) + * 4.3.5 (2019-10-07) * bug #33742 [Crawler] document $default as string|null (nicolas-grekas) From b959f05d989600f5e24bf5bc57969d093453c0e4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 1 Nov 2019 11:00:03 +0100 Subject: [PATCH 72/72] updated VERSION for 4.3.6 --- 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 3c3276188ab96..d91b4f64d9ce6 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 $requestStackSize = 0; private $resetServices = false; - const VERSION = '4.3.6-DEV'; + const VERSION = '4.3.6'; const VERSION_ID = 40306; const MAJOR_VERSION = 4; const MINOR_VERSION = 3; const RELEASE_VERSION = 6; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '01/2020'; const END_OF_LIFE = '07/2020';