diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index f5471bf653f4b..335dfd82e4186 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,17 @@ in 2.7 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.7.0...v2.7.1 +* 2.7.32 (2017-07-17) + + * security #23507 [Security] validate empty passwords again (xabbuh) + * bug #23526 [HttpFoundation] Set meta refresh time to 0 in RedirectResponse content (jnvsor) + * bug #23468 [DI] Handle root namespace in service definitions (ro0NL) + * bug #23256 [Security] Fix authentication.failure event not dispatched on AccountStatusException (chalasr) + * bug #23461 Use rawurlencode() to transform the Cookie into a string (javiereguiluz) + * bug #23459 [TwigBundle] allow to configure custom formats in XML configs (xabbuh) + * bug #23261 Fixed absolute url generation for query strings and hash urls (alexander-schranz) + * bug #23398 [Filesystem] Dont copy perms when origin is remote (nicolas-grekas) + * 2.7.31 (2017-07-05) * bug #23378 [FrameworkBundle] Do not remove files from assets dir (1ed) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 3e670f8d67e90..47a6cf9986dcf 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -19,13 +19,13 @@ Symfony is the result of the work of many people who made the code better - Ryan Weaver (weaverryan) - Javier Eguiluz (javier.eguiluz) - Hugo Hamon (hhamon) - - Abdellatif Ait boudad (aitboudad) - Maxime Steinhausser (ogizanagi) + - Abdellatif Ait boudad (aitboudad) - Robin Chalas (chalas_r) - Romain Neutron (romain) - Pascal Borreli (pborreli) - - Wouter De Jong (wouterj) - Grégoire Pineau (lyrixx) + - Wouter De Jong (wouterj) - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - Lukas Kahwe Smith (lsmith) @@ -35,8 +35,8 @@ Symfony is the result of the work of many people who made the code better - Benjamin Eberlei (beberlei) - Igor Wiedler (igorw) - Eriksen Costa (eriksencosta) - - Jules Pietri (heah) - Roland Franssen (ro0) + - Jules Pietri (heah) - Sarah Khalil (saro0h) - Guilhem Niot (energetick) - Jonathan Wage (jwage) @@ -93,6 +93,7 @@ Symfony is the result of the work of many people who made the code better - Maxime STEINHAUSSER - Alexander M. Turek (derrabus) - Michal Piotrowski (eventhorizon) + - Dany Maillard (maidmaid) - Issei Murasawa (issei_m) - Tim Nagel (merk) - Brice BERNARD (brikou) @@ -133,7 +134,6 @@ Symfony is the result of the work of many people who made the code better - Guilherme Blanco (guilhermeblanco) - Pablo Godel (pgodel) - Jérémie Augustin (jaugustin) - - Dany Maillard (maidmaid) - Andréia Bohner (andreia) - Rafael Dohms (rdohms) - Arnaud Kleinpeter (nanocom) @@ -141,6 +141,7 @@ Symfony is the result of the work of many people who made the code better - David Maicher (dmaicher) - Mikael Pajunen - Joel Wurtz (brouznouf) + - Jérôme Vasseur (jvasseur) - Grégoire Paris (greg0ire) - Philipp Wahala (hifi) - Vyacheslav Pavlov @@ -150,7 +151,6 @@ Symfony is the result of the work of many people who made the code better - Thomas Rabaix (rande) - Rouven Weßling (realityking) - Teoh Han Hui (teohhanhui) - - Jérôme Vasseur (jvasseur) - Clemens Tolboom - Helmer Aaviksoo - Hiromi Hishida (77web) @@ -162,6 +162,7 @@ Symfony is the result of the work of many people who made the code better - Artur Kotyrba - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - James Halsall (jaitsu) + - Chris Wilkinson (thewilkybarkid) - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) @@ -174,7 +175,6 @@ Symfony is the result of the work of many people who made the code better - Dennis Benkert (denderello) - Benjamin Dulau (dbenjamin) - Mathieu Lemoine (lemoinem) - - Chris Wilkinson (thewilkybarkid) - Andreas Hucks (meandmymonkey) - Noel Guilbert (noel) - Stepan Anchugov (kix) @@ -238,6 +238,7 @@ Symfony is the result of the work of many people who made the code better - Alif Rachmawadi - Kristen Gilden (kgilden) - Pierre-Yves LEBECQ (pylebecq) + - Jordan Samouh (jordansamouh) - Alex Pott - Jakub Kucharovic (jkucharovic) - Uwe Jäger (uwej711) @@ -248,6 +249,7 @@ Symfony is the result of the work of many people who made the code better - GordonsLondon - Jan Sorgalla (jsor) - Ray + - Nikolay Labinskiy (e-moe) - Leo Feyer - Chekote - Thomas Adam @@ -274,8 +276,8 @@ Symfony is the result of the work of many people who made the code better - Marc Weistroff (futurecat) - Christian Schmidt - Hidde Wieringa (hiddewie) + - Alessandro Chitolina - Chad Sikorra (chadsikorra) - - Jordan Samouh (jordansamouh) - Chris Smith (cs278) - Florian Klein (docteurklein) - Manuel Kiessling (manuelkiessling) @@ -294,7 +296,6 @@ Symfony is the result of the work of many people who made the code better - Victor Bocharsky (bocharsky_bw) - Jan Decavele (jandc) - Gustavo Piltcher - - Nikolay Labinskiy (e-moe) - Stepan Tanasiychuk (stfalcon) - Tiago Ribeiro (fixe) - Hidde Boomsma (hboomsma) @@ -309,6 +310,7 @@ Symfony is the result of the work of many people who made the code better - Thomas Schulz (king2500) - Dariusz Rumiński - Berny Cantos (xphere81) + - Thierry Thuon (lepiaf) - Ricard Clau (ricardclau) - Mark Challoner (markchalloner) - Gregor Harlan (gharlan) @@ -327,6 +329,7 @@ Symfony is the result of the work of many people who made the code better - Inal DJAFAR (inalgnu) - Christian Gärtner (dagardner) - Tomasz Kowalczyk (thunderer) + - Michael Babker (mbabker) - François-Xavier de Guillebon (de-gui_f) - Damien Alexandre (damienalexandre) - Felix Labrecque @@ -335,7 +338,6 @@ Symfony is the result of the work of many people who made the code better - Robbert Klarenbeek (robbertkl) - Thomas Calvet (fancyweb) - Niels Keurentjes (curry684) - - Alessandro Chitolina - JhonnyL - hossein zolfi (ocean) - Clément Gautier (clementgautier) @@ -401,6 +403,7 @@ Symfony is the result of the work of many people who made the code better - Olivier Dolbeau (odolbeau) - Jan Rosier (rosier) - Thomas Royer (cydonia7) + - Arturs Vonda - Josip Kruslin - Asmir Mustafic (goetas) - vagrant @@ -428,6 +431,7 @@ Symfony is the result of the work of many people who made the code better - David Badura (davidbadura) - Zander Baldwin - Adam Harvey + - Maxime Veber (nek-) - Alex Bakhturin - Alexander Obuhovich (aik099) - boombatower @@ -441,6 +445,7 @@ Symfony is the result of the work of many people who made the code better - Gladhon - Benoît Burnichon (bburnichon) - Sebastian Bergmann + - Miroslav Sustek - Pablo Díez (pablodip) - Kevin McBride - Sergio Santoro @@ -550,7 +555,6 @@ Symfony is the result of the work of many people who made the code better - Maxime Douailin - Jean Pasdeloup (pasdeloup) - Benjamin Cremer (bcremer) - - Thierry Thuon (lepiaf) - Javier López (loalf) - Reinier Kip - Geoffrey Brier (geoffrey-brier) @@ -572,6 +576,7 @@ Symfony is the result of the work of many people who made the code better - Alex Bogomazov (alebo) - maxime.steinhausser - Stefan Warman + - Thomas Perez (scullwm) - Tristan Maindron (tmaindron) - Wesley Lancel - Ke WANG (yktd26) @@ -580,7 +585,6 @@ Symfony is the result of the work of many people who made the code better - Sergey Kolodyazhnyy (skolodyazhnyy) - umpirski - Denis Brumann (dbrumann) - - Michael Babker (mbabker) - Quentin de Longraye (quentinus95) - Chris Heng (gigablah) - Richard Bradley @@ -590,7 +594,6 @@ Symfony is the result of the work of many people who made the code better - Michael Devery (mickadoo) - Antoine Corcy - Artur Eshenbrener - - Arturs Vonda - Sascha Grossenbacher - Szijarto Tamas - Catalin Dan @@ -620,7 +623,6 @@ Symfony is the result of the work of many people who made the code better - develop - ReenExe - Mark Sonnabaum - - Maxime Veber (nek-) - Richard Quadling - jochenvdv - Arturas Smorgun (asarturas) @@ -669,7 +671,6 @@ Symfony is the result of the work of many people who made the code better - Christian Soronellas (theunic) - Yosmany Garcia (yosmanyga) - Wouter de Wild - - Miroslav Sustek - Degory Valentine - Benoit Lévêque (benoit_leveque) - Jeroen Fiege (fieg) @@ -693,6 +694,7 @@ Symfony is the result of the work of many people who made the code better - Jan Prieser - Adrien Lucas (adrienlucas) - Zhuravlev Alexander (scif) + - Yanick Witschi (toflar) - James Michael DuPont - Tom Klingenberg - Christopher Hall (mythmakr) @@ -834,7 +836,6 @@ Symfony is the result of the work of many people who made the code better - Danilo Silva - Zachary Tong (polyfractal) - Hryhorii Hrebiniuk - - Thomas Perez (scullwm) - Dennis Fridrich (dfridrich) - hamza - dantleech @@ -863,6 +864,7 @@ Symfony is the result of the work of many people who made the code better - Goran Juric - Laurent Ghirardotti (laurentg) - Nicolas Macherey + - AKeeman (akeeman) - Lin Clark - Jeremy David (jeremy.david) - Robin Lehrmann (robinlehrmann) @@ -1104,6 +1106,7 @@ Symfony is the result of the work of many people who made the code better - Max Romanovsky (maxromanovsky) - Mathieu Morlon - Daniel Tschinder + - Alexander Schranz - Rafał Muszyński (rafmus90) - Timothy Anido (xanido) - Rick Prent @@ -1411,6 +1414,7 @@ Symfony is the result of the work of many people who made the code better - Rosio (ben-rosio) - Simon Paarlberg (blamh) - Jeroen Thora (bolle) + - Brieuc THOMAS (brieucthomas) - Masao Maeda (brtriver) - Darius Leskauskas (darles) - David Joos (djoos) @@ -1440,7 +1444,6 @@ Symfony is the result of the work of many people who made the code better - Cyrille Jouineau (tuxosaurus) - Yorkie Chadwick (yorkie76) - GuillaumeVerdon - - Yanick Witschi - Ondrej Mirtes - akimsko - Youpie diff --git a/composer.json b/composer.json index 1770bc4f305af..a7f3bbf9078d9 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": ">=5.3.9", + "ext-xml": "*", "doctrine/common": "~2.4", "paragonie/random_compat": "~1.0", "symfony/polyfill-apcu": "~1.1", diff --git a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php index 90b515ee320ba..0dad40cfa0a3f 100644 --- a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php @@ -72,6 +72,13 @@ public function generateAbsoluteUrl($path) $port = ':'.$this->requestContext->getHttpsPort(); } + if ('#' === $path[0]) { + $queryString = $this->requestContext->getQueryString(); + $path = $this->requestContext->getPathInfo().($queryString ? '?'.$queryString : '').$path; + } elseif ('?' === $path[0]) { + $path = $this->requestContext->getPathInfo().$path; + } + if ('/' !== $path[0]) { $path = rtrim($this->requestContext->getBaseUrl(), '/').'/'.$path; } @@ -82,6 +89,12 @@ public function generateAbsoluteUrl($path) return $path; } + if ('#' === $path[0]) { + $path = $request->getRequestUri().$path; + } elseif ('?' === $path[0]) { + $path = $request->getPathInfo().$path; + } + if (!$path || '/' !== $path[0]) { $prefix = $request->getPathInfo(); $last = strlen($prefix) - 1; diff --git a/src/Symfony/Bridge/Twig/Form/TwigRenderer.php b/src/Symfony/Bridge/Twig/Form/TwigRenderer.php index 2485c0a88c530..9f4d7c56ea886 100644 --- a/src/Symfony/Bridge/Twig/Form/TwigRenderer.php +++ b/src/Symfony/Bridge/Twig/Form/TwigRenderer.php @@ -19,16 +19,19 @@ */ class TwigRenderer extends FormRenderer implements TwigRendererInterface { - /** - * @var TwigRendererEngineInterface - */ - private $engine; - public function __construct(TwigRendererEngineInterface $engine, $csrfTokenManager = null) { parent::__construct($engine, $csrfTokenManager); + } - $this->engine = $engine; + /** + * Returns the engine used by this renderer. + * + * @return TwigRendererEngineInterface The renderer engine + */ + public function getEngine() + { + return parent::getEngine(); } /** @@ -36,6 +39,6 @@ public function __construct(TwigRendererEngineInterface $engine, $csrfTokenManag */ public function setEnvironment(Environment $environment) { - $this->engine->setEnvironment($environment); + $this->getEngine()->setEnvironment($environment); } } diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php index 8f0c66ad78bb4..fcff0c0e1b93b 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/HttpFoundationExtensionTest.php @@ -42,6 +42,15 @@ public function getGenerateAbsoluteUrlData() array('http://example.com/baz', 'http://example.com/baz', '/'), array('https://example.com/baz', 'https://example.com/baz', '/'), array('//example.com/baz', '//example.com/baz', '/'), + + array('http://localhost/foo/bar?baz', '?baz', '/foo/bar'), + array('http://localhost/foo/bar?baz=1', '?baz=1', '/foo/bar?foo=1'), + array('http://localhost/foo/baz?baz=1', 'baz?baz=1', '/foo/bar?foo=1'), + + array('http://localhost/foo/bar#baz', '#baz', '/foo/bar'), + array('http://localhost/foo/bar?0#baz', '#baz', '/foo/bar?0'), + array('http://localhost/foo/bar?baz=1#baz', '?baz=1#baz', '/foo/bar?foo=1'), + array('http://localhost/foo/baz?baz=1#baz', 'baz?baz=1#baz', '/foo/bar?foo=1'), ); } diff --git a/src/Symfony/Bundle/DebugBundle/composer.json b/src/Symfony/Bundle/DebugBundle/composer.json index d4cba7fc2410b..3fde4a67247eb 100644 --- a/src/Symfony/Bundle/DebugBundle/composer.json +++ b/src/Symfony/Bundle/DebugBundle/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": ">=5.3.9", + "ext-xml": "*", "symfony/http-kernel": "~2.6", "symfony/twig-bridge": "~2.6", "symfony/var-dumper": "~2.6" diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 3da10d429d4bf..6d6073f7f0bc3 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": ">=5.3.9", + "ext-xml": "*", "symfony/security": "~2.7", "symfony/security-acl": "~2.7", "symfony/http-kernel": "~2.7" diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd index 474b6c9721e0c..70b6de5c38d5c 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/schema/twig-1.0.xsd @@ -9,6 +9,9 @@ + + + @@ -28,6 +31,18 @@ + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/formats.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/formats.php new file mode 100644 index 0000000000000..630a9a9edc01a --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/formats.php @@ -0,0 +1,14 @@ +loadFromExtension('twig', array( + 'date' => array( + 'format' => 'Y-m-d', + 'interval_format' => '%d', + 'timezone' => 'Europe/Berlin', + ), + 'number_format' => array( + 'decimals' => 2, + 'decimal_point' => ',', + 'thousands_separator' => '.', + ), +)); diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/formats.xml b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/formats.xml new file mode 100644 index 0000000000000..1ab39e49229cd --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/formats.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/formats.yml b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/formats.yml new file mode 100644 index 0000000000000..290921630f9e6 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/yml/formats.yml @@ -0,0 +1,9 @@ +twig: + date: + format: Y-m-d + interval_format: '%d' + timezone: Europe/Berlin + number_format: + decimals: 2 + decimal_point: ',' + thousands_separator: . diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php index f5809cc045c42..f385ec04fd28c 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php @@ -150,6 +150,26 @@ public function testLoadDefaultTemplateEscapingGuesserConfiguration($format) $this->assertEquals('name', $options['autoescape']); } + /** + * @dataProvider getFormats + */ + public function testLoadCustomDateFormats($fileFormat) + { + $container = $this->createContainer(); + $container->registerExtension(new TwigExtension()); + $this->loadFromFile($container, 'formats', $fileFormat); + $this->compileContainer($container); + + $environmentConfigurator = $container->getDefinition('twig.configurator.environment'); + + $this->assertSame('Y-m-d', $environmentConfigurator->getArgument(0)); + $this->assertSame('%d', $environmentConfigurator->getArgument(1)); + $this->assertSame('Europe/Berlin', $environmentConfigurator->getArgument(2)); + $this->assertSame(2, $environmentConfigurator->getArgument(3)); + $this->assertSame(',', $environmentConfigurator->getArgument(4)); + $this->assertSame('.', $environmentConfigurator->getArgument(5)); + } + public function testGlobalsWithDifferentTypesAndValues() { $globals = array( diff --git a/src/Symfony/Component/BrowserKit/Cookie.php b/src/Symfony/Component/BrowserKit/Cookie.php index 42f184d532e02..c042c6a525295 100644 --- a/src/Symfony/Component/BrowserKit/Cookie.php +++ b/src/Symfony/Component/BrowserKit/Cookie.php @@ -62,7 +62,7 @@ public function __construct($name, $value, $expires = null, $path = null, $domai $this->rawValue = $value; } else { $this->value = $value; - $this->rawValue = urlencode($value); + $this->rawValue = rawurlencode($value); } $this->name = $name; $this->path = empty($path) ? '/' : $path; diff --git a/src/Symfony/Component/BrowserKit/Tests/CookieTest.php b/src/Symfony/Component/BrowserKit/Tests/CookieTest.php index 38ea81220bb2c..2f5a08d104143 100644 --- a/src/Symfony/Component/BrowserKit/Tests/CookieTest.php +++ b/src/Symfony/Component/BrowserKit/Tests/CookieTest.php @@ -16,6 +16,21 @@ class CookieTest extends TestCase { + public function testToString() + { + $cookie = new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true); + $this->assertEquals('foo=bar; expires=Fri, 20 May 2011 15:25:52 GMT; domain=.myfoodomain.com; path=/; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie'); + + $cookie = new Cookie('foo', 'bar with white spaces', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true); + $this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20 May 2011 15:25:52 GMT; domain=.myfoodomain.com; path=/; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)'); + + $cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com'); + $this->assertEquals('foo=; expires=Thu, 01 Jan 1970 00:00:01 GMT; domain=.myfoodomain.com; path=/admin/; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL'); + + $cookie = new Cookie('foo', 'bar', 0, '/', ''); + $this->assertEquals('foo=bar; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; httponly', (string) $cookie); + } + /** * @dataProvider getTestsForToFromString */ diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index f6c953f550993..7bf2e36ec2da2 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -29,16 +29,6 @@ * * Parameter and service keys are case insensitive. * - * A service id can contain lowercased letters, digits, underscores, and dots. - * Underscores are used to separate words, and dots to group services - * under namespaces: - * - *
    - *
  • request
  • - *
  • mysql_session_storage
  • - *
  • symfony.mysql_session_storage
  • - *
