Merge branch '2.6' into 2.7

* 2.6: (24 commits)
  [HttpKernel] Embed the original exception as previous to bounced exceptions
  [Enhancement] netbeans - force interactive shell when limited detection
  [FrameworkBundle] fixes displaying of deprecation notices.
  Revert "Added missing changelog entry"
  [Debug] Tweak docblocks
  [Debug] Rework a bit the PHP doc
  Added missing changelog entry
  [StringUtil] Fixed singularification of 'movies'
  [Debug] Renamed "context" key to "scope_vars" to avoid any ambiguity
  Fix some phpdocs for Twig extensions & templating helpers
  [Debug] Made code in ErrorHandler easier to read
  Use specialized config methods instead of the generic ifTrue() method
  Fix the AJAX profiling
  bumped Symfony version to 2.6.7
  updated VERSION for 2.6.6
  updated CHANGELOG for 2.6.6
  Safe escaping of fragments for eval()
  bumped Symfony version to 2.3.28
  updated VERSION for 2.3.27
  update CONTRIBUTORS for 2.3.27
  ...

Conflicts:
	src/Symfony/Component/Debug/ErrorHandler.php
	src/Symfony/Component/HttpKernel/Kernel.php
This commit is contained in:
Nicolas Grekas 2015-04-03 17:24:01 +02:00
commit 0b39ce2315
35 changed files with 304 additions and 245 deletions

View File

@ -7,6 +7,16 @@ 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 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 To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.3.0...v2.3.1
* 2.3.27 (2015-04-01)
* security #14167 CVE-2015-2308 (nicolas-grekas)
* security #14166 CVE-2015-2309 (neclimdul)
* bug #14010 Replace GET parameters when changed in form (WouterJ)
* bug #13991 [Dependency Injection] Improve PhpDumper Performance for huge Containers (BattleRattle)
* bug #13997 [2.3+][Form][DoctrineBridge] Improved loading of entities and documents (guilhermeblanco)
* bug #13953 [Translation][MoFileLoader] fixed load empty translation. (aitboudad)
* bug #13912 [DependencyInjection] Highest precedence for user parameters (lyrixx)
* 2.3.26 (2015-03-17) * 2.3.26 (2015-03-17)
* bug #13927 Fixing wrong variable name from #13519 (weaverryan) * bug #13927 Fixing wrong variable name from #13519 (weaverryan)

View File

@ -7,6 +7,26 @@ in 2.6 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 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.6.0...v2.6.1 To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.6.0...v2.6.1
* 2.6.6 (2015-04-01)
* security #14167 CVE-2015-2308 (nicolas-grekas)
* security #14166 CVE-2015-2309 (neclimdul)
* bug #14126 [VarDumper] Fix toggle action to see source excerpt (nicolas-grekas)
* bug #14114 [VarDumper] Fix dumping references as properties (nicolas-grekas)
* bug #14074 [VarDumper] Fix dumping ThrowingCasterException (nicolas-grekas)
* bug #12948 [Form] [TwigBridge] Bootstrap layout whitespace control (mvar)
* bug #14046 [Security] StringUtils::equals() arguments in RememberMe Cookie based implementation are confused (zerkms)
* bug #14010 Replace GET parameters when changed in form (WouterJ)
* bug #13991 [Dependency Injection] Improve PhpDumper Performance for huge Containers (BattleRattle)
* bug #13886 [FrameworkBundle][debug:config] added support for dynamic configurations... (aitboudad)
* bug #14013 [DependencyInjection] prevent inlining service configurators (xabbuh)
* bug #14012 [DomCrawler] Improve namespace discovery performance (jakzal)
* bug #13997 [2.3+][Form][DoctrineBridge] Improved loading of entities and documents (guilhermeblanco)
* bug #13978 [WebProfilerBundle] Fix javascript toolbar on IE8 (romainneutron)
* bug #13987 [WebProfilerBundle] fixed undefined buttons variable. (aitboudad)
* bug #13953 [Translation][MoFileLoader] fixed load empty translation. (aitboudad)
* bug #13912 [DependencyInjection] Highest precedence for user parameters (lyrixx)
* 2.6.5 (2015-03-17) * 2.6.5 (2015-03-17)
* bug #13944 [HttpKernel] UriSigner::buildUrl - default params for http_build_query (Jakub Simon) * bug #13944 [HttpKernel] UriSigner::buildUrl - default params for http_build_query (Jakub Simon)

View File

