diff --git a/CHANGELOG-4.2.md b/CHANGELOG-4.2.md index 8611ee540a1ca..5f18cce5375ef 100644 --- a/CHANGELOG-4.2.md +++ b/CHANGELOG-4.2.md @@ -7,6 +7,19 @@ in 4.2 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.2.0...v4.2.1 +* 4.2.7 (2019-04-17) + + * bug #31107 [Routing] fix trailing slash redirection with non-greedy trailing vars (nicolas-grekas) + * bug #31108 [FrameworkBundle] decorate the ValidatorBuilder's translator with LegacyTranslatorProxy (nicolas-grekas) + * bug #31121 [HttpKernel] Fix get session when the request stack is empty (yceruto) + * bug #31084 [HttpFoundation] Make MimeTypeExtensionGuesser case insensitive (vermeirentony) + * bug #31142 Revert "bug #30423 [Security] Rework firewall's access denied rule (dimabory)" (chalasr) + * security #cve-2019-10910 [DI] Check service IDs are valid (nicolas-grekas) + * security #cve-2019-10909 [FrameworkBundle][Form] Fix XSS issues in the form theme of the PHP templating engine (stof) + * security #cve-2019-10912 [Cache][PHPUnit Bridge] Prevent destructors with side-effects from being unserialized (nicolas-grekas) + * security #cve-2019-10911 [Security] Add a separator in the remember me cookie hash (pborreli) + * security #cve-2019-10913 [HttpFoundation] reject invalid method override (nicolas-grekas) + * 4.2.6 (2019-04-16) * bug #31088 [DI] fix removing non-shared definition while inlining them (nicolas-grekas) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index efb1b16d81ab9..146b9822ffdce 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -25,66 +25,66 @@ Symfony is the result of the work of many people who made the code better - Hugo Hamon (hhamon) - Abdellatif Ait boudad (aitboudad) - Romain Neutron (romain) + - Samuel ROZE (sroze) - Pascal Borreli (pborreli) - Wouter De Jong (wouterj) - - Samuel ROZE (sroze) - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - Lukas Kahwe Smith (lsmith) - Martin Hasoň (hason) - Jeremy Mikola (jmikola) + - Yonel Ceruto (yonelceruto) - Jean-François Simon (jfsimon) + - Jules Pietri (heah) - Benjamin Eberlei (beberlei) - Igor Wiedler (igorw) - - Yonel Ceruto (yonelceruto) - - Jules Pietri (heah) - Eriksen Costa (eriksencosta) - Guilhem Niot (energetick) - Sarah Khalil (saro0h) + - Hamza Amrouche (simperfit) - Jonathan Wage (jwage) - Tobias Nyholm (tobias) - - Hamza Amrouche (simperfit) + - Lynn van der Berg (kjarli) - Diego Saint Esteben (dosten) - - Iltar van der Berg (kjarli) - Alexandre Salomé (alexandresalome) - William Durand (couac) - ornicar - - Francis Besset (francisbesset) + - Jérémy DERUSSÉ (jderusse) - Dany Maillard (maidmaid) + - Francis Besset (francisbesset) - stealth35 ‏ (stealth35) - Alexander Mols (asm89) - - Bulat Shakirzyanov (avalanche123) - - Jérémy DERUSSÉ (jderusse) - Matthias Pigulla (mpdude) + - Bulat Shakirzyanov (avalanche123) + - Alexander M. Turek (derrabus) - Saša Stamenković (umpirsky) - Peter Rehm (rpet) - Kevin Bond (kbond) - Pierre du Plessis (pierredup) - Henrik Bjørnskov (henrikbjorn) - - Alexander M. Turek (derrabus) - Miha Vrhovnik - Diego Saint Esteben (dii3g0) - Konstantin Kudryashov (everzet) + - Gábor Egyed (1ed) - Bilal Amarni (bamarni) + - Titouan Galopin (tgalopin) - Mathieu Piot (mpiot) + - David Maicher (dmaicher) - Florin Patan (florinpatan) - - Gábor Egyed (1ed) + - Grégoire Paris (greg0ire) - Gabriel Ostrolucký (gadelat) - - Titouan Galopin (tgalopin) + - Valentin Udaltsov (vudaltsov) - Vladimir Reznichenko (kalessil) - Jáchym Toušek (enumag) - - David Maicher (dmaicher) + - Konstantin Myakshin (koc) - Michel Weimerskirch (mweimerskirch) - Andrej Hudec (pulzarraider) - - Konstantin Myakshin (koc) - Eric Clemmons (ericclemmons) - Charles Sarrazin (csarrazi) - Christian Raue - Issei Murasawa (issei_m) - - Valentin Udaltsov (vudaltsov) - Arnout Boks (aboks) - Deni - - Grégoire Paris (greg0ire) - Henrik Westphal (snc) - Dariusz Górecki (canni) - Douglas Greenshields (shieldo) @@ -99,7 +99,9 @@ Symfony is the result of the work of many people who made the code better - Jordan Alliot (jalliot) - Jérôme Tamarelle (gromnan) - John Wards (johnwards) + - Thomas Calvet (fancyweb) - Fran Moreno (franmomu) + - David Buchmann (dbu) - Antoine Hérault (herzult) - Paráda József (paradajozsef) - Arnaud Le Blanc (arnaud-lb) @@ -111,66 +113,66 @@ Symfony is the result of the work of many people who made the code better - Chris Wilkinson (thewilkybarkid) - marc.weistroff - Tomáš Votruba (tomas_votruba) - - David Buchmann (dbu) - lenar - Alexander Schwenn (xelaris) - Włodzimierz Gajda (gajdaw) - - Thomas Calvet (fancyweb) - Jérôme Vasseur (jvasseur) - Peter Kokot (maastermedia) - Jacob Dreesen (jdreesen) - Florian Voutzinos (florianv) - Colin Frei + - Javier Spagnoletti (phansys) - Adrien Brault (adrienbrault) - Joshua Thijssen - Daniel Wehner (dawehner) - excelwebzone - Gordon Franke (gimler) - Sebastiaan Stok (sstok) - - Javier Spagnoletti (phansys) - Fabien Pennequin (fabienpennequin) + - Théo FIDRY (theofidry) - Eric GELOEN (gelo) + - Joel Wurtz (brouznouf) - Lars Strojny (lstrojny) - Tugdual Saunier (tucksaun) - - Théo FIDRY (theofidry) - Robert Schönthal (digitalkaoz) - Florian Lonqueu-Brochard (florianlb) + - Oskar Stark (oskarstark) - Stefano Sala (stefano.sala) - Evgeniy (ewgraf) - Alex Pott - Vincent AUBERT (vincent) - Juti Noppornpitak (shiroyuki) - Anthony MARTIN (xurudragon) - - Oskar Stark (oskarstark) - Tigran Azatyan (tigranazatyan) - Sebastian Hörl (blogsh) - Daniel Gomes (danielcsgomes) - - Joel Wurtz (brouznouf) - Gabriel Caruso - Hidenori Goto (hidenorigoto) - Arnaud Kleinpeter (nanocom) - Jannik Zschiesche (apfelbox) - Guilherme Blanco (guilhermeblanco) - Teoh Han Hui (teohhanhui) + - SpacePossum - Pablo Godel (pgodel) - Jérémie Augustin (jaugustin) + - Oleg Voronkovich - Andréia Bohner (andreia) - Philipp Wahala (hifi) - Julien Falque (julienfalque) - Rafael Dohms (rdohms) - jwdeitch - Mikael Pajunen - - Oleg Voronkovich + - Niels Keurentjes (curry684) - Vyacheslav Pavlov - Richard van Laak (rvanlaak) - Richard Shank (iampersistent) - Thomas Rabaix (rande) - Rouven Weßling (realityking) + - François-Xavier de Guillebon (de-gui_f) - Clemens Tolboom - Helmer Aaviksoo - Alessandro Chitolina (alekitto) - Hiromi Hishida (77web) - - Niels Keurentjes (curry684) - Matthieu Ouellette-Vachon (maoueh) - Michał Pipa (michal.pipa) - Dawid Nowak @@ -179,7 +181,6 @@ Symfony is the result of the work of many people who made the code better - Artur Kotyrba - Tyson Andre - GDIBass - - SpacePossum - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - James Halsall (jaitsu) - Matthieu Napoli (mnapoli) @@ -198,8 +199,10 @@ Symfony is the result of the work of many people who made the code better - Dennis Benkert (denderello) - DQNEO - Samuel NELA (snela) + - Gregor Harlan (gharlan) + - Gary PEGEOT (gary-p) + - Ruben Gonzalez (rubenrua) - Benjamin Dulau (dbenjamin) - - François-Xavier de Guillebon (de-gui_f) - Mathieu Lemoine (lemoinem) - Christian Schmidt - Andreas Hucks (meandmymonkey) @@ -221,9 +224,10 @@ Symfony is the result of the work of many people who made the code better - fivestar - Dominique Bongiraud - Jeremy Livingston (jeremylivingston) + - Vincent Touzet (vincenttouzet) + - Jan Schädlich (jschaedl) - Michael Lee (zerustech) - Matthieu Auger (matthieuauger) - - Gregor Harlan (gharlan) - Leszek Prabucki (l3l0) - Fabien Bourigault (fbourigault) - François Zaninotto (fzaninotto) @@ -233,10 +237,10 @@ Symfony is the result of the work of many people who made the code better - Andreas Schempp (aschempp) - Justin Hileman (bobthecow) - Blanchon Vincent (blanchonvincent) + - Alexander Schranz (alexander-schranz) - Michele Orselli (orso) - Sven Paulus (subsven) - Maxime Veber (nek-) - - Gary PEGEOT (gary-p) - Rui Marinho (ruimarinho) - Massimiliano Arione (garak) - Eugene Wissner @@ -250,7 +254,6 @@ Symfony is the result of the work of many people who made the code better - Loïc Faugeron - Hidde Wieringa (hiddewie) - Marco Pivetta (ocramius) - - Jan Schädlich (jschaedl) - Rob Frawley 2nd (robfrawley) - julien pauli (jpauli) - Lorenz Schori @@ -265,24 +268,24 @@ Symfony is the result of the work of many people who made the code better - Elnur Abdurrakhimov (elnur) - Manuel Reinhard (sprain) - Danny Berger (dpb587) - - Ruben Gonzalez (rubenrua) - Adam Prager (padam87) - Benoît Burnichon (bburnichon) - Roman Marintšenko (inori) - Xavier Montaña Carreras (xmontana) + - Rémon van de Kamp (rpkamp) - Mickaël Andrieu (mickaelandrieu) - Xavier Perez - Arjen Brouwer (arjenjb) - Katsuhiro OGAWA - Patrick McDougle (patrick-mcdougle) - Alif Rachmawadi + - Anton Chernikov (anton_ch1989) - Kristen Gilden (kgilden) - Pierre-Yves LEBECQ (pylebecq) - Jordan Samouh (jordansamouh) - Baptiste Lafontaine (magnetik) - Jakub Kucharovic (jkucharovic) - Edi Modrić (emodric) - - Alexander Schranz (alexander-schranz) - Uwe Jäger (uwej711) - Eugene Leonovich (rybakit) - Filippo Tessarotto @@ -311,18 +314,20 @@ Symfony is the result of the work of many people who made the code better - Beau Simensen (simensen) - Michael Hirschler (mvhirsch) - Robert Kiss (kepten) + - Zan Baldwin (zanderbaldwin) - Roumen Damianoff (roumen) - Antonio J. García Lagar (ajgarlag) - Kim Hemsø Rasmussen (kimhemsoe) + - Przemysław Bogusz (przemyslaw-bogusz) - Pascal Luna (skalpa) - Wouter Van Hecke - Jérôme Parmentier (lctrs) - Peter Kruithof (pkruithof) - Michael Holm (hollo) - - Remon van de Kamp (rpkamp) - Mathieu Lechat - Marc Weistroff (futurecat) - Christian Schmidt + - Patrick Landolt (scube) - MatTheCat - Chad Sikorra (chadsikorra) - Chris Smith (cs278) @@ -342,6 +347,7 @@ Symfony is the result of the work of many people who made the code better - Jerzy Zawadzki (jzawadzki) - Wouter J - Ismael Ambrosi (iambrosi) + - Emmanuel BORGES (eborges78) - François Pluchino (francoispluchino) - Aurelijus Valeiša (aurelijus) - Jan Decavele (jandc) @@ -360,18 +366,18 @@ Symfony is the result of the work of many people who made the code better - janschoenherr - Emanuele Gaspari (inmarelibero) - Dariusz Rumiński - - Vincent Touzet (vincenttouzet) - Berny Cantos (xphere81) - Thierry Thuon (lepiaf) - Ricard Clau (ricardclau) - Mark Challoner (markchalloner) - Gennady Telegin (gtelegin) + - renanbr - Erin Millard - Artur Melo (restless) - Matthew Lewinski (lewinski) - Magnus Nordlander (magnusnordlander) - - Zan Baldwin (zanderbaldwin) - Thomas Royer (cydonia7) + - Nicolas LEFEVRE (nicoweb) - alquerci - Mateusz Sip (mateusz_sip) - Andre Rømcke (andrerom) @@ -402,12 +408,13 @@ Symfony is the result of the work of many people who made the code better - ShinDarth - Stéphane PY (steph_py) - Philipp Kräutli (pkraeutli) - - Anton Chernikov (anton_ch1989) - Grzegorz (Greg) Zdanowski (kiler129) - Iker Ibarguren (ikerib) - Kirill chEbba Chebunin (chebba) - Greg Thornton (xdissent) + - Quynh Xuan Nguyen (xuanquynh) - Martin Hujer (martinhujer) + - Philipp Cordes - Costin Bereveanu (schniper) - Loïc Chardonnet (gnusat) - Marek Kalnik (marekkalnik) @@ -426,7 +433,6 @@ Symfony is the result of the work of many people who made the code better - Romain Gautier (mykiwi) - Joe Lencioni - Daniel Tschinder - - Emmanuel BORGES (eborges78) - vladimir.reznichenko - Kai - Lee Rowlands @@ -460,7 +466,6 @@ Symfony is the result of the work of many people who made the code better - Webnet team (webnet) - Jan Schumann - Niklas Fiekas - - renanbr - Markus Bachmann (baachi) - lancergr - Mihai Stancu @@ -468,7 +473,6 @@ Symfony is the result of the work of many people who made the code better - Olivier Dolbeau (odolbeau) - Jan Rosier (rosier) - Alessandro Lai (jean85) - - Nicolas LEFEVRE (nicoweb) - Arturs Vonda - Josip Kruslin - Asmir Mustafic (goetas) @@ -477,9 +481,12 @@ Symfony is the result of the work of many people who made the code better - EdgarPE - Florian Pfitzer (marmelatze) - Asier Illarramendi (doup) + - Martijn Cuppens - Vlad Gregurco (vgregurco) + - Maciej Malarz (malarzm) - Boris Vujicic (boris.vujicic) - Chris Sedlmayr (catchamonkey) + - Dmytro Borysovskyi (dmytr0) - Kamil Kokot (pamil) - Seb Koelen - Christoph Mewes (xrstf) @@ -491,7 +498,7 @@ Symfony is the result of the work of many people who made the code better - Jonas Flodén (flojon) - Gonzalo Vilaseca (gonzalovilaseca) - Marcin Sikoń (marphi) - - Przemysław Bogusz (przemyslaw-bogusz) + - Denis Brumann (dbrumann) - Dominik Zogg (dominik.zogg) - Marek Pietrzak - Luc Vieillescazes (iamluc) @@ -506,6 +513,7 @@ Symfony is the result of the work of many people who made the code better - Rhodri Pugh (rodnaph) - Sam Fleming (sam_fleming) - Alex Bakhturin + - Pol Dellaiera (drupol) - insekticid - Alexander Obuhovich (aik099) - boombatower @@ -534,7 +542,6 @@ Symfony is the result of the work of many people who made the code better - ondrowan - Barry vd. Heuvel (barryvdh) - Craig Duncan (duncan3dc) - - Patrick Landolt (scube) - Sébastien Alfaiate (seb33300) - Evan S Kaufman (evanskaufman) - mcben @@ -559,10 +566,10 @@ Symfony is the result of the work of many people who made the code better - Almog Baku (almogbaku) - Scott Arciszewski - Xavier HAUSHERR - - Philipp Cordes - Norbert Orzechowicz (norzechowicz) - Denis Charrier (brucewouaigne) - Matthijs van den Bos (matthijs) + - Jaik Dean (jaikdean) - Lenard Palko - Nils Adermann (naderman) - Gábor Fási @@ -604,6 +611,7 @@ Symfony is the result of the work of many people who made the code better - Aurélien Fredouelle - Pavel Campr (pcampr) - Johnny Robeson (johnny) + - Marko Kaznovac (kaznovac) - Disquedur - Michiel Boeckaert (milio) - Geoffrey Tran (geoff) @@ -634,6 +642,7 @@ Symfony is the result of the work of many people who made the code better - Sinan Eldem - Alexandre Dupuy (satchette) - Malte Blättermann + - Desjardins Jérôme (jewome62) - Kévin THERAGE (kevin_therage) - Simeon Kolev (simeon_kolev9) - Nahuel Cuesta (ncuesta) @@ -667,11 +676,11 @@ Symfony is the result of the work of many people who made the code better - DerManoMann - Rostyslav Kinash - Dennis Fridrich (dfridrich) - - Maciej Malarz (malarzm) - Daisuke Ohata - Vincent Simonin - Alex Bogomazov (alebo) - maxime.steinhausser + - dFayet - adev - Stefan Warman - Arkadius Stefanski (arkadius) @@ -686,7 +695,6 @@ Symfony is the result of the work of many people who made the code better - Miquel Rodríguez Telep (mrtorrent) - Sergey Kolodyazhnyy (skolodyazhnyy) - umpirski - - Denis Brumann (dbrumann) - Quentin de Longraye (quentinus95) - Chris Heng (gigablah) - Shaun Simmons (simshaun) @@ -736,6 +744,7 @@ Symfony is the result of the work of many people who made the code better - VJ - RJ Garcia - Delf Tonder (leberknecht) + - Raulnet - Mark Sonnabaum - Massimiliano Braglia (massimilianobraglia) - Richard Quadling @@ -746,6 +755,8 @@ Symfony is the result of the work of many people who made the code better - Michael Piecko - yclian - Aleksey Prilipko + - Tomas Norkūnas (norkunas) + - Andrew Berry - twifty - Indra Gunawan (guind) - Peter Ward @@ -783,6 +794,7 @@ Symfony is the result of the work of many people who made the code better - Andrew Tchircoff (andrewtch) - michaelwilliams - 1emming + - Matthias Althaus - Leevi Graham (leevigraham) - Nykopol (nykopol) - Tri Pham (phamuyentri) @@ -813,6 +825,7 @@ Symfony is the result of the work of many people who made the code better - Denis Zunke (donalberto) - Ahmadou Waly Ndiaye (waly) - Ahmed TAILOULOUTE (ahmedtai) + - Jonathan Johnson (jrjohnson) - Olivier Maisonneuve (olineuve) - Pedro Miguel Maymone de Resende (pedroresende) - Masterklavi @@ -824,7 +837,6 @@ Symfony is the result of the work of many people who made the code better - Jayson Xu (superjavason) - Christopher Hertel (chertel) - Hubert Lenoir (hubert_lenoir) - - Jaik Dean (jaikdean) - fago - Harm van Tilborg - Jan Prieser @@ -842,7 +854,6 @@ Symfony is the result of the work of many people who made the code better - Reen Lokum - Andreas Möller (localheinz) - Martin Parsiegla (spea) - - Nguyen Xuan Quynh (xuanquynh) - Quentin Schuler - Pierre Vanliefland (pvanliefland) - Roy Klutman (royklutman) @@ -854,6 +865,7 @@ Symfony is the result of the work of many people who made the code better - Abhoryo - Fabian Vogler (fabian) - Korvin Szanto + - soyuka - Stéphan Kochen - Arjan Keeman - Alaattin Kahramanlar (alaattin) @@ -938,7 +950,6 @@ Symfony is the result of the work of many people who made the code better - Stéphane Delprat - Brian Freytag (brianfreytag) - Samuele Lilli (doncallisto) - - Marko Kaznovac (kaznovac) - Brunet Laurent (lbrunet) - Florent Viel (luxifer) - Mikhail Yurasov (mym) @@ -949,11 +960,13 @@ Symfony is the result of the work of many people who made the code better - Benoît Merlet (trompette) - Koen Kuipers - datibbaw + - Rokas Mikalkėnas (rokasm) - Erik Saunier (snickers) - Rootie - Kyle - Daniel Alejandro Castro Arellano (lexcast) - sensio + - Chris Tanaskoski - Thomas Jarrand - Sebastien Morel (plopix) - Patrick Kaufmann @@ -961,6 +974,7 @@ Symfony is the result of the work of many people who made the code better - Reece Fowell (reecefowell) - Mátyás Somfai (smatyas) - stefan.r + - Guillaume Gammelin - Valérian Galliat - d-ph - Renan Taranto (renan-taranto) @@ -971,6 +985,7 @@ Symfony is the result of the work of many people who made the code better - Christian Jul Jensen - Alexandre GESLIN (alexandregeslin) - The Whole Life to Learn + - Mikkel Paulson - ergiegonzaga - Farhad Safarov - Alexis Lefebvre @@ -978,6 +993,7 @@ Symfony is the result of the work of many people who made the code better - Sam Malone - Phan Thanh Ha (haphan) - Chris Jones (leek) + - neghmurken - xaav - Mahmoud Mostafa (mahmoud) - Ahmed Abdou @@ -988,6 +1004,7 @@ Symfony is the result of the work of many people who made the code better - Sander Marechal - Franz Wilding (killerpoke) - ProgMiner + - Jonas Elfering - Oleg Golovakhin (doc_tr) - Joost van Driel - Icode4Food (icode4food) @@ -1096,6 +1113,7 @@ Symfony is the result of the work of many people who made the code better - Christian - Denis Golubovskiy (bukashk0zzz) - Sergii Smertin (nfx) + - Mikkel Paulson - Michał Strzelecki - Soner Sayakci - hugofonseca (fonsecas72) @@ -1200,6 +1218,7 @@ Symfony is the result of the work of many people who made the code better - MightyBranch - Kacper Gunia (cakper) - Peter Thompson (petert82) + - error56 - Felicitus - Krzysztof Przybyszewski - alexpozzi @@ -1237,6 +1256,7 @@ Symfony is the result of the work of many people who made the code better - stoccc - Tomasz Szymczyk (karion) - Alex Vasilchenko + - sez-open - Xavier Coureau - ConneXNL - Aharon Perkel @@ -1273,7 +1293,6 @@ Symfony is the result of the work of many people who made the code better - Saem Ghani - Clément LEFEBVRE - Conrad Kleinespel - - Matthias Althaus - Zacharias Luiten - Sebastian Utz - Adrien Gallou (agallou) @@ -1299,6 +1318,7 @@ Symfony is the result of the work of many people who made the code better - Andy Raines - Anthony Ferrara - Geoffrey Pécro (gpekz) + - Jérémy DECOOL (jdecool) - Klaas Cuvelier (kcuvelier) - Flavien Knuchel (knuch) - Mathieu TUDISCO (mathieutu) @@ -1330,7 +1350,6 @@ Symfony is the result of the work of many people who made the code better - Philip Frank - Lance McNearney - Giorgio Premi - - Andrew Berry - ncou - Ian Carroll - caponica @@ -1361,7 +1380,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) - - Jonathan Johnson (jrjohnson) - Dāvis Zālītis (k0d3r1s) - Carsten Nielsen (phreaknerd) - Roger Guasch (rogerguasch) @@ -1417,11 +1435,13 @@ Symfony is the result of the work of many people who made the code better - Mike Meier - Tim Jabs - Sebastian Ionescu + - Pablo Ogando Ferreira - Thomas Ploch - Simon Neidhold - Valentin VALCIU - Jeremiah VALERIE - Julien Menth + - Yannick Snobbert - Kevin Dew - James Cowgill - 1ma (jautenim) @@ -1436,6 +1456,7 @@ Symfony is the result of the work of many people who made the code better - Lance Chen - Ciaran McNulty (ciaranmcnulty) - Andrew (drew) + - Giso Stallenberg (gisostallenberg) - kor3k kor3k (kor3k) - Stelian Mocanita (stelian) - Justin (wackymole) @@ -1495,7 +1516,6 @@ Symfony is the result of the work of many people who made the code better - Martynas Sudintas (martiis) - ryunosuke - victoria - - Dmytro Borysovskyi (dmytr0) - Francisco Facioni (fran6co) - Iwan van Staveren (istaveren) - Povilas S. (povilas) @@ -1579,6 +1599,7 @@ Symfony is the result of the work of many people who made the code better - loru88 - Romain Dorgueil - Christopher Parotat + - Dennis Haarbrink - me_shaon - 蝦米 - Grayson Koonce (breerly) @@ -1632,6 +1653,7 @@ Symfony is the result of the work of many people who made the code better - Jan van Thoor (janvt) - Johannes Müller (johmue) - Jordi Llonch (jordillonch) + - Nicholas Ruunu (nicholasruunu) - Cédric Dugat (ph3nol) - Philip Dahlstrøm (phidah) - Milos Colakovic (project2481) @@ -1713,6 +1735,7 @@ Symfony is the result of the work of many people who made the code better - Pedro Magalhães (pmmaga) - Rares Vlaseanu (raresvla) - tante kinast (tante) + - Ahmed Hannachi (tiecoders) - Vincent LEFORT (vlefort) - Darryl Hein (xmmedia) - Sadicov Vladimir (xtech) @@ -1734,6 +1757,7 @@ Symfony is the result of the work of many people who made the code better - Oleg Andreyev - neFAST - Pierre Rineau + - Florian Morello - Maxim Lovchikov - adenkejawen - Florent SEVESTRE (aniki-taicho) @@ -1764,7 +1788,6 @@ Symfony is the result of the work of many people who made the code better - timaschew - Jochen Mandl - Marin Nicolae - - soyuka - Alessandro Loffredo - Ian Phillips - Marco Lipparini @@ -1786,6 +1809,7 @@ Symfony is the result of the work of many people who made the code better - insidestyles - Maerlyn - Even André Fiskvik + - Александр Ли - Arjan Keeman - Erik van Wingerden - Valouleloup @@ -1846,6 +1870,7 @@ Symfony is the result of the work of many people who made the code better - Michael Pohlers (mick_the_big) - mlpo (mlpo) - Marek Šimeček (mssimi) + - Dmitriy Tkachenko (neka) - Cayetano Soriano Gallego (neoshadybeat) - Olivier Laviale (olvlvl) - Ondrej Machulda (ondram) @@ -2114,7 +2139,6 @@ Symfony is the result of the work of many people who made the code better - Ala Eddine Khefifi (nayzo) - emilienbouard (neime) - Nicholas Byfleet (nickbyfleet) - - Tomas Norkūnas (norkunas) - Marco Petersen (ocrampete16) - ollie harridge (ollietb) - Dimitri Gritsajuk (ottaviano) @@ -2131,7 +2155,6 @@ Symfony is the result of the work of many people who made the code better - Ralf Kuehnel (ralfkuehnel) - Brayden Williams (redstar504) - Rich Sage (richsage) - - Rokas Mikalkėnas (rokasm) - Bart Ruysseveldt (ruyss) - scourgen hung (scourgen) - Sebastian Busch (sebu) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php index 8e9bdbe92ed4d..d68aa2888218b 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php @@ -102,6 +102,16 @@ private function findSutFqcn($test) return $sutFqcn; } + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + public function __destruct() { if (!$this->warnings) { diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index b527e039662bb..cf2723796106e 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -83,6 +83,16 @@ public function __construct(array $mockedNamespaces = array()) } } + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + public function __destruct() { if (0 < $this->state) { diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index 208639a4b1ec3..70ca302affeb4 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -53,7 +53,7 @@ public function getProxyFactoryCode(Definition $definition, $id, $factoryCode = $instantiation = 'return'; if ($definition->isShared()) { - $instantiation .= sprintf(' $this->%s[\'%s\'] =', $definition->isPublic() && !$definition->isPrivate() ? 'services' : 'privates', $id); + $instantiation .= sprintf(' $this->%s[%s] =', $definition->isPublic() && !$definition->isPrivate() ? 'services' : 'privates', var_export($id, true)); } if (null === $factoryCode) { diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 6bb39e9f0e411..2f9378e163943 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -134,7 +134,7 @@ CHANGELOG The default value will be `state_machine` in Symfony 4.0. * Deprecated the `CompilerDebugDumpPass` class * Deprecated the "framework.trusted_proxies" configuration option and the corresponding "kernel.trusted_proxies" parameter - * Added a new new version strategy option called json_manifest_path + * Added a new version strategy option called "json_manifest_path" that allows you to use the `JsonManifestVersionStrategy`. * Added `Symfony\Bundle\FrameworkBundle\Controller\AbstractController`. It provides the same helpers as the `Controller` class, but does not allow accessing the dependency diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index b390f2978113b..a52caa46c032d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -97,6 +97,7 @@ use Symfony\Component\Translation\Translator; use Symfony\Component\Validator\ConstraintValidatorInterface; use Symfony\Component\Validator\ObjectInitializerInterface; +use Symfony\Component\Validator\Util\LegacyTranslatorProxy; use Symfony\Component\WebLink\HttpHeaderSerializer; use Symfony\Component\Workflow; use Symfony\Component\Workflow\WorkflowInterface; @@ -1107,6 +1108,12 @@ private function registerValidationConfiguration(array $config, ContainerBuilder $validatorBuilder = $container->getDefinition('validator.builder'); + if (class_exists(LegacyTranslatorProxy::class)) { + $calls = $validatorBuilder->getMethodCalls(); + $calls[1] = ['setTranslator', [new Definition(LegacyTranslatorProxy::class, [new Reference('translator')])]]; + $validatorBuilder->setMethodCalls($calls); + } + $container->setParameter('validator.translation_domain', $config['translation_domain']); $files = ['xml' => [], 'yml' => []]; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php index c63d354e1789c..6a57d585c7b57 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php @@ -11,7 +11,7 @@ 0): ?> block($form, 'choice_widget_options', ['choices' => $preferred_choices]) ?> 0 && null !== $separator): ?> - + block($form, 'choice_widget_options', ['choices' => $choices]) ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_errors.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_errors.html.php index 77c60d7dfb3d3..d97179e9a680c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_errors.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_errors.html.php @@ -1,7 +1,7 @@ 0): ?> diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_start.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_start.html.php index ba2f3a4791987..7e244258053ff 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_start.html.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_start.html.php @@ -1,6 +1,6 @@ -
action="" $v) { printf(' %s="%s"', $view->escape($k), $view->escape($v)); } ?> enctype="multipart/form-data"> + action="escape($action) ?>" $v) { printf(' %s="%s"', $view->escape($k), $view->escape($v)); } ?> enctype="multipart/form-data"> - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 862786c9b8b80..b6b520daa19cb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -50,6 +50,7 @@ use Symfony\Component\Serializer\Serializer; use Symfony\Component\Translation\DependencyInjection\TranslatorPass; use Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass; +use Symfony\Component\Validator\Util\LegacyTranslatorProxy; use Symfony\Component\Workflow; abstract class FrameworkExtensionTest extends TestCase @@ -818,7 +819,11 @@ public function testValidation() $this->assertSame('setConstraintValidatorFactory', $calls[0][0]); $this->assertEquals([new Reference('validator.validator_factory')], $calls[0][1]); $this->assertSame('setTranslator', $calls[1][0]); - $this->assertEquals([new Reference('translator')], $calls[1][1]); + if (class_exists(LegacyTranslatorProxy::class)) { + $this->assertEquals([new Definition(LegacyTranslatorProxy::class, [new Reference('translator')])], $calls[1][1]); + } else { + $this->assertEquals([new Reference('translator')], $calls[1][1]); + } $this->assertSame('setTranslationDomain', $calls[2][0]); $this->assertSame(['%validator.translation_domain%'], $calls[2][1]); $this->assertSame('addXmlMappings', $calls[3][0]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php index 80fa74bb13cad..adbfe942a7a3f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php @@ -64,6 +64,16 @@ public function getLogDir() return $this->cacheDir; } + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + public function __destruct() { $fs = new Filesystem(); diff --git a/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php b/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php index c20be5eecb698..3f684acd685d3 100644 --- a/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php +++ b/src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php @@ -122,6 +122,16 @@ public static function throwError($type, $message, $file, $line) throw new \ErrorException($message, 0, $type, $file, $line); } + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + public function __destruct() { if (method_exists(parent::class, '__destruct')) { diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index dde0af7653025..251eeb8321a62 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -828,6 +828,10 @@ public function setAlias($alias, $id) { $alias = (string) $alias; + if ('' === $alias || '\\' === $alias[-1] || \strlen($alias) !== strcspn($alias, "\0\r\n'")) { + throw new InvalidArgumentException(sprintf('Invalid alias id: "%s"', $alias)); + } + if (\is_string($id)) { $id = new Alias($id); } elseif (!$id instanceof Alias) { @@ -981,6 +985,10 @@ public function setDefinition($id, Definition $definition) $id = (string) $id; + if ('' === $id || '\\' === $id[-1] || \strlen($id) !== strcspn($id, "\0\r\n'")) { + throw new InvalidArgumentException(sprintf('Invalid service id: "%s"', $id)); + } + unset($this->aliasDefinitions[$id], $this->removedIds[$id]); return $this->definitions[$id] = $definition; diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index f58e8b56d9fc2..ba704d5d9ef60 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -506,7 +506,7 @@ private function addServiceInstance(string $id, Definition $definition, bool $is $instantiation = ''; if (!$isProxyCandidate && $definition->isShared() && !isset($this->singleUsePrivateIds[$id])) { - $instantiation = sprintf('$this->%s[\'%s\'] = %s', $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', $id, $isSimpleInstance ? '' : '$instance'); + $instantiation = sprintf('$this->%s[%s] = %s', $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', $this->doExport($id), $isSimpleInstance ? '' : '$instance'); } elseif (!$isSimpleInstance) { $instantiation = '$instance'; } @@ -674,6 +674,9 @@ private function addService(string $id, Definition $definition): array * Gets the $public '$id'$shared$autowired service. * * $return +EOF; + $code = str_replace('*/', ' ', $code).<<addServiceInclude($id, $definition); if ($this->getProxyDumper()->isProxyCandidate($definition)) { - $factoryCode = $asFile ? ($definition->isShared() ? "\$this->load('%s.php', false)" : "\$this->factories['%2$s'](false)") : '$this->%s(false)'; - $code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->export($id))); + $factoryCode = $asFile ? ($definition->isShared() ? "\$this->load('%s.php', false)" : "\$this->factories[%2\$s](false)") : '$this->%s(false)'; + $code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->doExport($id))); } if ($definition->isDeprecated()) { @@ -762,14 +765,14 @@ private function addInlineReference(string $id, Definition $definition, string $ $code .= sprintf(<<<'EOTXT' - if (isset($this->%s['%s'])) { - return $this->%1$s['%2$s']; + if (isset($this->%s[%s])) { + return $this->%1$s[%2$s]; } EOTXT , $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', - $id + $this->doExport($id) ); return $code; @@ -861,7 +864,7 @@ private function generateServiceFiles(array $services) $code = ["\n", $code]; } $code[1] = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $code[1]))); - $factory = sprintf('$this->factories%s[\'%s\']', $definition->isPublic() ? '' : "['service_container']", $id); + $factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id)); $lazyloadInitialization = $definition->isLazy() ? '$lazyLoad = true' : ''; $code[1] = sprintf("%s = function (%s) {\n%s};\n\nreturn %1\$s();\n", $factory, $lazyloadInitialization, $code[1]); @@ -1383,14 +1386,14 @@ private function getServiceConditionals($value): string if (!$this->container->hasDefinition($service)) { return 'false'; } - $conditions[] = sprintf("isset(\$this->%s['%s'])", $this->container->getDefinition($service)->isPublic() ? 'services' : 'privates', $service); + $conditions[] = sprintf("isset(\$this->%s[%s])", $this->container->getDefinition($service)->isPublic() ? 'services' : 'privates', $this->doExport($service)); } foreach (ContainerBuilder::getServiceConditionals($value) as $service) { if ($this->container->hasDefinition($service) && !$this->container->getDefinition($service)->isPublic()) { continue; } - $conditions[] = sprintf("\$this->has('%s')", $service); + $conditions[] = sprintf("\$this->has(%s)", $this->doExport($service)); } if (!$conditions) { @@ -1508,7 +1511,7 @@ private function dumpValue($value, bool $interpolate = true): string $serviceMap .= sprintf("\n %s => [%s, %s, %s, %s],", $this->export($k), $this->export($definition->isShared() ? ($definition->isPublic() ? 'services' : 'privates') : false), - $this->export($id), + $this->doExport($id), $this->export(ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $v->getInvalidBehavior() && !\is_string($load) ? $this->generateMethodName($id).($load ? '.php' : '') : null), $this->export($load) ); @@ -1605,11 +1608,11 @@ private function dumpParameter(string $name): string } if (!preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $dumpedValue)) { - return sprintf("\$this->parameters['%s']", $name); + return sprintf('$this->parameters[%s]', $this->doExport($name)); } } - return sprintf("\$this->getParameter('%s')", $name); + return sprintf('$this->getParameter(%s)', $this->doExport($name)); } private function getServiceCall(string $id, Reference $reference = null): string @@ -1624,7 +1627,7 @@ private function getServiceCall(string $id, Reference $reference = null): string if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) { if ($definition->isSynthetic()) { - $code = sprintf('$this->get(\'%s\'%s)', $id, null !== $reference ? ', '.$reference->getInvalidBehavior() : ''); + $code = sprintf('$this->get(%s%s)', $this->doExport($id), null !== $reference ? ', '.$reference->getInvalidBehavior() : ''); } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { $code = 'null'; if (!$definition->isShared()) { @@ -1638,20 +1641,20 @@ private function getServiceCall(string $id, Reference $reference = null): string } $code = $this->addNewInstance($definition, '', $id); if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) { - $code = sprintf('$this->%s[\'%s\'] = %s', $definition->isPublic() ? 'services' : 'privates', $id, $code); + $code = sprintf('$this->%s[%s] = %s', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code); } $code = "($code)"; } elseif ($this->asFiles && !$this->isHotPath($definition)) { $code = sprintf("\$this->load('%s.php')", $this->generateMethodName($id)); if (!$definition->isShared()) { - $factory = sprintf('$this->factories%s[\'%s\']', $definition->isPublic() ? '' : "['service_container']", $id); + $factory = sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id)); $code = sprintf('(isset(%s) ? %1$s() : %s)', $factory, $code); } } else { $code = sprintf('$this->%s()', $this->generateMethodName($id)); } if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) { - $code = sprintf('($this->%s[\'%s\'] ?? %s)', $definition->isPublic() ? 'services' : 'privates', $id, $code); + $code = sprintf('($this->%s[%s] ?? %s)', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code); } return $code; @@ -1660,12 +1663,12 @@ private function getServiceCall(string $id, Reference $reference = null): string return 'null'; } if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $reference->getInvalidBehavior()) { - $code = sprintf('$this->get(\'%s\', /* ContainerInterface::NULL_ON_INVALID_REFERENCE */ %d)', $id, ContainerInterface::NULL_ON_INVALID_REFERENCE); + $code = sprintf('$this->get(%s, /* ContainerInterface::NULL_ON_INVALID_REFERENCE */ %d)', $this->doExport($id), ContainerInterface::NULL_ON_INVALID_REFERENCE); } else { - $code = sprintf('$this->get(\'%s\')', $id); + $code = sprintf('$this->get(%s)', $this->doExport($id)); } - return sprintf('($this->services[\'%s\'] ?? %s)', $id, $code); + return sprintf('($this->services[%s] ?? %s)', $this->doExport($id), $code); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 4f505735bb95e..53b337ed56ef9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -195,6 +195,38 @@ public function testNonSharedServicesReturnsDifferentInstances() $this->assertNotSame($builder->get('bar'), $builder->get('bar')); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException + * @dataProvider provideBadId + */ + public function testBadAliasId($id) + { + $builder = new ContainerBuilder(); + $builder->setAlias($id, 'foo'); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException + * @dataProvider provideBadId + */ + public function testBadDefinitionId($id) + { + $builder = new ContainerBuilder(); + $builder->setDefinition($id, new Definition('Foo')); + } + + public function provideBadId() + { + return [ + [''], + ["\0"], + ["\r"], + ["\n"], + ["'"], + ['ab\\'], + ]; + } + /** * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException * @expectedExceptionMessage You have requested a synthetic service ("foo"). The DIC does not know how to construct this service. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 9a77e51548a5e..358384b4dea34 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -261,12 +261,18 @@ public function testAddServiceIdWithUnsupportedCharacters() { $class = 'Symfony_DI_PhpDumper_Test_Unsupported_Characters'; $container = new ContainerBuilder(); + $container->setParameter("'", 'oh-no'); + $container->register("foo*/oh-no", 'FooClass')->setPublic(true); $container->register('bar$', 'FooClass')->setPublic(true); $container->register('bar$!', 'FooClass')->setPublic(true); $container->compile(); $dumper = new PhpDumper($container); - eval('?>'.$dumper->dump(['class' => $class])); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_unsupported_characters.php', $dumper->dump(['class' => $class])); + + require_once self::$fixturesPath.'/php/services_unsupported_characters.php'; + + $this->assertTrue(method_exists($class, 'getFooOhNoService')); $this->assertTrue(method_exists($class, 'getBarService')); $this->assertTrue(method_exists($class, 'getBar2Service')); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services33.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services33.php index e1c7a5b953146..398c4406b1684 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services33.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services33.php @@ -55,7 +55,7 @@ public function getRemovedIds() */ protected function getFooService() { - return $this->services['Bar\Foo'] = new \Bar\Foo(); + return $this->services['Bar\\Foo'] = new \Bar\Foo(); } /** @@ -65,6 +65,6 @@ protected function getFooService() */ protected function getFoo2Service() { - return $this->services['Foo\Foo'] = new \Foo\Foo(); + return $this->services['Foo\\Foo'] = new \Foo\Foo(); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_adawson.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_adawson.php index 6239128bc4c79..4fde7e6d5d237 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_adawson.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_adawson.php @@ -60,11 +60,11 @@ public function getRemovedIds() */ protected function getBusService() { - $a = ($this->services['App\Db'] ?? $this->getDbService()); + $a = ($this->services['App\\Db'] ?? $this->getDbService()); - $this->services['App\Bus'] = $instance = new \App\Bus($a); + $this->services['App\\Bus'] = $instance = new \App\Bus($a); - $b = ($this->privates['App\Schema'] ?? $this->getSchemaService()); + $b = ($this->privates['App\\Schema'] ?? $this->getSchemaService()); $c = new \App\Registry(); $c->processor = [0 => $a, 1 => $instance]; @@ -83,9 +83,9 @@ protected function getBusService() */ protected function getDbService() { - $this->services['App\Db'] = $instance = new \App\Db(); + $this->services['App\\Db'] = $instance = new \App\Db(); - $instance->schema = ($this->privates['App\Schema'] ?? $this->getSchemaService()); + $instance->schema = ($this->privates['App\\Schema'] ?? $this->getSchemaService()); return $instance; } @@ -97,12 +97,12 @@ protected function getDbService() */ protected function getSchemaService() { - $a = ($this->services['App\Db'] ?? $this->getDbService()); + $a = ($this->services['App\\Db'] ?? $this->getDbService()); - if (isset($this->privates['App\Schema'])) { - return $this->privates['App\Schema']; + if (isset($this->privates['App\\Schema'])) { + return $this->privates['App\\Schema']; } - return $this->privates['App\Schema'] = new \App\Schema($a); + return $this->privates['App\\Schema'] = new \App\Schema($a); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php index ee6e3d8205f4d..cca9d46cd02f2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php @@ -70,7 +70,7 @@ public function getRemovedIds() */ protected function getParentNotExistsService() { - return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists(); + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\ParentNotExists'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists(); } /** @@ -80,7 +80,7 @@ protected function getParentNotExistsService() */ protected function getC1Service() { - return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C1'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C1(); + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C1'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C1(); } /** @@ -93,7 +93,7 @@ protected function getC2Service() include_once $this->targetDirs[1].'/includes/HotPath/C2.php'; include_once $this->targetDirs[1].'/includes/HotPath/C3.php'; - return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3()); + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3()); } public function getParameter($name) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_self_ref.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_self_ref.php index 8b9703cd86c0e..ea76b0d15780b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_self_ref.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_self_ref.php @@ -59,7 +59,7 @@ protected function getFooService() $b = new \App\Baz($a); $b->bar = $a; - $this->services['App\Foo'] = $instance = new \App\Foo($b); + $this->services['App\\Foo'] = $instance = new \App\Foo($b); $a->foo = $instance; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_rot13_env.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_rot13_env.php index 64cc5df2580cb..6d8cce591e721 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_rot13_env.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_rot13_env.php @@ -60,7 +60,7 @@ public function getRemovedIds() */ protected function getRot13EnvVarProcessorService() { - return $this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor(); + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Dumper\\Rot13EnvVarProcessor'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor(); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php index b60b3b87b3de0..bdd5e1dce0fa4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php @@ -60,7 +60,7 @@ public function getRemovedIds() */ protected function getTestServiceSubscriberService() { - return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber(); + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber(); } /** @@ -85,6 +85,6 @@ protected function getFooServiceService() */ protected function getCustomDefinitionService() { - return $this->privates['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition(); + return $this->privates['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition(); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_unsupported_characters.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_unsupported_characters.php new file mode 100644 index 0000000000000..754d615df6dfc --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_unsupported_characters.php @@ -0,0 +1,151 @@ +parameters = $this->getDefaultParameters(); + + $this->services = $this->privates = []; + $this->methodMap = [ + 'bar$' => 'getBarService', + 'bar$!' => 'getBar2Service', + 'foo*/oh-no' => 'getFooohnoService', + ]; + + $this->aliases = []; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + /** + * Gets the public 'bar$' shared service. + * + * @return \FooClass + */ + protected function getBarService() + { + return $this->services['bar$'] = new \FooClass(); + } + + /** + * Gets the public 'bar$!' shared service. + * + * @return \FooClass + */ + protected function getBar2Service() + { + return $this->services['bar$!'] = new \FooClass(); + } + + /** + * Gets the public 'foo oh-no' shared service. + * + * @return \FooClass + */ + protected function getFooohnoService() + { + return $this->services['foo*/oh-no'] = new \FooClass(); + } + + public function getParameter($name) + { + $name = (string) $name; + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = []; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + '\'' => 'oh-no', + ]; + } +} diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateIntervalTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateIntervalTypeTest.php index 6e19b9fc3d22d..4add8b13bfbf2 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateIntervalTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateIntervalTypeTest.php @@ -442,7 +442,7 @@ public function testSubmitNullUsesDateEmptyData($widget, $emptyData, $expectedDa public function provideEmptyData() { - $expectedData = \DateInterval::createFromDateString('6 years and 4 months'); + $expectedData = new \DateInterval('P6Y4M'); return [ 'Simple field' => ['single_text', 'P6Y4M0D', $expectedData], diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php index d5acb34094c11..c0f9140c800a2 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php @@ -808,6 +808,12 @@ class MimeTypeExtensionGuesser implements ExtensionGuesserInterface */ public function guess($mimeType) { - return isset($this->defaultExtensions[$mimeType]) ? $this->defaultExtensions[$mimeType] : null; + if (isset($this->defaultExtensions[$mimeType])) { + return $this->defaultExtensions[$mimeType]; + } + + $lcMimeType = strtolower($mimeType); + + return isset($this->defaultExtensions[$lcMimeType]) ? $this->defaultExtensions[$lcMimeType] : null; } } diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index 7cf2120a51786..2b4fc0c02e82c 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1214,22 +1214,37 @@ public function setMethod($method) */ public function getMethod() { - if (null === $this->method) { - $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET')); - - if ('POST' === $this->method) { - if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) { - $this->method = strtoupper($method); - } elseif (self::$httpMethodParameterOverride) { - $method = $this->request->get('_method', $this->query->get('_method', 'POST')); - if (\is_string($method)) { - $this->method = strtoupper($method); - } - } - } + if (null !== $this->method) { + return $this->method; + } + + $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET')); + + if ('POST' !== $this->method) { + return $this->method; + } + + $method = $this->headers->get('X-HTTP-METHOD-OVERRIDE'); + + if (!$method && self::$httpMethodParameterOverride) { + $method = $this->request->get('_method', $this->query->get('_method', 'POST')); + } + + if (!\is_string($method)) { + return $this->method; + } + + $method = strtoupper($method); + + if (\in_array($method, ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'PATCH', 'PURGE', 'TRACE'], true)) { + return $this->method = $method; + } + + if (!preg_match('/^[A-Z]++$/D', $method)) { + throw new SuspiciousOperationException(sprintf('Invalid method override "%s".', $method)); } - return $this->method; + return $this->method = $method; } /** diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/case-sensitive-mime-type.xlsm b/src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/case-sensitive-mime-type.xlsm new file mode 100644 index 0000000000000..94d85e6132c55 Binary files /dev/null and b/src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/case-sensitive-mime-type.xlsm differ diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php b/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php index 3952a69c69eb5..8f5f48a066207 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/File/UploadedFileTest.php @@ -94,6 +94,18 @@ public function testGuessClientExtensionWithIncorrectMimeType() $this->assertEquals('jpeg', $file->guessClientExtension()); } + public function testCaseSensitiveMimeType() + { + $file = new UploadedFile( + __DIR__.'/Fixtures/case-sensitive-mime-type.xlsm', + 'test.xlsm', + 'application/vnd.ms-excel.sheet.macroEnabled.12', + null + ); + + $this->assertEquals('xlsm', $file->guessClientExtension()); + } + public function testErrorIsOkByDefault() { $file = new UploadedFile( diff --git a/src/Symfony/Component/HttpKernel/EventListener/SessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/SessionListener.php index aaf3be507facd..c466fb7c9ed2d 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/SessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/SessionListener.php @@ -40,7 +40,8 @@ protected function getSession() if ($this->container->has('session_storage') && ($storage = $this->container->get('session_storage')) instanceof NativeSessionStorage - && $this->container->get('request_stack')->getMasterRequest()->isSecure() + && ($masterRequest = $this->container->get('request_stack')->getMasterRequest()) + && $masterRequest->isSecure() ) { $storage->setOptions(['cookie_secure' => true]); } diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index bdba3ad5aad5e..94e87d880b323 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -73,11 +73,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '4.2.6'; - const VERSION_ID = 40206; + const VERSION = '4.2.7'; + const VERSION_ID = 40207; const MAJOR_VERSION = 4; const MINOR_VERSION = 2; - const RELEASE_VERSION = 6; + const RELEASE_VERSION = 7; const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '07/2019'; diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php index 47ac75e8bcc17..f931f6dacdc4c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php @@ -15,8 +15,10 @@ use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ServiceLocator; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; @@ -41,8 +43,16 @@ public function testSessionIsSet() { $session = $this->getMockBuilder(Session::class)->disableOriginalConstructor()->getMock(); + $requestStack = $this->getMockBuilder(RequestStack::class)->getMock(); + $requestStack->expects($this->once())->method('getMasterRequest')->willReturn(null); + + $sessionStorage = $this->getMockBuilder(NativeSessionStorage::class)->getMock(); + $sessionStorage->expects($this->never())->method('setOptions')->with(['cookie_secure' => true]); + $container = new Container(); $container->set('session', $session); + $container->set('request_stack', $requestStack); + $container->set('session_storage', $sessionStorage); $request = new Request(); $listener = new SessionListener($container); diff --git a/src/Symfony/Component/Ldap/Tests/LdapTestCase.php b/src/Symfony/Component/Ldap/Tests/LdapTestCase.php index 2e5fa9a34b18b..cc50ecae73dc1 100644 --- a/src/Symfony/Component/Ldap/Tests/LdapTestCase.php +++ b/src/Symfony/Component/Ldap/Tests/LdapTestCase.php @@ -8,6 +8,14 @@ class LdapTestCase extends TestCase { protected function getLdapConfig() { + $h = @ldap_connect(getenv('LDAP_HOST'), getenv('LDAP_PORT')); + + if (!$h || !@ldap_bind($h)) { + $this->markTestSkipped('No server is listening on LDAP_HOST:LDAP_PORT'); + } + + ldap_close($h); + return [ 'host' => getenv('LDAP_HOST'), 'port' => getenv('LDAP_PORT'), diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherTrait.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherTrait.php index c544921692946..b77c53085495c 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherTrait.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherTrait.php @@ -131,6 +131,15 @@ private function doMatch(string $pathinfo, array &$allow = [], array &$allowSche } $hasTrailingVar = $trimmedPathinfo !== $pathinfo && $hasTrailingVar; + + if ($hasTrailingVar && ($hasTrailingSlash || '/' !== substr($matches[\count($vars)], -1)) && preg_match($regex, $this->matchHost ? $host.'.'.$trimmedPathinfo : $trimmedPathinfo, $n) && $m === (int) $n['MARK']) { + if ($hasTrailingSlash) { + $matches = $n; + } else { + $hasTrailingVar = false; + } + } + if ('/' !== $pathinfo && !$hasTrailingVar && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) { if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) { return $allow = $allowSchemes = []; @@ -138,10 +147,6 @@ private function doMatch(string $pathinfo, array &$allow = [], array &$allowSche continue; } - if ($hasTrailingSlash && $hasTrailingVar && preg_match($regex, $this->matchHost ? $host.'.'.$trimmedPathinfo : $trimmedPathinfo, $n) && $m === (int) $n['MARK']) { - $matches = $n; - } - foreach ($vars as $i => $v) { if (isset($matches[1 + $i])) { $ret[$v] = $matches[1 + $i]; diff --git a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php index 318a141985601..5b6c0440da9cc 100644 --- a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -158,6 +158,14 @@ protected function matchCollection($pathinfo, RouteCollection $routes) $hasTrailingVar = $trimmedPathinfo !== $pathinfo && preg_match('#\{\w+\}/?$#', $route->getPath()); + if ($hasTrailingVar && ($hasTrailingSlash || '/' !== substr($matches[(\count($matches) - 1) >> 1], -1)) && preg_match($regex, $trimmedPathinfo, $m)) { + if ($hasTrailingSlash) { + $matches = $m; + } else { + $hasTrailingVar = false; + } + } + if ('/' !== $pathinfo && !$hasTrailingVar && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) { if ($supportsTrailingSlash && (!$requiredMethods || \in_array('GET', $requiredMethods))) { return $this->allow = $this->allowSchemes = []; @@ -166,10 +174,6 @@ protected function matchCollection($pathinfo, RouteCollection $routes) continue; } - if ($hasTrailingSlash && $hasTrailingVar && preg_match($regex, $trimmedPathinfo, $m)) { - $matches = $m; - } - $hostMatches = []; if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { continue; diff --git a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php index a1de37048fcae..42acb04857586 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php @@ -187,6 +187,17 @@ public function testSlashAndVerbPrecedenceWithRedirection() $this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons')); } + public function testNonGreedyTrailingRequirement() + { + $coll = new RouteCollection(); + $coll->add('a', new Route('/{a}', [], ['a' => '\d+'])); + + $matcher = $this->getUrlMatcher($coll); + $matcher->expects($this->once())->method('redirect')->with('/123')->willReturn([]); + + $this->assertEquals(['_route' => 'a', 'a' => '123'], $matcher->match('/123/')); + } + protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) { return $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', [$routes, $context ?: new RequestContext()]); diff --git a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php index 08e08f7454c3a..2aa3ac621fc10 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php @@ -131,6 +131,8 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event } catch (\Exception $e) { $event->setException($e); } + + return; } if (null !== $this->logger) { @@ -148,7 +150,7 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event $subRequest = $this->httpUtils->createRequest($event->getRequest(), $this->errorPage); $subRequest->attributes->set(Security::ACCESS_DENIED_ERROR, $exception); - $event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST)); + $event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true)); $event->allowCustomResponseCode(); } } catch (\Exception $e) { diff --git a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php index c208c588f181e..4ae4277b6965e 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php +++ b/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php @@ -122,6 +122,6 @@ protected function generateCookieValue($class, $username, $expires, $password) */ protected function generateCookieHash($class, $username, $expires, $password) { - return hash_hmac('sha256', $class.$username.$expires.$password, $this->getSecret()); + return hash_hmac('sha256', $class.self::COOKIE_DELIMITER.$username.self::COOKIE_DELIMITER.$expires.self::COOKIE_DELIMITER.$password, $this->getSecret()); } } diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php index 3220e43e70e95..53fedebcad705 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php @@ -130,8 +130,10 @@ public function testAccessDeniedExceptionFullFledgedAndWithAccessDeniedHandlerAn { $event = $this->createEvent($exception); - $listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $this->createCustomAccessDeniedHandler(new Response('error'))); + $accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock(); + $accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue(new Response('error'))); + $listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $accessDeniedHandler); $listener->onKernelException($event); $this->assertEquals('error', $event->getResponse()->getContent()); @@ -145,48 +147,13 @@ public function testAccessDeniedExceptionNotFullFledged(\Exception $exception, \ { $event = $this->createEvent($exception); - $listener = $this->createExceptionListener($this->createTokenStorage(), $this->createTrustResolver(false), null, $this->createEntryPoint()); - $listener->onKernelException($event); - - $this->assertEquals('OK', $event->getResponse()->getContent()); - $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); - } - - /** - * @dataProvider getAccessDeniedExceptionProvider - */ - public function testAccessDeniedExceptionNotFullFledgedAndWithAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null) - { - $event = $this->createEvent($exception); - - $listener = $this->createExceptionListener($this->createTokenStorage(), $this->createTrustResolver(false), null, $this->createEntryPoint(), null, $this->createCustomAccessDeniedHandler(new Response('denied', 403))); - $listener->onKernelException($event); - - $this->assertEquals('denied', $event->getResponse()->getContent()); - $this->assertEquals(403, $event->getResponse()->getStatusCode()); - $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); - } - - /** - * @dataProvider getAccessDeniedExceptionProvider - */ - public function testAccessDeniedExceptionNotFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null) - { - $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(); - $kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('Unauthorized', 401))); - - $event = $this->createEvent($exception, $kernel); - - $httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock(); - $httpUtils->expects($this->once())->method('createRequest')->will($this->returnValue(Request::create('/error'))); + $tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(); + $tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock())); - $listener = $this->createExceptionListener($this->createTokenStorage(), $this->createTrustResolver(true), $httpUtils, null, '/error'); + $listener = $this->createExceptionListener($tokenStorage, $this->createTrustResolver(false), null, $this->createEntryPoint()); $listener->onKernelException($event); - $this->assertTrue($event->isAllowingCustomResponseCode()); - - $this->assertEquals('Unauthorized', $event->getResponse()->getContent()); - $this->assertEquals(401, $event->getResponse()->getStatusCode()); + $this->assertEquals('OK', $event->getResponse()->getContent()); $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); } @@ -201,22 +168,6 @@ public function getAccessDeniedExceptionProvider() ]; } - private function createTokenStorage() - { - $tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(); - $tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock())); - - return $tokenStorage; - } - - private function createCustomAccessDeniedHandler(Response $response) - { - $accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock(); - $accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue($response)); - - return $accessDeniedHandler; - } - private function createEntryPoint(Response $response = null) { $entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock(); diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf index 02eece5965d14..79171bc0dfa6e 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.lt.xlf @@ -334,6 +334,34 @@ This value should be valid JSON. Ši reikšmė turi būti tinkamo JSON formato. + + This collection should contain only unique elements. + Sąraše turi būti tik unikalios reikšmės. + + + This value should be positive. + Reikšmė turi būti teigiama. + + + This value should be either positive or zero. + Reikšmė turi būti teigiama arba lygi nuliui. + + + This value should be negative. + Reikšmė turi būti neigiama. + + + This value should be either negative or zero. + Reikšmė turi būti neigiama arba lygi nuliui. + + + This value is not a valid timezone. + Reikšmė nėra tinkama laiko juosta. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Slaptažodis yra nutekėjęs duomenų saugumo pažeidime, jo naudoti negalima. Prašome naudoti kitą slaptažodį. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf index 75dc329589730..1c408585b28f1 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf @@ -314,6 +314,54 @@ This is not a valid Business Identifier Code (BIC). Ito ay hindi isang balidong Business Identifier Code (BIC). + + Error + Error + + + This is not a valid UUID. + Ito ay hindi wastong UUID. + + + This value should be a multiple of {{ compared_value }}. + Ang halagang ito ay dapat multiple ng {{ compared_value }}. + + + This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}. + Ang Business Identifier Code (BIC) na ito ay walang kaugnayan sa IBAN {{ iban }}. + + + This value should be valid JSON. + Ang halagang ito ay dapat naka wastong JSON. + + + This collection should contain only unique elements. + Ang mga elemento ng koleksyong ito ay dapat magkakaiba. + + + This value should be positive. + Ang halagang ito ay dapat positibo. + + + This value should be either positive or zero. + Ang halagang ito ay dapat positibo o zero. + + + This value should be negative. + Ang halagang ito ay dapat negatibo. + + + This value should be either negative or zero. + Ang halagang ito ay dapat negatibo o zero. + + + This value is not a valid timezone. + Ang halagang ito ay hindi wastong timezone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Naikalat ang password na ito sa isang data breach at hindi na dapat gamitin. Mangyaring gumamit ng ibang pang password. + diff --git a/src/Symfony/Component/Validator/ValidatorBuilder.php b/src/Symfony/Component/Validator/ValidatorBuilder.php index fb643327125d5..0766a2e9f399a 100644 --- a/src/Symfony/Component/Validator/ValidatorBuilder.php +++ b/src/Symfony/Component/Validator/ValidatorBuilder.php @@ -258,7 +258,11 @@ public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterfac */ public function setTranslator(LegacyTranslatorInterface $translator) { - $this->translator = $translator instanceof LegacyTranslatorProxy ? $translator->getTranslator() : $translator; + $this->translator = $translator; + + while ($this->translator instanceof LegacyTranslatorProxy) { + $this->translator = $this->translator->getTranslator(); + } return $this; } diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/IntlCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/IntlCasterTest.php index 7c8e02858bde5..c93b9df83d55a 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/IntlCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/IntlCasterTest.php @@ -54,12 +54,12 @@ public function testCastNumberFormatter() $expectedAttribute11 = $var->getAttribute(\NumberFormatter::GROUPING_SIZE); $expectedAttribute12 = $var->getAttribute(\NumberFormatter::ROUNDING_MODE); $expectedAttribute13 = number_format($var->getAttribute(\NumberFormatter::ROUNDING_INCREMENT), 1); - $expectedAttribute14 = $var->getAttribute(\NumberFormatter::FORMAT_WIDTH); + $expectedAttribute14 = $this->getDump($var->getAttribute(\NumberFormatter::FORMAT_WIDTH)); $expectedAttribute15 = $var->getAttribute(\NumberFormatter::PADDING_POSITION); $expectedAttribute16 = $var->getAttribute(\NumberFormatter::SECONDARY_GROUPING_SIZE); $expectedAttribute17 = $var->getAttribute(\NumberFormatter::SIGNIFICANT_DIGITS_USED); - $expectedAttribute18 = $var->getAttribute(\NumberFormatter::MIN_SIGNIFICANT_DIGITS); - $expectedAttribute19 = $var->getAttribute(\NumberFormatter::MAX_SIGNIFICANT_DIGITS); + $expectedAttribute18 = $this->getDump($var->getAttribute(\NumberFormatter::MIN_SIGNIFICANT_DIGITS)); + $expectedAttribute19 = $this->getDump($var->getAttribute(\NumberFormatter::MAX_SIGNIFICANT_DIGITS)); $expectedAttribute20 = $var->getAttribute(\NumberFormatter::LENIENT_PARSE); $expectedTextAttribute1 = $var->getTextAttribute(\NumberFormatter::POSITIVE_PREFIX); diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php index fd8194cca5959..99cdd7274d941 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php @@ -37,7 +37,7 @@ public function testReflectionCaster() %A] constants: array:3 [ "IS_IMPLICIT_ABSTRACT" => 16 - "IS_EXPLICIT_ABSTRACT" => 32 + "IS_EXPLICIT_ABSTRACT" => %d "IS_FINAL" => %d ] properties: array:%d [