From 27e8cd289cc1f3511ccf77ae30b574ceb524aa51 Mon Sep 17 00:00:00 2001 From: mlazovla Date: Thu, 10 Aug 2017 12:58:49 +0200 Subject: [PATCH 01/40] Filtering empty uuids in ORMQueryBuilderLoader. --- .../Form/ChoiceList/ORMQueryBuilderLoader.php | 2 +- .../Doctrine/Tests/Fixtures/GuidIdEntity.php | 28 +++++++++++++ .../Doctrine/Tests/Fixtures/UuidIdEntity.php | 28 +++++++++++++ .../ChoiceList/ORMQueryBuilderLoaderTest.php | 40 +++++++++++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/GuidIdEntity.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/UuidIdEntity.php diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index 8930dc9f27377..297e2ddfe7a43 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php @@ -106,7 +106,7 @@ public function getEntitiesByIds($identifier, array $values) $values = array_values(array_filter($values, function ($v) { return (string) $v === (string) (int) $v || ctype_digit($v); })); - } elseif ('guid' === $metadata->getTypeOfField($identifier)) { + } elseif (in_array($metadata->getTypeOfField($identifier), array('uuid', 'guid'))) { $parameterType = Connection::PARAM_STR_ARRAY; // Like above, but we just filter out empty strings. diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/GuidIdEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/GuidIdEntity.php new file mode 100644 index 0000000000000..517f57495169a --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/GuidIdEntity.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class GuidIdEntity +{ + /** @Id @Column(type="guid") */ + protected $id; + + public function __construct($id) + { + $this->id = $id; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/UuidIdEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/UuidIdEntity.php new file mode 100644 index 0000000000000..4998f7d7c5454 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/UuidIdEntity.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class UuidIdEntity +{ + /** @Id @Column(type="uuid") */ + protected $id; + + public function __construct($id) + { + $this->id = $id; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php index b14044fb24804..1db089d5975d3 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php @@ -107,6 +107,38 @@ public function testFilterNonIntegerValues() $loader->getEntitiesByIds('id', array(1, '', 2, 3, 'foo', '9223372036854775808')); } + /** + * @dataProvider provideGuidEntityClasses + */ + public function testFilterEmptyUuids($entityClass) + { + $em = DoctrineTestHelper::createTestEntityManager(); + + $query = $this->getMockBuilder('QueryMock') + ->setMethods(array('setParameter', 'getResult', 'getSql', '_doExecute')) + ->getMock(); + + $query->expects($this->once()) + ->method('setParameter') + ->with('ORMQueryBuilderLoader_getEntitiesByIds_id', array('71c5fd46-3f16-4abb-bad7-90ac1e654a2d', 'b98e8e11-2897-44df-ad24-d2627eb7f499'), Connection::PARAM_STR_ARRAY) + ->willReturn($query); + + $qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder') + ->setConstructorArgs(array($em)) + ->setMethods(array('getQuery')) + ->getMock(); + + $qb->expects($this->once()) + ->method('getQuery') + ->willReturn($query); + + $qb->select('e') + ->from($entityClass, 'e'); + + $loader = new ORMQueryBuilderLoader($qb); + $loader->getEntitiesByIds('id', array('71c5fd46-3f16-4abb-bad7-90ac1e654a2d', '', 'b98e8e11-2897-44df-ad24-d2627eb7f499')); + } + public function testEmbeddedIdentifierName() { if (Version::compare('2.5.0') > 0) { @@ -140,4 +172,12 @@ public function testEmbeddedIdentifierName() $loader = new ORMQueryBuilderLoader($qb); $loader->getEntitiesByIds('id.value', array(1, '', 2, 3, 'foo')); } + + public function provideGuidEntityClasses() + { + return array( + array('Symfony\Bridge\Doctrine\Tests\Fixtures\GuidIdEntity'), + array('Symfony\Bridge\Doctrine\Tests\Fixtures\UuidIdEntity'), + ); + } } From f8a75180e0b098c97a55ba21200ed3a2e95b798b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 24 Aug 2017 08:39:03 +0200 Subject: [PATCH 02/40] [Cache] Use namespace versioning for backends that dont support clearing by keys --- .../Cache/Adapter/AbstractAdapter.php | 2 +- .../Component/Cache/Adapter/ProxyAdapter.php | 2 +- src/Symfony/Component/Cache/CacheItem.php | 4 ++ .../Component/Cache/Simple/AbstractCache.php | 2 +- .../Component/Cache/Tests/CacheItemTest.php | 2 +- .../Component/Cache/Traits/AbstractTrait.php | 46 +++++++++++++++++-- .../Component/Cache/Traits/MemcachedTrait.php | 3 +- .../Component/Cache/Traits/RedisTrait.php | 8 ++-- 8 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index 9bc05fd2b30fd..6b38991b77e1e 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -38,7 +38,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface */ protected function __construct($namespace = '', $defaultLifetime = 0) { - $this->namespace = '' === $namespace ? '' : $this->getId($namespace).':'; + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':'; if (null !== $this->maxIdLength && strlen($namespace) > $this->maxIdLength - 24) { throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, strlen($namespace), $namespace)); } diff --git a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php index 4f37ffd731931..cd310be062069 100644 --- a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php @@ -35,7 +35,7 @@ public function __construct(CacheItemPoolInterface $pool, $namespace = '', $defa { $this->pool = $pool; $this->poolHash = $poolHash = spl_object_hash($pool); - $this->namespace = '' === $namespace ? '' : $this->getId($namespace); + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace); $this->namespaceLen = strlen($namespace); $this->createCacheItem = \Closure::bind( function ($key, $innerItem) use ($defaultLifetime, $poolHash) { diff --git a/src/Symfony/Component/Cache/CacheItem.php b/src/Symfony/Component/Cache/CacheItem.php index 55e25de9a9513..d6f629b2abc70 100644 --- a/src/Symfony/Component/Cache/CacheItem.php +++ b/src/Symfony/Component/Cache/CacheItem.php @@ -148,6 +148,8 @@ public function getPreviousTags() * * @param string $key The key to validate * + * @return string + * * @throws InvalidArgumentException When $key is not valid */ public static function validateKey($key) @@ -161,6 +163,8 @@ public static function validateKey($key) if (false !== strpbrk($key, '{}()/\@:')) { throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters {}()/\@:', $key)); } + + return $key; } /** diff --git a/src/Symfony/Component/Cache/Simple/AbstractCache.php b/src/Symfony/Component/Cache/Simple/AbstractCache.php index e4046463f1609..264eb60653339 100644 --- a/src/Symfony/Component/Cache/Simple/AbstractCache.php +++ b/src/Symfony/Component/Cache/Simple/AbstractCache.php @@ -37,7 +37,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface protected function __construct($namespace = '', $defaultLifetime = 0) { $this->defaultLifetime = max(0, (int) $defaultLifetime); - $this->namespace = '' === $namespace ? '' : $this->getId($namespace).':'; + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':'; if (null !== $this->maxIdLength && strlen($namespace) > $this->maxIdLength - 24) { throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, strlen($namespace), $namespace)); } diff --git a/src/Symfony/Component/Cache/Tests/CacheItemTest.php b/src/Symfony/Component/Cache/Tests/CacheItemTest.php index 4e455c64a48cc..daca925fd5b78 100644 --- a/src/Symfony/Component/Cache/Tests/CacheItemTest.php +++ b/src/Symfony/Component/Cache/Tests/CacheItemTest.php @@ -18,7 +18,7 @@ class CacheItemTest extends TestCase { public function testValidKey() { - $this->assertNull(CacheItem::validateKey('foo')); + $this->assertSame('foo', CacheItem::validateKey('foo')); } /** diff --git a/src/Symfony/Component/Cache/Traits/AbstractTrait.php b/src/Symfony/Component/Cache/Traits/AbstractTrait.php index 375ccf7620d83..108ac67c8e12f 100644 --- a/src/Symfony/Component/Cache/Traits/AbstractTrait.php +++ b/src/Symfony/Component/Cache/Traits/AbstractTrait.php @@ -24,6 +24,8 @@ trait AbstractTrait use LoggerAwareTrait; private $namespace; + private $namespaceVersion = ''; + private $versioningIsEnabled = false; private $deferred = array(); /** @@ -102,10 +104,18 @@ public function hasItem($key) */ public function clear() { + if ($cleared = $this->versioningIsEnabled) { + $this->namespaceVersion = 2; + foreach ($this->doFetch(array('@'.$this->namespace)) as $v) { + $this->namespaceVersion = 1 + (int) $v; + } + $this->namespaceVersion .= ':'; + $cleared = $this->doSave(array('@'.$this->namespace => $this->namespaceVersion), 0); + } $this->deferred = array(); try { - return $this->doClear($this->namespace); + return $this->doClear($this->namespace) || $cleared; } catch (\Exception $e) { CacheItem::log($this->logger, 'Failed to clear the cache', array('exception' => $e)); @@ -158,6 +168,27 @@ public function deleteItems(array $keys) return $ok; } + /** + * Enables/disables versioning of items. + * + * When versioning is enabled, clearing the cache is atomic and doesn't require listing existing keys to proceed, + * but old keys may need garbage collection and extra round-trips to the back-end are required. + * + * Calling this method also clears the memoized namespace version and thus forces a resynchonization of it. + * + * @param bool $enable + * + * @return bool the previous state of versioning + */ + public function enableVersioning($enable = true) + { + $wasEnabled = $this->versioningIsEnabled; + $this->versioningIsEnabled = (bool) $enable; + $this->namespaceVersion = ''; + + return $wasEnabled; + } + /** * Like the native unserialize() function but throws an exception if anything goes wrong. * @@ -189,11 +220,18 @@ private function getId($key) { CacheItem::validateKey($key); + if ($this->versioningIsEnabled && '' === $this->namespaceVersion) { + $this->namespaceVersion = '1:'; + foreach ($this->doFetch(array('@'.$this->namespace)) as $v) { + $this->namespaceVersion = $v; + } + } + if (null === $this->maxIdLength) { - return $this->namespace.$key; + return $this->namespace.$this->namespaceVersion.$key; } - if (strlen($id = $this->namespace.$key) > $this->maxIdLength) { - $id = $this->namespace.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -22); + if (strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { + $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -22); } return $id; diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php index 8a836bac18c45..6dc46e9dd8da2 100644 --- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php +++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php @@ -54,6 +54,7 @@ private function init(\Memcached $client, $namespace, $defaultLifetime) } parent::__construct($namespace, $defaultLifetime); + $this->enableVersioning(); } /** @@ -242,7 +243,7 @@ protected function doDelete(array $ids) */ protected function doClear($namespace) { - return $this->checkResultCode($this->getClient()->flush()); + return false; } private function checkResultCode($result) diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php index b45d65adc8530..6202051a8de5d 100644 --- a/src/Symfony/Component/Cache/Traits/RedisTrait.php +++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php @@ -46,7 +46,9 @@ public function init($redisClient, $namespace = '', $defaultLifetime = 0) if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) { throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0])); } - if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\Client) { + if ($redisClient instanceof \RedisCluster) { + $this->enableversioning(); + } elseif (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \Predis\Client) { throw new InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, is_object($redisClient) ? get_class($redisClient) : gettype($redisClient))); } $this->redis = $redisClient; @@ -171,8 +173,8 @@ protected function doHave($id) */ protected function doClear($namespace) { - // When using a native Redis cluster, clearing the cache cannot work and always returns false. - // Clearing the cache should then be done by any other means (e.g. by restarting the cluster). + // When using a native Redis cluster, clearing the cache is done by versioning in AbstractTrait::clear(). + // This means old keys are not really removed until they expire and may need gargage collection. $cleared = true; $hosts = array($this->redis); From 7229a363a54e86111fc7aa7f1b46967d648d9397 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 11:40:29 -0700 Subject: [PATCH 03/40] updated CHANGELOG for 2.7.34 --- CHANGELOG-2.7.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index d08766327bc5e..f742ca8ea0385 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,19 @@ 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.34 (2017-08-28) + + * bug #23989 [Debug] Remove false-positive check in DebugClassLoader (nicolas-grekas) + * bug #23982 [VarDumper] Strengthen dumped JS (nicolas-grekas) + * bug #23925 [Validator] Fix use of GroupSequenceProvider in child classes (linniksa) + * bug #23945 [Validator] Fix Greek translation (azhurb) + * bug #23909 [Console] Initialize lazily to render exceptions properly (nicolas-grekas) + * bug #23856 [DI] Fix dumping abstract with YamlDumper (nicolas-grekas) + * bug #23752 Ignore memcached missing key error on session destroy (jderusse) + * bug #23658 [HttpFoundation] Generate safe fallback filename for wrongly encoded filename (xelaris) + * bug #23783 Avoid infinite loops when profiler data is malformed (javiereguiluz) + * bug #23729 [Bridge\ProxyManager] Dont call __destruct() on non-instantiated services (nicolas-grekas) + * 2.7.33 (2017-08-01) * bug #22244 [Console] Fix passing options with defaultCommand (Jakub Sacha) From 0978a4c2abcf51d3ac426f467f34e3ca1d429d6c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 11:40:34 -0700 Subject: [PATCH 04/40] update CONTRIBUTORS for 2.7.34 --- CONTRIBUTORS.md | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1b059f5012cb7..ced9b18126294 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -7,8 +7,8 @@ Symfony is the result of the work of many people who made the code better - Fabien Potencier (fabpot) - Nicolas Grekas (nicolas-grekas) - Bernhard Schussek (bschussek) - - Tobias Schultze (tobion) - Christian Flothmann (xabbuh) + - Tobias Schultze (tobion) - Christophe Coevoet (stof) - Jordi Boggiano (seldaek) - Victor Berchet (victor) @@ -37,8 +37,8 @@ Symfony is the result of the work of many people who made the code better - Roland Franssen (ro0) - Eriksen Costa (eriksencosta) - Jules Pietri (heah) - - Sarah Khalil (saro0h) - Guilhem Niot (energetick) + - Sarah Khalil (saro0h) - Jonathan Wage (jwage) - Diego Saint Esteben (dosten) - Alexandre Salomé (alexandresalome) @@ -65,20 +65,20 @@ Symfony is the result of the work of many people who made the code better - Michel Weimerskirch (mweimerskirch) - Eric Clemmons (ericclemmons) - Charles Sarrazin (csarrazi) - - Christian Raue - Konstantin Myakshin (koc) + - Christian Raue + - Dany Maillard (maidmaid) - Arnout Boks (aboks) + - Jérémy DERUSSÉ (jderusse) - Deni - Henrik Westphal (snc) - Dariusz Górecki (canni) - Jáchym Toušek (enumag) - Titouan Galopin (tgalopin) - Douglas Greenshields (shieldo) - - Dany Maillard (maidmaid) - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) - - Jérémy DERUSSÉ (jderusse) - Graham Campbell (graham) - Daniel Holmes (dholmes) - Toni Uebernickel (havvg) @@ -87,24 +87,24 @@ Symfony is the result of the work of many people who made the code better - Jérôme Tamarelle (gromnan) - John Wards (johnwards) - Dariusz Ruminski + - Alexander M. Turek (derrabus) - Fran Moreno (franmomu) - Antoine Hérault (herzult) + - Tobias Nyholm (tobias) - Paráda József (paradajozsef) - Issei Murasawa (issei_m) - Arnaud Le Blanc (arnaud-lb) - Maxime STEINHAUSSER - - Alexander M. Turek (derrabus) - Michal Piotrowski (eventhorizon) - - Tim Nagel (merk) - Yonel Ceruto González (yonelceruto) + - Tim Nagel (merk) - Brice BERNARD (brikou) - Baptiste Clavié (talus) - Vladimir Reznichenko (kalessil) - marc.weistroff - lenar - - Tobias Nyholm (tobias) - - Włodzimierz Gajda (gajdaw) - Alexander Schwenn (xelaris) + - Włodzimierz Gajda (gajdaw) - Jacob Dreesen (jdreesen) - Florian Voutzinos (florianv) - Colin Frei @@ -152,7 +152,9 @@ Symfony is the result of the work of many people who made the code better - Rouven Weßling (realityking) - Teoh Han Hui (teohhanhui) - Clemens Tolboom + - Oleg Voronkovich - Helmer Aaviksoo + - Lars Strojny (lstrojny) - Hiromi Hishida (77web) - Matthieu Ouellette-Vachon (maoueh) - Michał Pipa (michal.pipa) @@ -166,7 +168,6 @@ Symfony is the result of the work of many people who made the code better - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) - - Lars Strojny (lstrojny) - Possum - Dorian Villet (gnutix) - Richard Miller (mr_r_miller) @@ -183,7 +184,6 @@ Symfony is the result of the work of many people who made the code better - Daniel Espendiller - sun (sun) - Larry Garfield (crell) - - Oleg Voronkovich - Martin Schuhfuß (usefulthink) - apetitpa - Matthieu Bontemps (mbontemps) @@ -334,9 +334,11 @@ Symfony is the result of the work of many people who made the code better - Damien Alexandre (damienalexandre) - Felix Labrecque - Yaroslav Kiliba + - Amrouche Hamza - Terje Bråten - Robbert Klarenbeek (robbertkl) - Thomas Calvet (fancyweb) + - Valentin Udaltsov (vudaltsov) - Niels Keurentjes (curry684) - JhonnyL - David Badura (davidbadura) @@ -387,6 +389,7 @@ Symfony is the result of the work of many people who made the code better - Karel Souffriau - Christophe L. (christophelau) - Anthon Pang (robocoder) + - Jérôme Parmentier (lctrs) - Emanuele Gaspari (inmarelibero) - Sébastien Santoro (dereckson) - Brian King @@ -421,7 +424,6 @@ Symfony is the result of the work of many people who made the code better - Dirk Pahl (dirkaholic) - cedric lombardot (cedriclombardot) - Jonas Flodén (flojon) - - Amrouche Hamza - Marcin Sikoń (marphi) - Dominik Zogg (dominik.zogg) - Marek Pietrzak @@ -432,6 +434,7 @@ Symfony is the result of the work of many people who made the code better - Zander Baldwin - Adam Harvey - Maxime Veber (nek-) + - Sanpi - Alex Bakhturin - Alexander Obuhovich (aik099) - boombatower @@ -512,6 +515,7 @@ Symfony is the result of the work of many people who made the code better - Dave Hulbert (dave1010) - Ivan Rey (ivanrey) - Marcin Chyłek (songoq) + - Ben Scott - Ned Schwartz - Ziumin - Jeremy Benoist @@ -520,7 +524,6 @@ Symfony is the result of the work of many people who made the code better - Benjamin Laugueux (yzalis) - Zach Badgett (zachbadgett) - Aurélien Fredouelle - - Jérôme Parmentier (lctrs) - Pavel Campr (pcampr) - Johnny Robeson (johnny) - Disquedur @@ -592,7 +595,6 @@ Symfony is the result of the work of many people who made the code better - Ulumuddin Yunus (joenoez) - Luc Vieillescazes (iamluc) - Johann Saunier (prophet777) - - Valentin Udaltsov (vudaltsov) - Michael Devery (mickadoo) - Antoine Corcy - Artur Eshenbrener @@ -671,9 +673,11 @@ Symfony is the result of the work of many people who made the code better - Andrew Hilobok (hilobok) - Noah Heck (myesain) - Christian Soronellas (theunic) + - Adam Szaraniec (mimol) - Yosmany Garcia (yosmanyga) - Wouter de Wild - Degory Valentine + - izzyp - Benoit Lévêque (benoit_leveque) - Jeroen Fiege (fieg) - Krzysiek Łabuś @@ -709,7 +713,6 @@ Symfony is the result of the work of many people who made the code better - Pierre Vanliefland (pvanliefland) - Sofiane HADDAG (sofhad) - frost-nzcr4 - - Sanpi - Abhoryo - Fabian Vogler (fabian) - Korvin Szanto @@ -742,7 +745,6 @@ Symfony is the result of the work of many people who made the code better - Omar Yepez (oyepez003) - mwsaz - Jelle Kapitein - - Ben Scott - Benoît Bourgeois - mantulo - corphi @@ -877,6 +879,7 @@ Symfony is the result of the work of many people who made the code better - Boris Vujicic (boris.vujicic) - Max Beutel - Antanas Arvasevicius + - Maximilian Berghoff (electricmaxxx) - nacho - Piotr Antosik (antek88) - Artem Lopata @@ -910,6 +913,7 @@ Symfony is the result of the work of many people who made the code better - Matteo Giachino (matteosister) - Alex Demchenko (pilot) - Tadas Gliaubicas (tadcka) + - Thanos Polymeneas (thanos) - Benoit Garret - Jakub Sacha - DerManoMann @@ -1098,7 +1102,6 @@ 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 @@ -1171,6 +1174,7 @@ Symfony is the result of the work of many people who made the code better - César Suárez (csuarez) - Nicolas Badey (nico-b) - Shane Preece (shane) + - Johannes Goslar - Geoff - georaldc - Malte Wunsch @@ -1204,6 +1208,7 @@ Symfony is the result of the work of many people who made the code better - catch - Alexandre Segura - Josef Cech + - Harold Iedema - Arnau González (arnaugm) - Simon Bouland (bouland) - Matthew Foster (mfoster) @@ -1236,7 +1241,6 @@ Symfony is the result of the work of many people who made the code better - Dennis Væversted - nuncanada - flack - - izzyp - František Bereň - Mike Francis - Christoph Nissle (derstoffel) @@ -1477,6 +1481,7 @@ Symfony is the result of the work of many people who made the code better - Ismail Asci (ismailasci) - Simon CONSTANS (kosssi) - Kristof Van Cauwenbergh (kristofvc) + - Paulius Jarmalavičius (pjarmalavicius) - Ramon Henrique Ornelas (ramonornela) - Markus S. (staabm) - Till Klampaeckel (till) @@ -1569,11 +1574,13 @@ Symfony is the result of the work of many people who made the code better - Matt Janssen - Peter Gribanov - Ben Johnson + - Florent Mata - kwiateusz - David Soria Parra - Sergiy Sokolenko - dinitrol - Penny Leach + - Yurii K - Richard Trebichavský - g123456789l - Jonathan Vollebregt @@ -1651,6 +1658,7 @@ Symfony is the result of the work of many people who made the code better - samuel laulhau (lalop) - Laurent Bachelier (laurentb) - Florent Viel (luxifer) + - Matthieu Mota (matthieumota) - Matthieu Moquet (mattketmo) - Moritz Borgmann (mborgmann) - Michal Čihař (mcihar) From 0f45d7963a0df843daab33f986e138732ec7c089 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 11:40:36 -0700 Subject: [PATCH 05/40] updated VERSION for 2.7.34 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 401a3626d84b4..c14964609235c 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.34-DEV'; + const VERSION = '2.7.34'; const VERSION_ID = 20734; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; const RELEASE_VERSION = 34; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From bc4e01500b4d0bdf5683ed09b635a85367902307 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 12:18:16 -0700 Subject: [PATCH 06/40] bumped Symfony version to 2.7.35 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index c14964609235c..0fcbbe47fddea 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.34'; - const VERSION_ID = 20734; + const VERSION = '2.7.35-DEV'; + const VERSION_ID = 20735; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; - const RELEASE_VERSION = 34; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 35; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From 2bba09c51ebeb119cd154e97899c04fbc9ab45ea Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 12:21:33 -0700 Subject: [PATCH 07/40] updated CHANGELOG for 2.8.27 --- CHANGELOG-2.8.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG-2.8.md b/CHANGELOG-2.8.md index 5fdc52f111daa..abb1235519a77 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.27 (2017-08-28) + + * bug #23989 [Debug] Remove false-positive check in DebugClassLoader (nicolas-grekas) + * bug #23982 [VarDumper] Strengthen dumped JS (nicolas-grekas) + * bug #23925 [Validator] Fix use of GroupSequenceProvider in child classes (linniksa) + * bug #23945 [Validator] Fix Greek translation (azhurb) + * bug #23909 [Console] Initialize lazily to render exceptions properly (nicolas-grekas) + * bug #23856 [DI] Fix dumping abstract with YamlDumper (nicolas-grekas) + * bug #23752 Ignore memcached missing key error on session destroy (jderusse) + * bug #23658 [HttpFoundation] Generate safe fallback filename for wrongly encoded filename (xelaris) + * bug #23783 Avoid infinite loops when profiler data is malformed (javiereguiluz) + * bug #23729 [Bridge\ProxyManager] Dont call __destruct() on non-instantiated services (nicolas-grekas) + * 2.8.26 (2017-08-01) * bug #22244 [Console] Fix passing options with defaultCommand (Jakub Sacha) From 527e17138377d847a8493ab0b3910e9878612e1c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 12:21:40 -0700 Subject: [PATCH 08/40] updated VERSION for 2.8.27 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index ff1dc40d15fb8..89aaa72cf9a35 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.27-DEV'; + const VERSION = '2.8.27'; const VERSION_ID = 20827; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; const RELEASE_VERSION = 27; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From e313e69e98a1c6f2f960de0b6321bbb43d3c5b85 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 12:33:37 -0700 Subject: [PATCH 09/40] bumped Symfony version to 2.8.28 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 89aaa72cf9a35..4758961c4d9d7 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.27'; - const VERSION_ID = 20827; + const VERSION = '2.8.28-DEV'; + const VERSION_ID = 20828; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; - const RELEASE_VERSION = 27; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 28; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From 9280ca429ea515c4d49a72ce236872562eb9c4a9 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 15:49:36 -0700 Subject: [PATCH 10/40] bumped Symfony version to 3.3.9 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 0fa9dbd5451b6..f8ed2b08b4b63 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -61,12 +61,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface private $projectDir; - const VERSION = '3.3.8'; - const VERSION_ID = 30308; + const VERSION = '3.3.9-DEV'; + const VERSION_ID = 30309; const MAJOR_VERSION = 3; const MINOR_VERSION = 3; - const RELEASE_VERSION = 8; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 9; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '01/2018'; const END_OF_LIFE = '07/2018'; From a8e6aac2f58ca3f12c931f20a6de29ef46686dc8 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 29 Aug 2017 14:43:33 +0200 Subject: [PATCH 11/40] [DI] Don't track merged configs when the extension doesn't expose it --- .../Compiler/MergeExtensionConfigurationPass.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php index 853b1fd05e96e..c3b4d78dd622d 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php @@ -67,7 +67,7 @@ public function process(ContainerBuilder $container) if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) { // don't keep track of env vars that are *overridden* when configs are merged - $resolvingBag->freezeAfterProcessing($extension); + $resolvingBag->freezeAfterProcessing($extension, $tmpContainer); } $container->merge($tmpContainer); @@ -92,12 +92,16 @@ public function __construct(parent $parameterBag) $this->mergeEnvPlaceholders($parameterBag); } - public function freezeAfterProcessing(Extension $extension) + public function freezeAfterProcessing(Extension $extension, ContainerBuilder $container) { + if (!$config = $extension->getProcessedConfigs()) { + // Extension::processConfiguration() wasn't called, we cannot know how configs were merged + return; + } $this->processedEnvPlaceholders = array(); - // serialize config to catch env vars nested in object graphs - $config = serialize($extension->getProcessedConfigs()); + // serialize config and container to catch env vars nested in object graphs + $config = serialize($config).serialize($container->getDefinitions()).serialize($container->getAliases()).serialize($container->getParameterBag()->all()); foreach (parent::getEnvPlaceholders() as $env => $placeholders) { foreach ($placeholders as $placeholder) { From 9d444421ea80f43b58a3b254ef78c58b2f1a9f4a Mon Sep 17 00:00:00 2001 From: Guillaume LECERF Date: Mon, 28 Aug 2017 23:40:21 +0200 Subject: [PATCH 12/40] Always require symfony/polyfill-apcu to provide APCuIterator everywhere --- composer.json | 2 +- .../Cache/Tests/Adapter/ApcuAdapterTest.php | 25 +++++++++++++++++++ src/Symfony/Component/Cache/composer.json | 6 ++--- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index ff894a349e227..d55f29f6aaa8a 100644 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "psr/link": "^1.0", "psr/log": "~1.0", "psr/simple-cache": "^1.0", + "symfony/polyfill-apcu": "~1.1", "symfony/polyfill-intl-icu": "~1.0", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php56": "~1.0", @@ -96,7 +97,6 @@ "predis/predis": "~1.0", "egulias/email-validator": "~1.2,>=1.2.8|~2.0", "symfony/phpunit-bridge": "~3.2", - "symfony/polyfill-apcu": "~1.1", "symfony/security-acl": "~2.8|~3.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0", "sensio/framework-extra-bundle": "^3.0.2" diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php index 6cad6135cf4a0..75b3fa299ec29 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php @@ -77,6 +77,31 @@ public function testVersion() $this->assertNull($item->get()); } + public function testNamespace() + { + $namespace = str_replace('\\', '.', get_class($this)); + + $pool1 = new ApcuAdapter($namespace.'_1', 0, 'p1'); + + $item = $pool1->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertTrue($pool1->save($item->set('bar'))); + + $item = $pool1->getItem('foo'); + $this->assertTrue($item->isHit()); + $this->assertSame('bar', $item->get()); + + $pool2 = new ApcuAdapter($namespace.'_2', 0, 'p1'); + + $item = $pool2->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get()); + + $item = $pool1->getItem('foo'); + $this->assertTrue($item->isHit()); + $this->assertSame('bar', $item->get()); + } + public function testWithCliSapi() { try { diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json index f32117b038479..78f5c026805da 100644 --- a/src/Symfony/Component/Cache/composer.json +++ b/src/Symfony/Component/Cache/composer.json @@ -23,7 +23,8 @@ "php": "^5.5.9|>=7.0.8", "psr/cache": "~1.0", "psr/log": "~1.0", - "psr/simple-cache": "^1.0" + "psr/simple-cache": "^1.0", + "symfony/polyfill-apcu": "~1.1" }, "require-dev": { "cache/integration-tests": "dev-master", @@ -34,9 +35,6 @@ "conflict": { "symfony/var-dumper": "<3.3" }, - "suggest": { - "symfony/polyfill-apcu": "For using ApcuAdapter on HHVM" - }, "autoload": { "psr-4": { "Symfony\\Component\\Cache\\": "" }, "exclude-from-classmap": [ From d5cb1fe711b7ab87732ebf5c96b58351dbdc3fc0 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 31 Jul 2017 16:54:24 +0200 Subject: [PATCH 13/40] Fixed the escaping of back slashes and << in console output --- .../Component/Console/Formatter/OutputFormatter.php | 7 ++++--- .../Console/Tests/Formatter/OutputFormatterTest.php | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/src/Symfony/Component/Console/Formatter/OutputFormatter.php index dc192711e6093..c8a6a780b0580 100644 --- a/src/Symfony/Component/Console/Formatter/OutputFormatter.php +++ b/src/Symfony/Component/Console/Formatter/OutputFormatter.php @@ -50,7 +50,8 @@ public static function escapeTrailingBackslash($text) if ('\\' === substr($text, -1)) { $len = strlen($text); $text = rtrim($text, '\\'); - $text .= str_repeat('<<', $len - strlen($text)); + $text = str_replace("\0", '', $text); + $text .= str_repeat("\0", $len - strlen($text)); } return $text; @@ -165,8 +166,8 @@ public function format($message) $output .= $this->applyCurrentStyle(substr($message, $offset)); - if (false !== strpos($output, '<<')) { - return strtr($output, array('\\<' => '<', '<<' => '\\')); + if (false !== strpos($output, "\0")) { + return strtr($output, array("\0" => '\\', '\\<' => '<')); } return str_replace('\\<', '<', $output); diff --git a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php index 866c31a443754..00e5231d80498 100644 --- a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php +++ b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php @@ -28,6 +28,9 @@ public function testLGCharEscaping() $formatter = new OutputFormatter(true); $this->assertEquals('fooformat('foo\\assertEquals('foo << bar', $formatter->format('foo << bar')); + $this->assertEquals('foo << bar \\', $formatter->format('foo << bar \\')); + $this->assertEquals("foo << \033[32mbar \\ baz\033[39m \\", $formatter->format('foo << bar \\ baz \\')); $this->assertEquals('some info', $formatter->format('\\some info\\')); $this->assertEquals('\\some info\\', OutputFormatter::escape('some info')); From 7855748c7896e9dd6e4219846a9ead000a6cc913 Mon Sep 17 00:00:00 2001 From: Thomas Perez Date: Mon, 28 Aug 2017 15:57:41 +0200 Subject: [PATCH 14/40] Update NoSuchPropertyException message for writeProperty --- src/Symfony/Component/PropertyAccess/PropertyAccessor.php | 2 +- .../PropertyAccess/Tests/PropertyAccessorCollectionTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index d0cadcf65722c..af999153727f0 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -649,7 +649,7 @@ private function writeProperty($zval, $property, $value) } elseif (self::ACCESS_TYPE_MAGIC === $access[self::ACCESS_TYPE]) { $object->{$access[self::ACCESS_NAME]}($value); } elseif (self::ACCESS_TYPE_NOT_FOUND === $access[self::ACCESS_TYPE]) { - throw new NoSuchPropertyException(sprintf('Could not determine access type for property "%s".', $property)); + throw new NoSuchPropertyException(sprintf('Could not determine access type for property "%s" in class "%s".', $property, get_class($object))); } else { throw new NoSuchPropertyException($access[self::ACCESS_NAME]); } diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php index b4dc05dac323f..1f10262305242 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php @@ -148,7 +148,7 @@ public function testSetValueCallsAdderAndRemoverForNestedCollections() /** * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException - * @expectedExceptionMessage Could not determine access type for property "axes". + * @expectedExceptionMessageRegExp /Could not determine access type for property "axes" in class "Mock_PropertyAccessorCollectionTest_CarNoAdderAndRemover_[^"]*"./ */ public function testSetValueFailsIfNoAdderNorRemoverFound() { From c8b65aeb8b7e9c9d835897036854d0a7256804a7 Mon Sep 17 00:00:00 2001 From: Florent Mata Date: Wed, 30 Aug 2017 16:46:23 +0200 Subject: [PATCH 15/40] [ExpressionLanguage] throws an exception on calling uncallable method --- .../Component/ExpressionLanguage/Node/GetAttrNode.php | 5 ++++- .../Tests/ExpressionLanguageTest.php | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/ExpressionLanguage/Node/GetAttrNode.php b/src/Symfony/Component/ExpressionLanguage/Node/GetAttrNode.php index b3f98bf565f08..23310e3e4abdf 100644 --- a/src/Symfony/Component/ExpressionLanguage/Node/GetAttrNode.php +++ b/src/Symfony/Component/ExpressionLanguage/Node/GetAttrNode.php @@ -77,8 +77,11 @@ public function evaluate($functions, $values) if (!is_object($obj)) { throw new \RuntimeException('Unable to get a property on a non-object.'); } + if (!is_callable($toCall = array($obj, $this->nodes['attribute']->attributes['value']))) { + throw new \RuntimeException(sprintf('Unable to call method "%s" of object "%s".', $this->nodes['attribute']->attributes['value'], get_class($obj))); + } - return call_user_func_array(array($obj, $this->nodes['attribute']->attributes['value']), $this->nodes['arguments']->evaluate($functions, $values)); + return call_user_func_array($toCall, $this->nodes['arguments']->evaluate($functions, $values)); case self::ARRAY_CALL: $array = $this->nodes['node']->evaluate($functions, $values); diff --git a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php index 07f4b1e8a08cb..0ef278c901496 100644 --- a/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php +++ b/src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php @@ -163,6 +163,16 @@ public function testRegisterAfterEval($registerCallback) $registerCallback($el); } + /** + * @expectedException \RuntimeException + * @expectedExceptionMessageRegExp /Unable to call method "\w+" of object "\w+"./ + */ + public function testCallBadCallable() + { + $el = new ExpressionLanguage(); + $el->evaluate('foo.myfunction()', array('foo' => new \stdClass())); + } + /** * @dataProvider getRegisterCallbacks * @expectedException \LogicException From a2af9a940f24f157bf0256dc4af1af9b9f4516e6 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 1 Sep 2017 15:23:39 +0200 Subject: [PATCH 16/40] Improved how links are displayed in exception messages --- .../Bundle/TwigBundle/Resources/views/exception.css.twig | 4 ++-- src/Symfony/Component/Debug/ExceptionHandler.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig index 84112fad6ed94..9f12edece1e71 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig @@ -84,8 +84,8 @@ header .container { display: flex; justify-content: space-between; } .exception-message { flex-grow: 1; } .exception-message, .exception-message a { color: #FFF; font-size: 21px; font-weight: 400; margin: 0; } .exception-message.long { font-size: 18px; } -.exception-message a { text-decoration: none; } -.exception-message a:hover { text-decoration: underline; } +.exception-message a { border-bottom: 1px solid rgba(255, 255, 255, 0.5); font-size: inherit; text-decoration: none; } +.exception-message a:hover { border-bottom-color: #ffffff; } .exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; } diff --git a/src/Symfony/Component/Debug/ExceptionHandler.php b/src/Symfony/Component/Debug/ExceptionHandler.php index 0ecd2a5347f27..a82a3246d9eaa 100644 --- a/src/Symfony/Component/Debug/ExceptionHandler.php +++ b/src/Symfony/Component/Debug/ExceptionHandler.php @@ -310,8 +310,8 @@ public function getStylesheet(FlattenException $exception) .exception-message { flex-grow: 1; padding: 30px 0; } .exception-message, .exception-message a { color: #FFF; font-size: 21px; font-weight: 400; margin: 0; } .exception-message.long { font-size: 18px; } - .exception-message a { text-decoration: none; } - .exception-message a:hover { text-decoration: underline; } + .exception-message a { border-bottom: 1px solid rgba(255, 255, 255, 0.5); font-size: inherit; text-decoration: none; } + .exception-message a:hover { border-bottom-color: #ffffff; } .exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; } From fb5135b742c482ca981ade0db56db7440ed224e6 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 1 Sep 2017 15:44:20 +0200 Subject: [PATCH 17/40] Improved the design of the redirection method in the web toolbar --- .../WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig | 1 + 1 file changed, 1 insertion(+) 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 7ef299437bb5f..3a65e1d0537d6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig @@ -250,6 +250,7 @@ font-size: 12px; height: 17px; line-height: 17px; + margin-right: 5px; } .sf-toolbar-status-green .sf-toolbar-label, From 2f292c247eef1b47dd6d2abc7760ab8a515470d9 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Thu, 31 Aug 2017 12:18:43 +0300 Subject: [PATCH 18/40] #24046 added check for ext-dom to XmlUtil::loadFile --- src/Symfony/Component/Config/Util/XmlUtils.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/Config/Util/XmlUtils.php b/src/Symfony/Component/Config/Util/XmlUtils.php index 25d9b0a0abe5d..0f16fc080bf05 100644 --- a/src/Symfony/Component/Config/Util/XmlUtils.php +++ b/src/Symfony/Component/Config/Util/XmlUtils.php @@ -37,9 +37,14 @@ private function __construct() * @return \DOMDocument * * @throws \InvalidArgumentException When loading of XML file returns error + * @throws \RuntimeException When DOM extension is missing */ public static function loadFile($file, $schemaOrCallable = null) { + if (!extension_loaded('dom')) { + throw new \RuntimeException('Extension DOM is required.'); + } + $content = @file_get_contents($file); if ('' === trim($content)) { throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file)); From 26948cf565709d3a5524a52b5d1b5d65b3c88f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sun, 3 Sep 2017 14:43:23 +0200 Subject: [PATCH 19/40] Fix race condition in tests between cache and lock --- .../Component/Cache/Tests/Adapter/AbstractRedisAdapterTest.php | 1 - .../Component/Cache/Tests/Adapter/PredisClusterAdapterTest.php | 1 - .../Component/Cache/Tests/Simple/AbstractRedisCacheTest.php | 1 - 3 files changed, 3 deletions(-) diff --git a/src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTest.php index 86b16d436f23f..d9353821ae6ef 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/AbstractRedisAdapterTest.php @@ -41,7 +41,6 @@ public static function setupBeforeClass() public static function tearDownAfterClass() { - self::$redis->flushDB(); self::$redis = null; } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PredisClusterAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PredisClusterAdapterTest.php index 6ed1c7d6a9f3b..38915397da993 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PredisClusterAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PredisClusterAdapterTest.php @@ -21,7 +21,6 @@ public static function setupBeforeClass() public static function tearDownAfterClass() { - self::$redis->getConnection()->getConnectionByKey('foo')->executeCommand(self::$redis->createCommand('FLUSHDB')); self::$redis = null; } } diff --git a/src/Symfony/Component/Cache/Tests/Simple/AbstractRedisCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/AbstractRedisCacheTest.php index 1d097fff85fcd..f70f49d5dbaa6 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/AbstractRedisCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/AbstractRedisCacheTest.php @@ -41,7 +41,6 @@ public static function setupBeforeClass() public static function tearDownAfterClass() { - self::$redis->flushDB(); self::$redis = null; } } From 263b95e1d1b071d6660d11732844313db80374e7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 3 Sep 2017 20:01:57 +0200 Subject: [PATCH 20/40] [DI] Minor fix in dumped code --- .../Component/DependencyInjection/Dumper/PhpDumper.php | 8 ++------ .../DependencyInjection/Tests/Fixtures/php/services9.php | 8 ++++---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 6e2230ea6cb14..ef56da6bdcebd 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1579,13 +1579,9 @@ private function getServiceCall($id, Reference $reference = null) $code = sprintf('$this->get(\'%s\')', $id); } - if ($this->container->hasDefinition($id) && $this->container->getDefinition($id)->isShared()) { - // The following is PHP 5.5 syntax for what could be written as "(\$this->services['$id'] ?? $code)" on PHP>=7.0 + // The following is PHP 5.5 syntax for what could be written as "(\$this->services['$id'] ?? $code)" on PHP>=7.0 - $code = "\${(\$_ = isset(\$this->services['$id']) ? \$this->services['$id'] : $code) && false ?: '_'}"; - } - - return $code; + return "\${(\$_ = isset(\$this->services['$id']) ? \$this->services['$id'] : $code) && false ?: '_'}"; } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index 4998b60f4c719..77cc57604c770 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -280,7 +280,7 @@ protected function getLazyContextIgnoreInvalidRefService() return $this->services['lazy_context_ignore_invalid_ref'] = new \LazyContext(new RewindableGenerator(function () { yield 0 => ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->get('foo.baz')) && false ?: '_'}; if ($this->has('invalid')) { - yield 1 => $this->get('invalid', ContainerInterface::NULL_ON_INVALID_REFERENCE); + yield 1 => ${($_ = isset($this->services['invalid']) ? $this->services['invalid'] : $this->get('invalid', ContainerInterface::NULL_ON_INVALID_REFERENCE)) && false ?: '_'}; } }, function () { return 1 + (int) ($this->has('invalid')); @@ -301,12 +301,12 @@ protected function getMethodCall1Service() $this->services['method_call1'] = $instance = new \Bar\FooClass(); $instance->setBar(${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'}); - $instance->setBar($this->get('foo2', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + $instance->setBar(${($_ = isset($this->services['foo2']) ? $this->services['foo2'] : $this->get('foo2', ContainerInterface::NULL_ON_INVALID_REFERENCE)) && false ?: '_'}); if ($this->has('foo3')) { - $instance->setBar($this->get('foo3', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + $instance->setBar(${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : $this->get('foo3', ContainerInterface::NULL_ON_INVALID_REFERENCE)) && false ?: '_'}); } if ($this->has('foobaz')) { - $instance->setBar($this->get('foobaz', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + $instance->setBar(${($_ = isset($this->services['foobaz']) ? $this->services['foobaz'] : $this->get('foobaz', ContainerInterface::NULL_ON_INVALID_REFERENCE)) && false ?: '_'}); } $instance->setBar((${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'}->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default")))); From 2ba5005830187a01fdeb033edf6ae96d0bfcd643 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Mon, 4 Sep 2017 22:01:21 +0200 Subject: [PATCH 21/40] Fix ArrayInput::toString() for VALUE_IS_ARRAY options/args --- src/Symfony/Component/Console/Input/ArrayInput.php | 10 ++++++++-- .../Component/Console/Tests/Input/ArrayInputTest.php | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Input/ArrayInput.php b/src/Symfony/Component/Console/Input/ArrayInput.php index e9d4f8e842a9f..4937860b83204 100644 --- a/src/Symfony/Component/Console/Input/ArrayInput.php +++ b/src/Symfony/Component/Console/Input/ArrayInput.php @@ -101,9 +101,15 @@ public function __toString() $params = array(); foreach ($this->parameters as $param => $val) { if ($param && '-' === $param[0]) { - $params[] = $param.('' != $val ? '='.$this->escapeToken($val) : ''); + if (is_array($val)) { + foreach ($val as $v) { + $params[] = $param.('' != $v ? '='.$this->escapeToken($v) : ''); + } + } else { + $params[] = $param.('' != $val ? '='.$this->escapeToken($val) : ''); + } } else { - $params[] = $this->escapeToken($val); + $params[] = is_array($val) ? array_map(array($this, 'escapeToken'), $val) : $this->escapeToken($val); } } diff --git a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php index 06e65f7398bdc..608020a5caa55 100644 --- a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php @@ -140,5 +140,8 @@ public function testToString() { $input = new ArrayInput(array('-f' => null, '-b' => 'bar', '--foo' => 'b a z', '--lala' => null, 'test' => 'Foo', 'test2' => "A\nB'C")); $this->assertEquals('-f -b=bar --foo='.escapeshellarg('b a z').' --lala Foo '.escapeshellarg("A\nB'C"), (string) $input); + + $input = new ArrayInput(array('-b' => array('bval_1', 'bval_2'), '--f' => array('fval_1', 'fval_2'))); + $this->assertSame('-b=bval_1 -b=bval_2 --f=fval_1 --f=fval_2', (string) $input); } } From 66621cc559b08889f11a559d47ecb4fd01183320 Mon Sep 17 00:00:00 2001 From: Oleg Voronkovich Date: Sun, 3 Sep 2017 20:54:53 +0300 Subject: [PATCH 22/40] [Dotenv] Add a BC break note --- src/Symfony/Component/Dotenv/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Dotenv/CHANGELOG.md b/src/Symfony/Component/Dotenv/CHANGELOG.md index 2204282c26ca6..f04cc1bdf7bba 100644 --- a/src/Symfony/Component/Dotenv/CHANGELOG.md +++ b/src/Symfony/Component/Dotenv/CHANGELOG.md @@ -4,4 +4,5 @@ CHANGELOG 3.3.0 ----- + * [BC BREAK] Since v3.3.7, the latest Dotenv files override the previous ones. Real env vars are not affected and are not overridden. * added the component From 0caeeff48a5d09d4b1dcddb8d9ca0ee0a0c1cde5 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Tue, 5 Sep 2017 13:23:06 +0200 Subject: [PATCH 23/40] Create directories recursively in the PHPUnit bridge --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index c19d30f4af9e6..a2747f3be2a09 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -41,7 +41,7 @@ $COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') || ($COMPOSER = rt if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__FILE__)."\n".getenv('SYMFONY_PHPUNIT_REMOVE') !== @file_get_contents("$PHPUNIT_DIR/.$PHPUNIT_VERSION.md5")) { // Build a standalone phpunit without symfony/yaml nor prophecy by default - @mkdir($PHPUNIT_DIR); + @mkdir($PHPUNIT_DIR, 0777, true); chdir($PHPUNIT_DIR); if (file_exists("phpunit-$PHPUNIT_VERSION")) { passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? '(del /S /F /Q %s & rmdir %1$s) >nul': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION")); From 9cadeb8af2986f00134a5107e368f32b876aef91 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 5 Sep 2017 22:39:38 +0200 Subject: [PATCH 24/40] Don't use return on Assert::markTestSkipped. --- .../DependencyInjection/Tests/Loader/IniFileLoaderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/IniFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/IniFileLoaderTest.php index 003cd714b1fa9..d3c2dfc76fc5e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/IniFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/IniFileLoaderTest.php @@ -51,7 +51,7 @@ public function testTypeConversions($key, $value, $supported) public function testTypeConversionsWithNativePhp($key, $value, $supported) { if (defined('HHVM_VERSION_ID')) { - return $this->markTestSkipped(); + $this->markTestSkipped(); } if (!$supported) { From cfc9346f660d6c8917a6e60a41935268e73a43b7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 6 Sep 2017 10:30:21 +0200 Subject: [PATCH 25/40] [travis] update to trusty --- .travis.yml | 8 ++------ appveyor.yml | 6 +++--- src/Symfony/Bundle/SecurityBundle/composer.json | 16 ++++++++-------- .../Component/HttpFoundation/JsonResponse.php | 4 ++-- .../HttpFoundation/Tests/JsonResponseTest.php | 7 +++++-- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index b7ce58bd8ffbb..e01ab63ab3227 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: php -dist: precise +dist: trusty sudo: false git: @@ -13,17 +13,14 @@ addons: env: global: - - MIN_PHP=5.3.9 + - MIN_PHP=5.4.9 - SYMFONY_PROCESS_PHP_TEST_BINARY=~/.phpenv/versions/5.6/bin/php matrix: include: - # Use the newer stack for HHVM as HHVM does not support Precise anymore since a long time and so Precise has an outdated version - php: hhvm-3.18 sudo: required - dist: trusty group: edge - - php: 5.3 - php: 5.4 - php: 5.5 - php: 5.6 @@ -99,7 +96,6 @@ before_install: echo opcache.enable_cli = 1 >> $INI echo hhvm.jit = 0 >> $INI echo apc.enable_cli = 1 >> $INI - echo extension = ldap.so >> $INI [[ $PHP = 5.* ]] && echo extension = memcache.so >> $INI if [[ $PHP = 5.* ]]; then echo extension = mongo.so >> $INI diff --git a/appveyor.yml b/appveyor.yml index ae43082f82fd8..6d869967263bd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,8 +17,8 @@ init: install: - mkdir c:\php && cd c:\php - appveyor DownloadFile https://raw.githubusercontent.com/symfony/binary-utils/master/cacert.pem - - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php-5.3.11-nts-Win32-VC9-x86.zip - - 7z x php-5.3.11-nts-Win32-VC9-x86.zip -y >nul + - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php-5.3.9-nts-Win32-VC9-x86.zip + - 7z x php-5.3.9-nts-Win32-VC9-x86.zip -y >nul - appveyor DownloadFile https://raw.githubusercontent.com/symfony/binary-utils/master/ICU-51.2-dlls.zip - 7z x ICU-51.2-dlls.zip -y >nul - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.1.3-Win32-VC14-x86.zip @@ -61,7 +61,7 @@ test_script: - cd c:\php && 7z x php-7.1.3-Win32-VC14-x86.zip -y >nul && copy /Y php.ini-min php.ini - cd c:\projects\symfony - php phpunit src\Symfony --exclude-group benchmark,intl-data || SET X=!errorlevel! - - cd c:\php && 7z x php-5.3.11-nts-Win32-VC9-x86.zip -y >nul && copy /Y php.ini-min php.ini + - cd c:\php && 7z x php-5.3.9-nts-Win32-VC9-x86.zip -y >nul && copy /Y php.ini-min php.ini - cd c:\projects\symfony - SET SYMFONY_PHPUNIT_SKIPPED_TESTS=phpunit.skipped - php phpunit src\Symfony --exclude-group benchmark,intl-data || SET X=!errorlevel! diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 6d6073f7f0bc3..69091f5269c32 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -23,20 +23,20 @@ "symfony/http-kernel": "~2.7" }, "require-dev": { - "symfony/browser-kit": "~2.4", + "symfony/browser-kit": "~2.7", "symfony/console": "~2.7", - "symfony/css-selector": "^2.0.5", - "symfony/dependency-injection": "^2.6.6", - "symfony/dom-crawler": "^2.0.5", + "symfony/css-selector": "^2.7", + "symfony/dependency-injection": "^2.7", + "symfony/dom-crawler": "^2.7", "symfony/form": "~2.7.15|^2.8.8", "symfony/framework-bundle": "~2.7.25|^2.8.18", "symfony/http-foundation": "~2.7", "symfony/twig-bundle": "~2.7", "symfony/twig-bridge": "^2.7.4", - "symfony/process": "^2.0.5", - "symfony/validator": "~2.5", - "symfony/yaml": "^2.0.5", - "symfony/expression-language": "~2.6", + "symfony/process": "^2.7", + "symfony/validator": "~2.7", + "symfony/yaml": "^2.7", + "symfony/expression-language": "~2.7", "doctrine/doctrine-bundle": "~1.2", "twig/twig": "~1.34|~2.4", "ircmaxell/password-compat": "~1.0" diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index c6e0ba6541061..621c8410c2c21 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -121,7 +121,7 @@ public function setData($data = array()) $data = json_encode($data, $this->encodingOptions); } else { try { - if (\PHP_VERSION_ID < 50400) { + if (!interface_exists('JsonSerializable', false)) { // PHP 5.3 triggers annoying warnings for some // types that can't be serialized as JSON (INF, resources, etc.) // but doesn't provide the JsonSerializable interface. @@ -153,7 +153,7 @@ public function setData($data = array()) if (\PHP_VERSION_ID < 50500) { restore_error_handler(); } - if (\PHP_VERSION_ID >= 50400 && 'Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { + if (interface_exists('JsonSerializable', false) && 'Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { throw $e->getPrevious() ?: $e; } throw $e; diff --git a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php index 8156da06939e4..e15505cc6948e 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -206,10 +206,13 @@ public function testSetContent() /** * @expectedException \Exception * @expectedExceptionMessage This error is expected - * @requires PHP 5.4 */ public function testSetContentJsonSerializeError() { + if (!interface_exists('JsonSerializable', false)) { + $this->markTestSkipped('JsonSerializable is required.'); + } + $serializable = new JsonSerializableObject(); JsonResponse::create($serializable); @@ -224,7 +227,7 @@ public function testSetComplexCallback() } } -if (interface_exists('JsonSerializable')) { +if (interface_exists('JsonSerializable', false)) { class JsonSerializableObject implements \JsonSerializable { public function jsonSerialize() From a0f9f2c53739ef336064e9e3d5ecd0c0d2046418 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 5 Sep 2017 19:39:30 +0200 Subject: [PATCH 26/40] check permissions if dump target dir is missing `is_dir()` returns `false` if the parent directory misses the executable bit even when the directory itself is present. --- src/Symfony/Component/Filesystem/Filesystem.php | 10 ++++++++++ .../Filesystem/Tests/FilesystemTest.php | 16 ++++++++++++++++ .../Filesystem/Tests/FilesystemTestCase.php | 1 + 3 files changed, 27 insertions(+) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index bc2e3dcc2d897..bbef48b466885 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -532,6 +532,16 @@ public function dumpFile($filename, $content, $mode = 0666) $dir = dirname($filename); if (!is_dir($dir)) { + $oldCwd = getcwd(); + + if (!@chdir(dirname($dir))) { + // When the parent directory misses the executable permission bit, we are unable to enter it and thus + // cannot check if the target directory exists. + throw new IOException(sprintf('Unable to detect if the target directory "%s" exists.', $dir)); + } + + chdir($oldCwd); + $this->mkdir($dir); } diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index b7bdfac4155e0..44eeceabd9f49 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1102,6 +1102,22 @@ public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile() $this->assertFilePermissions(745, $filename); } + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + * @expectedExceptionMessageRegExp /^Unable to detect if the target directory ".*" exists\.$/ + */ + public function testDumpFailsWithExceptionIfExecutablePermissionsForTheParentDirectoryAreMissing() + { + $this->markAsSkippedIfChmodIsMissing(); + + $target = $this->workspace.DIRECTORY_SEPARATOR.'foo'; + $file = $target.DIRECTORY_SEPARATOR.'foobar'; + mkdir($target); + chmod($this->workspace, 0666); + + $this->filesystem->dumpFile($file, 'baz'); + } + public function testCopyShouldKeepExecutionPermission() { $this->markAsSkippedIfChmodIsMissing(); diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php index 5586a00547a68..47598b29427da 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php @@ -61,6 +61,7 @@ protected function tearDown() $this->longPathNamesWindows = array(); } + chmod($this->workspace, 0777); $this->filesystem->remove($this->workspace); umask($this->umask); } From d1fe4153a16489d153e5660c8407789929d32ef1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 6 Sep 2017 18:53:48 +0200 Subject: [PATCH 27/40] [HttpFoundation] Fix logic when JsonSerializable is missing --- .../Component/HttpFoundation/JsonResponse.php | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 621c8410c2c21..8837175df8d10 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -127,30 +127,31 @@ public function setData($data = array()) // but doesn't provide the JsonSerializable interface. set_error_handler(function () { return false; }); $data = @json_encode($data, $this->encodingOptions); - } else { + restore_error_handler(); + } elseif (\PHP_VERSION_ID < 50500) { // PHP 5.4 and up wrap exceptions thrown by JsonSerializable // objects in a new exception that needs to be removed. // Fortunately, PHP 5.5 and up do not trigger any warning anymore. - if (\PHP_VERSION_ID < 50500) { - // Clear json_last_error() - json_encode(null); - $errorHandler = set_error_handler('var_dump'); - restore_error_handler(); - set_error_handler(function () use ($errorHandler) { - if (JSON_ERROR_NONE === json_last_error()) { - return $errorHandler && false !== call_user_func_array($errorHandler, func_get_args()); - } - }); - } - + // Clear json_last_error() + json_encode(null); + $errorHandler = set_error_handler('var_dump'); + restore_error_handler(); + set_error_handler(function () use ($errorHandler) { + if (JSON_ERROR_NONE === json_last_error()) { + return $errorHandler && false !== call_user_func_array($errorHandler, func_get_args()); + } + }); + $data = json_encode($data, $this->encodingOptions); + restore_error_handler(); + } else { $data = json_encode($data, $this->encodingOptions); } - - if (\PHP_VERSION_ID < 50500) { + } catch (\Error $e) { + if (\PHP_VERSION_ID < 50500 || !interface_exists('JsonSerializable', false)) { restore_error_handler(); } } catch (\Exception $e) { - if (\PHP_VERSION_ID < 50500) { + if (\PHP_VERSION_ID < 50500 || !interface_exists('JsonSerializable', false)) { restore_error_handler(); } if (interface_exists('JsonSerializable', false) && 'Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { From e4ce14d0737495ab76d3d580b79c9c8e5be6bf53 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 6 Sep 2017 19:03:33 +0200 Subject: [PATCH 28/40] [travis] add ldap.so for php70 --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index e01ab63ab3227..1d31503dcbd77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -120,6 +120,11 @@ before_install: - | # Install extra PHP extensions + if [[ ! $skip && $PHP = 7.0 ]]; then + wget https://github.com/symfony/binary-utils/releases/download/v0.1/ldap-php70.tar.bz2 + tar -xjf ldap-php70.tar.bz2 + echo extension = $(pwd)/ldap.so >> $INI + fi if [[ ! $skip && $PHP = 5.* ]]; then ([[ $deps ]] || tfold ext.symfony_debug 'cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> '"$INI") && tfold ext.memcached pecl install -f memcached-2.1.0 && From 07933655e868303a46db98475162aed9c872e500 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 6 Sep 2017 19:21:48 +0200 Subject: [PATCH 29/40] [travis] fix minor php7.0 version --- .travis.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index c5aa9c01c74ff..a9b4bb229554e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ matrix: group: edge - php: 5.5 - php: 5.6 - - php: 7.0 + - php: 7.0.8 env: deps=high - php: 7.1 env: deps=low @@ -128,7 +128,7 @@ before_install: - | # Install extra PHP extensions - if [[ ! $skip && $PHP = 7.0 ]]; then + if [[ ! $skip && $PHP = 7.0.* ]]; then wget https://github.com/symfony/binary-utils/releases/download/v0.1/ldap-php70.tar.bz2 tar -xjf ldap-php70.tar.bz2 echo extension = $(pwd)/ldap.so >> $INI @@ -197,10 +197,7 @@ install: elif [[ $deps = high ]]; then echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP && $PHPUNIT_X$LEGACY'" elif [[ $deps = low ]]; then - echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT_X'" && - # Test the PhpUnit bridge on PHP 5.3, using the original phpunit script - tfold src/Symfony/Bridge/PhpUnit \ - "cd src/Symfony/Bridge/PhpUnit && wget https://phar.phpunit.de/phpunit-4.8.phar && phpenv global 5.3 && composer update --no-progress --ansi && php phpunit-4.8.phar" + echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT_X'" elif [[ $PHP = hhvm* ]]; then $PHPUNIT --exclude-group benchmark,intl-data else From 73cdb68308670ea6e9caede76738aa31adbcf8b7 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Wed, 6 Sep 2017 15:05:48 -0400 Subject: [PATCH 30/40] Get KERNEL_CLASS through $_ENV too --- src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php index 26781cdf2285c..af8f4300f2961 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php @@ -106,8 +106,9 @@ private static function getPhpUnitCliConfigArgument() */ protected static function getKernelClass() { - if (isset($_SERVER['KERNEL_CLASS'])) { - if (!class_exists($class = $_SERVER['KERNEL_CLASS'])) { + if (isset($_SERVER['KERNEL_CLASS']) || isset($_ENV['KERNEL_CLASS'])) { + $class = isset($_SERVER['KERNEL_CLASS']) ? $_SERVER['KERNEL_CLASS'] : $_ENV['KERNEL_CLASS']; + if (!class_exists($class)) { throw new \RuntimeException(sprintf('Class "%s" doesn\'t exist or cannot be autoloaded. Check that the KERNEL_CLASS value in phpunit.xml matches the fully-qualified class name of your Kernel or override the %s::createKernel() method.', $class, static::class)); } From cf11fb9652f6c41c986d740a20429a1523cb65a5 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Wed, 6 Sep 2017 18:24:46 -0400 Subject: [PATCH 31/40] Get KERNEL_DIR through $_ENV too for KernelTestCase --- src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php index 351a8cc80a15d..5dadca83f2e1b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php @@ -105,8 +105,8 @@ private static function getPhpUnitCliConfigArgument() */ protected static function getKernelClass() { - if (isset($_SERVER['KERNEL_DIR'])) { - $dir = $_SERVER['KERNEL_DIR']; + if (isset($_SERVER['KERNEL_DIR']) || isset($_ENV['KERNEL_DIR'])) { + $dir = isset($_SERVER['KERNEL_DIR']) ? $_SERVER['KERNEL_DIR'] : $_ENV['KERNEL_DIR']; if (!is_dir($dir)) { $phpUnitDir = static::getPhpUnitXmlDir(); From b9c6928d7e3070d6ae07c55505ac7f333f82d98c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 7 Sep 2017 14:05:56 +0200 Subject: [PATCH 32/40] [HttpKernel] "controller.service_arguments" services should be public --- .../RegisterControllerArgumentLocatorsPass.php | 1 + ...RegisterControllerArgumentLocatorsPassTest.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php index 222185f52766f..9c00f99b7b003 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php @@ -50,6 +50,7 @@ public function process(ContainerBuilder $container) foreach ($container->findTaggedServiceIds($this->controllerTag, true) as $id => $tags) { $def = $container->getDefinition($id); + $def->setPublic(true); $class = $def->getClass(); $autowire = $def->isAutowired(); diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php index 0542698d694ef..83a07cb4663d2 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterControllerArgumentLocatorsPassTest.php @@ -266,6 +266,21 @@ public function testArgumentWithNoTypeHintIsOk() $locator = $container->getDefinition((string) $resolver->getArgument(0))->getArgument(0); $this->assertEmpty(array_keys($locator)); } + + public function testControllersAreMadePublic() + { + $container = new ContainerBuilder(); + $resolver = $container->register('argument_resolver.service')->addArgument(array()); + + $container->register('foo', ArgumentWithoutTypeController::class) + ->setPublic(false) + ->addTag('controller.service_arguments'); + + $pass = new RegisterControllerArgumentLocatorsPass(); + $pass->process($container); + + $this->assertTrue($container->getDefinition('foo')->isPublic()); + } } class RegisterTestController From a29e0694de139965a1e8e1f69dd84b46cca8ce89 Mon Sep 17 00:00:00 2001 From: Sergey Linnik Date: Tue, 5 Sep 2017 10:54:44 +0300 Subject: [PATCH 33/40] [Security] Fix exception when use_referer option is true and referer is not set or empty --- .../DefaultAuthenticationSuccessHandler.php | 5 ++--- .../DefaultAuthenticationSuccessHandlerTest.php | 10 ++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php index 7da6e35572b47..b7411e2c11d6c 100644 --- a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php +++ b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php @@ -118,12 +118,11 @@ protected function determineTargetUrl(Request $request) return $targetUrl; } - if ($this->options['use_referer']) { - $targetUrl = $request->headers->get('Referer'); + if ($this->options['use_referer'] && $targetUrl = $request->headers->get('Referer')) { if (false !== $pos = strpos($targetUrl, '?')) { $targetUrl = substr($targetUrl, 0, $pos); } - if ($targetUrl !== $this->httpUtils->generateUri($request, $this->options['login_path'])) { + if ($targetUrl && $targetUrl !== $this->httpUtils->generateUri($request, $this->options['login_path'])) { return $targetUrl; } } diff --git a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php index b42f840358e03..a7b8547b6b53d 100644 --- a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php @@ -83,6 +83,16 @@ public function getRequestRedirections() array(), '/', ), + 'target path as referer when referer not set' => array( + Request::create('/'), + array('use_referer' => true), + '/', + ), + 'target path as referer when referer is ?' => array( + Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => '?')), + array('use_referer' => true), + '/', + ), 'target path should be different than login URL' => array( Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/login')), array('use_referer' => true, 'login_path' => '/login'), From 3eb79e5197c8b4184bf4a250fc04bf4175bf65c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Fri, 8 Sep 2017 15:50:13 +0200 Subject: [PATCH 34/40] [Fabbot] Do not run php-cs-fixer if there are no change in src/ --- .php_cs.dist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.php_cs.dist b/.php_cs.dist index 140fd3265011c..6282431a419d4 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -1,5 +1,9 @@ setRules(array( '@Symfony' => true, From 1605ce1f074d96c3e62eeb297b00a66ce9a28c53 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 8 Sep 2017 16:43:09 +0200 Subject: [PATCH 35/40] [Filesystem] skip tests if not applicable --- src/Symfony/Component/Filesystem/Tests/FilesystemTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 44eeceabd9f49..67ccdd1eb06d2 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1115,6 +1115,10 @@ public function testDumpFailsWithExceptionIfExecutablePermissionsForTheParentDir mkdir($target); chmod($this->workspace, 0666); + if (false !== @chdir($this->workspace)) { + $this->markTestSkipped('Test skipped as the used PHP version does not prevent entering directories without the required permissions.'); + } + $this->filesystem->dumpFile($file, 'baz'); } From 7793b797afbbe07d34b3ade2a4a368ddc5654af4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 8 Sep 2017 18:12:06 -0700 Subject: [PATCH 36/40] Revert "bug #24105 [Filesystem] check permissions if dump target dir is missing (xabbuh)" This reverts commit d74144fc0b588bb8d7e0f73e6063e4022946f8e5, reversing changes made to 2b79f484058bd3265a39709e97a8787044b2ae7d. --- .../Component/Filesystem/Filesystem.php | 10 ---------- .../Filesystem/Tests/FilesystemTest.php | 20 ------------------- .../Filesystem/Tests/FilesystemTestCase.php | 1 - 3 files changed, 31 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index bbef48b466885..bc2e3dcc2d897 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -532,16 +532,6 @@ public function dumpFile($filename, $content, $mode = 0666) $dir = dirname($filename); if (!is_dir($dir)) { - $oldCwd = getcwd(); - - if (!@chdir(dirname($dir))) { - // When the parent directory misses the executable permission bit, we are unable to enter it and thus - // cannot check if the target directory exists. - throw new IOException(sprintf('Unable to detect if the target directory "%s" exists.', $dir)); - } - - chdir($oldCwd); - $this->mkdir($dir); } diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 67ccdd1eb06d2..b7bdfac4155e0 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1102,26 +1102,6 @@ public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile() $this->assertFilePermissions(745, $filename); } - /** - * @expectedException \Symfony\Component\Filesystem\Exception\IOException - * @expectedExceptionMessageRegExp /^Unable to detect if the target directory ".*" exists\.$/ - */ - public function testDumpFailsWithExceptionIfExecutablePermissionsForTheParentDirectoryAreMissing() - { - $this->markAsSkippedIfChmodIsMissing(); - - $target = $this->workspace.DIRECTORY_SEPARATOR.'foo'; - $file = $target.DIRECTORY_SEPARATOR.'foobar'; - mkdir($target); - chmod($this->workspace, 0666); - - if (false !== @chdir($this->workspace)) { - $this->markTestSkipped('Test skipped as the used PHP version does not prevent entering directories without the required permissions.'); - } - - $this->filesystem->dumpFile($file, 'baz'); - } - public function testCopyShouldKeepExecutionPermission() { $this->markAsSkippedIfChmodIsMissing(); diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php index 47598b29427da..5586a00547a68 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTestCase.php @@ -61,7 +61,6 @@ protected function tearDown() $this->longPathNamesWindows = array(); } - chmod($this->workspace, 0777); $this->filesystem->remove($this->workspace); umask($this->umask); } From bfae4549680358a6fd4d9fb82f047048efdc57d6 Mon Sep 17 00:00:00 2001 From: SpacePossum Date: Mon, 11 Sep 2017 07:17:31 +0200 Subject: [PATCH 37/40] Remove `protected_to_private` rule. --- .php_cs.dist | 1 + 1 file changed, 1 insertion(+) diff --git a/.php_cs.dist b/.php_cs.dist index 2e432b791eed0..04d9ec5bdc5a8 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -13,6 +13,7 @@ return PhpCsFixer\Config::create() 'braces' => array('allow_single_line_closure' => true), 'heredoc_to_nowdoc' => false, 'phpdoc_annotation_without_dot' => false, + 'protected_to_private' => false, )) ->setRiskyAllowed(true) ->setFinder( From 122da5add5fd298983503e82fb8a47a10f258d79 Mon Sep 17 00:00:00 2001 From: Mara Blaga Date: Mon, 11 Sep 2017 15:10:51 +0100 Subject: [PATCH 38/40] [DomCrawler] Fix conversion to int on GetPhpFiles --- src/Symfony/Component/DomCrawler/Form.php | 12 ++++++++++++ src/Symfony/Component/DomCrawler/Tests/FormTest.php | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php index bad1b34935d04..db4d60dd3d141 100644 --- a/src/Symfony/Component/DomCrawler/Form.php +++ b/src/Symfony/Component/DomCrawler/Form.php @@ -172,6 +172,18 @@ public function getPhpFiles() if (!empty($qs)) { parse_str($qs, $expandedValue); $varName = substr($name, 0, strlen(key($expandedValue))); + + array_walk_recursive( + $expandedValue, + function (&$value, $key) { + if (ctype_digit($value) && ('size' === $key || 'error' === $key)) { + $value = (int) $value; + } + } + ); + + reset($expandedValue); + $values = array_replace_recursive($values, array($varName => current($expandedValue))); } } diff --git a/src/Symfony/Component/DomCrawler/Tests/FormTest.php b/src/Symfony/Component/DomCrawler/Tests/FormTest.php index 0a4cd7201e1bb..437a5ddaf0cbf 100644 --- a/src/Symfony/Component/DomCrawler/Tests/FormTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/FormTest.php @@ -456,6 +456,15 @@ public function testGetPhpFiles() $form = $this->createForm('
'); $this->assertEquals(array('f.o o' => array('bar' => array('ba.z' => array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => 4, 'size' => 0), array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => 4, 'size' => 0)))), $form->getPhpFiles(), '->getPhpFiles() preserves periods and spaces in names recursively'); + + $form = $this->createForm('
'); + $files = $form->getPhpFiles(); + + $this->assertSame(0, $files['foo']['bar']['size'], '->getPhpFiles() converts size to int'); + $this->assertSame(4, $files['foo']['bar']['error'], '->getPhpFiles() converts error to int'); + + $form = $this->createForm('
'); + $this->assertEquals(array('size' => array('error' => array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => 4, 'size' => 0))), $form->getPhpFiles(), '->getPhpFiles() int conversion does not collide with file names'); } /** From 4fa6fcfb93e0adda06a8136dc3870f84fc48dceb Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 11 Sep 2017 09:13:13 -0700 Subject: [PATCH 39/40] updated CHANGELOG for 3.3.9 --- CHANGELOG-3.3.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG-3.3.md b/CHANGELOG-3.3.md index 3331ea2a1d1fa..320bf84f1dc7d 100644 --- a/CHANGELOG-3.3.md +++ b/CHANGELOG-3.3.md @@ -7,6 +7,23 @@ in 3.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/v3.3.0...v3.3.1 +* 3.3.9 (2017-09-11) + + * bug #24141 [DomCrawler] Fix conversion to int on GetPhpFiles (MaraBlaga) + * bug #23853 Filtering empty uuids in ORMQueryBuilderLoader. (mlazovla) + * bug #24101 [Security] Fix exception when use_referer option is true and referer is not set or empty (linniksa) + * bug #24105 [Filesystem] check permissions if dump target dir is missing (xabbuh) + * bug #24126 [HttpKernel] "controller.service_arguments" services should be public (nicolas-grekas) + * bug #24113 [FrameworkBundle] Get KERNEL_CLASS through $_ENV too for KernelTestCase (yceruto) + * bug #24115 [FrameworkBundle] Get KERNEL_DIR through $_ENV too for KernelTestCase (yceruto) + * bug #24041 [ExpressionLanguage] throws an exception on calling uncallable method (fmata) + * bug #24096 Fix ArrayInput::toString() for VALUE_IS_ARRAY options/args (chalasr) + * bug #24082 [DI] Minor fix in dumped code (nicolas-grekas) + * bug #23969 [Cache] Use namespace versioning for backends that dont support clearing by keys (nicolas-grekas) + * bug #24021 [DI] Don't track merged configs when the extension doesn't expose it (nicolas-grekas) + * bug #24011 [Cache] Always require symfony/polyfill-apcu to provide APCuIterator everywhere (guillaumelecerf) + * bug #23730 Fixed the escaping of back slashes and << in console output (javiereguiluz) + * 3.3.8 (2017-08-28) * bug #24016 [DI] Fix tracking env var placeholders nested in object graphs (nicolas-grekas) From b9c93f1faa5e0555e2f768fc974fc05d4080a07d Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 11 Sep 2017 09:13:23 -0700 Subject: [PATCH 40/40] updated VERSION for 3.3.9 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index f8ed2b08b4b63..5f986cf4f9f09 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -61,12 +61,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface private $projectDir; - const VERSION = '3.3.9-DEV'; + const VERSION = '3.3.9'; const VERSION_ID = 30309; const MAJOR_VERSION = 3; const MINOR_VERSION = 3; const RELEASE_VERSION = 9; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '01/2018'; const END_OF_LIFE = '07/2018';