@ -11,8 +11,8 @@ Symfony is the result of the work of many people who made the code better
- Jordi Boggiano (seldaek) - Jordi Boggiano (seldaek)
- Johannes S (johannes) - Johannes S (johannes)
- Kris Wallsmith (kriswallsmith) - Kris Wallsmith (kriswallsmith)
- Christophe Coevoet (stof)
- Nicolas Grekas (nicolas-grekas) - Nicolas Grekas (nicolas-grekas)
- Christophe Coevoet (stof)
- Jakub Zalas (jakubzalas) - Jakub Zalas (jakubzalas)
- Pascal Borreli (pborreli) - Pascal Borreli (pborreli)
- Hugo Hamon (hhamon) - Hugo Hamon (hhamon)
@ -21,9 +21,9 @@ Symfony is the result of the work of many people who made the code better
- Ryan Weaver (weaverryan) - Ryan Weaver (weaverryan)
- Lukas Kahwe Smith (lsmith) - Lukas Kahwe Smith (lsmith)
- Romain Neutron (romain) - Romain Neutron (romain)
- Christian Flothmann (xabbuh)
- Jeremy Mikola (jmikola) - Jeremy Mikola (jmikola)
- Jean-François Simon (jfsimon) - Jean-François Simon (jfsimon)
- Christian Flothmann (xabbuh)
- Benjamin Eberlei (beberlei) - Benjamin Eberlei (beberlei)
- Igor Wiedler (igorw) - Igor Wiedler (igorw)
- Martin Hasoň (hason) - Martin Hasoň (hason)
@ -37,16 +37,16 @@ Symfony is the result of the work of many people who made the code better
- stealth35 (stealth35) - stealth35 (stealth35)
- Alexander Mols (asm89) - Alexander Mols (asm89)
- Bulat Shakirzyanov (avalanche123) - Bulat Shakirzyanov (avalanche123)
- Abdellatif Ait boudad (aitboudad)
- Francis Besset (francisbesset) - Francis Besset (francisbesset)
- Saša Stamenković (umpirsky) - Saša Stamenković (umpirsky)
- Henrik Bjørnskov (henrikbjorn) - Henrik Bjørnskov (henrikbjorn)
- Miha Vrhovnik - Miha Vrhovnik
- Kévin Dunglas (dunglas)
- Sarah Khalil (saro0h)
- Konstantin Kudryashov (everzet) - Konstantin Kudryashov (everzet)
- Bilal Amarni (bamarni) - Bilal Amarni (bamarni)
- Kévin Dunglas (dunglas)
- Florin Patan (florinpatan) - Florin Patan (florinpatan)
- Abdellatif Ait Boudad (aitboudad)
- Sarah Khalil (saro0h)
- Eric Clemmons (ericclemmons) - Eric Clemmons (ericclemmons)
- Andrej Hudec (pulzarraider) - Andrej Hudec (pulzarraider)
- Deni - Deni
@ -61,13 +61,14 @@ Symfony is the result of the work of many people who made the code better
- Daniel Holmes (dholmes) - Daniel Holmes (dholmes)
- Bart van den Burg (burgov) - Bart van den Burg (burgov)
- Jordan Alliot (jalliot) - Jordan Alliot (jalliot)
- Kevin Bond (kbond)
- John Wards (johnwards) - John Wards (johnwards)
- Fran Moreno (franmomu) - Fran Moreno (franmomu)
- Antoine Hérault (herzult)
- Kevin Bond (kbond)
- Toni Uebernickel (havvg)
- Luis Cordova (cordoval) - Luis Cordova (cordoval)
- Antoine Hérault (herzult)
- Toni Uebernickel (havvg)
- Arnaud Le Blanc (arnaud-lb) - Arnaud Le Blanc (arnaud-lb)
- Gábor Egyed (1ed)
- Tim Nagel (merk) - Tim Nagel (merk)
- Brice BERNARD (brikou) - Brice BERNARD (brikou)
- marc.weistroff - marc.weistroff
@ -78,7 +79,6 @@ Symfony is the result of the work of many people who made the code better
- Colin Frei - Colin Frei
- Jérôme Tamarelle (gromnan) - Jérôme Tamarelle (gromnan)
- Adrien Brault (adrienbrault) - Adrien Brault (adrienbrault)
- Gábor Egyed (1ed)
- excelwebzone - excelwebzone
- Jacob Dreesen (jdreesen) - Jacob Dreesen (jdreesen)
- Fabien Pennequin (fabienpennequin) - Fabien Pennequin (fabienpennequin)
@ -93,26 +93,29 @@ Symfony is the result of the work of many people who made the code better
- Daniel Gomes (danielcsgomes) - Daniel Gomes (danielcsgomes)
- Hidenori Goto (hidenorigoto) - Hidenori Goto (hidenorigoto)
- David Buchmann (dbu) - David Buchmann (dbu)
- Guilherme Blanco (guilhermeblanco)
- Jérémy DERUSSÉ (jderusse) - Jérémy DERUSSÉ (jderusse)
- Pablo Godel (pgodel) - Pablo Godel (pgodel)
- Eric GELOEN (gelo) - Eric GELOEN (gelo)
- Jérémie Augustin (jaugustin) - Jérémie Augustin (jaugustin)
- Rafael Dohms (rdohms) - Rafael Dohms (rdohms)
- Guilherme Blanco (guilhermeblanco)
- Tigran Azatyan (tigranazatyan) - Tigran Azatyan (tigranazatyan)
- Javier Eguiluz (javier.eguiluz) - Javier Eguiluz (javier.eguiluz)
- Arnaud Kleinpeter (nanocom) - Arnaud Kleinpeter (nanocom)
- Richard Shank (iampersistent) - Richard Shank (iampersistent)
- Dariusz Ruminski
- Clemens Tolboom - Clemens Tolboom
- Helmer Aaviksoo - Helmer Aaviksoo
- Sebastiaan Stok (sstok) - Sebastiaan Stok (sstok)
- Hiromi Hishida (77web) - Hiromi Hishida (77web)
- Matthieu Ouellette-Vachon (maoueh) - Matthieu Ouellette-Vachon (maoueh)
- Michał Pipa (michal.pipa) - Michał Pipa (michal.pipa)
- Issei Murasawa (issei_m)
- Amal Raghav (kertz) - Amal Raghav (kertz)
- Jonathan Ingram (jonathaningram) - Jonathan Ingram (jonathaningram)
- Artur Kotyrba - Artur Kotyrba
- Rouven Weßling (realityking) - Rouven Weßling (realityking)
- Andréia Bohner (andreia)
- Dmitrii Chekaliuk (lazyhammer) - Dmitrii Chekaliuk (lazyhammer)
- Clément JOBEILI (dator) - Clément JOBEILI (dator)
- Dorian Villet (gnutix) - Dorian Villet (gnutix)
@ -123,14 +126,12 @@ Symfony is the result of the work of many people who made the code better
- Benjamin Dulau (dbenjamin) - Benjamin Dulau (dbenjamin)
- Matthias Pigulla (mpdude) - Matthias Pigulla (mpdude)
- Andreas Hucks (meandmymonkey) - Andreas Hucks (meandmymonkey)
- Andréia Bohner (andreia)
- Noel Guilbert (noel) - Noel Guilbert (noel)
- Joel Wurtz (brouznouf) - Joel Wurtz (brouznouf)
- Charles Sarrazin (csarrazi) - Charles Sarrazin (csarrazi)
- bronze1man - bronze1man
- sun (sun) - sun (sun)
- Larry Garfield (crell) - Larry Garfield (crell)
- Issei Murasawa (issei_m)
- Martin Schuhfuß (usefulthink) - Martin Schuhfuß (usefulthink)
- Thomas Rabaix (rande) - Thomas Rabaix (rande)
- Matthieu Bontemps (mbontemps) - Matthieu Bontemps (mbontemps)
@ -163,6 +164,7 @@ Symfony is the result of the work of many people who made the code better
- Xavier Montaña Carreras (xmontana) - Xavier Montaña Carreras (xmontana)
- Michele Orselli (orso) - Michele Orselli (orso)
- Chris Wilkinson (thewilkybarkid) - Chris Wilkinson (thewilkybarkid)
- Joshua Thijssen
- Xavier Perez - Xavier Perez
- Arjen Brouwer (arjenjb) - Arjen Brouwer (arjenjb)
- Katsuhiro OGAWA - Katsuhiro OGAWA
@ -181,16 +183,18 @@ Symfony is the result of the work of many people who made the code better
- Jeremy Livingston (jeremylivingston) - Jeremy Livingston (jeremylivingston)
- Nikita Konstantinov - Nikita Konstantinov
- Wodor Wodorski - Wodor Wodorski
- Matthieu Auger (matthieuauger)
- julien pauli (jpauli) - julien pauli (jpauli)
- Beau Simensen (simensen) - Beau Simensen (simensen)
- Robert Kiss (kepten) - Robert Kiss (kepten)
- John Kary (johnkary)
- Ruben Gonzalez (rubenrua) - Ruben Gonzalez (rubenrua)
- Kim Hemsø Rasmussen (kimhemsoe) - Kim Hemsø Rasmussen (kimhemsoe)
- Florian Lonqueu-Brochard (florianlb) - Florian Lonqueu-Brochard (florianlb)
- Tom Van Looy (tvlooy) - Tom Van Looy (tvlooy)
- Wouter Van Hecke - Wouter Van Hecke
- Joshua Thijssen
- Peter Kruithof (pkruithof) - Peter Kruithof (pkruithof)
- Vladimir Reznichenko (kalessil)
- Michael Holm (hollo) - Michael Holm (hollo)
- Warnar Boekkooi (boekkooi) - Warnar Boekkooi (boekkooi)
- Marc Weistroff (futurecat) - Marc Weistroff (futurecat)
@ -222,7 +226,6 @@ Symfony is the result of the work of many people who made the code better
- Marco Pivetta (ocramius) - Marco Pivetta (ocramius)
- Ricard Clau (ricardclau) - Ricard Clau (ricardclau)
- Erin Millard - Erin Millard
- John Kary (johnkary)
- Matthew Lewinski (lewinski) - Matthew Lewinski (lewinski)
- alquerci - alquerci
- Francesco Levorato - Francesco Levorato
@ -232,7 +235,6 @@ Symfony is the result of the work of many people who made the code better
- Inal DJAFAR (inalgnu) - Inal DJAFAR (inalgnu)
- Christian Gärtner (dagardner) - Christian Gärtner (dagardner)
- Felix Labrecque - Felix Labrecque
- Vladimir Reznichenko (kalessil)
- Yaroslav Kiliba - Yaroslav Kiliba
- Sébastien Lavoie (lavoiesl) - Sébastien Lavoie (lavoiesl)
- Terje Bråten - Terje Bråten
@ -283,7 +285,6 @@ Symfony is the result of the work of many people who made the code better
- Brian King - Brian King
- Michel Salib (michelsalib) - Michel Salib (michelsalib)
- geoffrey - geoffrey
- Matthieu Auger (matthieuauger)
- Lorenz Schori - Lorenz Schori
- Jeanmonod David (jeanmonod) - Jeanmonod David (jeanmonod)
- Jan Schumann - Jan Schumann
@ -309,7 +310,6 @@ Symfony is the result of the work of many people who made the code better
- Christian Schmidt - Christian Schmidt
- Marcin Sikoń (marphi) - Marcin Sikoń (marphi)
- franek (franek) - franek (franek)
- Dariusz Ruminski
- Adam Harvey - Adam Harvey
- Diego Saint Esteben (dii3g0) - Diego Saint Esteben (dii3g0)
- Alex Bakhturin - Alex Bakhturin
@ -336,6 +336,7 @@ Symfony is the result of the work of many people who made the code better
- mmoreram - mmoreram
- Markus Lanthaler (lanthaler) - Markus Lanthaler (lanthaler)
- Vicent Soria Durá (vicentgodella) - Vicent Soria Durá (vicentgodella)
- Anthony Ferrara
- Ioan Negulescu - Ioan Negulescu
- Jakub Škvára (jskvara) - Jakub Škvára (jskvara)
- Daniel Beyer - Daniel Beyer
@ -343,9 +344,11 @@ Symfony is the result of the work of many people who made the code better
- alexpods - alexpods
- Erik Trapman (eriktrapman) - Erik Trapman (eriktrapman)
- De Cock Xavier (xdecock) - De Cock Xavier (xdecock)
- Scott Arciszewski
- Norbert Orzechowicz (norzechowicz) - Norbert Orzechowicz (norzechowicz)
- Tobias Nyholm (tobias) - Tobias Nyholm (tobias)
- Matthijs van den Bos (matthijs) - Matthijs van den Bos (matthijs)
- Loick Piera (pyrech)
- Lenard Palko - Lenard Palko
- Nils Adermann (naderman) - Nils Adermann (naderman)
- Gábor Fási - Gábor Fási
@ -371,9 +374,11 @@ Symfony is the result of the work of many people who made the code better
- Zach Badgett (zachbadgett) - Zach Badgett (zachbadgett)
- Aurélien Fredouelle - Aurélien Fredouelle
- Pavel Campr (pcampr) - Pavel Campr (pcampr)
- Maxime Steinhausser (ogizanagi)
- Disquedur - Disquedur
- Geoffrey Tran (geoff) - Geoffrey Tran (geoff)
- Jan Behrens - Jan Behrens
- Mantas Var (mvar)
- Sebastian Krebs - Sebastian Krebs
- Christopher Davis (chrisguitarguy) - Christopher Davis (chrisguitarguy)
- Thomas Lallement (raziel057) - Thomas Lallement (raziel057)
@ -387,6 +392,7 @@ Symfony is the result of the work of many people who made the code better
- Max Rath (drak3) - Max Rath (drak3)
- Stéphane Escandell (sescandell) - Stéphane Escandell (sescandell)
- Sinan Eldem - Sinan Eldem
- Alexandre Dupuy (satchette)
- Nahuel Cuesta (ncuesta) - Nahuel Cuesta (ncuesta)
- Chris Boden (cboden) - Chris Boden (cboden)
- Asmir Mustafic (goetas) - Asmir Mustafic (goetas)
@ -484,7 +490,6 @@ Symfony is the result of the work of many people who made the code better
- Xavier Lacot (xavier) - Xavier Lacot (xavier)
- Olivier Maisonneuve (olineuve) - Olivier Maisonneuve (olineuve)
- Francis Turmel (fturmel) - Francis Turmel (fturmel)
- Loick Piera (pyrech)
- cgonzalez - cgonzalez
- Ben - Ben
- Jayson Xu (superjavason) - Jayson Xu (superjavason)
@ -506,6 +511,7 @@ Symfony is the result of the work of many people who made the code better
- Fabian Vogler (fabian) - Fabian Vogler (fabian)
- Korvin Szanto - Korvin Szanto
- Maksim Kotlyar (makasim) - Maksim Kotlyar (makasim)
- Ivan Kurnosov
- Neil Ferreira - Neil Ferreira
- Dmitry Parnas (parnas) - Dmitry Parnas (parnas)
- DQNEO - DQNEO
@ -516,6 +522,7 @@ Symfony is the result of the work of many people who made the code better
- David Romaní - David Romaní
- Patrick Allaert - Patrick Allaert
- Gustavo Falco (gfalco) - Gustavo Falco (gfalco)
- Matt Robinson (inanimatt)
- Aleksey Podskrebyshev - Aleksey Podskrebyshev
- David Marín Carreño (davefx) - David Marín Carreño (davefx)
- Jörn Lang (j.lang) - Jörn Lang (j.lang)
@ -580,6 +587,7 @@ Symfony is the result of the work of many people who made the code better
- Michael Tibben - Michael Tibben
- Sander Marechal - Sander Marechal
- Radosław Benkel - Radosław Benkel
- Marcos Sánchez
- ttomor - ttomor
- Mei Gwilym (meigwilym) - Mei Gwilym (meigwilym)
- Michael H. Arieli (excelwebzone) - Michael H. Arieli (excelwebzone)
@ -622,6 +630,7 @@ Symfony is the result of the work of many people who made the code better
- nacho - nacho
- Piotr Antosik (antek88) - Piotr Antosik (antek88)
- Artem Lopata - Artem Lopata
- Samuel ROZE (sroze)
- Marcos Quesada (marcos_quesada) - Marcos Quesada (marcos_quesada)
- Matthew Vickery (mattvick) - Matthew Vickery (mattvick)
- Dan Finnie - Dan Finnie
@ -675,6 +684,7 @@ Symfony is the result of the work of many people who made the code better
- Yannick - Yannick
- Eduardo García Sanz (coma) - Eduardo García Sanz (coma)
- Sebastian Grodzicki (sgrodzicki) - Sebastian Grodzicki (sgrodzicki)
- Michael Lee (zerustech)
- Roy Van Ginneken - Roy Van Ginneken
- David de Boer (ddeboer) - David de Boer (ddeboer)
- Gilles Doge (gido) - Gilles Doge (gido)
@ -721,6 +731,7 @@ Symfony is the result of the work of many people who made the code better
- Malaney J. Hill - Malaney J. Hill
- Christian Flach (cmfcmf) - Christian Flach (cmfcmf)
- Cédric Girard (enk_) - Cédric Girard (enk_)
- Lars Ambrosius Wallenborn (larsborn)
- Oriol Mangas Abellan (oriolman) - Oriol Mangas Abellan (oriolman)
- Sebastian Göttschkes (sgoettschkes) - Sebastian Göttschkes (sgoettschkes)
- Tatsuya Tsuruoka - Tatsuya Tsuruoka
@ -847,6 +858,7 @@ Symfony is the result of the work of many people who made the code better
- Gunnar Lium (gunnarlium) - Gunnar Lium (gunnarlium)
- Tiago Garcia (tiagojsag) - Tiago Garcia (tiagojsag)
- Artiom - Artiom
- Jakub Simon
- Bouke Haarsma - Bouke Haarsma
- Martin Eckhardt - Martin Eckhardt
- Denis Zunke - Denis Zunke
@ -876,7 +888,6 @@ Symfony is the result of the work of many people who made the code better
- Vasily Khayrulin (sirian) - Vasily Khayrulin (sirian)
- Stefan Koopmanschap (skoop) - Stefan Koopmanschap (skoop)
- Stefan Hüsges (tronsha) - Stefan Hüsges (tronsha)
- Ivan Kurnosov
- stloyd - stloyd
- Chris Tickner - Chris Tickner
- Andrew Coulton - Andrew Coulton
@ -905,7 +916,6 @@ Symfony is the result of the work of many people who made the code better
- Julius Beckmann - Julius Beckmann
- Romain Dorgueil - Romain Dorgueil
- Grayson Koonce (breerly) - Grayson Koonce (breerly)
- Matt Robinson (inanimatt)
- Karim Cassam Chenaï (ka) - Karim Cassam Chenaï (ka)
- Nicolas Bastien (nicolas_bastien) - Nicolas Bastien (nicolas_bastien)
- Andy Stanberry - Andy Stanberry
@ -992,6 +1002,7 @@ Symfony is the result of the work of many people who made the code better
- grifx - grifx
- Robert Campbell - Robert Campbell
- Matt Lehner - Matt Lehner
- Hidde Wieringa
- Hein Zaw Htet™ - Hein Zaw Htet™
- Ruben Kruiswijk - Ruben Kruiswijk
- Michael J - Michael J
@ -1048,9 +1059,7 @@ Symfony is the result of the work of many people who made the code better
- Muriel (metalmumu) - Muriel (metalmumu)
- Michaël Perrin (michael.perrin) - Michaël Perrin (michael.perrin)
- Michael Pohlers (mick_the_big) - Michael Pohlers (mick_the_big)
- Mantas Var (mvar)
- Cayetano Soriano Gallego (neoshadybeat) - Cayetano Soriano Gallego (neoshadybeat)
- Maxime Steinhausser (ogizanagi)
- Pablo Monterde Perez (plebs) - Pablo Monterde Perez (plebs)
- Jimmy Leger (redpanda) - Jimmy Leger (redpanda)
- Cyrille Jouineau (tuxosaurus) - Cyrille Jouineau (tuxosaurus)
@ -1128,6 +1137,7 @@ Symfony is the result of the work of many people who made the code better
- Brian Freytag - Brian Freytag
- Skorney - Skorney
- mieszko4 - mieszko4
- Neophy7e
- Arrilot - Arrilot
- Markus Staab - Markus Staab
- Pierre-Louis LAUNAY - Pierre-Louis LAUNAY
@ -1140,6 +1150,8 @@ Symfony is the result of the work of many people who made the code better
- Sema - Sema
- Thorsten Hallwas - Thorsten Hallwas
- Michael Squires - Michael Squires
- Norman Soetbeer
- Benjamin Long
- Matt Janssen - Matt Janssen
- Peter Gribanov - Peter Gribanov
- kwiateusz - kwiateusz
@ -1235,6 +1247,7 @@ Symfony is the result of the work of many people who made the code better
- Vincent (vincent1870) - Vincent (vincent1870)
- Eugene Babushkin (warl) - Eugene Babushkin (warl)
- Xavier Amado (xamado) - Xavier Amado (xamado)
- Jesper Søndergaard Pedersen (zerrvox)
- Florent Cailhol - Florent Cailhol
- szymek - szymek
- craigmarvelley - craigmarvelley