- * * A service can also be defined by creating a method named * getXXXService(), where XXX is the camelized version of the id: * diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 09d22fcb5fd3d..1665f7542b7ce 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -377,15 +377,9 @@ private function addServiceReturn($id, $definition) */ private function addServiceInstance($id, Definition $definition) { - $class = $definition->getClass(); - - if ('\\' === substr($class, 0, 1)) { - $class = substr($class, 1); - } - - $class = $this->dumpValue($class); + $class = $this->dumpValue($definition->getClass()); - if (0 === strpos($class, "'") && !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + if (0 === strpos($class, "'") && !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id)); } @@ -1440,11 +1434,13 @@ private function dumpLiteralClass($class) if (false !== strpos($class, '$')) { throw new RuntimeException('Cannot dump definitions which have a variable class name.'); } - if (0 !== strpos($class, "'") || !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + if (0 !== strpos($class, "'") || !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { throw new RuntimeException(sprintf('Cannot dump definition because of invalid class name (%s)', $class ?: 'n/a')); } - return '\\'.substr(str_replace('\\\\', '\\', $class), 1, -1); + $class = substr(str_replace('\\\\', '\\', $class), 1, -1); + + return 0 === strpos($class, '\\') ? $class : '\\'.$class; } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php index 02018c5a0a999..5ec0deed3d3a4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php @@ -134,8 +134,8 @@ public function testGetServiceIds() public function testSet() { $sc = new Container(); - $sc->set('foo', $foo = new \stdClass()); - $this->assertSame($foo, $sc->get('foo'), '->set() sets a service'); + $sc->set('._. \\o/', $foo = new \stdClass()); + $this->assertSame($foo, $sc->get('._. \\o/'), '->set() sets a service'); } public function testSetWithNullResetTheService() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 41b6c375d8aab..1ce5b7b9993d8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -339,4 +339,17 @@ public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServic $this->addToAssertionCount(1); } + + public function testDumpHandlesLiteralClassWithRootNamespace() + { + $container = new ContainerBuilder(); + $container->register('foo', '\\stdClass'); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Literal_Class_With_Root_Namespace'))); + + $container = new \Symfony_DI_PhpDumper_Test_Literal_Class_With_Root_Namespace(); + + $this->assertInstanceOf('stdClass', $container->get('foo')); + } } diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index e60d4690738ad..bc2e3dcc2d897 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -37,7 +37,8 @@ class Filesystem */ public function copy($originFile, $targetFile, $overwriteNewerFiles = false) { - if (stream_is_local($originFile) && !is_file($originFile)) { + $originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://'); + if ($originIsLocal && !is_file($originFile)) { throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile); } @@ -68,11 +69,13 @@ public function copy($originFile, $targetFile, $overwriteNewerFiles = false) throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile); } - // Like `cp`, preserve executable permission bits - @chmod($targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111)); + if ($originIsLocal) { + // Like `cp`, preserve executable permission bits + @chmod($targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111)); - if (stream_is_local($originFile) && $bytesCopied !== ($bytesOrigin = filesize($originFile))) { - throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile); + if ($bytesCopied !== $bytesOrigin = filesize($originFile)) { + throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile); + } } } } diff --git a/src/Symfony/Component/HttpFoundation/Cookie.php b/src/Symfony/Component/HttpFoundation/Cookie.php index 91783a6ad2b50..fb1e7dfd74ea4 100644 --- a/src/Symfony/Component/HttpFoundation/Cookie.php +++ b/src/Symfony/Component/HttpFoundation/Cookie.php @@ -82,7 +82,7 @@ public function __toString() if ('' === (string) $this->getValue()) { $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001); } else { - $str .= urlencode($this->getValue()); + $str .= rawurlencode($this->getValue()); if (0 !== $this->getExpiresTime()) { $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()); diff --git a/src/Symfony/Component/HttpFoundation/RedirectResponse.php b/src/Symfony/Component/HttpFoundation/RedirectResponse.php index 5a775ad159f3a..4118fff24c892 100644 --- a/src/Symfony/Component/HttpFoundation/RedirectResponse.php +++ b/src/Symfony/Component/HttpFoundation/RedirectResponse.php @@ -83,7 +83,7 @@ public function setTargetUrl($url) - + Redirecting to %1$s diff --git a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php index f3f74f635eb40..2d9fb09d3d4b6 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php @@ -160,6 +160,9 @@ public function testToString() $cookie = new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true); $this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie'); + $cookie = new Cookie('foo', 'bar with white spaces', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true); + $this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)'); + $cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com'); $this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; path=/admin/; domain=.myfoodomain.com; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL'); diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 6233186a48e22..44b7ef2bca903 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,11 +58,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.31'; - const VERSION_ID = 20731; + const VERSION = '2.7.32'; + const VERSION_ID = 20732; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; - const RELEASE_VERSION = 31; + const RELEASE_VERSION = 32; const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '05/2018'; diff --git a/src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php b/src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php index 16de8daaeda93..4c0a7459d070c 100644 --- a/src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php +++ b/src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php @@ -83,9 +83,9 @@ public function authenticate(TokenInterface $token) break; } } catch (AccountStatusException $e) { - $e->setToken($token); + $lastException = $e; - throw $e; + break; } catch (AuthenticationException $e) { $lastException = $e; } diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationProviderManagerTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationProviderManagerTest.php index 9b8105012c3d8..373369d455959 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationProviderManagerTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationProviderManagerTest.php @@ -13,6 +13,9 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; +use Symfony\Component\Security\Core\AuthenticationEvents; +use Symfony\Component\Security\Core\Event\AuthenticationEvent; +use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; use Symfony\Component\Security\Core\Exception\ProviderNotFoundException; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\AccountStatusException; @@ -124,6 +127,50 @@ public function testEraseCredentialFlag() $this->assertEquals('bar', $token->getCredentials()); } + public function testAuthenticateDispatchesAuthenticationFailureEvent() + { + $token = new UsernamePasswordToken('foo', 'bar', 'key'); + $provider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock(); + $provider->expects($this->once())->method('supports')->willReturn(true); + $provider->expects($this->once())->method('authenticate')->willThrowException($exception = new AuthenticationException()); + + $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); + $dispatcher + ->expects($this->once()) + ->method('dispatch') + ->with(AuthenticationEvents::AUTHENTICATION_FAILURE, $this->equalTo(new AuthenticationFailureEvent($token, $exception))); + + $manager = new AuthenticationProviderManager(array($provider)); + $manager->setEventDispatcher($dispatcher); + + try { + $manager->authenticate($token); + $this->fail('->authenticate() should rethrow exceptions'); + } catch (AuthenticationException $e) { + $this->assertSame($token, $exception->getToken()); + } + } + + public function testAuthenticateDispatchesAuthenticationSuccessEvent() + { + $token = new UsernamePasswordToken('foo', 'bar', 'key'); + + $provider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock(); + $provider->expects($this->once())->method('supports')->willReturn(true); + $provider->expects($this->once())->method('authenticate')->willReturn($token); + + $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); + $dispatcher + ->expects($this->once()) + ->method('dispatch') + ->with(AuthenticationEvents::AUTHENTICATION_SUCCESS, $this->equalTo(new AuthenticationEvent($token))); + + $manager = new AuthenticationProviderManager(array($provider)); + $manager->setEventDispatcher($dispatcher); + + $this->assertSame($token, $manager->authenticate($token)); + } + protected function getAuthenticationProvider($supports, $token = null, $exception = null) { $provider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock(); diff --git a/src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php b/src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php index 7ebe65c647d99..942a4a6350f27 100644 --- a/src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordValidatorTest.php @@ -90,6 +90,29 @@ public function testPasswordIsNotValid() ->assertRaised(); } + /** + * @dataProvider emptyPasswordData + */ + public function testEmptyPasswordsAreNotValid($password) + { + $constraint = new UserPassword(array( + 'message' => 'myMessage', + )); + + $this->validator->validate($password, $constraint); + + $this->buildViolation('myMessage') + ->assertRaised(); + } + + public function emptyPasswordData() + { + return array( + array(null), + array(''), + ); + } + /** * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException */ diff --git a/src/Symfony/Component/Security/Core/User/UserProviderInterface.php b/src/Symfony/Component/Security/Core/User/UserProviderInterface.php index d17e3b704d981..03f38f08848ba 100644 --- a/src/Symfony/Component/Security/Core/User/UserProviderInterface.php +++ b/src/Symfony/Component/Security/Core/User/UserProviderInterface.php @@ -50,7 +50,7 @@ interface UserProviderInterface public function loadUserByUsername($username); /** - * Refreshes the user for the account interface. + * Refreshes the user. * * It is up to the implementation to decide if the user data should be * totally reloaded (e.g. from the database), or if the UserInterface @@ -61,7 +61,7 @@ public function loadUserByUsername($username); * * @return UserInterface * - * @throws UnsupportedUserException if the account is not supported + * @throws UnsupportedUserException if the user is not supported */ public function refreshUser(UserInterface $user); diff --git a/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php b/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php index 5f4c146cab469..c2ab13b2f6d29 100644 --- a/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php +++ b/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php @@ -40,6 +40,8 @@ public function validate($password, Constraint $constraint) } if (null === $password || '' === $password) { + $this->context->addViolation($constraint->message); + return; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy