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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,7 +16,7 @@
<tag name="monolog.logger" channel="php" />
<argument /><!-- Exception handler -->
<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>true</argument>
<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.
*
* @return string The canonical name
* {@inheritdoc}
*/
public function getName()
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -88,10 +88,13 @@
{% if collector.logs %}
<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 %}
<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 %}">
{{ logger.display_message(loop.index, log) }}
</li>
{% for log in collector.logs %}
{% 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) %}
{% if priority == '-100' ? is_deprecation : log.priority >= priority %}
<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 %}
<li><em>No logs available for this priority.</em></li>
{% endfor %}
@ -104,15 +107,18 @@
{% endblock %}
{% macro display_message(log_index, log) %}
{% 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) %}
DEPRECATION - {{ log.message }}
{% set id = 'sf-call-stack-' ~ log_index %}
<a href="#" onclick="Sfjs.toggle('{{ id }}', document.getElementById('{{ id }}-on'), document.getElementById('{{ id }}-off')); return false;">
<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">
<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">
</a>
{% for index, call in log.context.stack if index > 1 %}
{% macro display_message(log_index, log, is_deprecation) %}
{% if is_deprecation %}
{% set stack = log.context.stack|default([]) %}
{% if stack %}
<a href="#" onclick="Sfjs.toggle('{{ id }}', document.getElementById('{{ id }}-on'), document.getElementById('{{ id }}-off')); return false;">
<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">
<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">
</a>
{% endif %}
{% for index, call in stack if index > 1 %}
{% if index == 2 %}
<ul class="sf-call-stack" id="{{ id }}" style="display: none">
{% 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>
{% if index == log.context.stack|length - 1 %}
{% if index == stack|length - 1 %}
</ul>
{% endif %}
{% endfor %}

View File

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

View File

@ -834,7 +834,7 @@ class Application
$input->setInteractive(false);
} elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
$inputStream = $this->getHelperSet()->get('question')->getInputStream();
if (!@posix_isatty($inputStream)) {
if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
$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 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 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 bool $replace Replace or amend the previous value
@ -356,69 +356,71 @@ class ErrorHandler
$throw = $this->thrownErrors & $type & $level;
$type &= $level | $this->screamedErrors;
if ($type && ($log || $throw)) {
if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) {
$e = $context; // Whatever the signature of the method,
unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
$context = $e;
}
if (!$type || (!$log && !$throw)) {
return $type && $log;
}
if ($throw) {
if (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {
// Checking for class existence is a work around for https://bugs.php.net/42098
$throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
} else {
$throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
}
if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) {
$e = $context; // Whatever the signature of the method,
unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
$context = $e;
}
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.
$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;
if ($throw) {
if (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {
// Checking for class existence is a work around for https://bugs.php.net/42098
$throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
} 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) {
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);
}
$throw->errorHandlerCanary = new ErrorHandlerCanary();
}
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 $throw;
}
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)
{
self::$reservedMemory = '';
$handler = set_error_handler('var_dump', 0);
$handler = is_array($handler) ? $handler[0] : null;
restore_error_handler();
if ($handler instanceof self) {
if (null === $error) {
$error = error_get_last();
}
try {
while (self::$stackedErrorLevels) {
static::unstackErrors();
}
} catch (\Exception $exception) {
// Handled below
}
if (!$handler instanceof self) {
return;
}
if ($error && ($error['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))) {
// Let's not throw anymore but keep logging
$handler->throwAt(0, true);
if (null === $error) {
$error = error_get_last();
}
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 {
while (self::$stackedErrorLevels) {
static::unstackErrors();
}
} catch (\Exception $exception) {
// Handled below
}
try {
$handler->handleException($exception, $error);
} catch (FatalErrorException $e) {
// Ignore this re-throw
if ($error && ($error['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))) {
// Let's not throw anymore but keep logging
$handler->throwAt(0, true);
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();
$ip = $this->server->get('REMOTE_ADDR');
if (!self::$trustedProxies) {
if (!$this->isFromTrustedProxy()) {
return array($ip);
}
@ -1000,7 +1000,7 @@ class Request
*/
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])) {
return $port;
}
@ -1236,7 +1236,7 @@ class Request
*/
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'));
}
@ -1264,7 +1264,7 @@ class Request
*/
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);
$host = $elements[count($elements) - 1];
@ -1981,4 +1981,9 @@ class Request
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_PORT' => '8443',
));
$port = $request->getPort();
$this->assertEquals(8443, $port, 'With PROTO and PORT set PORT takes precedence.');
$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, $request->getPort(), 'With PROTO and PORT set PORT takes precedence.');
$request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
'HTTP_X_FORWARDED_PROTO' => 'https',
));
$port = $request->getPort();
$this->assertEquals(443, $port, 'With only PROTO set getPort() defaults to 443.');
$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, $request->getPort(), 'With only PROTO set getPort() defaults to 443.');
$request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
'HTTP_X_FORWARDED_PROTO' => 'http',
));
$port = $request->getPort();
$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() ignores trusted headers on untrusted connection.');
$request->server->set('REMOTE_ADDR', '1.1.1.1');
$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(
'HTTP_X_FORWARDED_PROTO' => 'On',
));
$port = $request->getPort();
$this->assertEquals(443, $port, 'With only PROTO set and value is On, getPort() defaults to 443.');
$this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is On, getPort() ignores trusted headers on untrusted connection.');
$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(
'HTTP_X_FORWARDED_PROTO' => '1',
));
$port = $request->getPort();
$this->assertEquals(443, $port, 'With only PROTO set and value is 1, getPort() defaults to 443.');
$this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is 1, getPort() ignores trusted headers on untrusted connection.');
$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(
'HTTP_X_FORWARDED_PROTO' => 'something-else',
@ -1066,6 +1068,8 @@ class RequestTest extends \PHPUnit_Framework_TestCase
$request->headers->set('X_FORWARDED_PROTO', 'https');
Request::setTrustedProxies(array('1.1.1.1'));
$this->assertFalse($request->isSecure());
$request->server->set('REMOTE_ADDR', '1.1.1.1');
$this->assertTrue($request->isSecure());
Request::setTrustedProxies(array());
@ -1544,7 +1548,15 @@ class RequestTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(443, $request->getPort());
$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
Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
$request->headers->set('X_FORWARDED_PROTO', 'ssl');
$this->assertTrue($request->isSecure());

View File

@ -29,6 +29,10 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
class Esi implements SurrogateInterface
{
private $contentTypes;
private $phpEscapeMap = array(
array('<?', '<%', '<s', '<S'),
array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>', '<?php echo "<s"; ?>', '<?php echo "<S"; ?>'),
);
/**
* 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
$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\: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->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
{
private $contentTypes;
private $phpEscapeMap = array(
array('<?', '<%', '<s', '<S'),
array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>', '<?php echo "<s"; ?>', '<?php echo "<S"; ?>'),
);
/**
* 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
$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->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();
$request = Request::create('/');
$response = new Response('foo <?php die("foo"); ?><%= "lala" %>');
$response = new Response('<?php <? <% <script language=php>');
$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();
$request = Request::create('/');
$response = new Response('foo <?php die("foo"); ?><%= "lala" %>');
$response = new Response('<?php <? <% <script language=php>');
$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)
array('seci', 4, false, true, array('ex', 'ix', 'ice')),
// movies (movie)
array('seivom', 6, true, true, 'movie'),
// babies (baby)
array('sei', 3, false, true, 'y'),

View File

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