View File

@ -16,6 +16,9 @@ use Symfony\Component\DependencyInjection\Container;
class ContainerAwareEventManagerTest extends \PHPUnit_Framework_TestCase class ContainerAwareEventManagerTest extends \PHPUnit_Framework_TestCase
{ {
private $container;
private $evm;
protected function setUp() protected function setUp()
{ {
$this->container = new Container(); $this->container = new Container();

View File

@ -212,6 +212,9 @@ class CodeExtension extends \Twig_Extension
}, $text); }, $text);
} }
/**
* {@inheritdoc}
*/
public function getName() public function getName()
{ {
return 'code'; return 'code';

View File

@ -81,6 +81,9 @@ class HttpKernelExtension extends \Twig_Extension
return new ControllerReference($controller, $attributes, $query); return new ControllerReference($controller, $attributes, $query);
} }
/**
* {@inheritdoc}
*/
public function getName() public function getName()
{ {
return 'http_kernel'; return 'http_kernel';

View File

@ -89,9 +89,7 @@ class RoutingExtension extends \Twig_Extension
} }
/** /**
* Returns the name of the extension. * {@inheritdoc}
*
* @return string The extension name
*/ */
public function getName() public function getName()
{ {

View File

@ -52,9 +52,7 @@ class SecurityExtension extends \Twig_Extension
} }
/** /**
* Returns the name of the extension. * {@inheritdoc}
*
* @return string The extension name
*/ */
public function getName() public function getName()
{ {

View File

@ -99,9 +99,7 @@ class TranslationExtension extends \Twig_Extension
} }
/** /**
* Returns the name of the extension. * {@inheritdoc}
*
* @return string The extension name
*/ */
public function getName() public function getName()
{ {

View File

@ -56,9 +56,7 @@ class YamlExtension extends \Twig_Extension
} }
/** /**
* Returns the name of the extension. * {@inheritdoc}
*
* @return string The extension name
*/ */
public function getName() public function getName()
{ {

View File

@ -156,10 +156,7 @@ class Configuration implements ConfigurationInterface
->booleanNode('test')->end() ->booleanNode('test')->end()
->scalarNode('default_locale')->defaultValue('en')->end() ->scalarNode('default_locale')->defaultValue('en')->end()
->arrayNode('trusted_hosts') ->arrayNode('trusted_hosts')
->beforeNormalization() ->beforeNormalization()->ifString()->then(function ($v) { return array($v); })->end()
->ifTrue(function ($v) { return is_string($v); })
->then(function ($v) { return array($v); })
->end()
->prototype('scalar')->end() ->prototype('scalar')->end()
->end() ->end()
->end() ->end()
@ -426,7 +423,7 @@ class Configuration implements ConfigurationInterface
->addDefaultChildrenIfNoneSet() ->addDefaultChildrenIfNoneSet()
->prototype('scalar')->defaultValue('FrameworkBundle:Form')->end() ->prototype('scalar')->defaultValue('FrameworkBundle:Form')->end()
->validate() ->validate()
->ifTrue(function ($v) {return !in_array('FrameworkBundle:Form', $v); }) ->ifNotInArray(array('FrameworkBundle:Form'))
->then(function ($v) { ->then(function ($v) {
return array_merge(array('FrameworkBundle:Form'), $v); return array_merge(array('FrameworkBundle:Form'), $v);
}) })

View File

@ -16,7 +16,7 @@
<tag name="monolog.logger" channel="php" /> <tag name="monolog.logger" channel="php" />
<argument /><!-- Exception handler --> <argument /><!-- Exception handler -->
<argument type="service" id="logger" on-invalid="null" /> <argument type="service" id="logger" on-invalid="null" />
<argument /><!-- Log levels map for enabled error levels --> <argument>null</argument><!-- Log levels map for enabled error levels -->
<argument>null</argument> <argument>null</argument>
<argument>true</argument> <argument>true</argument>
<argument>null</argument><!-- %templating.helper.code.file_link_format% --> <argument>null</argument><!-- %templating.helper.code.file_link_format% -->

View File

@ -58,9 +58,7 @@ class ActionsHelper extends Helper
} }
/** /**
* Returns the canonical name of this helper. * {@inheritdoc}
*
* @return string The canonical name
*/ */
public function getName() public function getName()
{ {

View File

@ -205,9 +205,7 @@ class CodeHelper extends Helper
} }
/** /**
* Returns the canonical name of this helper. * {@inheritdoc}
*
* @return string The canonical name
*/ */
public function getName() public function getName()
{ {

View File

@ -83,9 +83,7 @@ class RequestHelper extends Helper
} }
/** /**
* Returns the canonical name of this helper. * {@inheritdoc}
*
* @return string The canonical name
*/ */
public function getName() public function getName()
{ {

View File

@ -50,9 +50,7 @@ class RouterHelper extends Helper
} }
/** /**
* Returns the canonical name of this helper. * {@inheritdoc}
*
* @return string The canonical name
*/ */
public function getName() public function getName()
{ {

View File

@ -86,9 +86,7 @@ class SessionHelper extends Helper
} }
/** /**
* Returns the canonical name of this helper. * {@inheritdoc}
*
* @return string The canonical name
*/ */
public function getName() public function getName()
{ {

View File

@ -50,9 +50,7 @@ class TranslatorHelper extends Helper
} }
/** /**
* Returns the canonical name of this helper. * {@inheritdoc}
*
* @return string The canonical name
*/ */
public function getName() public function getName()
{ {

View File

@ -76,9 +76,7 @@ class LogoutUrlHelper extends Helper
} }
/** /**
* Returns the canonical name of this helper. * {@inheritdoc}
*
* @return string The canonical name
*/ */
public function getName() public function getName()
{ {

View File

@ -43,9 +43,7 @@ class SecurityHelper extends Helper
} }
/** /**
* Returns the canonical name of this helper. * {@inheritdoc}
*
* @return string The canonical name
*/ */
public function getName() public function getName()
{ {

View File

@ -81,7 +81,7 @@ class Configuration implements ConfigurationInterface
->prototype('scalar')->defaultValue('form_div_layout.html.twig')->end() ->prototype('scalar')->defaultValue('form_div_layout.html.twig')->end()
->example(array('MyBundle::form.html.twig')) ->example(array('MyBundle::form.html.twig'))
->validate() ->validate()
->ifTrue(function ($v) { return !in_array('form_div_layout.html.twig', $v); }) ->ifNotInArray(array('form_div_layout.html.twig'))
->then(function ($v) { ->then(function ($v) {
return array_merge(array('form_div_layout.html.twig'), $v); return array_merge(array('form_div_layout.html.twig'), $v);
}) })

View File

@ -77,6 +77,9 @@ class ActionsExtension extends \Twig_Extension
); );
} }
/**
* {@inheritdoc}
*/
public function getName() public function getName()
{ {
return 'actions'; return 'actions';

View File

@ -83,9 +83,7 @@ class AssetsExtension extends \Twig_Extension
} }
/** /**
* Returns the name of the extension. * {@inheritdoc}
*
* @return string The extension name
*/ */
public function getName() public function getName()
{ {

View File

@ -88,10 +88,13 @@
{% if collector.logs %} {% if collector.logs %}
<ul class="alt"> <ul class="alt">
{% for log in collector.logs if priority >= 0 and log.priority >= priority or priority < 0 and log.context.type|default(0) == priority %} {% for log in collector.logs %}
<li class="{{ cycle(['odd', 'even'], loop.index) }}{% if log.priority >= 400 %} error{% elseif log.priority >= 300 %} warning{% endif %}{% if log.context.scream is defined %} scream{% endif %}"> {% set is_deprecation = log.context.level is defined and log.context.type is defined and (constant('E_DEPRECATED') == log.context.type or constant('E_USER_DEPRECATED') == log.context.type) %}
{{ logger.display_message(loop.index, log) }} {% if priority == '-100' ? is_deprecation : log.priority >= priority %}
</li> <li class="{{ cycle(['odd', 'even'], loop.index) }}{% if log.context.scream is defined %} scream{% elseif log.priority >= 400 %} error{% elseif log.priority >= 300 %} warning{% endif %}">
{{ logger.display_message(loop.index, log, is_deprecation) }}
</li>
{% endif %}
{% else %} {% else %}
<li><em>No logs available for this priority.</em></li> <li><em>No logs available for this priority.</em></li>
{% endfor %} {% endfor %}
@ -104,15 +107,18 @@
{% endblock %} {% endblock %}
{% macro display_message(log_index, log) %} {% macro display_message(log_index, log, is_deprecation) %}
{% if log.context.level is defined and log.context.type is defined and (constant('E_DEPRECATED') == log.context.type or constant('E_USER_DEPRECATED') == log.context.type) %} {% if is_deprecation %}
DEPRECATION - {{ log.message }} {% set stack = log.context.stack|default([]) %}
{% set id = 'sf-call-stack-' ~ log_index %}
<a href="#" onclick="Sfjs.toggle('{{ id }}', document.getElementById('{{ id }}-on'), document.getElementById('{{ id }}-off')); return false;"> {% if stack %}
<img class="toggle" id="{{ id }}-off" alt="-" src="data:image/gif;base64,R0lGODlhEgASAMQSANft94TG57Hb8GS44ez1+mC24IvK6ePx+Wa44dXs92+942e54o3L6W2844/M6dnu+P/+/l614P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABIALAAAAAASABIAQAVCoCQBTBOd6Kk4gJhGBCTPxysJb44K0qD/ER/wlxjmisZkMqBEBW5NHrMZmVKvv9hMVsO+hE0EoNAstEYGxG9heIhCADs=" style="display:none"> <a href="#" onclick="Sfjs.toggle('{{ id }}', document.getElementById('{{ id }}-on'), document.getElementById('{{ id }}-off')); return false;">
<img class="toggle" id="{{ id }}-on" alt="+" src="data:image/gif;base64,R0lGODlhEgASAMQTANft99/v+Ga44bHb8ITG52S44dXs9+z1+uPx+YvK6WC24G+944/M6W28443L6dnu+Ge54v/+/l614P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABMALAAAAAASABIAQAVS4DQBTiOd6LkwgJgeUSzHSDoNaZ4PU6FLgYBA5/vFID/DbylRGiNIZu74I0h1hNsVxbNuUV4d9SsZM2EzWe1qThVzwWFOAFCQFa1RQq6DJB4iIQA7" style="display:inline"> <img class="toggle" id="{{ id }}-off" alt="-" src="data:image/gif;base64,R0lGODlhEgASAMQSANft94TG57Hb8GS44ez1+mC24IvK6ePx+Wa44dXs92+942e54o3L6W2844/M6dnu+P/+/l614P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABIALAAAAAASABIAQAVCoCQBTBOd6Kk4gJhGBCTPxysJb44K0qD/ER/wlxjmisZkMqBEBW5NHrMZmVKvv9hMVsO+hE0EoNAstEYGxG9heIhCADs=" style="display:none">
</a> <img class="toggle" id="{{ id }}-on" alt="+" src="data:image/gif;base64,R0lGODlhEgASAMQTANft99/v+Ga44bHb8ITG52S44dXs9+z1+uPx+YvK6WC24G+944/M6W28443L6dnu+Ge54v/+/l614P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABMALAAAAAASABIAQAVS4DQBTiOd6LkwgJgeUSzHSDoNaZ4PU6FLgYBA5/vFID/DbylRGiNIZu74I0h1hNsVxbNuUV4d9SsZM2EzWe1qThVzwWFOAFCQFa1RQq6DJB4iIQA7" style="display:inline">
{% for index, call in log.context.stack if index > 1 %} </a>
{% endif %}
{% for index, call in stack if index > 1 %}
{% if index == 2 %} {% if index == 2 %}
<ul class="sf-call-stack" id="{{ id }}" style="display: none"> <ul class="sf-call-stack" id="{{ id }}" style="display: none">
{% endif %} {% endif %}
@ -128,7 +134,7 @@
<li>Called from {{ call.file is defined and call.line is defined ? call.file|format_file(call.line, from) : from|raw }}</li> <li>Called from {{ call.file is defined and call.line is defined ? call.file|format_file(call.line, from) : from|raw }}</li>
{% if index == log.context.stack|length - 1 %} {% if index == stack|length - 1 %}
</ul> </ul>
{% endif %} {% endif %}
{% endfor %} {% endfor %}

View File

@ -199,7 +199,7 @@
} }
{% if excluded_ajax_paths is defined %} {% if excluded_ajax_paths is defined %}
if (window.XMLHttpRequest && XMLHttpRequest.addEventListener) { if (window.XMLHttpRequest && XMLHttpRequest.prototype.addEventListener) {
var proxied = XMLHttpRequest.prototype.open; var proxied = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) { XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {

View File

@ -834,7 +834,7 @@ class Application
$input->setInteractive(false); $input->setInteractive(false);
} elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) { } elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
$inputStream = $this->getHelperSet()->get('question')->getInputStream(); $inputStream = $this->getHelperSet()->get('question')->getInputStream();
if (!@posix_isatty($inputStream)) { if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
$input->setInteractive(false); $input->setInteractive(false);
} }
} }

