From 6af04bbac6f65739c00f8e16f4ec975f29f924de Mon Sep 17 00:00:00 2001 From: Vladimir Reznichenko Date: Wed, 9 Oct 2019 21:00:06 +0200 Subject: [PATCH 01/10] SCA: added missing break in a loop --- src/Symfony/Component/Cache/Traits/MemcachedTrait.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php index 999687de99..28046e475b 100644 --- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php +++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php @@ -249,6 +249,7 @@ trait MemcachedTrait foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) { if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) { $ok = false; + break; } } From d2a8e94c79b4d05b18c7ee0c246647647c1d8e2b Mon Sep 17 00:00:00 2001 From: detinkin <48881722+detinkin@users.noreply.github.com> Date: Wed, 9 Oct 2019 20:18:55 +0300 Subject: [PATCH 02/10] Missing argument in method_exists --- src/Symfony/Component/HttpClient/HttpClientTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpClient/HttpClientTrait.php b/src/Symfony/Component/HttpClient/HttpClientTrait.php index ab5f3502f7..2914ab20b6 100644 --- a/src/Symfony/Component/HttpClient/HttpClientTrait.php +++ b/src/Symfony/Component/HttpClient/HttpClientTrait.php @@ -196,7 +196,7 @@ trait HttpClientTrait $normalizedHeaders = []; foreach ($headers as $name => $values) { - if (\is_object($values) && method_exists('__toString')) { + if (\is_object($values) && method_exists($values, '__toString')) { $values = (string) $values; } From 21645a5b96dda40070c1555496ede2cb7bd0e213 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 Oct 2019 13:03:19 +0200 Subject: [PATCH 03/10] [VarDumper] fix resetting the "bold" state in CliDumper --- src/Symfony/Component/VarDumper/Dumper/CliDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php index 2bd347d96a..946df78257 100644 --- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php @@ -28,7 +28,7 @@ class CliDumper extends AbstractDumper protected $maxStringWidth = 0; protected $styles = [ // See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics - 'default' => '38;5;208', + 'default' => '0;38;5;208', 'num' => '1;38;5;38', 'const' => '1;38;5;208', 'str' => '1;38;5;113', From 843bb76f8ac02756932038255c7794b3a59058ce Mon Sep 17 00:00:00 2001 From: Anto Date: Fri, 11 Oct 2019 06:08:52 +0200 Subject: [PATCH 04/10] [PropertyInfo] Respect property name case when guessing from public method name --- .../Extractor/ReflectionExtractor.php | 4 ++-- .../Extractor/ReflectionExtractorTest.php | 2 ++ .../PropertyInfo/Tests/Fixtures/Dummy.php | 24 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index bb8138dc1a..dcb06ee192 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -103,8 +103,8 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp if (!$propertyName || isset($properties[$propertyName])) { continue; } - if (!$reflectionClass->hasProperty($propertyName) && !preg_match('/^[A-Z]{2,}/', $propertyName)) { - $propertyName = lcfirst($propertyName); + if ($reflectionClass->hasProperty($lowerCasedPropertyName = lcfirst($propertyName)) || (!$reflectionClass->hasProperty($propertyName) && !preg_match('/^[A-Z]{2,}/', $propertyName))) { + $propertyName = $lowerCasedPropertyName; } $properties[$propertyName] = $propertyName; } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 0ed5390bb5..5a5c0c7b62 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -59,6 +59,8 @@ class ReflectionExtractorTest extends TestCase '123', 'self', 'realParent', + 'xTotals', + 'YT', 'c', 'd', 'e', diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php index 5b82209e1d..663fef84c7 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php @@ -93,6 +93,16 @@ class Dummy extends ParentDummy */ public $j; + /** + * @var array + */ + private $xTotals; + + /** + * @var string + */ + private $YT; + /** * This should not be removed. * @@ -166,4 +176,18 @@ class Dummy extends ParentDummy public function setRealParent(parent $realParent) { } + + /** + * @return array + */ + public function getXTotals() + { + } + + /** + * @return string + */ + public function getYT() + { + } } From 30180417823e5f41c69cbb1fd6eee07e71c13c6c Mon Sep 17 00:00:00 2001 From: soufianZantar Date: Mon, 5 Aug 2019 10:42:16 +0200 Subject: [PATCH 05/10] [Dotenv] search variable values in ENV first then env file --- src/Symfony/Component/Dotenv/Dotenv.php | 38 ++++++++++++------- .../Component/Dotenv/Tests/DotenvTest.php | 17 +++++++++ src/Symfony/Component/Dotenv/composer.json | 2 +- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index c6fc3cbda9..78bc83334e 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -183,6 +183,8 @@ final class Dotenv throw $this->createFormatException('Whitespace are not supported before the value'); } + $loadedVars = array_flip(explode(',', isset($_SERVER['SYMFONY_DOTENV_VARS']) ? $_SERVER['SYMFONY_DOTENV_VARS'] : (isset($_ENV['SYMFONY_DOTENV_VARS']) ? $_ENV['SYMFONY_DOTENV_VARS'] : ''))); + unset($loadedVars['']); $v = ''; do { @@ -224,8 +226,8 @@ final class Dotenv ++$this->cursor; $value = str_replace(['\\"', '\r', '\n'], ['"', "\r", "\n"], $value); $resolvedValue = $value; - $resolvedValue = $this->resolveVariables($resolvedValue); - $resolvedValue = $this->resolveCommands($resolvedValue); + $resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars); + $resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars); $resolvedValue = str_replace('\\\\', '\\', $resolvedValue); $v .= $resolvedValue; } else { @@ -247,8 +249,8 @@ final class Dotenv } $value = rtrim($value); $resolvedValue = $value; - $resolvedValue = $this->resolveVariables($resolvedValue); - $resolvedValue = $this->resolveCommands($resolvedValue); + $resolvedValue = $this->resolveVariables($resolvedValue, $loadedVars); + $resolvedValue = $this->resolveCommands($resolvedValue, $loadedVars); $resolvedValue = str_replace('\\\\', '\\', $resolvedValue); if ($resolvedValue === $value && preg_match('/\s+/', $value)) { @@ -301,7 +303,7 @@ final class Dotenv } } - private function resolveCommands($value) + private function resolveCommands($value, $loadedVars) { if (false === strpos($value, '$')) { return $value; @@ -317,7 +319,7 @@ final class Dotenv ) /x'; - return preg_replace_callback($regex, function ($matches) { + return preg_replace_callback($regex, function ($matches) use ($loadedVars) { if ('\\' === $matches[1]) { return substr($matches[0], 1); } @@ -332,7 +334,15 @@ final class Dotenv $process = new Process('echo '.$matches[0]); $process->inheritEnvironmentVariables(true); - $process->setEnv($this->values); + + $env = []; + foreach ($this->values as $name => $value) { + if (isset($loadedVars[$name]) || (!isset($_ENV[$name]) && !(isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')))) { + $env[$name] = $value; + } + } + $process->setEnv($env); + try { $process->mustRun(); } catch (ProcessException $e) { @@ -343,7 +353,7 @@ final class Dotenv }, $value); } - private function resolveVariables($value) + private function resolveVariables($value, array $loadedVars) { if (false === strpos($value, '$')) { return $value; @@ -359,7 +369,7 @@ final class Dotenv (?P\})? # optional closing brace /x'; - $value = preg_replace_callback($regex, function ($matches) { + $value = preg_replace_callback($regex, function ($matches) use ($loadedVars) { // odd number of backslashes means the $ character is escaped if (1 === \strlen($matches['backslashes']) % 2) { return substr($matches[0], 1); @@ -375,14 +385,16 @@ final class Dotenv } $name = $matches['name']; - if (isset($this->values[$name])) { + if (isset($loadedVars[$name]) && isset($this->values[$name])) { $value = $this->values[$name]; - } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { - $value = $_SERVER[$name]; } elseif (isset($_ENV[$name])) { $value = $_ENV[$name]; + } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { + $value = $_SERVER[$name]; + } elseif (isset($this->values[$name])) { + $value = $this->values[$name]; } else { - $value = (string) getenv($name); + $value = ''; } if (!$matches['opening_brace'] && isset($matches['closing_brace'])) { diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php index b920270da9..dc7c4c1715 100644 --- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php +++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php @@ -63,6 +63,7 @@ class DotenvTest extends TestCase public function getEnvData() { putenv('LOCAL=local'); + $_ENV['LOCAL'] = 'local'; $_ENV['REMOTE'] = 'remote'; $tests = [ @@ -295,4 +296,20 @@ class DotenvTest extends TestCase $this->assertSame('baz1', getenv('BAZ')); $this->assertSame('/var/www', getenv('DOCUMENT_ROOT')); } + + public function testGetVariablesValueFromEnvFirst() + { + $_ENV['APP_ENV'] = 'prod'; + $dotenv = new Dotenv(true); + + $test = "APP_ENV=dev\nTEST1=foo1_\${APP_ENV}"; + $values = $dotenv->parse($test); + $this->assertSame('foo1_prod', $values['TEST1']); + + if ('\\' !== \DIRECTORY_SEPARATOR) { + $test = "APP_ENV=dev\nTEST2=foo2_\$(php -r 'echo \$_SERVER[\"APP_ENV\"];')"; + $values = $dotenv->parse($test); + $this->assertSame('foo2_prod', $values['TEST2']); + } + } } diff --git a/src/Symfony/Component/Dotenv/composer.json b/src/Symfony/Component/Dotenv/composer.json index 3bcfd89c8d..e35339c98e 100644 --- a/src/Symfony/Component/Dotenv/composer.json +++ b/src/Symfony/Component/Dotenv/composer.json @@ -19,7 +19,7 @@ "php": "^5.5.9|>=7.0.8" }, "require-dev": { - "symfony/process": "~3.2|~4.0" + "symfony/process": "^3.4.2|^4.0" }, "autoload": { "psr-4": { "Symfony\\Component\\Dotenv\\": "" }, From b17ebdf081047649334291d93bc4227e2496e07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gildas=20Qu=C3=A9m=C3=A9ner?= Date: Fri, 11 Oct 2019 18:56:51 +0200 Subject: [PATCH 06/10] bug #33942 [DI] Add extra type check to php dumper --- src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 64dfee8573..e7534ea321 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1889,7 +1889,7 @@ EOF; if (!$value = $edge->getSourceNode()->getValue()) { continue; } - if ($edge->isLazy() || !$value->isShared()) { + if ($edge->isLazy() || !$value instanceof Definition || !$value->isShared()) { return false; } $ids[$edge->getSourceNode()->getId()] = true; From c2dd804a24fffd10da659b36e65ec8cff7baa51f Mon Sep 17 00:00:00 2001 From: Reedy Date: Sat, 12 Oct 2019 01:38:35 +0100 Subject: [PATCH 07/10] Make Symfony\Contracts\Service\Test\ServiceLocatorTest abstract Also make getServiceLocator protected As per https://github.com/symfony/symfony/issues/33946#issuecomment-541100439 --- src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php b/src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php index 408c017c3e..5ed9149529 100644 --- a/src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php +++ b/src/Symfony/Contracts/Service/Test/ServiceLocatorTest.php @@ -15,9 +15,9 @@ use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; use Symfony\Contracts\Service\ServiceLocatorTrait; -class ServiceLocatorTest extends TestCase +abstract class ServiceLocatorTest extends TestCase { - public function getServiceLocator(array $factories) + protected function getServiceLocator(array $factories) { return new class($factories) implements ContainerInterface { use ServiceLocatorTrait; From 56895f12b92cc17baa978606cec56165ce56057a Mon Sep 17 00:00:00 2001 From: Ilia Lazarev Date: Sat, 12 Oct 2019 10:36:35 +0300 Subject: [PATCH 08/10] Add plus character `+` to legal mime subtype For example, the following mime type (used for epub) is not recognized given the current regexp: `application/epub+zip` --- .../HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php index b75242afd0..cfa76843cc 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php @@ -89,7 +89,7 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface $type = trim(ob_get_clean()); - if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) { + if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\+\.]+)#i', $type, $match)) { // it's not a type, but an error message return null; } From 946f0a1e11e5182364d42b323fa82df3212be591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vedran=20Miho=C4=8Dinec?= Date: Sat, 12 Oct 2019 09:41:19 +0200 Subject: [PATCH 09/10] [Cache] fixed TagAwareAdapter returning invalid cache --- .../Cache/Adapter/TagAwareAdapter.php | 12 ++- .../Tests/Adapter/TagAwareAdapterTest.php | 78 +++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index cac8a0ea18..fd038bc612 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -156,7 +156,12 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R if (!$this->pool->hasItem($key)) { return false; } - if (!$itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key)->get()) { + + if (!($itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key))->isHit()) { + return false; + } + + if (!$itemTags = $itemTags->get()) { return true; } @@ -296,7 +301,10 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R } unset($tagKeys[$key]); - $itemTags[$key] = $item->get() ?: []; + + if ($item->isHit()) { + $itemTags[$key] = $item->get() ?: []; + } if (!$tagKeys) { $tagVersions = $this->getTagVersions($itemTags); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php index c8677d5e28..0108b9250b 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php @@ -194,6 +194,84 @@ class TagAwareAdapterTest extends AdapterTestCase $this->assertTrue($pool->getItem('foo')->isHit()); } + public function testTagEntryIsCreatedForItemWithoutTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $adapter = new FilesystemAdapter(); + $this->assertTrue($adapter->hasItem(TagAwareAdapter::TAGS_PREFIX.$itemKey)); + } + + public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair + + $this->assertFalse($anotherPool->hasItem($itemKey)); + } + + public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair + + $item = $anotherPool->getItem($itemKey); + $this->assertFalse($item->isHit()); + } + + public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemAndOnlyHasTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem($itemKey); //simulate losing item but keeping tags + + $this->assertFalse($anotherPool->hasItem($itemKey)); + } + + public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem($itemKey); //simulate losing item but keeping tags + + $item = $anotherPool->getItem($itemKey); + $this->assertFalse($item->isHit()); + } + /** * @return MockObject|PruneableCacheInterface */ From 5c82d301a7cbfa1969adca52658e53f841d70b7a Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 13 Oct 2019 20:43:12 +0200 Subject: [PATCH 10/10] fix PHP 5.6 compatibility --- src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index fd038bc612..ff4fc9a29c 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -157,7 +157,9 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R return false; } - if (!($itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key))->isHit()) { + $itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key); + + if (!$itemTags->isHit()) { return false; }