diff --git a/.appveyor.yml b/.appveyor.yml index 8a880a9b3c063..fddaf7b75802c 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -46,6 +46,7 @@ install: - echo extension=php_fileinfo.dll >> php.ini-max - echo extension=php_pdo_sqlite.dll >> php.ini-max - echo extension=php_curl.dll >> php.ini-max + - echo extension=php_sodium.dll >> php.ini-max - copy /Y php.ini-max php.ini - cd c:\projects\symfony - IF NOT EXIST composer.phar (appveyor DownloadFile https://github.com/composer/composer/releases/download/2.0.0/composer.phar) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 23f535cb9b80e..c4b401d26f70e 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -29,7 +29,7 @@ jobs: - php: '8.1' mode: low-deps - php: '8.2' - mode: experimental + #mode: experimental fail-fast: false runs-on: ubuntu-20.04 diff --git a/CHANGELOG-6.0.md b/CHANGELOG-6.0.md index a221de2d0d7e4..f92727fee106c 100644 --- a/CHANGELOG-6.0.md +++ b/CHANGELOG-6.0.md @@ -7,6 +7,18 @@ in 6.0 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/v6.0.0...v6.0.1 +* 6.0.6 (2022-03-05) + + * bug #45619 [redis-messenger] remove undefined array key warnings (PhilETaylor) + * bug #45637 [Cache] do not pass DBAL connections to PDO adapters (xabbuh) + * bug #45631 [HttpFoundation] Fix PHP 8.1 deprecation in `Response::isNotModified` (HypeMC) + * bug #45610 [HttpKernel] Guard against bad profile data (nicolas-grekas) + * bug #45532 Fix deprecations on PHP 8.2 (nicolas-grekas) + * bug #45595 [FrameworkBundle] Fix resetting container between tests (nicolas-grekas) + * bug #45590 [Console] Revert StringInput bc break from #45088 (bobthecow) + * bug #45585 [HttpClient] fix checking for unset property on PHP <= 7.1.4 (nicolas-grekas) + * bug #45583 [WebProfilerBundle] Fixes HTML syntax regression introduced by #44570 (xavismeh) + * 6.0.5 (2022-02-28) * bug #45351 [WebProfilerBundle] Log section minor fixes (missing "notice" filter, log priority, accessibility) (Amunak) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index d287e27ee871e..c8eb4764f6c53 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -12,13 +12,13 @@ The Symfony Connect username in parenthesis allows to get more information - Tobias Schultze (tobion) - Robin Chalas (chalas_r) - Christophe Coevoet (stof) - - Wouter De Jong (wouterj) - Jérémy DERUSSÉ (jderusse) + - Wouter De Jong (wouterj) - Grégoire Pineau (lyrixx) - Maxime Steinhausser (ogizanagi) - Kévin Dunglas (dunglas) - - Jordi Boggiano (seldaek) - Thomas Calvet (fancyweb) + - Jordi Boggiano (seldaek) - Victor Berchet (victor) - Javier Eguiluz (javier.eguiluz) - Ryan Weaver (weaverryan) @@ -76,8 +76,8 @@ The Symfony Connect username in parenthesis allows to get more information - Saša Stamenković (umpirsky) - Peter Rehm (rpet) - Henrik Bjørnskov (henrikbjorn) - - Miha Vrhovnik - Antoine M (amakdessi) + - Miha Vrhovnik - Diego Saint Esteben (dii3g0) - Mathieu Piot (mpiot) - Konstantin Kudryashov (everzet) @@ -93,18 +93,18 @@ The Symfony Connect username in parenthesis allows to get more information - Eric Clemmons (ericclemmons) - Graham Campbell (graham) - Charles Sarrazin (csarrazi) + - Alexander Schranz (alexander-schranz) - Vasilij Dusko - Douglas Greenshields (shieldo) - David Buchmann (dbu) - - Alexander Schranz (alexander-schranz) - Arnout Boks (aboks) - Deni - Henrik Westphal (snc) - Dariusz Górecki (canni) - Fran Moreno (franmomu) + - Jérôme Vasseur (jvasseur) - Mathieu Santostefano (welcomattic) - Dariusz Ruminski - - Jérôme Vasseur (jvasseur) - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) @@ -119,11 +119,11 @@ The Symfony Connect username in parenthesis allows to get more information - Alexandre Daubois (alexandre-daubois) - Julien Falque (julienfalque) - Baptiste Clavié (talus) + - Massimiliano Arione (garak) + - Mathias Arlaud (mtarld) - Antoine Hérault (herzult) - Paráda József (paradajozsef) - Vincent Langlet (deviling) - - Massimiliano Arione (garak) - - Mathias Arlaud (mtarld) - Arnaud Le Blanc (arnaud-lb) - Przemysław Bogusz (przemyslaw-bogusz) - Maxime STEINHAUSSER @@ -182,6 +182,7 @@ The Symfony Connect username in parenthesis allows to get more information - Juti Noppornpitak (shiroyuki) - Simon Berger - Anthony MARTIN (xurudragon) + - Alexander Menshchikov (zmey_kk) - Sebastian Hörl (blogsh) - Daniel Gomes (danielcsgomes) - Hidenori Goto (hidenorigoto) @@ -192,7 +193,6 @@ The Symfony Connect username in parenthesis allows to get more information - Guilherme Blanco (guilhermeblanco) - Marco Pivetta (ocramius) - SpacePossum - - Alexander Menshchikov (zmey_kk) - Pablo Godel (pgodel) - Andreas Braun - Jérémie Augustin (jaugustin) @@ -236,6 +236,7 @@ The Symfony Connect username in parenthesis allows to get more information - Matthieu Ouellette-Vachon (maoueh) - Michał Pipa (michal.pipa) - Dawid Nowak + - Martin Hujer (martinhujer) - Roman Martinuk (a2a4) - Amal Raghav (kertz) - Jonathan Ingram (jonathaningram) @@ -264,7 +265,6 @@ The Symfony Connect username in parenthesis allows to get more information - Dorian Villet (gnutix) - Michaël Perrin (michael.perrin) - Sergey Linnik (linniksa) - - Martin Hujer (martinhujer) - Richard Miller (mr_r_miller) - Mario A. Alvarez Garcia (nomack84) - Dennis Benkert (denderello) @@ -281,6 +281,7 @@ The Symfony Connect username in parenthesis allows to get more information - Benjamin Dulau (dbenjamin) - Baptiste Lafontaine (magnetik) - Mathieu Lemoine (lemoinem) + - Justin Hileman (bobthecow) - Denis Brumann (dbrumann) - Christian Schmidt - Andreas Hucks (meandmymonkey) @@ -308,6 +309,7 @@ The Symfony Connect username in parenthesis allows to get more information - Dominique Bongiraud - dFayet - Jeremy Livingston (jeremylivingston) + - Karoly Gossler (connorhu) - soyuka - Michael Lee (zerustech) - Matthieu Auger (matthieuauger) @@ -318,7 +320,6 @@ The Symfony Connect username in parenthesis allows to get more information - jeff - John Kary (johnkary) - fd6130 (fdtvui) - - Justin Hileman (bobthecow) - Blanchon Vincent (blanchonvincent) - Maciej Malarz (malarzm) - Michele Orselli (orso) @@ -346,7 +347,6 @@ The Symfony Connect username in parenthesis allows to get more information - Mantis Development - Loïc Faugeron - quentin neyrat (qneyrat) - - Karoly Gossler (connorhu) - Marcin Szepczynski (czepol) - Rob Frawley 2nd (robfrawley) - Ahmed Raafat @@ -415,8 +415,10 @@ The Symfony Connect username in parenthesis allows to get more information - Wodor Wodorski - Guilhem N (guilhemn) - Mohammad Emran Hasan (phpfour) + - Christopher Davis (chrisguitarguy) - Dmitriy Mamontov (mamontovdmitriy) - Ben Ramsey (ramsey) + - Hugo Alliaume (kocal) - Laurent Masforné (heisenberg) - Sergey (upyx) - Giorgio Premi @@ -482,6 +484,7 @@ The Symfony Connect username in parenthesis allows to get more information - Aurelijus Valeiša (aurelijus) - Jan Decavele (jandc) - Gustavo Piltcher + - flack (flack) - Stepan Tanasiychuk (stfalcon) - Ivan Kurnosov - Tiago Ribeiro (fixe) @@ -508,7 +511,6 @@ The Symfony Connect username in parenthesis allows to get more information - Mark Challoner (markchalloner) - Loïc Frémont (loic425) - Oleksandr Barabolia (oleksandrbarabolia) - - Christopher Davis (chrisguitarguy) - ivan - Greg Anderson - Tri Pham (phamuyentri) @@ -539,6 +541,7 @@ The Symfony Connect username in parenthesis allows to get more information - Dmytro Borysovskyi (dmytr0) - Tomasz Kowalczyk (thunderer) - Artur Eshenbrener + - Dries Vints - Thomas Perez (scullwm) - Yoann RENARD (yrenard) - Felix Labrecque @@ -548,6 +551,7 @@ The Symfony Connect username in parenthesis allows to get more information - Tim Goudriaan (codedmonkey) - Tarmo Leppänen (tarlepp) - Martin Auswöger + - Hubert Lenoir (hubert_lenoir) - Robbert Klarenbeek (robbertkl) - Hamza Makraz (makraz) - Eric Masoero (eric-masoero) @@ -556,7 +560,6 @@ The Symfony Connect username in parenthesis allows to get more information - hossein zolfi (ocean) - Clément Gautier (clementgautier) - Koen Reiniers (koenre) - - Hugo Alliaume (kocal) - Sanpi - Eduardo Gulias (egulias) - giulio de donato (liuggio) @@ -620,7 +623,6 @@ The Symfony Connect username in parenthesis allows to get more information - hubert lecorche (hlecorche) - Vladyslav Loboda - fritzmg - - flack (flack) - Marc Morales Valldepérez (kuert) - Jean-Baptiste GOMOND (mjbgo) - Vadim Kharitonov (virtuozzz) @@ -716,7 +718,6 @@ The Symfony Connect username in parenthesis allows to get more information - Jerzy (jlekowski) - Raulnet - Christian Wahler - - Dries Vints - Giso Stallenberg (gisostallenberg) - Gintautas Miselis - Rob Bast @@ -724,6 +725,7 @@ The Symfony Connect username in parenthesis allows to get more information - Pierre Rineau - Andreas Leathley (iquito) - Soufian EZ-ZANTAR (soezz) + - Arun Philip - Zander Baldwin - Marek Zajac - Adam Harvey @@ -769,6 +771,7 @@ The Symfony Connect username in parenthesis allows to get more information - nikos.sotiropoulos - Eduardo Oliveira (entering) - Oleksii Zhurbytskyi + - Bilge - Ilya Antipenko (aivus) - Ricardo Oliveira (ricardolotr) - Roy Van Ginneken (rvanginneken) @@ -799,7 +802,6 @@ The Symfony Connect username in parenthesis allows to get more information - alexpods - Dennis Langen (nijusan) - Adrien Wilmet (adrienfr) - - Hubert Lenoir (hubert_lenoir) - Adam Szaraniec (mimol) - Dariusz Ruminski - Erik Trapman (eriktrapman) @@ -926,6 +928,7 @@ The Symfony Connect username in parenthesis allows to get more information - Nicolas Martin (cocorambo) - Jon Gotlin (jongotlin) - Adrian Nguyen (vuphuong87) + - benjaminmal - Khoo Yong Jun - Sebastian Blum - Laurent Clouet @@ -973,6 +976,7 @@ The Symfony Connect username in parenthesis allows to get more information - Geoffrey Brier (geoffrey-brier) - Alexandre Parent - Roger Guasch (rogerguasch) + - DT Inier (gam6itko) - Vladimir Tsykun - Andrei O - Dustin Dobervich (dustin10) @@ -1050,7 +1054,6 @@ The Symfony Connect username in parenthesis allows to get more information - maxime.perrimond - Sascha Grossenbacher - cthulhu - - Arun Philip - Rémi Leclerc - Jonas Hünig - Szijarto Tamas @@ -1061,6 +1064,7 @@ The Symfony Connect username in parenthesis allows to get more information - Kristijan Kanalas - Stephan Vock - Benjamin Zikarsky (bzikarsky) + - “Filip - Marion Hurteau - Dmitrii Lozhkin - Sobhan Sharifi (50bhan) @@ -1176,6 +1180,7 @@ The Symfony Connect username in parenthesis allows to get more information - Wickex - tuqqu - Neagu Cristian-Doru (cristian-neagu) + - Dude (b1rdex) - Dave Marshall (davedevelopment) - Jakub Kulhan (jakubkulhan) - Shaharia Azam @@ -1203,6 +1208,7 @@ The Symfony Connect username in parenthesis allows to get more information - SnakePin - vladimir.panivko - Josiah (josiah) + - Dennis Væversted (srnzitcom) - Guillaume Verstraete (versgui) - Joschi Kuphal - John Bohn (jbohn) @@ -1221,7 +1227,6 @@ The Symfony Connect username in parenthesis allows to get more information - Christian Soronellas (theunic) - kick-the-bucket - fedor.f - - Bilge - Yosmany Garcia (yosmanyga) - Jeremiasz Major - Wouter de Wild @@ -1265,6 +1270,7 @@ The Symfony Connect username in parenthesis allows to get more information - Zhuravlev Alexander (scif) - Stefano Degenkamp (steef) - James Michael DuPont + - Christian Gripp (core23) - Jake (jakesoft) - Flinsch - Quentin Dreyer @@ -1625,6 +1631,7 @@ The Symfony Connect username in parenthesis allows to get more information - Georgi Georgiev - Maximilian Berghoff (electricmaxxx) - nacho + - TristanPouliquen - Piotr Antosik (antek88) - mwos - Volker Killesreiter (ol0lll) @@ -1643,6 +1650,7 @@ The Symfony Connect username in parenthesis allows to get more information - Ken Marfilla (marfillaster) - benatespina (benatespina) - Denis Kop + - Andrey Lebedev (alebedev) - Jean-Guilhem Rouel (jean-gui) - Yoann MOROCUTTI - jfcixmedia @@ -1690,7 +1698,6 @@ The Symfony Connect username in parenthesis allows to get more information - Jakub Sacha - Julius Kiekbusch - Olaf Klischat - - benjaminmal - orlovv - Claude Dioudonnat - Jonathan Hedstrom @@ -1734,6 +1741,7 @@ The Symfony Connect username in parenthesis allows to get more information - Péter Buri (burci) - Evgeny Efimov (edefimov) - kaiwa + - Daniel Badura - Charles Sanquer (csanquer) - Albert Ganiev (helios-ag) - Neil Katin @@ -1762,6 +1770,7 @@ The Symfony Connect username in parenthesis allows to get more information - Amine Yakoubi - Eduardo García Sanz (coma) - Sergio (deverad) + - Arend Hummeling - Makdessi Alex - fduch (fduch) - Juan Miguel Besada Vidal (soutlink) @@ -1829,13 +1838,13 @@ The Symfony Connect username in parenthesis allows to get more information - Vlad Gapanovich (gapik) - Alexander Kurilo (kamazee) - Nyro (nyro) + - Konstantin Bogomolov - Marco - Marc Torres - Mark Spink - cesar - Alberto Aldegheri - Cesar Scur (cesarscur) - - “Filip - Dmitri Petmanson - heccjj - Alexandre Melard @@ -1918,6 +1927,7 @@ The Symfony Connect username in parenthesis allows to get more information - abluchet - Ruud Arentsen - Harald Tollefsen + - Tobias Bönner - Matthieu - Arend-Jan Tetteroo - Albin Kerouaton @@ -1979,6 +1989,7 @@ The Symfony Connect username in parenthesis allows to get more information - Volodymyr Kupriienko (greeflas) - Serhiy Lunak (slunak) - Wojciech Błoszyk (wbloszyk) + - Jiri Barous - Giorgio Premi - abunch - tamcy @@ -2000,6 +2011,7 @@ The Symfony Connect username in parenthesis allows to get more information - Frédéric Bouchery (fbouchery) - Patrick Daley (padrig) - Foxprodev + - developer-av - Max Summe - WedgeSama - Dale.Nash @@ -2103,6 +2115,7 @@ The Symfony Connect username in parenthesis allows to get more information - Simon Neidhold - Valentin VALCIU - Jeremiah VALERIE + - Alexandre Beaujour - Julien Menth - George Yiannoulopoulos - Yannick Snobbert @@ -2116,6 +2129,7 @@ The Symfony Connect username in parenthesis allows to get more information - bill moll - Benjamin Bender - PaoRuby + - Bizley - Jared Farrish - karl.rixon - raplider @@ -2236,12 +2250,14 @@ The Symfony Connect username in parenthesis allows to get more information - riadh26 - Konstantinos Alexiou - Andrii Boiko + - Dilek Erkut - Harold Iedema - WaiSkats - Morimoto Ryosuke - Ikhsan Agustian - Arnau González (arnaugm) - Simon Bouland (bouland) + - Christoph König (chriskoenig) - Jibé Barth (jibbarth) - Jm Aribau (jmaribau) - Matthew Foster (mfoster) @@ -2266,6 +2282,7 @@ The Symfony Connect username in parenthesis allows to get more information - Phil Davis - Gleb Sidora - David Stone + - Giorgio Premi - Gerhard Seidel (gseidel) - Jovan Perovic (jperovic) - Pablo Maria Martelletti (pmartelletti) @@ -2295,7 +2312,6 @@ The Symfony Connect username in parenthesis allows to get more information - Mickael GOETZ - Maciej Schmidt - botbotbot - - Dennis Væversted - Timon van der Vorm - nuncanada - František Bereň @@ -2390,6 +2406,7 @@ The Symfony Connect username in parenthesis allows to get more information - Roy-Orbison - Aaron Somi - kshida + - Yasmany Cubela Medina (bitgandtter) - Michał Dąbrowski (defrag) - Aryel Tupinamba (dfkimera) - Hans Höchtl (hhoechtl) @@ -2400,6 +2417,7 @@ The Symfony Connect username in parenthesis allows to get more information - Jawira Portugal (jawira) - Johannes Müller (johmue) - Jordi Llonch (jordillonch) + - Roman Igoshin (masterro) - Nicholas Ruunu (nicholasruunu) - Jeroen van den Nieuwenhuisen (nieuwenhuisen) - Cyril Pascal (paxal) @@ -2454,6 +2472,7 @@ The Symfony Connect username in parenthesis allows to get more information - Adam - Ivo - Ismo Vuorinen + - Valentin - Sören Bernstein - devel - taiiiraaa @@ -2556,6 +2575,7 @@ The Symfony Connect username in parenthesis allows to get more information - Veres Lajos - Ernest Hymel - Andrea Civita + - Nicolás Alonso - LoginovIlya - Nick Chiu - grifx @@ -2596,10 +2616,12 @@ The Symfony Connect username in parenthesis allows to get more information - David Windell - Frank Jogeleit - Ondřej Frei + - Volodymyr Panivko - Gabriel Birke - skafandri - Derek Bonner - martijn + - Jenne van der Meer - Storkeus - Alan Chen - Anton Zagorskii @@ -2610,10 +2632,12 @@ The Symfony Connect username in parenthesis allows to get more information - Even André Fiskvik - Agata - dakur + - Matthias Schmidt - florian-michael-mast - Александр Ли - Arjan Keeman - Vlad Dumitrache + - Alex Kalineskou - Erik van Wingerden - Valouleloup - robmro27 @@ -2675,6 +2699,7 @@ The Symfony Connect username in parenthesis allows to get more information - Kevin Verschaeve (keversc) - Kevin Herrera (kherge) - Luis Ramón López López (lrlopez) + - Vladislav Nikolayev (luxemate) - Martin Mandl (m2mtech) - Mehdi Mabrouk (mehdidev) - Bart Reunes (metalarend) @@ -2693,6 +2718,7 @@ The Symfony Connect username in parenthesis allows to get more information - Pablo Monterde Perez (plebs) - Pierre-Olivier Vares (povares) - Jimmy Leger (redpanda) + - Samaël Villette (samadu61) - Marcin Szepczynski (szepczynski) - Cyrille Jouineau (tuxosaurus) - Vladimir Chernyshev (volch) @@ -2721,6 +2747,7 @@ The Symfony Connect username in parenthesis allows to get more information - Gabriel Moreira - Alexey Popkov - ChS + - michal - Alexis MARQUIS - Joseph Deray - Damian Sromek @@ -2792,6 +2819,7 @@ The Symfony Connect username in parenthesis allows to get more information - Michel Bardelmeijer - Tomas Kmieliauskas - Ikko Ashimine + - Erwin Dirks - Brad Jones - Billie Thompson - lol768 @@ -2801,6 +2829,7 @@ The Symfony Connect username in parenthesis allows to get more information - Johannes - Jörg Rühl - George Dietrich + - jannick-holm - wesleyh - sergey - Menno Holtkamp @@ -2811,6 +2840,7 @@ The Symfony Connect username in parenthesis allows to get more information - Michael Genereux - patrick-mcdougle - Dariusz Czech + - Clemens Krack - Bruno Baguette - Jack Wright - MrNicodemuz @@ -2867,6 +2897,8 @@ The Symfony Connect username in parenthesis allows to get more information - bokonet - Arrilot - ampaze + - Gabrielle Langer + - Chris McGehee - Markus Staab - Pierre-Louis LAUNAY - djama @@ -2914,6 +2946,7 @@ The Symfony Connect username in parenthesis allows to get more information - Ilya Bulakh - David Soria Parra - Sergiy Sokolenko + - Cantepie - detinkin - Ahmed Abdulrahman - dinitrol @@ -2971,7 +3004,6 @@ The Symfony Connect username in parenthesis allows to get more information - Juan Ases García (ases) - Siragusa (asiragusa) - Daniel Basten (axhm3a) - - Dude (b1rdex) - Benedict Massolle (bemas) - Gerard Berengue Llobera (bere) - Bernd Matzner (bmatzner) @@ -2981,7 +3013,6 @@ The Symfony Connect username in parenthesis allows to get more information - Choong Wei Tjeng (choonge) - Kousuke Ebihara (co3k) - Loïc Vernet (coil) - - Christian Gripp (core23) - Christoph Schaefer (cvschaefer) - Damon Jones (damon__jones) - Alexandre Fiocre (demos77) @@ -3087,6 +3118,7 @@ The Symfony Connect username in parenthesis allows to get more information - Florent Cailhol - szymek - Ryan Linnit + - a.dmitryuk - Kovacs Nicolas - craigmarvelley - Stano Turza diff --git a/composer.json b/composer.json index e34ed24a4d6d8..0c750c584e9ca 100644 --- a/composer.json +++ b/composer.json @@ -131,7 +131,6 @@ "masterminds/html5": "^2.6", "monolog/monolog": "^1.25.1|^2", "nyholm/psr7": "^1.0", - "paragonie/sodium_compat": "^1.8", "pda/pheanstalk": "^4.0", "php-http/httplug": "^1.0|^2.0", "phpstan/phpdoc-parser": "^1.0", diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 37155c1fe4532..240e2eb976194 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -13,9 +13,9 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\DBAL\Types\Type; +use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\Tools\SchemaTool; use Doctrine\Persistence\ManagerRegistry; -use Doctrine\Persistence\Mapping\ClassMetadata; use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectRepository; use Symfony\Bridge\Doctrine\Tests\DoctrineTestHelper; @@ -111,7 +111,7 @@ protected function createEntityManagerMock($repositoryMock) ->willReturn($repositoryMock) ; - $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata = $this->createMock(ClassMetadataInfo::class); $classMetadata ->expects($this->any()) ->method('hasField') diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php index 0bb9591e185df..034cd001aaebb 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php @@ -162,7 +162,8 @@ public function testExtractEnum() $validator = Validation::createValidatorBuilder() ->addMethodMapping('loadValidatorMetadata') - ->enableAnnotationMapping() + ->enableAnnotationMapping(true) + ->addDefaultDoctrineAnnotationReader() ->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{^Symfony\\\\Bridge\\\\Doctrine\\\\Tests\\\\Fixtures\\\\DoctrineLoader}')) ->getValidator() ; diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php index a63cbb4667549..e787da909bbb3 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php @@ -185,6 +185,7 @@ function ($definition) { } } +#[\AllowDynamicProperties] final class DummyClass implements DummyInterface, SunnyInterface { private $ref; diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php index 4f09e52bdcbd1..a0581ff21fb6f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -28,14 +29,18 @@ public function process(ContainerBuilder $container) // "annotation_reader" at build time don't get any cache foreach ($container->findTaggedServiceIds('annotations.cached_reader') as $id => $tags) { $reader = $container->getDefinition($id); + $reader->setPublic(false); $properties = $reader->getProperties(); if (isset($properties['cacheProviderBackup'])) { $provider = $properties['cacheProviderBackup']->getValues()[0]; unset($properties['cacheProviderBackup']); $reader->setProperties($properties); - $container->set($id, null); - $container->setDefinition($id, $reader->replaceArgument(1, $provider)); + $reader->replaceArgument(1, $provider); + } elseif (4 <= \count($arguments = $reader->getArguments()) && $arguments[3] instanceof ServiceClosureArgument) { + $arguments[1] = $arguments[3]->getValues()[0]; + unset($arguments[3]); + $reader->setArguments($arguments); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 198a434c98603..ffb9beb9a0774 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -16,6 +16,7 @@ use Psr\Log\LogLevel; use Symfony\Bundle\FullStack; use Symfony\Component\Asset\Package; +use Symfony\Component\Cache\Adapter\DoctrineAdapter; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\NodeBuilder; use Symfony\Component\Config\Definition\Builder\TreeBuilder; @@ -1049,7 +1050,7 @@ private function addCacheSection(ArrayNodeDefinition $rootNode, callable $willBe ->scalarNode('default_redis_provider')->defaultValue('redis://localhost')->end() ->scalarNode('default_memcached_provider')->defaultValue('memcached://localhost')->end() ->scalarNode('default_doctrine_dbal_provider')->defaultValue('database_connection')->end() - ->scalarNode('default_pdo_provider')->defaultValue($willBeAvailable('doctrine/dbal', Connection::class) ? 'database_connection' : null)->end() + ->scalarNode('default_pdo_provider')->defaultValue($willBeAvailable('doctrine/dbal', Connection::class) && class_exists(DoctrineAdapter::class) ? 'database_connection' : null)->end() ->arrayNode('pools') ->useAttributeAsKey('name') ->prototype('array') diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 25fa6a30727f8..eb5aa9dba0368 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1594,9 +1594,10 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde $container ->getDefinition('annotations.cached_reader') + ->setPublic(true) // set to false in AddAnnotationsCachedReaderPass ->replaceArgument(2, $config['debug']) - // temporary property to lazy-reference the cache provider without using it until AddAnnotationsCachedReaderPass runs - ->setProperty('cacheProviderBackup', new ServiceClosureArgument(new Reference($cacheService))) + // reference the cache provider without using it until AddAnnotationsCachedReaderPass runs + ->addArgument(new ServiceClosureArgument(new Reference($cacheService))) ->addTag('annotations.cached_reader') ; diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index 90728d0a1b53c..c80177c5d39c0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -22,7 +22,6 @@ use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\HttpKernel\Profiler\Profile as HttpProfile; use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Contracts\Service\ResetInterface; /** * Simulates a browser and makes requests to a Kernel object. @@ -157,12 +156,8 @@ protected function doRequest(object $request): Response // avoid shutting down the Kernel if no request has been performed yet // WebTestCase::createClient() boots the Kernel but do not handle a request if ($this->hasPerformedRequest && $this->reboot) { - $container = $this->kernel->getContainer(); + $this->kernel->boot(); $this->kernel->shutdown(); - - if ($container instanceof ResetInterface) { - $container->reset(); - } } else { $this->hasPerformedRequest = true; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php index 7ecf76e0f36b6..d931c9366de2e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php @@ -15,7 +15,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Symfony\Component\HttpKernel\KernelInterface; -use Symfony\Contracts\Service\ResetInterface; /** * KernelTestCase is the base class for tests needing a Kernel. @@ -35,8 +34,6 @@ abstract class KernelTestCase extends TestCase protected static $booted = false; - private static ?ContainerInterface $kernelContainer = null; - protected function tearDown(): void { static::ensureKernelShutdown(); @@ -69,12 +66,11 @@ protected static function bootKernel(array $options = []): KernelInterface { static::ensureKernelShutdown(); - static::$kernel = static::createKernel($options); - static::$kernel->boot(); + $kernel = static::createKernel($options); + $kernel->boot(); + self::$kernel = $kernel; static::$booted = true; - self::$kernelContainer = static::$kernel->getContainer(); - return static::$kernel; } @@ -93,7 +89,7 @@ protected static function getContainer(): ContainerInterface } try { - return self::$kernelContainer->get('test.service_container'); + return self::$kernel->getContainer()->get('test.service_container'); } catch (ServiceNotFoundException $e) { throw new \LogicException('Could not find service "test.service_container". Try updating the "framework.test" config to "true".', 0, $e); } @@ -142,14 +138,9 @@ protected static function createKernel(array $options = []): KernelInterface protected static function ensureKernelShutdown() { if (null !== static::$kernel) { + static::$kernel->boot(); static::$kernel->shutdown(); static::$booted = false; } - - if (self::$kernelContainer instanceof ResetInterface) { - self::$kernelContainer->reset(); - } - - self::$kernelContainer = null; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/KernelBrowserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/KernelBrowserTest.php index 96eaaea7612af..404a239b51282 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/KernelBrowserTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/KernelBrowserTest.php @@ -51,6 +51,16 @@ public function testEnableRebootKernel() $client->request('GET', '/'); } + public function testRequestAfterKernelShutdownAndPerformedRequest() + { + $this->expectNotToPerformAssertions(); + + $client = static::createClient(['test_case' => 'TestServiceContainer']); + $client->request('GET', '/'); + static::ensureKernelShutdown(); + $client->request('GET', '/'); + } + private function getKernelMock() { $mock = $this->getMockBuilder($this->getKernelClass()) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Secrets/SodiumVaultTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Secrets/SodiumVaultTest.php index a9b88b1763bd5..de096ccb22de0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Secrets/SodiumVaultTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Secrets/SodiumVaultTest.php @@ -6,6 +6,9 @@ use Symfony\Bundle\FrameworkBundle\Secrets\SodiumVault; use Symfony\Component\Filesystem\Filesystem; +/** + * @requires extension sodium + */ class SodiumVaultTest extends TestCase { private $secretsDir; diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index f19610887be35..5c925160733b8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -64,7 +64,6 @@ "symfony/property-info": "^5.4|^6.0", "symfony/web-link": "^5.4|^6.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "paragonie/sodium_compat": "^1.8", "twig/twig": "^2.10|^3.0", "symfony/phpunit-bridge": "^5.4|^6.0" }, diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig index f54e276910efe..1a74431d898b5 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig @@ -8,13 +8,13 @@ {% block head %} - + {{ include('@WebProfiler/Profiler/profiler.css.twig') }} {% endblock %} - + if (null === localStorage.getItem('symfony/profiler/theme') || 'theme-auto' === localStorage.getItem('symfony/profiler/theme')) { document.body.classList.add((matchMedia('(prefers-color-scheme: dark)').matches ? 'theme-dark' : 'theme-light')); // needed to respond dynamically to OS changes without having to refresh the page diff --git a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php index 0f83ba364a281..ab12b0c5f380c 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php @@ -54,7 +54,7 @@ public function testPrune() public function testKnownTagVersionsTtl() { $itemsPool = new FilesystemAdapter('', 10); - $tagsPool = $this->createMock(AdapterInterface::class); + $tagsPool = new ArrayAdapter(); $pool = new TagAwareAdapter($itemsPool, $tagsPool, 10); @@ -62,13 +62,8 @@ public function testKnownTagVersionsTtl() $item->tag(['baz']); $item->expiresAfter(100); - $tag = $this->createMock(CacheItemInterface::class); - $tag->expects(self::exactly(2))->method('get')->willReturn(10); - $tag->expects(self::exactly(2))->method('set')->willReturn($tag); - - $tagsPool->expects(self::exactly(2))->method('getItems')->willReturn(new \ArrayIterator([ - 'baz'.TagAwareAdapter::TAGS_PREFIX => $tag, - ])); + $tag = $tagsPool->getItem('baz'.TagAwareAdapter::TAGS_PREFIX); + $tagsPool->save($tag->set(10)); $pool->save($item); $this->assertTrue($pool->getItem('foo')->isHit()); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php index 6d6cc0837065e..6f06a7a919627 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -56,6 +56,7 @@ public static function configureStatic1() class BarUserClass { + public $foo; public $bar; public function __construct(BarClass $bar) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php index 20bc928b9728c..c8a6b347a0029 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/foo.php @@ -4,6 +4,7 @@ class FooClass { + public $qux; public $foo; public $moo; diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index ee05c27dc423e..9f93c2d9cf4e8 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -1075,11 +1075,11 @@ private function convertToHtmlEntities(string $htmlContent, string $charset = 'U set_error_handler(function () { throw new \Exception(); }); try { - return mb_convert_encoding($htmlContent, 'HTML-ENTITIES', $charset); + return mb_encode_numericentity($htmlContent, [0x80, 0xFFFF, 0, 0xFFFF], $charset); } catch (\Exception|\ValueError $e) { try { $htmlContent = iconv($charset, 'UTF-8', $htmlContent); - $htmlContent = mb_convert_encoding($htmlContent, 'HTML-ENTITIES', 'UTF-8'); + $htmlContent = mb_encode_numericentity($htmlContent, [0x80, 0xFFFF, 0, 0xFFFF], 'UTF-8'); } catch (\Exception|\ValueError $e) { } diff --git a/src/Symfony/Component/Filesystem/Tests/Fixtures/MockStream/MockStream.php b/src/Symfony/Component/Filesystem/Tests/Fixtures/MockStream/MockStream.php index 179fae2d0a81e..9aa9f3e2f1c00 100644 --- a/src/Symfony/Component/Filesystem/Tests/Fixtures/MockStream/MockStream.php +++ b/src/Symfony/Component/Filesystem/Tests/Fixtures/MockStream/MockStream.php @@ -17,6 +17,8 @@ */ class MockStream { + public $context; + /** * Opens file or URL. * diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index accacff8e549b..3d20e26076f49 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -1064,8 +1064,7 @@ public function isNotModified(Request $request): bool $lastModified = $this->headers->get('Last-Modified'); $modifiedSince = $request->headers->get('If-Modified-Since'); - if ($ifNoneMatchEtags = $request->getETags()) { - $etag = $this->getEtag(); + if (($ifNoneMatchEtags = $request->getETags()) && (null !== $etag = $this->getEtag())) { if (0 == strncmp($etag, 'W/', 2)) { $etag = substr($etag, 2); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php index dc4a395c1690c..9bb39315b463b 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php @@ -275,6 +275,20 @@ public function testIsNotModifiedIfModifiedSinceAndEtagWithoutLastModified() $this->assertFalse($response->isNotModified($request)); } + public function testIfNoneMatchWithoutETag() + { + $request = new Request(); + $request->headers->set('If-None-Match', 'randomly_generated_etag'); + + $this->assertFalse((new Response())->isNotModified($request)); + + // Test wildcard + $request = new Request(); + $request->headers->set('If-None-Match', '*'); + + $this->assertFalse((new Response())->isNotModified($request)); + } + public function testIsValidateable() { $response = new Response('', 200, ['Last-Modified' => $this->createDateTimeOneHourAgo()->format(\DATE_RFC2822)]); diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index bc0a9db5a3ee0..7fbb334c8fde2 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -78,11 +78,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ private static array $freshCache = []; - public const VERSION = '6.0.5'; - public const VERSION_ID = 60005; + public const VERSION = '6.0.6'; + public const VERSION_ID = 60006; public const MAJOR_VERSION = 6; public const MINOR_VERSION = 0; - public const RELEASE_VERSION = 5; + public const RELEASE_VERSION = 6; public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '01/2023'; diff --git a/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php index 062e8d738cd41..6e71d0b5103f4 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php @@ -121,7 +121,11 @@ public function read(string $token): ?Profile $file = 'compress.zlib://'.$file; } - return $this->createProfileFromData($token, unserialize(file_get_contents($file))); + if (!$data = unserialize(file_get_contents($file))) { + return null; + } + + return $this->createProfileFromData($token, $data); } /** @@ -287,7 +291,11 @@ protected function createProfileFromData(string $token, array $data, Profile $pa $file = 'compress.zlib://'.$file; } - $profile->addChild($this->createProfileFromData($token, unserialize(file_get_contents($file)), $profile)); + if (!$childData = unserialize(file_get_contents($file))) { + continue; + } + + $profile->addChild($this->createProfileFromData($token, $childData, $profile)); } return $profile; diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php index 87223d61bf84a..c8c3ea1f26157 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php @@ -334,10 +334,12 @@ public function get(): ?array $queuedMessageCount = $this->rawCommand('ZCOUNT', 0, $now); while ($queuedMessageCount--) { - if (![$queuedMessage, $expiry] = $this->rawCommand('ZPOPMIN', 1)) { + if (!$message = $this->rawCommand('ZPOPMIN', 1)) { break; } + [$queuedMessage, $expiry] = $message; + if (\strlen($expiry) === \strlen($now) ? $expiry > $now : \strlen($expiry) < \strlen($now)) { // if a future-placed message is popped because of a race condition with // another running consumer, the message is readded to the queue diff --git a/src/Symfony/Component/Notifier/Tests/Event/FailedMessageEventTest.php b/src/Symfony/Component/Notifier/Tests/Event/FailedMessageEventTest.php index cf35a8483de9c..7e4f690b1690a 100644 --- a/src/Symfony/Component/Notifier/Tests/Event/FailedMessageEventTest.php +++ b/src/Symfony/Component/Notifier/Tests/Event/FailedMessageEventTest.php @@ -15,7 +15,7 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; -final class FailedMessageEventTest extends TestCase +class FailedMessageEventTest extends TestCase { /** * @dataProvider messagesProvider @@ -47,6 +47,8 @@ public function testFailedMessageEventIsDisptachIfError() $clientMock = $this->createMock(HttpClientInterface::class); $transport = new class($clientMock, $eventDispatcherMock) extends AbstractTransport { + public $exception; + public function __construct($client, EventDispatcherInterface $dispatcher = null) { $this->exception = new NullTransportException(); @@ -65,6 +67,7 @@ public function supports(MessageInterface $message): bool public function __toString(): string { + return ''; } }; diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummy.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummy.php index ac610f098607f..788313c2b8562 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummy.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummy.php @@ -2,6 +2,7 @@ namespace Symfony\Component\Serializer\Tests\Normalizer\Features; +#[\AllowDynamicProperties] class ObjectDummy { protected $foo; diff --git a/src/Symfony/Component/Translation/PseudoLocalizationTranslator.php b/src/Symfony/Component/Translation/PseudoLocalizationTranslator.php index 1d10e0ccb8ed4..848dc1d2ed8f6 100644 --- a/src/Symfony/Component/Translation/PseudoLocalizationTranslator.php +++ b/src/Symfony/Component/Translation/PseudoLocalizationTranslator.php @@ -123,7 +123,7 @@ private function getParts(string $originalTrans): array return [[true, true, $originalTrans]]; } - $html = mb_convert_encoding($originalTrans, 'HTML-ENTITIES', mb_detect_encoding($originalTrans, null, true) ?: 'UTF-8'); + $html = mb_encode_numericentity($originalTrans, [0x80, 0xFFFF, 0, 0xFFFF], mb_detect_encoding($originalTrans, null, true) ?: 'UTF-8'); $useInternalErrors = libxml_use_internal_errors(true); diff --git a/src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php index ebceb683ea01c..37cee4100c887 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php @@ -33,6 +33,7 @@ class ImageValidatorTest extends ConstraintValidatorTestCase protected $imageLandscape; protected $imagePortrait; protected $image4By3; + protected $image16By9; protected $imageCorrupted; protected $notAnImage; diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php index 40e97a534cb91..0befaa45d4e07 100644 --- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php @@ -960,7 +960,7 @@ protected function dumpLine(int $depth, bool $endOfValue = false) } $this->lastDepth = $depth; - $this->line = mb_convert_encoding($this->line, 'HTML-ENTITIES', 'UTF-8'); + $this->line = mb_encode_numericentity($this->line, [0x80, 0xFFFF, 0, 0xFFFF], 'UTF-8'); if (-1 === $depth) { AbstractDumper::dumpLine(0); diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php index b9f409d74ce61..915588c0009e5 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php @@ -175,7 +175,7 @@ public function testHtmlDump() trace: { %s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php:%d - …%d + …%d } } diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php index eb5e890c1be76..018e212ae9545 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php @@ -166,11 +166,13 @@ public function testCastObjectStorageDumpsInfo() public function testCastArrayObject() { - $var = new \ArrayObject([123]); + $var = new + #[\AllowDynamicProperties] + class([123]) extends \ArrayObject {}; $var->foo = 234; $expected = << 123 diff --git a/src/Symfony/Component/VarDumper/Tests/Dumper/HtmlDumperTest.php b/src/Symfony/Component/VarDumper/Tests/Dumper/HtmlDumperTest.php index 0234bf3494e17..6fab7c35245d5 100644 --- a/src/Symfony/Component/VarDumper/Tests/Dumper/HtmlDumperTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Dumper/HtmlDumperTest.php @@ -66,7 +66,7 @@ public function testGet() 6 => {$intMax} "str" => "d&%s;j&%s;\\n" 7 => b""" - é\\x01test\\t\\n + é\\x01test\\t\\n ing """ "[]" => [] diff --git a/src/Symfony/Component/VarDumper/Tests/Fixtures/dumb-var.php b/src/Symfony/Component/VarDumper/Tests/Fixtures/dumb-var.php index 8fb269805bf6f..fc48012f4d13f 100644 --- a/src/Symfony/Component/VarDumper/Tests/Fixtures/dumb-var.php +++ b/src/Symfony/Component/VarDumper/Tests/Fixtures/dumb-var.php @@ -3,6 +3,7 @@ namespace Symfony\Component\VarDumper\Tests\Fixture; if (!class_exists(\Symfony\Component\VarDumper\Tests\Fixture\DumbFoo::class)) { + #[\AllowDynamicProperties] class DumbFoo { public $foo = 'foo'; diff --git a/src/Symfony/Component/VarExporter/Internal/Exporter.php b/src/Symfony/Component/VarExporter/Internal/Exporter.php index 73a56105984c5..95f6d79dc506c 100644 --- a/src/Symfony/Component/VarExporter/Internal/Exporter.php +++ b/src/Symfony/Component/VarExporter/Internal/Exporter.php @@ -106,7 +106,15 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount } $properties = ['SplObjectStorage' => ["\0" => $properties]]; $arrayValue = (array) $value; - } elseif ($value instanceof \Serializable || $value instanceof \__PHP_Incomplete_Class) { + } elseif ($value instanceof \Serializable + || $value instanceof \__PHP_Incomplete_Class + || $value instanceof \DatePeriod + || (\PHP_VERSION_ID >= 80200 && ( + $value instanceof \DateTimeInterface + || $value instanceof \DateTimeZone + || $value instanceof \DateInterval + )) + ) { ++$objectsCount; $objectsPool[$value] = [$id = \count($objectsPool), serialize($value), [], 0]; $value = new Reference($id); diff --git a/src/Symfony/Component/VarExporter/Internal/Hydrator.php b/src/Symfony/Component/VarExporter/Internal/Hydrator.php index 364d292d916e7..5ed6bdc948e63 100644 --- a/src/Symfony/Component/VarExporter/Internal/Hydrator.php +++ b/src/Symfony/Component/VarExporter/Internal/Hydrator.php @@ -55,45 +55,14 @@ public static function hydrate($objects, $values, $properties, $value, $wakeups) public static function getHydrator($class) { - if ('stdClass' === $class) { - return self::$hydrators[$class] = static function ($properties, $objects) { - foreach ($properties as $name => $values) { - foreach ($values as $i => $v) { - $objects[$i]->$name = $v; - } - } - }; - } - - if (!class_exists($class) && !interface_exists($class, false) && !trait_exists($class, false)) { - throw new ClassNotFoundException($class); - } - $classReflector = new \ReflectionClass($class); - - if (!$classReflector->isInternal()) { - return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, $class); - } - - if ($classReflector->name !== $class) { - return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name); - } - switch ($class) { - case 'ArrayIterator': - case 'ArrayObject': - $constructor = \Closure::fromCallable([$classReflector->getConstructor(), 'invokeArgs']); - - return self::$hydrators[$class] = static function ($properties, $objects) use ($constructor) { + case 'stdClass': + return self::$hydrators[$class] = static function ($properties, $objects) { foreach ($properties as $name => $values) { - if ("\0" !== $name) { - foreach ($values as $i => $v) { - $objects[$i]->$name = $v; - } + foreach ($values as $i => $v) { + $objects[$i]->$name = $v; } } - foreach ($properties["\0"] ?? [] as $i => $v) { - $constructor($objects[$i], $v); - } }; case 'ErrorException': @@ -122,6 +91,38 @@ public static function getHydrator($class) }; } + if (!class_exists($class) && !interface_exists($class, false) && !trait_exists($class, false)) { + throw new ClassNotFoundException($class); + } + $classReflector = new \ReflectionClass($class); + + switch ($class) { + case 'ArrayIterator': + case 'ArrayObject': + $constructor = \Closure::fromCallable([$classReflector->getConstructor(), 'invokeArgs']); + + return self::$hydrators[$class] = static function ($properties, $objects) use ($constructor) { + foreach ($properties as $name => $values) { + if ("\0" !== $name) { + foreach ($values as $i => $v) { + $objects[$i]->$name = $v; + } + } + } + foreach ($properties["\0"] ?? [] as $i => $v) { + $constructor($objects[$i], $v); + } + }; + } + + if (!$classReflector->isInternal()) { + return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, $class); + } + + if ($classReflector->name !== $class) { + return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name); + } + $propertySetters = []; foreach ($classReflector->getProperties() as $propertyReflector) { if (!$propertyReflector->isStatic()) { diff --git a/src/Symfony/Component/VarExporter/Tests/Fixtures/array-object.php b/src/Symfony/Component/VarExporter/Tests/Fixtures/array-object.php index 4e2d4d13a3d89..22fb5c9b247d9 100644 --- a/src/Symfony/Component/VarExporter/Tests/Fixtures/array-object.php +++ b/src/Symfony/Component/VarExporter/Tests/Fixtures/array-object.php @@ -2,8 +2,8 @@ return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate( $o = [ - clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)['ArrayObject'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('ArrayObject')), - clone $p['ArrayObject'], + clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)['Symfony\\Component\\VarExporter\\Tests\\ArrayObject'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('Symfony\\Component\\VarExporter\\Tests\\ArrayObject')), + clone ($p['ArrayObject'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('ArrayObject')), ], null, [], diff --git a/src/Symfony/Component/VarExporter/Tests/Fixtures/datetime-legacy.php b/src/Symfony/Component/VarExporter/Tests/Fixtures/datetime-legacy.php new file mode 100644 index 0000000000000..7b217c5fb21b0 --- /dev/null +++ b/src/Symfony/Component/VarExporter/Tests/Fixtures/datetime-legacy.php @@ -0,0 +1,92 @@ + 'O:10:"DatePeriod":6:{s:5:"start";O:8:"DateTime":3:{s:4:"date";s:26:"2012-07-01 00:00:00.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}s:7:"current";N;s:3:"end";N;s:8:"interval";O:12:"DateInterval":16:{s:1:"y";i:0;s:1:"m";i:0;s:1:"d";i:7;s:1:"h";i:0;s:1:"i";i:0;s:1:"s";i:0;s:1:"f";d:0;s:7:"weekday";i:0;s:16:"weekday_behavior";i:0;s:17:"first_last_day_of";i:0;s:6:"invert";i:0;s:4:"days";b:0;s:12:"special_type";i:0;s:14:"special_amount";i:0;s:21:"have_weekday_relative";i:0;s:21:"have_special_relative";i:0;}s:11:"recurrences";i:5;s:18:"include_start_date";b:1;}', + ]), + null, + [ + 'stdClass' => [ + 'date' => [ + '1970-01-01 00:00:00.000000', + '1970-01-01 00:00:00.000000', + ], + 'timezone_type' => [ + 1, + 1, + 3, + ], + 'timezone' => [ + '+00:00', + '+00:00', + 'Europe/Paris', + ], + 'y' => [ + 3 => 0, + ], + 'm' => [ + 3 => 0, + ], + 'd' => [ + 3 => 7, + ], + 'h' => [ + 3 => 0, + ], + 'i' => [ + 3 => 0, + ], + 's' => [ + 3 => 0, + ], + 'f' => [ + 3 => 0.0, + ], + 'weekday' => [ + 3 => 0, + ], + 'weekday_behavior' => [ + 3 => 0, + ], + 'first_last_day_of' => [ + 3 => 0, + ], + 'invert' => [ + 3 => 0, + ], + 'days' => [ + 3 => false, + ], + 'special_type' => [ + 3 => 0, + ], + 'special_amount' => [ + 3 => 0, + ], + 'have_weekday_relative' => [ + 3 => 0, + ], + 'have_special_relative' => [ + 3 => 0, + ], + ], + ], + [ + $o[0], + $o[1], + $o[2], + $o[3], + $o[4], + ], + [ + 1 => 0, + 1, + 2, + 3, + ] +); diff --git a/src/Symfony/Component/VarExporter/Tests/Fixtures/datetime.php b/src/Symfony/Component/VarExporter/Tests/Fixtures/datetime.php index 1c916458c4f1a..1de8fa03f0919 100644 --- a/src/Symfony/Component/VarExporter/Tests/Fixtures/datetime.php +++ b/src/Symfony/Component/VarExporter/Tests/Fixtures/datetime.php @@ -1,25 +1,21 @@ [ - 'date' => [ - '1970-01-01 00:00:00.000000', - ], - 'timezone_type' => [ - 1, - ], - 'timezone' => [ - '+00:00', - ], - ], + $o[0], + $o[1], + $o[2], + $o[3], + $o[4], ], - $o[0], - [ - 1 => 0, - ] + [] ); diff --git a/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php b/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php index 744e576c0a0c9..cbd223642320b 100644 --- a/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php +++ b/src/Symfony/Component/VarExporter/Tests/InstantiatorTest.php @@ -53,16 +53,16 @@ public function testInstantiate() $expected = [ "\0".__NAMESPACE__."\Bar\0priv" => 123, "\0".__NAMESPACE__."\Foo\0priv" => 234, + 'dyn' => 345, ]; - $actual = (array) Instantiator::instantiate(Bar::class, ['priv' => 123], [Foo::class => ['priv' => 234]]); + $actual = (array) Instantiator::instantiate(Bar::class, ['dyn' => 345, 'priv' => 123], [Foo::class => ['priv' => 234]]); ksort($actual); $this->assertSame($expected, $actual); - $e = Instantiator::instantiate('Exception', ['foo' => 123, 'trace' => [234]]); + $e = Instantiator::instantiate('Exception', ['trace' => [234]]); - $this->assertSame(123, $e->foo); $this->assertSame([234], $e->getTrace()); } } @@ -72,6 +72,7 @@ class Foo private $priv; } +#[\AllowDynamicProperties] class Bar extends Foo { private $priv; diff --git a/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php b/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php index 3ded211f1c9df..307d6c6fc6c65 100644 --- a/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php +++ b/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php @@ -93,6 +93,10 @@ public function testExport(string $testName, $value, bool $staticValueExpected = $dump = str_replace(var_export(__FILE__, true), "\\dirname(__DIR__).\\DIRECTORY_SEPARATOR.'VarExporterTest.php'", $dump); $fixtureFile = __DIR__.'/Fixtures/'.$testName.'.php'; + + if (\PHP_VERSION_ID < 80200 && 'datetime' === $testName) { + $fixtureFile = __DIR__.'/Fixtures/'.$testName.'-legacy.php'; + } $this->assertStringEqualsFile($fixtureFile, $dump); if ('incomplete-class' === $testName || 'external-references' === $testName) { @@ -118,9 +122,15 @@ public function provideExport() yield ['bool', true, true]; yield ['simple-array', [123, ['abc']], true]; yield ['partially-indexed-array', [5 => true, 1 => true, 2 => true, 6 => true], true]; - yield ['datetime', \DateTime::createFromFormat('U', 0)]; - - $value = new \ArrayObject(); + yield ['datetime', [ + \DateTime::createFromFormat('U', 0), + \DateTimeImmutable::createFromFormat('U', 0), + new \DateTimeZone('Europe/Paris'), + new \DateInterval('P7D'), + new \DatePeriod('R4/2012-07-01T00:00:00Z/P7D'), + ]]; + + $value = \PHP_VERSION_ID >= 70406 ? new ArrayObject() : new \ArrayObject(); $value[0] = 1; $value->foo = new \ArrayObject(); $value[1] = $value; @@ -424,3 +434,8 @@ public function unserialize($ser) throw new \BadMethodCallException(); } } + +#[\AllowDynamicProperties] +class ArrayObject extends \ArrayObject +{ +}