View File

@ -240,7 +240,7 @@ class ErrorHandler
} }
/** /**
* Sets the error levels that are to be thrown. * Sets the PHP error levels that throw an exception when a PHP error occurs.
* *
* @param int $levels A bit field of E_* constants for thrown errors * @param int $levels A bit field of E_* constants for thrown errors
* @param bool $replace Replace or amend the previous value * @param bool $replace Replace or amend the previous value
@ -263,7 +263,7 @@ class ErrorHandler
} }
/** /**
* Sets the error levels that are logged or thrown with their local scope. * Sets the PHP error levels for which local variables are preserved.
* *
* @param int $levels A bit field of E_* constants for scoped errors * @param int $levels A bit field of E_* constants for scoped errors
* @param bool $replace Replace or amend the previous value * @param bool $replace Replace or amend the previous value
@ -282,7 +282,7 @@ class ErrorHandler
} }
/** /**
* Sets the error levels that are logged with their stack trace. * Sets the PHP error levels for which the stack trace is preserved.
* *
* @param int $levels A bit field of E_* constants for traced errors * @param int $levels A bit field of E_* constants for traced errors
* @param bool $replace Replace or amend the previous value * @param bool $replace Replace or amend the previous value
@ -356,69 +356,71 @@ class ErrorHandler
$throw = $this->thrownErrors & $type & $level; $throw = $this->thrownErrors & $type & $level;
$type &= $level | $this->screamedErrors; $type &= $level | $this->screamedErrors;
if ($type && ($log || $throw)) { if (!$type || (!$log && !$throw)) {
if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) { return $type && $log;
$e = $context; // Whatever the signature of the method, }
unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
$context = $e;
}
if ($throw) { if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) {
if (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) { $e = $context; // Whatever the signature of the method,
// Checking for class existence is a work around for https://bugs.php.net/42098 unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
$throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context); $context = $e;
} else { }
$throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
}
if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) { if ($throw) {
// Exceptions thrown from error handlers are sometimes not caught by the exception if (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {
// handler and shutdown handlers are bypassed before 5.4.8/5.3.18. // Checking for class existence is a work around for https://bugs.php.net/42098
// We temporarily re-enable display_errors to prevent any blank page related to this bug. $throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
$throw->errorHandlerCanary = new ErrorHandlerCanary();
}
throw $throw;
}
// For duplicated errors, log the trace only once
$e = md5("{$type}/{$line}/{$file}\x00{$message}", true);
$trace = true;
if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) {
$trace = false;
} else { } else {
$this->loggedTraces[$e] = 1; $throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
} }
$e = compact('type', 'file', 'line', 'level'); if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) {
// Exceptions thrown from error handlers are sometimes not caught by the exception
// handler and shutdown handlers are bypassed before 5.4.8/5.3.18.
// We temporarily re-enable display_errors to prevent any blank page related to this bug.
if ($type & $level) { $throw->errorHandlerCanary = new ErrorHandlerCanary();
if ($this->scopedErrors & $type) {
$e['context'] = $context;
if ($trace) {
$e['stack'] = debug_backtrace(true); // Provide object
}
} elseif ($trace) {
$e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
}
} }
if ($this->isRecursive) { throw $throw;
$log = 0; }
} elseif (self::$stackedErrorLevels) {
self::$stackedErrors[] = array($this->loggers[$type], $message, $e);
} else {
try {
$this->isRecursive = true;
$this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e);
$this->isRecursive = false;
} catch (\Exception $e) {
$this->isRecursive = false;
throw $e; // For duplicated errors, log the trace only once
$e = md5("{$type}/{$line}/{$file}\x00{$message}", true);
$trace = true;
if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) {
$trace = false;
} else {
$this->loggedTraces[$e] = 1;
}
$e = compact('type', 'file', 'line', 'level');
if ($type & $level) {
if ($this->scopedErrors & $type) {
$e['scope_vars'] = $context;
if ($trace) {
$e['stack'] = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
} }
} elseif ($trace) {
$e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
}
}
if ($this->isRecursive) {
$log = 0;
} elseif (self::$stackedErrorLevels) {
self::$stackedErrors[] = array($this->loggers[$type], $message, $e);
} else {
try {
$this->isRecursive = true;
$this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e);
$this->isRecursive = false;
} catch (\Exception $e) {
$this->isRecursive = false;
throw $e;
} }
} }
@ -487,40 +489,44 @@ class ErrorHandler
public static function handleFatalError(array $error = null) public static function handleFatalError(array $error = null)
{ {
self::$reservedMemory = ''; self::$reservedMemory = '';
$handler = set_error_handler('var_dump', 0); $handler = set_error_handler('var_dump', 0);
$handler = is_array($handler) ? $handler[0] : null; $handler = is_array($handler) ? $handler[0] : null;
restore_error_handler(); restore_error_handler();
if ($handler instanceof self) {
if (null === $error) {
$error = error_get_last();
}
try { if (!$handler instanceof self) {
while (self::$stackedErrorLevels) { return;
static::unstackErrors(); }
}
} catch (\Exception $exception) {
// Handled below
}
if ($error && ($error['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))) { if (null === $error) {
// Let's not throw anymore but keep logging $error = error_get_last();
$handler->throwAt(0, true); }
if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) { try {
$exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false); while (self::$stackedErrorLevels) {
} else { static::unstackErrors();
$exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true);
}
} elseif (!isset($exception)) {
return;
} }
} catch (\Exception $exception) {
// Handled below
}
try { if ($error && ($error['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))) {
$handler->handleException($exception, $error); // Let's not throw anymore but keep logging
} catch (FatalErrorException $e) { $handler->throwAt(0, true);
// Ignore this re-throw
if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
$exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false);
} else {
$exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true);
} }
} elseif (!isset($exception)) {
return;
}
try {
$handler->handleException($exception, $error);
} catch (FatalErrorException $e) {
// Ignore this re-throw
} }
} }

View File

@ -833,7 +833,7 @@ class Request
$clientIps = array(); $clientIps = array();
$ip = $this->server->get('REMOTE_ADDR'); $ip = $this->server->get('REMOTE_ADDR');
if (!self::$trustedProxies) { if (!$this->isFromTrustedProxy()) {
return array($ip); return array($ip);
} }
@ -1000,7 +1000,7 @@ class Request
*/ */
public function getPort() public function getPort()
{ {
if (self::$trustedProxies) { if ($this->isFromTrustedProxy()) {
if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && $port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT])) { if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && $port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT])) {
return $port; return $port;
} }
@ -1236,7 +1236,7 @@ class Request
*/ */
public function isSecure() public function isSecure()
{ {
if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) { if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) {
return in_array(strtolower(current(explode(',', $proto))), array('https', 'on', 'ssl', '1')); return in_array(strtolower(current(explode(',', $proto))), array('https', 'on', 'ssl', '1'));
} }
@ -1264,7 +1264,7 @@ class Request
*/ */
public function getHost() public function getHost()
{ {
if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) { if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) {
$elements = explode(',', $host); $elements = explode(',', $host);
$host = $elements[count($elements) - 1]; $host = $elements[count($elements) - 1];
@ -1981,4 +1981,9 @@ class Request
return new static($query, $request, $attributes, $cookies, $files, $server, $content); return new static($query, $request, $attributes, $cookies, $files, $server, $content);
} }
private function isFromTrustedProxy()
{
return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), self::$trustedProxies);
}
} }

View File

@ -743,35 +743,37 @@ class RequestTest extends \PHPUnit_Framework_TestCase
'HTTP_X_FORWARDED_PROTO' => 'https', 'HTTP_X_FORWARDED_PROTO' => 'https',
'HTTP_X_FORWARDED_PORT' => '8443', 'HTTP_X_FORWARDED_PORT' => '8443',
)); ));
$port = $request->getPort(); $this->assertEquals(80, $request->getPort(), 'With PROTO and PORT on untrusted connection server value takes precedence.');
$request->server->set('REMOTE_ADDR', '1.1.1.1');
$this->assertEquals(8443, $port, 'With PROTO and PORT set PORT takes precedence.'); $this->assertEquals(8443, $request->getPort(), 'With PROTO and PORT set PORT takes precedence.');
$request = Request::create('http://example.com', 'GET', array(), array(), array(), array( $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
'HTTP_X_FORWARDED_PROTO' => 'https', 'HTTP_X_FORWARDED_PROTO' => 'https',
)); ));
$port = $request->getPort(); $this->assertEquals(80, $request->getPort(), 'With only PROTO set getPort() ignores trusted headers on untrusted connection.');
$request->server->set('REMOTE_ADDR', '1.1.1.1');
$this->assertEquals(443, $port, 'With only PROTO set getPort() defaults to 443.'); $this->assertEquals(443, $request->getPort(), 'With only PROTO set getPort() defaults to 443.');
$request = Request::create('http://example.com', 'GET', array(), array(), array(), array( $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
'HTTP_X_FORWARDED_PROTO' => 'http', 'HTTP_X_FORWARDED_PROTO' => 'http',
)); ));
$port = $request->getPort(); $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() ignores trusted headers on untrusted connection.');
$request->server->set('REMOTE_ADDR', '1.1.1.1');
$this->assertEquals(80, $port, 'If X_FORWARDED_PROTO is set to HTTP return 80.'); $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() returns port of the original request.');
$request = Request::create('http://example.com', 'GET', array(), array(), array(), array( $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
'HTTP_X_FORWARDED_PROTO' => 'On', 'HTTP_X_FORWARDED_PROTO' => 'On',
)); ));
$port = $request->getPort(); $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is On, getPort() ignores trusted headers on untrusted connection.');
$this->assertEquals(443, $port, 'With only PROTO set and value is On, getPort() defaults to 443.'); $request->server->set('REMOTE_ADDR', '1.1.1.1');
$this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is On, getPort() defaults to 443.');
$request = Request::create('http://example.com', 'GET', array(), array(), array(), array( $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
'HTTP_X_FORWARDED_PROTO' => '1', 'HTTP_X_FORWARDED_PROTO' => '1',
)); ));
$port = $request->getPort(); $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is 1, getPort() ignores trusted headers on untrusted connection.');
$this->assertEquals(443, $port, 'With only PROTO set and value is 1, getPort() defaults to 443.'); $request->server->set('REMOTE_ADDR', '1.1.1.1');
$this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is 1, getPort() defaults to 443.');
$request = Request::create('http://example.com', 'GET', array(), array(), array(), array( $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
'HTTP_X_FORWARDED_PROTO' => 'something-else', 'HTTP_X_FORWARDED_PROTO' => 'something-else',
@ -1066,6 +1068,8 @@ class RequestTest extends \PHPUnit_Framework_TestCase
$request->headers->set('X_FORWARDED_PROTO', 'https'); $request->headers->set('X_FORWARDED_PROTO', 'https');
Request::setTrustedProxies(array('1.1.1.1')); Request::setTrustedProxies(array('1.1.1.1'));
$this->assertFalse($request->isSecure());
$request->server->set('REMOTE_ADDR', '1.1.1.1');
$this->assertTrue($request->isSecure()); $this->assertTrue($request->isSecure());
Request::setTrustedProxies(array()); Request::setTrustedProxies(array());
@ -1544,7 +1548,15 @@ class RequestTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(443, $request->getPort()); $this->assertEquals(443, $request->getPort());
$this->assertTrue($request->isSecure()); $this->assertTrue($request->isSecure());
// trusted proxy via setTrustedProxies()
Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'));
$this->assertEquals('3.3.3.3', $request->getClientIp());
$this->assertEquals('example.com', $request->getHost());
$this->assertEquals(80, $request->getPort());
$this->assertFalse($request->isSecure());
// check various X_FORWARDED_PROTO header values // check various X_FORWARDED_PROTO header values
Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
$request->headers->set('X_FORWARDED_PROTO', 'ssl'); $request->headers->set('X_FORWARDED_PROTO', 'ssl');
$this->assertTrue($request->isSecure()); $this->assertTrue($request->isSecure());

View File

@ -29,6 +29,10 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
class Esi implements SurrogateInterface class Esi implements SurrogateInterface
{ {
private $contentTypes; private $contentTypes;
private $phpEscapeMap = array(
array('<?', '<%', '<s', '<S'),
array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>', '<?php echo "<s"; ?>', '<?php echo "<S"; ?>'),
);
/** /**
* Constructor. * Constructor.
@ -209,10 +213,34 @@ class Esi implements SurrogateInterface
// we don't use a proper XML parser here as we can have ESI tags in a plain text response // we don't use a proper XML parser here as we can have ESI tags in a plain text response
$content = $response->getContent(); $content = $response->getContent();
$content = str_replace(array('<?', '<%'), array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>'), $content);
$content = preg_replace_callback('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', array($this, 'handleEsiIncludeTag'), $content);
$content = preg_replace('#<esi\:comment[^>]*(?:/|</esi\:comment)>#', '', $content);
$content = preg_replace('#<esi\:remove>.*?</esi\:remove>#', '', $content); $content = preg_replace('#<esi\:remove>.*?</esi\:remove>#', '', $content);
$content = preg_replace('#<esi\:comment[^>]*(?:/|</esi\:comment)>#', '', $content);
$chunks = preg_split('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
$chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]);
$i = 1;
while (isset($chunks[$i])) {
$options = array();
preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $chunks[$i], $matches, PREG_SET_ORDER);
foreach ($matches as $set) {
$options[$set[1]] = $set[2];
}
if (!isset($options['src'])) {
throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.');
}
$chunks[$i] = sprintf('<?php echo $this->surrogate->handle($this, %s, %s, %s) ?>'."\n",
var_export($options['src'], true),
var_export(isset($options['alt']) ? $options['alt'] : '', true),
isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false'
);
++$i;
$chunks[$i] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[$i]);
++$i;
}
$content = implode('', $chunks);
$response->setContent($content); $response->setContent($content);
$response->headers->set('X-Body-Eval', 'ESI'); $response->headers->set('X-Body-Eval', 'ESI');
@ -265,32 +293,4 @@ class Esi implements SurrogateInterface
} }
} }
} }
/**
* Handles an ESI include tag (called internally).
*
* @param array $attributes An array containing the attributes.
*
* @return string The response content for the include.
*
* @throws \RuntimeException
*/
private function handleEsiIncludeTag($attributes)
{
$options = array();
preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $attributes[1], $matches, PREG_SET_ORDER);
foreach ($matches as $set) {
$options[$set[1]] = $set[2];
}
if (!isset($options['src'])) {
throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.');
}
return sprintf('<?php echo $this->surrogate->handle($this, %s, %s, %s) ?>'."\n",
var_export($options['src'], true),
var_export(isset($options['alt']) ? $options['alt'] : '', true),
isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false'
);
}
} }

View File

@ -23,6 +23,10 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
class Ssi implements SurrogateInterface class Ssi implements SurrogateInterface
{ {
private $contentTypes; private $contentTypes;
private $phpEscapeMap = array(
array('<?', '<%', '<s', '<S'),
array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>', '<?php echo "<s"; ?>', '<?php echo "<S"; ?>'),
);
/** /**
* Constructor. * Constructor.
@ -122,8 +126,30 @@ class Ssi implements SurrogateInterface
// we don't use a proper XML parser here as we can have SSI tags in a plain text response // we don't use a proper XML parser here as we can have SSI tags in a plain text response
$content = $response->getContent(); $content = $response->getContent();
$content = str_replace(array('<?', '<%'), array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>'), $content);
$content = preg_replace_callback('#<!--\#include\s+(.*?)\s*-->#', array($this, 'handleIncludeTag'), $content); $chunks = preg_split('#<!--\#include\s+(.*?)\s*-->#', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
$chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]);
$i = 1;
while (isset($chunks[$i])) {
$options = array();
preg_match_all('/(virtual)="([^"]*?)"/', $chunks[$i], $matches, PREG_SET_ORDER);
foreach ($matches as $set) {
$options[$set[1]] = $set[2];
}
if (!isset($options['virtual'])) {
throw new \RuntimeException('Unable to process an SSI tag without a "virtual" attribute.');
}
$chunks[$i] = sprintf('<?php echo $this->surrogate->handle($this, %s, \'\', false) ?>'."\n",
var_export($options['virtual'], true)
);
++$i;
$chunks[$i] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[$i]);
++$i;
}
$content = implode('', $chunks);
$response->setContent($content); $response->setContent($content);
$response->headers->set('X-Body-Eval', 'SSI'); $response->headers->set('X-Body-Eval', 'SSI');
@ -166,30 +192,4 @@ class Ssi implements SurrogateInterface
} }
} }
} }
/**
* Handles an SSI include tag (called internally).
*
* @param array $attributes An array containing the attributes.
*
* @return string The response content for the include.
*
* @throws \RuntimeException
*/
private function handleIncludeTag($attributes)
{
$options = array();
preg_match_all('/(virtual)="([^"]*?)"/', $attributes[1], $matches, PREG_SET_ORDER);
foreach ($matches as $set) {
$options[$set[1]] = $set[2];
}
if (!isset($options['virtual'])) {
throw new \RuntimeException('Unable to process an SSI tag without a "virtual" attribute.');
}
return sprintf('<?php echo $this->surrogate->handle($this, %s, \'\', false) ?>'."\n",
var_export($options['virtual'], true)
);
}
} }

View File

@ -124,10 +124,10 @@ class EsiTest extends \PHPUnit_Framework_TestCase
$esi = new Esi(); $esi = new Esi();
$request = Request::create('/'); $request = Request::create('/');
$response = new Response('foo <?php die("foo"); ?><%= "lala" %>'); $response = new Response('<?php <? <% <script language=php>');
$esi->process($request, $response); $esi->process($request, $response);
$this->assertEquals('foo <?php echo "<?"; ?>php die("foo"); ?><?php echo "<%"; ?>= "lala" %>', $response->getContent()); $this->assertEquals('<?php echo "<?"; ?>php <?php echo "<?"; ?> <?php echo "<%"; ?> <?php echo "<s"; ?>cript language=php>', $response->getContent());
} }
/** /**

View File

@ -113,10 +113,10 @@ class SsiTest extends \PHPUnit_Framework_TestCase
$ssi = new Ssi(); $ssi = new Ssi();
$request = Request::create('/'); $request = Request::create('/');
$response = new Response('foo <?php die("foo"); ?><%= "lala" %>'); $response = new Response('<?php <? <% <script language=php>');
$ssi->process($request, $response); $ssi->process($request, $response);
$this->assertEquals('foo <?php echo "<?"; ?>php die("foo"); ?><?php echo "<%"; ?>= "lala" %>', $response->getContent()); $this->assertEquals('<?php echo "<?"; ?>php <?php echo "<?"; ?> <?php echo "<%"; ?> <?php echo "<s"; ?>cript language=php>', $response->getContent());
} }
/** /**

View File

@ -60,6 +60,9 @@ class StringUtil
// indices (index), appendices (appendix), prices (price) // indices (index), appendices (appendix), prices (price)
array('seci', 4, false, true, array('ex', 'ix', 'ice')), array('seci', 4, false, true, array('ex', 'ix', 'ice')),
// movies (movie)
array('seivom', 6, true, true, 'movie'),
// babies (baby) // babies (baby)
array('sei', 3, false, true, 'y'), array('sei', 3, false, true, 'y'),

View File

@ -99,6 +99,7 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase
array('men', 'man'), array('men', 'man'),
array('mice', 'mouse'), array('mice', 'mouse'),
array('moves', 'move'), array('moves', 'move'),
array('movies', 'movie'),
array('nebulae', 'nebula'), array('nebulae', 'nebula'),
array('neuroses', array('neuros', 'neurose', 'neurosis')), array('neuroses', array('neuros', 'neurose', 'neurosis')),
array('oases', array('oas', 'oase', 'oasis')), array('oases', array('oas', 'oase', 'oasis')),