diff --git a/CHANGELOG-2.3.md b/CHANGELOG-2.3.md
index b8e185e9de783..d0ca6221aca02 100644
--- a/CHANGELOG-2.3.md
+++ b/CHANGELOG-2.3.md
@@ -7,6 +7,35 @@ in 2.3 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.3.0...v2.3.1
+* 2.3.40 (2016-04-29)
+
+ * bug #18246 [DependencyInjection] fix ambiguous services schema (backbone87)
+ * bug #18603 [PropertyAccess] ->getValue() should be read-only (nicolas-grekas)
+ * bug #18280 [Routing] add query param if value is different from default (Tobion)
+ * bug #18515 [Filesystem] Better error handling in remove() (nicolas-grekas)
+ * bug #18449 [PropertyAccess] Fix regression (nicolas-grekas)
+ * bug #18467 [DependencyInjection] Resolve aliases before removing abstract services + add tests (nicolas-grekas)
+ * bug #18460 [DomCrawler] Fix select option with empty value (Matt Wells)
+ * bug #18425 [Security] Fixed SwitchUserListener when exiting an impersonation with AnonymousToken (lyrixx)
+ * bug #18317 [Form] fix "prototype" not required when parent form is not required (HeahDude)
+ * bug #18439 [Logging] Add support for Firefox (43+) in ChromePhpHandler (arjenm)
+ * bug #18385 Detect CLI color support for Windows 10 build 10586 (mlocati)
+ * bug #18426 [EventDispatcher] Try first if the event is Stopped (lyrixx)
+ * bug #18265 Optimize ReplaceAliasByActualDefinitionPass (ajb-in)
+ * bug #18358 [Form] NumberToLocalizedStringTransformer should return floats when possible (nicolas-grekas)
+ * bug #17926 [DependencyInjection] Enable alias for service_container (hason)
+ * bug #18336 [Debug] Fix handling of php7 throwables (nicolas-grekas)
+ * bug #18312 [ClassLoader] Fix storing not-found classes in APC cache (nicolas-grekas)
+ * bug #18255 [HttpFoundation] Fix support of custom mime types with parameters (Ener-Getick)
+ * bug #18259 [PropertyAccess] Backport fixes from 2.7 (nicolas-grekas)
+ * bug #18224 [PropertyAccess] Remove most ref mismatches to improve perf (nicolas-grekas)
+ * bug #18210 [PropertyAccess] Throw an UnexpectedTypeException when the type do not match (dunglas, nicolas-grekas)
+ * bug #18216 [Intl] Fix invalid numeric literal on PHP 7 (nicolas-grekas)
+ * bug #18147 [Validator] EmailValidator cannot extract hostname if email contains multiple @ symbols (natechicago)
+ * bug #18175 [Translation] Add support for fuzzy tags in PoFileLoader (nud)
+ * bug #18179 [Form] Fix NumberToLocalizedStringTransformer::reverseTransform with big integers (ovrflo, nicolas-grekas)
+ * bug #18164 [HttpKernel] set s-maxage only if all responses are cacheable (xabbuh)
+
* 2.3.39 (2016-03-13)
* bug #18080 [HttpFoundation] Set the Content-Range header if the requested Range is unsatisfied (jakzal)
diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md
index 5b1d9382488ff..89ee3b549f479 100644
--- a/CHANGELOG-2.7.md
+++ b/CHANGELOG-2.7.md
@@ -7,6 +7,37 @@ in 2.7 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/v2.7.0...v2.7.1
+* 2.7.12 (2016-04-29)
+
+ * bug #18180 [Form] fixed BC break with pre selection of choices with `ChoiceType` and its children (HeahDude)
+ * bug #18562 [WebProfilerBunde] Give an absolute url in case the request occured from another domain (romainneutron)
+ * bug #18603 [PropertyAccess] ->getValue() should be read-only (nicolas-grekas)
+ * bug #18593 [VarDumper] Fix dumping type hints for non-existing parent classes (nicolas-grekas)
+ * bug #18581 [Console] [TableHelper] make it work with SymfonyStyle. (aitboudad)
+ * bug #18280 [Routing] add query param if value is different from default (Tobion)
+ * bug #18496 [Console] use ANSI escape sequences in ProgressBar overwrite method (alekitto)
+ * bug #18491 [DependencyInjection] anonymous services are always private (xabbuh)
+ * bug #18515 [Filesystem] Better error handling in remove() (nicolas-grekas)
+ * bug #18449 [PropertyAccess] Fix regression (nicolas-grekas)
+ * bug #18429 [Console] Correct time formatting. (camporter)
+ * bug #18467 [DependencyInjection] Resolve aliases before removing abstract services + add tests (nicolas-grekas)
+ * bug #18460 [DomCrawler] Fix select option with empty value (Matt Wells)
+ * bug #18425 [Security] Fixed SwitchUserListener when exiting an impersonation with AnonymousToken (lyrixx)
+ * bug #18317 [Form] fix "prototype" not required when parent form is not required (HeahDude)
+ * bug #18439 [Logging] Add support for Firefox (43+) in ChromePhpHandler (arjenm)
+ * bug #18385 Detect CLI color support for Windows 10 build 10586 (mlocati)
+ * bug #18426 [EventDispatcher] Try first if the event is Stopped (lyrixx)
+ * bug #18394 [FrameworkBundle] Return the invokable service if its name is the class name (dunglas)
+ * bug #18265 Optimize ReplaceAliasByActualDefinitionPass (ajb-in)
+ * bug #18349 [Process] Fix stream_select priority when writing to stdin (nicolas-grekas)
+ * bug #18358 [Form] NumberToLocalizedStringTransformer should return floats when possible (nicolas-grekas)
+ * bug #17926 [DependencyInjection] Enable alias for service_container (hason)
+ * bug #18352 [Debug] Fix case sensitivity checks (nicolas-grekas)
+ * bug #18336 [Debug] Fix handling of php7 throwables (nicolas-grekas)
+ * bug #18354 [FrameworkBundle][TwigBridge] fix high deps tests (xabbuh)
+ * bug #18312 [ClassLoader] Fix storing not-found classes in APC cache (nicolas-grekas)
+ * bug #18298 [Validator] do not treat payload as callback (xabbuh)
+
* 2.7.11 (2016-03-25)
* bug #18255 [HttpFoundation] Fix support of custom mime types with parameters (Ener-Getick)
diff --git a/CHANGELOG-2.8.md b/CHANGELOG-2.8.md
index 854716d996a75..19d984b3f5b1d 100644
--- a/CHANGELOG-2.8.md
+++ b/CHANGELOG-2.8.md
@@ -7,6 +7,18 @@ in 2.8 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/v2.8.0...v2.8.1
+* 2.8.6 (2016-05-09)
+
+ * security #18736 Fixed issue with blank password with Ldap (csarrazi)
+ * security #18733 limited the maximum length of a submitted username (fabpot)
+ * bug #18730 [FrameworkBundle] prevent calling get() for service_container service (xabbuh)
+ * bug #18705 added a conflict between Monolog bridge 2.8 and HTTP Kernel 3.0+ (fabpot)
+ * bug #18709 [DependencyInjection] top-level anonymous services must be public (xabbuh)
+ * bug #18388 [EventDispatcher] check for method to exist (xabbuh)
+ * bug #18699 [DependencyInjection] Use the priority of service decoration on service with parent (hason)
+ * bug #18692 add @Event annotation for KernelEvents (Haehnchen)
+ * bug #18246 [DependencyInjection] fix ambiguous services schema (backbone87)
+
* 2.8.5 (2016-04-29)
* bug #18180 [Form] fixed BC break with pre selection of choices with `ChoiceType` and its children (HeahDude)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 79ca50e61c6f6..456aeba37aa74 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -9,25 +9,25 @@ Symfony is the result of the work of many people who made the code better
- Bernhard Schussek (bschussek)
- Tobias Schultze (tobion)
- Christophe Coevoet (stof)
+ - Christian Flothmann (xabbuh)
- Jordi Boggiano (seldaek)
- Victor Berchet (victor)
- - Christian Flothmann (xabbuh)
- Johannes S (johannes)
- Kris Wallsmith (kriswallsmith)
- Jakub Zalas (jakubzalas)
- Ryan Weaver (weaverryan)
- Javier Eguiluz (javier.eguiluz)
- Hugo Hamon (hhamon)
+ - Kévin Dunglas (dunglas)
- Abdellatif Ait boudad (aitboudad)
- Pascal Borreli (pborreli)
- - Kévin Dunglas (dunglas)
- Joseph Bielawski (stloyd)
- Wouter De Jong (wouterj)
- Karma Dordrak (drak)
- Romain Neutron (romain)
- Lukas Kahwe Smith (lsmith)
- - Jeremy Mikola (jmikola)
- Martin Hasoň (hason)
+ - Jeremy Mikola (jmikola)
- Jean-François Simon (jfsimon)
- Benjamin Eberlei (beberlei)
- Igor Wiedler (igorw)
@@ -42,6 +42,7 @@ Symfony is the result of the work of many people who made the code better
- ornicar
- stealth35 (stealth35)
- Alexander Mols (asm89)
+ - Jules Pietri (heah)
- Francis Besset (francisbesset)
- Bulat Shakirzyanov (avalanche123)
- Saša Stamenković (umpirsky)
@@ -56,13 +57,15 @@ Symfony is the result of the work of many people who made the code better
- Michel Weimerskirch (mweimerskirch)
- Eric Clemmons (ericclemmons)
- Andrej Hudec (pulzarraider)
+ - Peter Rehm (rpet)
- Christian Raue
- Matthias Pigulla (mpdude)
- - Peter Rehm (rpet)
- Deni
- Henrik Westphal (snc)
- Dariusz Górecki (canni)
- Arnout Boks (aboks)
+ - Iltar van der Berg (kjarli)
+ - Ener-Getick (energetick)
- Douglas Greenshields (shieldo)
- Lee McDermott
- Brandon Turner
@@ -71,21 +74,18 @@ Symfony is the result of the work of many people who made the code better
- Pierre du Plessis (pierredup)
- Bart van den Burg (burgov)
- Jordan Alliot (jalliot)
+ - Charles Sarrazin (csarrazi)
- John Wards (johnwards)
- Toni Uebernickel (havvg)
- Fran Moreno (franmomu)
- Graham Campbell (graham)
- Antoine Hérault (herzult)
- - Iltar van der Berg (kjarli)
- Arnaud Le Blanc (arnaud-lb)
- Jérôme Tamarelle (gromnan)
- - Jules Pietri (heah)
- Michal Piotrowski (eventhorizon)
- Tim Nagel (merk)
- Paráda József (paradajozsef)
- Brice BERNARD (brikou)
- - Ener-Getick (energetick)
- - Charles Sarrazin (csarrazi)
- Alexander M. Turek (derrabus)
- Dariusz Ruminski
- marc.weistroff
@@ -93,6 +93,7 @@ Symfony is the result of the work of many people who made the code better
- Włodzimierz Gajda (gajdaw)
- Alexander Schwenn (xelaris)
- Florian Voutzinos (florianv)
+ - Konstantin Myakshin (koc)
- Colin Frei
- Adrien Brault (adrienbrault)
- Joshua Thijssen
@@ -100,19 +101,18 @@ Symfony is the result of the work of many people who made the code better
- Peter Kokot (maastermedia)
- excelwebzone
- Jacob Dreesen (jdreesen)
- - Konstantin Myakshin (koc)
- Jérémy DERUSSÉ (jderusse)
- Vladimir Reznichenko (kalessil)
- Baptiste Clavié (talus)
- Fabien Pennequin (fabienpennequin)
- Gordon Franke (gimler)
+ - David Buchmann (dbu)
- Tomáš Votruba (tomas_votruba)
- Jáchym Toušek
- Robert Schönthal (digitalkaoz)
- Florian Lonqueu-Brochard (florianlb)
- Eric GELOEN (gelo)
- Stefano Sala (stefano.sala)
- - David Buchmann (dbu)
- Juti Noppornpitak (shiroyuki)
- Tigran Azatyan (tigranazatyan)
- Sebastian Hörl (blogsh)
@@ -127,26 +127,27 @@ Symfony is the result of the work of many people who made the code better
- Andréia Bohner (andreia)
- Rafael Dohms (rdohms)
- Arnaud Kleinpeter (nanocom)
+ - Joel Wurtz (brouznouf)
- Philipp Wahala (hifi)
- Richard Shank (iampersistent)
- Thomas Rabaix (rande)
- Vincent AUBERT (vincent)
- - Joel Wurtz (brouznouf)
- Mikael Pajunen
- Clemens Tolboom
- Helmer Aaviksoo
- Hiromi Hishida (77web)
+ - Richard van Laak (rvanlaak)
- Matthieu Ouellette-Vachon (maoueh)
- Michał Pipa (michal.pipa)
- Amal Raghav (kertz)
- Jonathan Ingram (jonathaningram)
+ - Titouan Galopin (tgalopin)
- Artur Kotyrba
- Rouven Weßling (realityking)
- Warnar Boekkooi (boekkooi)
- Dmitrii Chekaliuk (lazyhammer)
- Clément JOBEILI (dator)
- Daniel Wehner
- - Richard van Laak (rvanlaak)
- Possum
- Dorian Villet (gnutix)
- Javier Spagnoletti (phansys)
@@ -183,7 +184,6 @@ Symfony is the result of the work of many people who made the code better
- Sergey Linnik (linniksa)
- Michaël Perrin (michael.perrin)
- Marcel Beerta (mazen)
- - Titouan Galopin (tgalopin)
- Loïc Faugeron
- Jannik Zschiesche (apfelbox)
- Marco Pivetta (ocramius)
@@ -209,6 +209,7 @@ Symfony is the result of the work of many people who made the code better
- Katsuhiro OGAWA
- Alif Rachmawadi
- Kristen Gilden (kgilden)
+ - Dawid Nowak
- Pierre-Yves LEBECQ (pylebecq)
- Jakub Kucharovic (jkucharovic)
- Eugene Leonovich (rybakit)
@@ -226,6 +227,7 @@ Symfony is the result of the work of many people who made the code better
- Nikita Konstantinov
- Wodor Wodorski
- Thomas Lallement (raziel057)
+ - Matthieu Napoli (mnapoli)
- Beau Simensen (simensen)
- Michael Hirschler (mvhirsch)
- Robert Kiss (kepten)
@@ -237,7 +239,7 @@ Symfony is the result of the work of many people who made the code better
- Peter Kruithof (pkruithof)
- Michael Holm (hollo)
- Marc Weistroff (futurecat)
- - Dawid Nowak
+ - Hidde Wieringa (hiddewie)
- Chris Smith (cs278)
- Florian Klein (docteurklein)
- Manuel Kiessling (manuelkiessling)
@@ -272,12 +274,12 @@ Symfony is the result of the work of many people who made the code better
- janschoenherr
- Thomas Schulz (king2500)
- Berny Cantos (xphere81)
+ - Teoh Han Hui (teohhanhui)
- Ricard Clau (ricardclau)
- Mark Challoner (markchalloner)
- Gregor Harlan (gharlan)
- Gennady Telegin (gtelegin)
- Giorgio Premi
- - Matthieu Napoli (mnapoli)
- Ben Davies (bendavies)
- Erin Millard
- Artur Melo (restless)
@@ -296,6 +298,8 @@ Symfony is the result of the work of many people who made the code better
- Yaroslav Kiliba
- Terje Bråten
- Robbert Klarenbeek (robbertkl)
+ - Alessandro Chitolina
+ - JhonnyL
- hossein zolfi (ocean)
- Clément Gautier (clementgautier)
- Eduardo Gulias (egulias)
@@ -321,6 +325,7 @@ Symfony is the result of the work of many people who made the code better
- Kai
- Lee Rowlands
- Maximilian Reichel (phramz)
+ - Loick Piera (pyrech)
- Karoly Negyesi (chx)
- Ivan Kurnosov
- Xavier HAUSHERR
@@ -351,6 +356,7 @@ Symfony is the result of the work of many people who made the code better
- Niklas Fiekas
- Markus Bachmann (baachi)
- lancergr
+ - Mihai Stancu
- Olivier Dolbeau (odolbeau)
- Jan Rosier (rosier)
- vagrant
@@ -367,7 +373,6 @@ Symfony is the result of the work of many people who made the code better
- cedric lombardot (cedriclombardot)
- Jonas Flodén (flojon)
- Christian Schmidt
- - Hidde Wieringa (hiddewie)
- Marek Štípek (maryo)
- Marcin Sikoń (marphi)
- Dominik Zogg (dominik.zogg)
@@ -380,7 +385,6 @@ Symfony is the result of the work of many people who made the code better
- Zander Baldwin
- Adam Harvey
- Alex Bakhturin
- - Alessandro Chitolina
- boombatower
- Fabrice Bernhard (fabriceb)
- Jérôme Macias (jeromemacias)
@@ -425,12 +429,13 @@ Symfony is the result of the work of many people who made the code better
- Norbert Orzechowicz (norzechowicz)
- Denis Charrier (brucewouaigne)
- Matthijs van den Bos (matthijs)
- - Loick Piera (pyrech)
- Lenard Palko
- Nils Adermann (naderman)
- Gábor Fási
- DUPUCH (bdupuch)
- Benjamin Leveque (benji07)
+ - Nate (frickenate)
+ - jhonnyL
- sasezaki
- Dawid Pakuła (zulusx)
- Florian Rey (nervo)
@@ -453,7 +458,9 @@ Symfony is the result of the work of many people who made the code better
- Marcin Chyłek (songoq)
- Ned Schwartz
- Ziumin
+ - Jeremy Benoist
- Lenar Lõhmus
+ - Krzysztof Piasecki (krzysztek)
- Benjamin Laugueux (yzalis)
- Zach Badgett (zachbadgett)
- Aurélien Fredouelle
@@ -492,12 +499,13 @@ Symfony is the result of the work of many people who made the code better
- Javier López (loalf)
- Reinier Kip
- Dustin Dobervich (dustin10)
+ - Anne-Sophie Bachelard (annesophie)
- Sebastian Marek (proofek)
- Erkhembayar Gantulga (erheme318)
- Michal Trojanowski
- - Mihai Stancu
- David Fuhr
- Kamil Kokot (pamil)
+ - Aurimas Niekis (gcds)
- Max Grigorian (maxakawizard)
- Rostyslav Kinash
- Maciej Malarz (malarzm)
@@ -521,11 +529,13 @@ Symfony is the result of the work of many people who made the code better
- Arturs Vonda
- Sascha Grossenbacher
- Szijarto Tamas
+ - Catalin Dan
- Stephan Vock
- Benjamin Zikarsky (bzikarsky)
- Simon Schick (simonsimcity)
- redstar504
- Tristan Roussel
+ - Cameron Porter
- Hossein Bukhamsin
- Disparity
- origaminal
@@ -579,6 +589,7 @@ Symfony is the result of the work of many people who made the code better
- Romain Gautier (mykiwi)
- Yosmany Garcia (yosmanyga)
- Wouter de Wild
+ - Miroslav Sustek
- Degory Valentine
- Benoit Lévêque (benoit_leveque)
- Jeroen Fiege (fieg)
@@ -587,6 +598,8 @@ Symfony is the result of the work of many people who made the code better
- possum
- Denis Zunke (donalberto)
- Olivier Maisonneuve (olineuve)
+ - Michele Locati
+ - Masterklavi
- Francis Turmel (fturmel)
- cgonzalez
- Ben
@@ -598,6 +611,7 @@ Symfony is the result of the work of many people who made the code better
- Adrien Lucas (adrienlucas)
- James Michael DuPont
- Tom Klingenberg
+ - Jhonny Lidfors (jhonne)
- Christopher Hall (mythmakr)
- Paul Kamer (pkamer)
- Rafał Wrzeszcz (rafalwrzeszcz)
@@ -607,6 +621,7 @@ Symfony is the result of the work of many people who made the code better
- Pierre Vanliefland (pvanliefland)
- Sofiane HADDAG (sofhad)
- frost-nzcr4
+ - Arjen van der Meijden
- Abhoryo
- Fabian Vogler (fabian)
- Korvin Szanto
@@ -614,6 +629,7 @@ Symfony is the result of the work of many people who made the code better
- Maksim Kotlyar (makasim)
- Neil Ferreira
- Dmitry Parnas (parnas)
+ - Théo FIDRY (theofidry)
- Paul LE CORRE
- DQNEO
- Emanuele Iannone
@@ -670,10 +686,8 @@ Symfony is the result of the work of many people who made the code better
- omerida
- Gábor Tóth
- Daniel Cestari
- - Jeremy Benoist
- David Lima
- Jérôme Vasseur
- - Krzysztof Piasecki (krzysztek)
- Brunet Laurent (lbrunet)
- Magnus Nordlander (magnusnordlander)
- Mikhail Yurasov (mym)
@@ -715,7 +729,6 @@ Symfony is the result of the work of many people who made the code better
- fabios
- Sander Coolen (scoolen)
- Nicolas Le Goff (nlegoff)
- - Anne-Sophie Bachelard (annesophie)
- Manuele Menozzi
- Anton Babenko (antonbabenko)
- Irmantas Šiupšinskas (irmantas)
@@ -723,6 +736,7 @@ Symfony is the result of the work of many people who made the code better
- Zachary Tong (polyfractal)
- Hryhorii Hrebiniuk
- mcfedr (mcfedr)
+ - hamza
- dantleech
- Xavier Leune
- Tero Alén (tero)
@@ -735,6 +749,7 @@ Symfony is the result of the work of many people who made the code better
- Sortex
- chispita
- Wojciech Sznapka
+ - Ariel J. Birnbaum
- Arjan Keeman
- Máximo Cuadros (mcuadros)
- tamirvs
@@ -750,7 +765,6 @@ Symfony is the result of the work of many people who made the code better
- Ville Mattila
- Boris Vujicic (boris.vujicic)
- Max Beutel
- - Catalin Dan
- nacho
- Piotr Antosik (antek88)
- Artem Lopata
@@ -783,6 +797,7 @@ Symfony is the result of the work of many people who made the code better
- Benoit Garret
- Thomas Royer (cydonia7)
- DerManoMann
+ - Jhonny Lidfors (jhonny)
- Julien Bianchi (jubianchi)
- Marcin Chwedziak
- Roland Franssen (ro0)
@@ -796,7 +811,6 @@ Symfony is the result of the work of many people who made the code better
- rpg600
- Péter Buri (burci)
- Davide Borsatto (davide.borsatto)
- - Teoh Han Hui (teohhanhui)
- kaiwa
- Charles Sanquer (csanquer)
- Albert Ganiev (helios-ag)
@@ -899,6 +913,7 @@ Symfony is the result of the work of many people who made the code better
- Berat Doğan
- Anthony Ferrara
- Klaas Cuvelier (kcuvelier)
+ - Steve Frécinaux
- ShiraNai7
- Vašek Purchart (vasek-purchart)
- Janusz Jabłoński (yanoosh)
@@ -919,7 +934,6 @@ Symfony is the result of the work of many people who made the code better
- Pete Mitchell (peterjmit)
- Tom Corrigan (tomcorrigan)
- Martin Pärtel
- - Miroslav Sustek
- Patrick Daley (padrig)
- Xavier Briand (xavierbriand)
- Max Summe
@@ -943,7 +957,6 @@ Symfony is the result of the work of many people who made the code better
- Nathaniel Catchpole
- Jose Gonzalez
- Adrien Samson (adriensamson)
- - Aurimas Niekis (gcds)
- Samuel Gordalina (gordalina)
- Max Romanovsky (maxromanovsky)
- Mathieu Morlon
@@ -960,6 +973,7 @@ Symfony is the result of the work of many people who made the code better
- r1pp3rj4ck
- Robert Queck
- mlively
+ - Amine Matmati
- Fabian Steiner (fabstei)
- Klaus Silveira (klaussilveira)
- Thomas Chmielowiec (chmielot)
@@ -984,6 +998,7 @@ Symfony is the result of the work of many people who made the code better
- Benjamin Bender
- Konrad Mohrfeldt
- Lance Chen
+ - Andrey Astakhov (aast)
- kor3k kor3k (kor3k)
- Stelian Mocanita (stelian)
- Flavian (2much)
@@ -1010,6 +1025,7 @@ Symfony is the result of the work of many people who made the code better
- Jakub Simon
- Bouke Haarsma
- Martin Eckhardt
+ - natechicago
- Jonathan Poston
- Adrian Olek (adrianolek)
- Przemysław Piechota (kibao)
@@ -1032,12 +1048,13 @@ Symfony is the result of the work of many people who made the code better
- Josef Cech
- Arnau González (arnaugm)
- Simon Bouland (bouland)
- - Nate (frickenate)
- Matthew Foster (mfoster)
- Paul Seiffert (seiffert)
- Vasily Khayrulin (sirian)
- Stefan Koopmanschap (skoop)
- Stefan Hüsges (tronsha)
+ - Dan Blows
+ - Matt Wells
- stloyd
- Chris Tickner
- Andrew Coulton
@@ -1051,6 +1068,7 @@ Symfony is the result of the work of many people who made the code better
- Andreas
- Thomas Chmielowiec
- Andrey Ryaguzov
+ - Peter Bex
- Manatsawin Hanmongkolchai
- Gunther Konig
- Maciej Schmidt
@@ -1081,10 +1099,12 @@ Symfony is the result of the work of many people who made the code better
- Aarón Nieves Fernández
- Mike Meier
- Kirill Saksin
+ - Koalabaerchen
- michalmarcinkowski
- Warwick
- Chris
- JakeFr
+ - Simon Sargeant
- efeen
- Michał Dąbrowski (defrag)
- Nathanael Noblet (gnat)
@@ -1118,10 +1138,12 @@ Symfony is the result of the work of many people who made the code better
- Jason Woods
- dened
- Dmitry Korotovsky
+ - Michael van Tricht
- Sam Ward
- Walther Lalk
- Adam
- devel
+ - taiiiraaa
- Trevor Suarez
- gedrox
- dropfen
@@ -1229,6 +1251,7 @@ Symfony is the result of the work of many people who made the code better
- Muriel (metalmumu)
- Michael Pohlers (mick_the_big)
- Cayetano Soriano Gallego (neoshadybeat)
+ - Patrick McDougle (patrick-mcdougle)
- Pablo Monterde Perez (plebs)
- Jimmy Leger (redpanda)
- Cyrille Jouineau (tuxosaurus)
@@ -1269,6 +1292,7 @@ Symfony is the result of the work of many people who made the code better
- Myke79
- Brian Debuire
- Piers Warmers
+ - Guilliam Xavier
- Sylvain Lorinet
- klyk50
- Andreas Lutro
@@ -1332,6 +1356,7 @@ Symfony is the result of the work of many people who made the code better
- Norman Soetbeer
- zorn
- Benjamin Long
+ - Robin Chalas
- Matt Janssen
- Peter Gribanov
- kwiateusz
@@ -1382,6 +1407,7 @@ Symfony is the result of the work of many people who made the code better
- Adel ELHAIBA (eadel)
- Damián Nohales (eagleoneraptor)
- Elliot Anderson (elliot)
+ - Sergey Zolotov (enleur)
- Fabien D. (fabd)
- Sorin Gitlan (forapathy)
- Yohan Giarelli (frequence-web)
@@ -1395,6 +1421,7 @@ Symfony is the result of the work of many people who made the code better
- Jose Manuel Gonzalez (jgonzalez)
- Jorge Maiden (jorgemaiden)
- Justin Rainbow (jrainbow)
+ - Juan Luis (juanlugb)
- JuntaTom (juntatom)
- Ismail Faizi (kanafghan)
- Sébastien Armand (khepin)
@@ -1439,6 +1466,7 @@ Symfony is the result of the work of many people who made the code better
- Víctor Mateo (victormateo)
- Vincent (vincent1870)
- Eugene Babushkin (warl)
+ - Wouter Sioen (wouter_sioen)
- Xavier Amado (xamado)
- Jesper Søndergaard Pedersen (zerrvox)
- Florent Cailhol
@@ -1451,6 +1479,8 @@ Symfony is the result of the work of many people who made the code better
- Andreas Streichardt
- smokeybear87
- Gustavo Adrian
+ - Kevin Weber
+ - Sergey Fedotov
- Michael
- fh-github@fholzhauer.de
- Mark Topper
diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json
index 500a9f57c43b1..433e0e103ff4c 100644
--- a/src/Symfony/Bridge/Monolog/composer.json
+++ b/src/Symfony/Bridge/Monolog/composer.json
@@ -24,6 +24,9 @@
"symfony/console": "~2.4|~3.0.0",
"symfony/event-dispatcher": "~2.2|~3.0.0"
},
+ "conflict": {
+ "symfony/http-kernel": ">=3.0"
+ },
"suggest": {
"symfony/http-kernel": "For using the debugging handlers together with the response life cycle of the HTTP kernel.",
"symfony/console": "For the possibility to show log messages in console commands depending on verbosity settings. You need version ~2.3 of the console for it.",
diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php
index ae13d543b0e1e..3f3c577b846df 100644
--- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php
+++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php
@@ -33,6 +33,8 @@ public function testCreateProxyServiceWithRuntimeInstantiator()
$builder->register('foo1', 'ProxyManagerBridgeFooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php');
$builder->getDefinition('foo1')->setLazy(true);
+ $builder->compile();
+
/* @var $foo1 \ProxyManager\Proxy\LazyLoadingInterface|\ProxyManager\Proxy\ValueHolderInterface */
$foo1 = $builder->get('foo1');
diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php
index d6e0c14da4893..33334e79920c9 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php
@@ -274,6 +274,10 @@ protected function resolveServiceDefinition(ContainerBuilder $builder, $serviceI
return $builder->getAlias($serviceId);
}
+ if ('service_container' === $serviceId) {
+ return $builder;
+ }
+
// the service has been injected in some special way, just return the service
return $builder->get($serviceId);
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php
index 62ebee9121cb4..dca8ffc4839ee 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php
@@ -234,7 +234,6 @@ protected function describeContainerServices(ContainerBuilder $builder, array $o
$alias = $definition;
$tableRows[] = array_merge(array($serviceId, sprintf('alias for "%s"', $alias)), $tagsCount ? array_fill(0, $tagsCount, '') : array());
} else {
- // we have no information (happens with "service_container")
$tableRows[] = array_merge(array($serviceId, get_class($definition)), $tagsCount ? array_fill(0, $tagsCount, '') : array());
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
index 4cef7df71401a..e4457d4608451 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
@@ -105,7 +105,7 @@ private function completeDefinition($id, Definition $definition)
$this->populateAvailableTypes();
}
- if (isset($this->types[$typeHint->name])) {
+ if (isset($this->types[$typeHint->name]) && !isset($this->notGuessableTypes[$typeHint->name])) {
$value = new Reference($this->types[$typeHint->name]);
} else {
try {
@@ -190,22 +190,26 @@ private function populateAvailableType($id, Definition $definition)
*/
private function set($type, $id)
{
- if (isset($this->definedTypes[$type]) || isset($this->notGuessableTypes[$type])) {
+ if (isset($this->definedTypes[$type])) {
return;
}
- if (isset($this->types[$type])) {
- if ($this->types[$type] === $id) {
- return;
- }
+ if (!isset($this->types[$type])) {
+ $this->types[$type] = $id;
- unset($this->types[$type]);
- $this->notGuessableTypes[$type] = true;
+ return;
+ }
+ if ($this->types[$type] === $id) {
return;
}
- $this->types[$type] = $id;
+ if (!isset($this->notGuessableTypes[$type])) {
+ $this->notGuessableTypes[$type] = true;
+ $this->types[$type] = (array) $this->types[$type];
+ }
+
+ $this->types[$type][] = $id;
}
/**
@@ -220,8 +224,14 @@ private function set($type, $id)
*/
private function createAutowiredDefinition(\ReflectionClass $typeHint, $id)
{
- if (isset($this->notGuessableTypes[$typeHint->name]) || !$typeHint->isInstantiable()) {
- throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s".', $typeHint->name, $id));
+ if (isset($this->notGuessableTypes[$typeHint->name])) {
+ throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Several services implementing this type have been declared: "%s".', $typeHint->name, $id, implode('", "', $this->types[$typeHint->name])));
+ }
+
+ $noAvailableDefinitionMessage = sprintf('Unable to autowire argument of type "%s" for the service "%s". This type cannot be instantiated automatically and no service implementing this type is declared.', $typeHint->name, $id);
+
+ if (!$typeHint->isInstantiable()) {
+ throw new RuntimeException($noAvailableDefinitionMessage);
}
$argumentId = sprintf('autowired.%s', $typeHint->name);
@@ -230,7 +240,12 @@ private function createAutowiredDefinition(\ReflectionClass $typeHint, $id)
$argumentDefinition->setPublic(false);
$this->populateAvailableType($argumentId, $argumentDefinition);
- $this->completeDefinition($argumentId, $argumentDefinition);
+
+ try {
+ $this->completeDefinition($argumentId, $argumentDefinition);
+ } catch (RuntimeException $e) {
+ throw new RuntimeException($noAvailableDefinitionMessage, 0, $e);
+ }
return new Reference($argumentId);
}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
index e654819c0edd1..55f1a24513dfc 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
@@ -174,7 +174,7 @@ private function resolveDefinition(ContainerBuilder $container, DefinitionDecora
if (null === $decoratedService) {
$def->setDecoratedService($decoratedService);
} else {
- $def->setDecoratedService($decoratedService[0], $decoratedService[1]);
+ $def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2]);
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 8da4bcd8e2b2a..300a19ffcfdb9 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -315,6 +315,10 @@ private function processAnonymousServices(\DOMDocument $xml, $file)
if ($services = $this->getChildren($node, 'service')) {
$definitions[$id] = array($services[0], $file, false);
$services[0]->setAttribute('id', $id);
+
+ // anonymous services are always private
+ // we could not use the constant false here, because of XML parsing
+ $services[0]->setAttribute('public', 'false');
}
}
}
@@ -334,9 +338,6 @@ private function processAnonymousServices(\DOMDocument $xml, $file)
foreach ($definitions as $id => $def) {
list($domElement, $file, $wild) = $def;
- // anonymous services are always private
- // we could not use the constant false here, because of XML parsing
- $domElement->setAttribute('public', 'false');
if (null !== $definition = $this->parseDefinition($domElement, $file)) {
$this->container->setDefinition($id, $definition);
diff --git a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
index 382fca18519a3..71a95758eec96 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
+++ b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
@@ -24,14 +24,28 @@
]]>
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass());
}
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
+ * @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a". This type cannot be instantiated automatically and no service implementing this type is declared.
+ */
+ public function testCreateNonInstanciable()
+ {
+ $container = new ContainerBuilder();
+
+ $aDefinition = $container->register('a', __NAMESPACE__.'\CannotBeAutowired');
+ $aDefinition->setAutowired(true);
+
+ $pass = new AutowirePass();
+ $pass->process($container);
+ }
+
public function testResolveParameter()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
index 15de79042ccd9..c56d199b2ffbe 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
@@ -276,10 +276,12 @@ public function testSetDecoratedServiceOnServiceHasParent()
$container->register('parent', 'stdClass');
$container->setDefinition('child1', new DefinitionDecorator('parent'))
- ->setDecoratedService('foo', 'foo_inner')
+ ->setDecoratedService('foo', 'foo_inner', 5)
;
- $this->assertEquals(array('foo', 'foo_inner', 0), $container->getDefinition('child1')->getDecoratedService());
+ $this->process($container);
+
+ $this->assertEquals(array('foo', 'foo_inner', 5), $container->getDefinition('child1')->getDecoratedService());
}
public function testDecoratedServiceCopiesDeprecatedStatusFromParent()
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
index b0f3535308fdd..5d7b3f0fac1e9 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
@@ -200,7 +200,7 @@ public function testLoadAnonymousServices()
$service = $container->getDefinition($id);
}
$this->assertEquals('BizClass', $service->getClass(), '->load() uses the same configuration as for the anonymous ones');
- $this->assertFalse($service->isPublic());
+ $this->assertTrue($service->isPublic());
// anonymous services are shared when using decoration definitions
$container->compile();
diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json
index 619c9e6304864..db30f65a710a1 100644
--- a/src/Symfony/Component/DependencyInjection/composer.json
+++ b/src/Symfony/Component/DependencyInjection/composer.json
@@ -29,6 +29,7 @@
"suggest": {
"symfony/yaml": "",
"symfony/config": "",
+ "symfony/expression-language": "For using expressions in service container configuration",
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them"
},
"autoload": {
diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
index e729eeb103715..9b460f55f6ac3 100644
--- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
+++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
@@ -104,6 +104,10 @@ public function getListeners($eventName = null)
*/
public function getListenerPriority($eventName, $listener)
{
+ if (!method_exists($this->dispatcher, 'getListenerPriority')) {
+ return 0;
+ }
+
return $this->dispatcher->getListenerPriority($eventName, $listener);
}
diff --git a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
index 2dd8292a1b3e6..dd54e73b34f24 100644
--- a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
+++ b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
@@ -73,6 +73,16 @@ public function testGetListenerPriority()
$this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0]));
}
+ public function testGetListenerPriorityReturnsZeroWhenWrappedMethodDoesNotExist()
+ {
+ $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
+ $traceableEventDispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
+ $traceableEventDispatcher->addListener('foo', function () {}, 123);
+ $listeners = $traceableEventDispatcher->getListeners('foo');
+
+ $this->assertSame(0, $traceableEventDispatcher->getListenerPriority('foo', $listeners[0]));
+ }
+
public function testAddRemoveSubscriber()
{
$dispatcher = new EventDispatcher();
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index cfb6781f394da..a95bd97ee3a21 100644
--- a/src/Symfony/Component/HttpKernel/Kernel.php
+++ b/src/Symfony/Component/HttpKernel/Kernel.php
@@ -59,11 +59,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $startTime;
protected $loadClassCache;
- const VERSION = '2.8.5';
- const VERSION_ID = 20805;
+ const VERSION = '2.8.6';
+ const VERSION_ID = 20806;
const MAJOR_VERSION = 2;
const MINOR_VERSION = 8;
- const RELEASE_VERSION = 5;
+ const RELEASE_VERSION = 6;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '11/2018';
diff --git a/src/Symfony/Component/HttpKernel/KernelEvents.php b/src/Symfony/Component/HttpKernel/KernelEvents.php
index 8768979da6bd4..abbbfcc0048b9 100644
--- a/src/Symfony/Component/HttpKernel/KernelEvents.php
+++ b/src/Symfony/Component/HttpKernel/KernelEvents.php
@@ -108,6 +108,10 @@ final class KernelEvents
*
* This event allows you to reset the global and environmental state of
* the application, when it was changed during the request.
+ * The event listener method receives a
+ * Symfony\Component\HttpKernel\Event\FinishRequestEvent instance.
+ *
+ * @Event
*
* @var string
*/
diff --git a/src/Symfony/Component/OptionsResolver/README.md b/src/Symfony/Component/OptionsResolver/README.md
index 5768f68e7ff7d..245e69b548d6d 100644
--- a/src/Symfony/Component/OptionsResolver/README.md
+++ b/src/Symfony/Component/OptionsResolver/README.md
@@ -1,7 +1,7 @@
OptionsResolver Component
=========================
-The OptionsResolver component is `array_replace on steroids. It allows you to
+The OptionsResolver component is `array_replace` on steroids. It allows you to
create an options system with required options, defaults, validation (type,
value), normalization and more.
diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
index 9b7262d237595..63454a5b45319 100644
--- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
+++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
@@ -40,7 +40,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
/**
* @internal
*
- * @var array[]
+ * @var string[]
*/
public static $arrayMutatorPrefixes = array('add', 'remove');
diff --git a/src/Symfony/Component/Routing/Generator/UrlGenerator.php b/src/Symfony/Component/Routing/Generator/UrlGenerator.php
index d139e40857131..4a6b742ea0a9c 100644
--- a/src/Symfony/Component/Routing/Generator/UrlGenerator.php
+++ b/src/Symfony/Component/Routing/Generator/UrlGenerator.php
@@ -75,11 +75,6 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
'%7C' => '|',
);
- /**
- * @var string This regexp matches all characters that are not or should not be encoded by rawurlencode (see list in array above).
- */
- private $urlEncodingSkipRegexp = '#[^-.~a-zA-Z0-9_/@:;,=+!*|]#';
-
/**
* Constructor.
*
@@ -201,21 +196,19 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa
if ('' === $url) {
$url = '/';
- } elseif (preg_match($this->urlEncodingSkipRegexp, $url)) {
- // the context base URL is already encoded (see Symfony\Component\HttpFoundation\Request)
- $url = strtr(rawurlencode($url), $this->decodedChars);
}
+ // the contexts base URL is already encoded (see Symfony\Component\HttpFoundation\Request)
+ $url = strtr(rawurlencode($url), $this->decodedChars);
+
// the path segments "." and ".." are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3
// so we need to encode them as they are not used for this purpose here
// otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route
- if (false !== strpos($url, '/.')) {
- $url = strtr($url, array('/../' => '/%2E%2E/', '/./' => '/%2E/'));
- if ('/..' === substr($url, -3)) {
- $url = substr($url, 0, -2).'%2E%2E';
- } elseif ('/.' === substr($url, -2)) {
- $url = substr($url, 0, -1).'%2E';
- }
+ $url = strtr($url, array('/../' => '/%2E%2E/', '/./' => '/%2E/'));
+ if ('/..' === substr($url, -3)) {
+ $url = substr($url, 0, -2).'%2E%2E';
+ } elseif ('/.' === substr($url, -2)) {
+ $url = substr($url, 0, -1).'%2E';
}
$schemeAuthority = '';
@@ -292,7 +285,7 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa
if ($extra && $query = http_build_query($extra, '', '&')) {
// "/" and "?" can be left decoded for better user experience, see
// http://tools.ietf.org/html/rfc3986#section-3.4
- $url .= '?'.(false === strpos($query, '%2F') ? $query : strtr($query, array('%2F' => '/')));
+ $url .= '?'.strtr($query, array('%2F' => '/'));
}
return $url;
diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php
index adc42ef3b38f5..e887f99af7963 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php
@@ -73,6 +73,10 @@ protected function checkAuthentication(UserInterface $user, UsernamePasswordToke
$username = $token->getUsername();
$password = $token->getCredentials();
+ if ('' === $password) {
+ throw new BadCredentialsException('The presented password must not be empty.');
+ }
+
try {
$username = $this->ldap->escape($username, '', LDAP_ESCAPE_DN);
$dn = str_replace('{username}', $username, $this->dnString);
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php
index 22fc611b2a16b..71dea3230783e 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php
@@ -26,7 +26,7 @@ class AnonymousToken extends AbstractToken
* Constructor.
*
* @param string $secret A secret used to make sure the token is created by the app and not by a malicious client
- * @param string $user The user
+ * @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string.
* @param RoleInterface[] $roles An array of roles
*/
public function __construct($secret, $user, array $roles = array())
diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
index 1798203690455..5a3fc95327c08 100644
--- a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
+++ b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php
@@ -26,7 +26,7 @@ class PreAuthenticatedToken extends AbstractToken
/**
* Constructor.
*
- * @param string|object $user The user
+ * @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string.
* @param mixed $credentials The user credentials
* @param string $providerKey The provider key
* @param RoleInterface[]|string[] $roles An array of roles
diff --git a/src/Symfony/Component/Security/Core/AuthenticationEvents.php b/src/Symfony/Component/Security/Core/AuthenticationEvents.php
index 90b714267466c..13bce30768908 100644
--- a/src/Symfony/Component/Security/Core/AuthenticationEvents.php
+++ b/src/Symfony/Component/Security/Core/AuthenticationEvents.php
@@ -20,6 +20,8 @@ final class AuthenticationEvents
* The event listener method receives a
* Symfony\Component\Security\Core\Event\AuthenticationEvent instance.
*
+ * @Event
+ *
* @var string
*/
const AUTHENTICATION_SUCCESS = 'security.authentication.success';
@@ -32,6 +34,8 @@ final class AuthenticationEvents
* Symfony\Component\Security\Core\Event\AuthenticationFailureEvent
* instance.
*
+ * @Event
+ *
* @var string
*/
const AUTHENTICATION_FAILURE = 'security.authentication.failure';
diff --git a/src/Symfony/Component/Security/Core/Security.php b/src/Symfony/Component/Security/Core/Security.php
index 14d32f81482e5..84cc77dcf7f32 100644
--- a/src/Symfony/Component/Security/Core/Security.php
+++ b/src/Symfony/Component/Security/Core/Security.php
@@ -21,4 +21,5 @@ final class Security
const ACCESS_DENIED_ERROR = '_security.403_error';
const AUTHENTICATION_ERROR = '_security.last_error';
const LAST_USERNAME = '_security.last_username';
+ const MAX_USERNAME_LENGTH = 4096;
}
diff --git a/src/Symfony/Component/Security/Core/SecurityContextInterface.php b/src/Symfony/Component/Security/Core/SecurityContextInterface.php
index 2a06ca426a487..73edd2383573b 100644
--- a/src/Symfony/Component/Security/Core/SecurityContextInterface.php
+++ b/src/Symfony/Component/Security/Core/SecurityContextInterface.php
@@ -26,4 +26,5 @@ interface SecurityContextInterface extends TokenStorageInterface, AuthorizationC
const ACCESS_DENIED_ERROR = Security::ACCESS_DENIED_ERROR;
const AUTHENTICATION_ERROR = Security::AUTHENTICATION_ERROR;
const LAST_USERNAME = Security::LAST_USERNAME;
+ const MAX_USERNAME_LENGTH = Security::MAX_USERNAME_LENGTH;
}
diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php
index 844bceff019cb..fbb4d733a93c4 100644
--- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php
+++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php
@@ -21,6 +21,23 @@
*/
class LdapBindAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
{
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedExceptionMessage The presented password must not be empty.
+ */
+ public function testEmptyPasswordShouldThrowAnException()
+ {
+ $userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
+ $ldap = $this->getMock('Symfony\Component\Ldap\LdapClientInterface');
+ $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
+
+ $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap);
+ $reflection = new \ReflectionMethod($provider, 'checkAuthentication');
+ $reflection->setAccessible(true);
+
+ $reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', '', 'key'));
+ }
+
/**
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
* @expectedExceptionMessage The presented password is invalid.
@@ -40,7 +57,7 @@ public function testBindFailureShouldThrowAnException()
$reflection = new \ReflectionMethod($provider, 'checkAuthentication');
$reflection->setAccessible(true);
- $reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', '', 'key'));
+ $reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', 'bar', 'key'));
}
public function testRetrieveUser()
diff --git a/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php
index 436376360be3a..331d018471de8 100644
--- a/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php
@@ -24,6 +24,7 @@
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\ParameterBagUtils;
@@ -127,6 +128,10 @@ protected function attemptAuthentication(Request $request)
$password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
}
+ if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
+ throw new BadCredentialsException('Invalid username.');
+ }
+
$request->getSession()->set(Security::LAST_USERNAME, $username);
$token = $this->simpleAuthenticator->createToken($request, $username, $password, $this->providerKey);
diff --git a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
index 24c3ca6509c26..866d0c32d9c8b 100644
--- a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
@@ -25,6 +25,7 @@
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
@@ -102,6 +103,10 @@ protected function attemptAuthentication(Request $request)
$password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
}
+ if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
+ throw new BadCredentialsException('Invalid username.');
+ }
+
$request->getSession()->set(Security::LAST_USERNAME, $username);
return $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $password, $this->providerKey));
diff --git a/src/Symfony/Component/Security/Tests/Http/Firewall/UsernamePasswordFormAuthenticationListenerTest.php b/src/Symfony/Component/Security/Tests/Http/Firewall/UsernamePasswordFormAuthenticationListenerTest.php
new file mode 100644
index 0000000000000..b7c6ab9db5752
--- /dev/null
+++ b/src/Symfony/Component/Security/Tests/Http/Firewall/UsernamePasswordFormAuthenticationListenerTest.php
@@ -0,0 +1,78 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Tests\Http\Firewall;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener;
+use Symfony\Component\Security\Core\SecurityContextInterface;
+
+class UsernamePasswordFormAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getUsernameForLength
+ */
+ public function testHandleWhenUsernameLength($username, $ok)
+ {
+ $request = Request::create('/login_check', 'POST', array('_username' => $username));
+ $request->setSession($this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface'));
+
+ $httpUtils = $this->getMock('Symfony\Component\Security\Http\HttpUtils');
+ $httpUtils
+ ->expects($this->any())
+ ->method('checkRequestPath')
+ ->will($this->returnValue(true))
+ ;
+
+ $failureHandler = $this->getMock('Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface');
+ $failureHandler
+ ->expects($ok ? $this->never() : $this->once())
+ ->method('onAuthenticationFailure')
+ ->will($this->returnValue(new Response()))
+ ;
+
+ $authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager')->disableOriginalConstructor()->getMock();
+ $authenticationManager
+ ->expects($ok ? $this->once() : $this->never())
+ ->method('authenticate')
+ ->will($this->returnValue(new Response()))
+ ;
+
+ $listener = new UsernamePasswordFormAuthenticationListener(
+ $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'),
+ $authenticationManager,
+ $this->getMock('Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface'),
+ $httpUtils,
+ 'TheProviderKey',
+ $this->getMock('Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface'),
+ $failureHandler,
+ array('require_previous_session' => false)
+ );
+
+ $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false);
+ $event
+ ->expects($this->any())
+ ->method('getRequest')
+ ->will($this->returnValue($request))
+ ;
+
+ $listener->handle($event);
+ }
+
+ public function getUsernameForLength()
+ {
+ return array(
+ array(str_repeat('x', SecurityContextInterface::MAX_USERNAME_LENGTH + 1), false),
+ array(str_repeat('x', SecurityContextInterface::MAX_USERNAME_LENGTH - 1), true),
+ );
+ }
+}