From 688425e84aa4d588e055d4629b1006b6240428d0 Mon Sep 17 00:00:00 2001
From: Simon Gilli <typo3@gilbertsoft.org>
Date: Sun, 9 Aug 2020 16:12:53 +0200
Subject: [PATCH] [BUGFIX] Avoid empty cache identifiers

Currently it is possible to add an invalid cache configuration with
empty identifiers. This change avoids this behavior by checking the
indentifiers while changing the cache configuration at the
CacheManager.

Resolves: #91959
Resolves: #91773
Releases: master, 10.4
Change-Id: Icfb25ab52418da166582dba4bca389250325097b
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/65229
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Daniel Haupt <mail@danielhaupt.de>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Oliver Klee <typo3-coding@oliverklee.de>
Reviewed-by: Daniel Haupt <mail@danielhaupt.de>
Reviewed-by: Benni Mack <benni@typo3.org>
---
 .../core/Classes/Cache/CacheManager.php       |  8 +++-
 .../Tests/Unit/Cache/CacheManagerTest.php     | 44 +++++++++++++++++++
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/typo3/sysext/core/Classes/Cache/CacheManager.php b/typo3/sysext/core/Classes/Cache/CacheManager.php
index 0272037848de..ec34f469f28b 100644
--- a/typo3/sysext/core/Classes/Cache/CacheManager.php
+++ b/typo3/sysext/core/Classes/Cache/CacheManager.php
@@ -96,13 +96,19 @@ class CacheManager implements SingletonInterface
         $newConfiguration = [];
         $migratedConfiguration = [];
         foreach ($cacheConfigurations as $identifier => $configuration) {
+            if (empty($identifier)) {
+                throw new \InvalidArgumentException('A cache identifier was not set.', 1596980032);
+            }
             if (!is_array($configuration)) {
                 throw new \InvalidArgumentException('The cache configuration for cache "' . $identifier . '" was not an array as expected.', 1231259656);
             }
             // Fallback layer, will be removed in TYPO3 v11.0.
             if (strpos($identifier, 'cache_') === 0) {
-                trigger_error('Accessing a cache with the "cache_" prefix as in "' . $identifier . '" is not necessary anymore, and should be called without the cache prefix.', E_USER_DEPRECATED);
                 $identifier = substr($identifier, 6);
+                if (empty($identifier)) {
+                    throw new \InvalidArgumentException('A cache identifier was not set.', 1596980033);
+                }
+                trigger_error('Accessing a cache with the "cache_" prefix as in "' . $identifier . '" is not necessary anymore, and should be called without the cache prefix.', E_USER_DEPRECATED);
                 $migratedConfiguration[$identifier] = $configuration;
             } else {
                 $newConfiguration[$identifier] = $configuration;
diff --git a/typo3/sysext/core/Tests/Unit/Cache/CacheManagerTest.php b/typo3/sysext/core/Tests/Unit/Cache/CacheManagerTest.php
index e2ae47958f84..59fd653a4bc7 100644
--- a/typo3/sysext/core/Tests/Unit/Cache/CacheManagerTest.php
+++ b/typo3/sysext/core/Tests/Unit/Cache/CacheManagerTest.php
@@ -537,4 +537,48 @@ class CacheManagerTest extends UnitTestCase
         $manager->setCacheConfigurations($rawConfiguration);
         self::assertEquals($expectedConfiguration, $manager->_get('cacheConfigurations'));
     }
+
+    /**
+     * @test
+     */
+    public function setCacheConfigurationsThrowsExceptionIfConfiguredCacheDoesNotHaveAnIdentifier()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionCode(1596980032);
+
+        /** @var \PHPUnit\Framework\MockObject\MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface|CacheManager $manager */
+        $manager = $this->getAccessibleMock(CacheManager::class, ['dummy']);
+        $manager->setCacheConfigurations([
+            '' => [
+                'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
+                'backend' => \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class,
+                'options' => [
+                    'compression' => true,
+                ],
+                'groups' => ['pages'],
+            ]
+        ]);
+    }
+
+    /**
+     * @test
+     */
+    public function setCacheConfigurationsThrowsExceptionIfMigratedConfiguredCacheDoesNotHaveAnIdentifier()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionCode(1596980033);
+
+        /** @var \PHPUnit\Framework\MockObject\MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface|CacheManager $manager */
+        $manager = $this->getAccessibleMock(CacheManager::class, ['dummy']);
+        $manager->setCacheConfigurations([
+            'cache_' => [
+                'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
+                'backend' => \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class,
+                'options' => [
+                    'compression' => true,
+                ],
+                'groups' => ['pages'],
+            ]
+        ]);
+    }
 }
-- 
GitLab