diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index cf90bc2e50f34..f5471bf653f4b 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,10 @@ 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.31 (2017-07-05) + + * bug #23378 [FrameworkBundle] Do not remove files from assets dir (1ed) + * 2.7.30 (2017-07-03) * bug #23341 [DoctrineBridge][Security][Validator] do not validate empty values (xabbuh) diff --git a/CHANGELOG-2.8.md b/CHANGELOG-2.8.md index 661863ef7ce54..a73a824d4cf45 100644 --- a/CHANGELOG-2.8.md +++ b/CHANGELOG-2.8.md @@ -7,6 +7,19 @@ in 2.8 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.8.0...v2.8.1 +* 2.8.25 (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 #23540 Disable inlining deprecated services (alekitto) + * 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 #23460 Don't display the Symfony debug toolbar when printing the page (javiereguiluz) + * 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.8.24 (2017-07-05) * bug #23378 [FrameworkBundle] Do not remove files from assets dir (1ed) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0b695308c528f..3e670f8d67e90 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -70,9 +70,9 @@ Symfony is the result of the work of many people who made the code better - Deni - Henrik Westphal (snc) - Dariusz Górecki (canni) + - Jáchym Toušek (enumag) - Titouan Galopin (tgalopin) - Douglas Greenshields (shieldo) - - Jáchym Toušek (enumag) - Konstantin Myakshin (koc) - Lee McDermott - Brandon Turner @@ -99,11 +99,12 @@ Symfony is the result of the work of many people who made the code better - Baptiste Clavié (talus) - Vladimir Reznichenko (kalessil) - marc.weistroff + - Yonel Ceruto González (yonelceruto) - lenar - Włodzimierz Gajda (gajdaw) - - Yonel Ceruto González (yonelceruto) - Alexander Schwenn (xelaris) - Jacob Dreesen (jdreesen) + - Tobias Nyholm (tobias) - Florian Voutzinos (florianv) - Colin Frei - Adrien Brault (adrienbrault) @@ -111,7 +112,6 @@ Symfony is the result of the work of many people who made the code better - Peter Kokot (maastermedia) - David Buchmann (dbu) - excelwebzone - - Tobias Nyholm (tobias) - Tomáš Votruba (tomas_votruba) - Fabien Pennequin (fabienpennequin) - Gordon Franke (gimler) @@ -133,12 +133,15 @@ 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) - jwdeitch + - David Maicher (dmaicher) - Mikael Pajunen - Joel Wurtz (brouznouf) + - Grégoire Paris (greg0ire) - Philipp Wahala (hifi) - Vyacheslav Pavlov - Richard van Laak (rvanlaak) @@ -147,11 +150,9 @@ 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) - - David Maicher (dmaicher) - Jérôme Vasseur (jvasseur) - Clemens Tolboom - Helmer Aaviksoo - - Grégoire Paris (greg0ire) - Hiromi Hishida (77web) - Matthieu Ouellette-Vachon (maoueh) - Michał Pipa (michal.pipa) @@ -234,7 +235,6 @@ Symfony is the result of the work of many people who made the code better - Arjen Brouwer (arjenjb) - Katsuhiro OGAWA - Patrick McDougle (patrick-mcdougle) - - Dany Maillard (maidmaid) - Alif Rachmawadi - Kristen Gilden (kgilden) - Pierre-Yves LEBECQ (pylebecq) @@ -620,6 +620,7 @@ 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) @@ -642,6 +643,7 @@ Symfony is the result of the work of many people who made the code better - Trent Steel (trsteel88) - Yuen-Chi Lian - Besnik Br + - Jose Gonzalez - Dariusz Ruminski - Joshua Nye - Claudio Zizza @@ -1081,7 +1083,6 @@ Symfony is the result of the work of many people who made the code better - Max Summe - WedgeSama - Felds Liscia - - Maxime Veber (nek-) - Sullivan SENECHAL - Tadcka - Beth Binkovitz @@ -1092,12 +1093,12 @@ Symfony is the result of the work of many people who made the code better - Tomaz Ahlin - Marcus Stöhr (dafish) - Emmanuel Vella (emmanuel.vella) + - Adam Szaraniec (mimol) - Carsten Nielsen (phreaknerd) - Mathieu Rochette - Jay Severson - René Kerner - Nathaniel Catchpole - - Jose Gonzalez - Adrien Samson (adriensamson) - Samuel Gordalina (gordalina) - Max Romanovsky (maxromanovsky) @@ -1258,6 +1259,7 @@ Symfony is the result of the work of many people who made the code better - Aarón Nieves Fernández - Mike Meier - Kirill Saksin + - Julien Pauli - Koalabaerchen - michalmarcinkowski - Warwick @@ -1305,6 +1307,7 @@ Symfony is the result of the work of many people who made the code better - klemens - dened - Dmitry Korotovsky + - mcorteel - Michael van Tricht - Sam Ward - Walther Lalk @@ -1335,6 +1338,7 @@ Symfony is the result of the work of many people who made the code better - Jan Marek (janmarek) - Mark de Haan (markdehaan) - Dan Patrick (mdpatrick) + - Pedro Magalhães (pmmaga) - Rares Vlaseanu (raresvla) - tante kinast (tante) - Vincent LEFORT (vlefort) @@ -1542,6 +1546,7 @@ Symfony is the result of the work of many people who made the code better - Abdulkadir N. A. - Yevgen Kovalienia - Lebnik + - Shude - Ondřej Führer - Sema - Elan Ruusamäe diff --git a/composer.json b/composer.json index 8da4f2529cc93..8e2db75120a47 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": ">=5.3.9", + "ext-xml": "*", "doctrine/common": "~2.4", "twig/twig": "~1.34|~2.4", "psr/log": "~1.0", 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 0221a3f2bb81e..98305f79dcbcc 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|~3.0.0", "symfony/twig-bridge": "~2.6|~3.0.0", "symfony/var-dumper": "~2.6|~3.0.0" diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 34117bff7cb6e..04fd6473053e8 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.8|~3.0.0", "symfony/security-acl": "~2.7|~3.0.0", "symfony/http-kernel": "~2.7|~3.0.0", 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/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig index c148954f5a9c8..16a3310d77178 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig @@ -527,3 +527,10 @@ padding: 5px 0; margin-right: 10px; } + +/***** Media query print: Do not print the Toolbar. *****/ +@media print { + .sf-toolbar { + display: none; + } +} 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/Compiler/InlineServiceDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php index 1beaaf0c53ce0..bf95ea5b0a269 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php @@ -113,7 +113,7 @@ private function isInlineableDefinition(ContainerBuilder $container, $id, Defini return true; } - if ($definition->isPublic() || $definition->isLazy()) { + if ($definition->isDeprecated() || $definition->isPublic() || $definition->isLazy()) { return false; } diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index ea804c701bb0f..869339ef63132 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -30,16 +30,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 6c131aae19770..713550bb4109e 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)); } @@ -1460,11 +1454,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/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 732ce97a17dcc..3c14bfc19895e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -891,6 +891,27 @@ public function testAutowiring() $this->assertEquals('a', (string) $container->getDefinition('b')->getArgument(0)); } + + /** + * This test checks the trigger of a deprecation note and should not be removed in major releases. + * + * @group legacy + * @expectedDeprecation The "foo" service is deprecated. You should stop using it, as it will soon be removed. + */ + public function testPrivateServiceTriggersDeprecation() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass') + ->setPublic(false) + ->setDeprecated(true); + $container->register('bar', 'stdClass') + ->setPublic(true) + ->setProperty('foo', new Reference('foo')); + + $container->compile(); + + $container->get('bar'); + } } class FooClass diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php index dbe18f607e968..721932591f177 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 06d4c70ad2e08..c49586463d7cc 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -347,4 +347,43 @@ 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')); + } + + /** + * This test checks the trigger of a deprecation note and should not be removed in major releases. + * + * @group legacy + * @expectedDeprecation The "foo" service is deprecated. You should stop using it, as it will soon be removed. + */ + public function testPrivateServiceTriggersDeprecation() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass') + ->setPublic(false) + ->setDeprecated(true); + $container->register('bar', 'stdClass') + ->setPublic(true) + ->setProperty('foo', new Reference('foo')); + + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Private_Service_Triggers_Deprecation'))); + + $container = new \Symfony_DI_PhpDumper_Test_Private_Service_Triggers_Deprecation(); + + $container->get('bar'); + } } diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index cfa6540399dbe..56f8c85a38109 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 056d2e2aad253..a94e866c36fbb 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,11 +59,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.24'; - const VERSION_ID = 20824; + const VERSION = '2.8.25'; + const VERSION_ID = 20825; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; - const RELEASE_VERSION = 24; + const RELEASE_VERSION = 25; const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/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 146ed65ad303d..9570edc2776ab 100644 --- a/src/Symfony/Component/Security/Core/User/UserProviderInterface.php +++ b/src/Symfony/Component/Security/Core/User/UserProviderInterface.php @@ -48,7 +48,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 @@ -59,7 +59,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