From 5543170af36a3e3f065455099dd849a473a5c6b0 Mon Sep 17 00:00:00 2001
From: Alexander Schnitzler <git@alexanderschnitzler.de>
Date: Mon, 11 May 2020 17:33:41 +0200
Subject: [PATCH] [TASK] Fix phpstan checkFunctionArgumentTypes errors in
 ext:core Cache

This patch fixes incompatible type usage in function arguments
and is preparatory work for introducing native type hints and
strict mode in all core files.

Releases: master, 10.4
Resolves: #92265
Change-Id: I0c53064dc7b719ea266d54a169e2c16c924d1060
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/65663
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Oliver Bartsch <bo@cedev.de>
Tested-by: Alexander Schnitzler <git@alexanderschnitzler.de>
Tested-by: Daniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Oliver Klee <typo3-coding@oliverklee.de>
Reviewed-by: Alexander Schnitzler <git@alexanderschnitzler.de>
Reviewed-by: Daniel Goerz <daniel.goerz@posteo.de>
---
 .../Classes/Cache/Backend/AbstractBackend.php |  2 ++
 .../Classes/Cache/Backend/FileBackend.php     | 20 +++++++++----------
 .../core/Classes/Cache/Backend/PdoBackend.php |  3 +++
 .../Classes/Cache/Backend/RedisBackend.php    |  2 +-
 .../Cache/Backend/SimpleFileBackend.php       |  2 +-
 .../Cache/Backend/Typo3DatabaseBackend.php    |  4 ++--
 .../core/Classes/Cache/CacheManager.php       |  2 +-
 7 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/typo3/sysext/core/Classes/Cache/Backend/AbstractBackend.php b/typo3/sysext/core/Classes/Cache/Backend/AbstractBackend.php
index 9e20e7abd2ed..641229512d3d 100644
--- a/typo3/sysext/core/Classes/Cache/Backend/AbstractBackend.php
+++ b/typo3/sysext/core/Classes/Cache/Backend/AbstractBackend.php
@@ -122,6 +122,8 @@ abstract class AbstractBackend implements BackendInterface, LoggerAwareInterface
      */
     public function flushByTags(array $tags)
     {
+        // todo: flushByTag is not necessarily implemented since it's neither defined of the interface, nor defined in
+        //       this class as abstract method. Therefore this potentially triggers a fatal error during runtime.
         array_walk($tags, [$this, 'flushByTag']);
     }
 
diff --git a/typo3/sysext/core/Classes/Cache/Backend/FileBackend.php b/typo3/sysext/core/Classes/Cache/Backend/FileBackend.php
index b21613fd1a08..d648b1cca38b 100644
--- a/typo3/sysext/core/Classes/Cache/Backend/FileBackend.php
+++ b/typo3/sysext/core/Classes/Cache/Backend/FileBackend.php
@@ -107,7 +107,7 @@ class FileBackend extends SimpleFileBackend implements FreezableBackendInterface
         parent::setCache($cache);
         if (file_exists($this->cacheDirectory . 'FrozenCache.data')) {
             $this->frozen = true;
-            $this->cacheEntryIdentifiers = unserialize(file_get_contents($this->cacheDirectory . 'FrozenCache.data'));
+            $this->cacheEntryIdentifiers = unserialize((string)file_get_contents($this->cacheDirectory . 'FrozenCache.data'));
         }
     }
 
@@ -139,9 +139,9 @@ class FileBackend extends SimpleFileBackend implements FreezableBackendInterface
         }
         $this->remove($entryIdentifier);
         $temporaryCacheEntryPathAndFilename = $this->cacheDirectory . StringUtility::getUniqueId() . '.temp';
-        $lifetime = $lifetime ?? $this->defaultLifetime;
-        $expiryTime = $lifetime === 0 ? 0 : $GLOBALS['EXEC_TIME'] + $lifetime;
-        $metaData = str_pad($expiryTime, self::EXPIRYTIME_LENGTH) . implode(' ', $tags) . str_pad(strlen($data), self::DATASIZE_DIGITS);
+        $lifetime = (int)($lifetime ?? $this->defaultLifetime);
+        $expiryTime = $lifetime === 0 ? 0 : (int)($GLOBALS['EXEC_TIME'] + $lifetime);
+        $metaData = str_pad((string)$expiryTime, self::EXPIRYTIME_LENGTH) . implode(' ', $tags) . str_pad((string)strlen($data), self::DATASIZE_DIGITS);
         $result = file_put_contents($temporaryCacheEntryPathAndFilename, $data . $metaData);
         GeneralUtility::fixPermissions($temporaryCacheEntryPathAndFilename);
         if ($result === false) {
@@ -181,12 +181,12 @@ class FileBackend extends SimpleFileBackend implements FreezableBackendInterface
         }
         $dataSize = (int)file_get_contents(
             $pathAndFilename,
-            null,
+            false,
             null,
             filesize($pathAndFilename) - self::DATASIZE_DIGITS,
             self::DATASIZE_DIGITS
         );
-        return file_get_contents($pathAndFilename, null, null, 0, $dataSize);
+        return file_get_contents($pathAndFilename, false, null, 0, $dataSize);
     }
 
     /**
@@ -256,12 +256,12 @@ class FileBackend extends SimpleFileBackend implements FreezableBackendInterface
             $cacheEntryPathAndFilename = $directoryIterator->getPathname();
             $index = (int)file_get_contents(
                 $cacheEntryPathAndFilename,
-                null,
+                false,
                 null,
                 filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS,
                 self::DATASIZE_DIGITS
             );
-            $metaData = file_get_contents($cacheEntryPathAndFilename, null, null, $index);
+            $metaData = (string)file_get_contents($cacheEntryPathAndFilename, false, null, $index);
             $expiryTime = (int)substr($metaData, 0, self::EXPIRYTIME_LENGTH);
             if ($expiryTime !== 0 && $expiryTime < $now) {
                 continue;
@@ -318,12 +318,12 @@ class FileBackend extends SimpleFileBackend implements FreezableBackendInterface
         }
         $index = (int)file_get_contents(
             $cacheEntryPathAndFilename,
-            null,
+            false,
             null,
             filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS,
             self::DATASIZE_DIGITS
         );
-        $expiryTime = (int)file_get_contents($cacheEntryPathAndFilename, null, null, $index, self::EXPIRYTIME_LENGTH);
+        $expiryTime = (int)file_get_contents($cacheEntryPathAndFilename, false, null, $index, self::EXPIRYTIME_LENGTH);
         return $expiryTime !== 0 && $expiryTime < $GLOBALS['EXEC_TIME'];
     }
 
diff --git a/typo3/sysext/core/Classes/Cache/Backend/PdoBackend.php b/typo3/sysext/core/Classes/Cache/Backend/PdoBackend.php
index 1735580d2825..070fbf143eb5 100644
--- a/typo3/sysext/core/Classes/Cache/Backend/PdoBackend.php
+++ b/typo3/sysext/core/Classes/Cache/Backend/PdoBackend.php
@@ -284,6 +284,9 @@ class PdoBackend extends AbstractBackend implements TaggableBackendInterface
     protected function importSql(\PDO $databaseHandle, string $pdoDriver, string $pathAndFilename): void
     {
         $sql = file($pathAndFilename, FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES);
+        if ($sql === false) {
+            throw new \RuntimeException('Error while reading file "' . $pathAndFilename . '".', 1601021306);
+        }
         // Remove MySQL style key length delimiters (yuck!) if we are not setting up a MySQL db
         if (strpos($pdoDriver, 'mysql') !== 0) {
             $sql = preg_replace('/"\\([0-9]+\\)/', '"', $sql);
diff --git a/typo3/sysext/core/Classes/Cache/Backend/RedisBackend.php b/typo3/sysext/core/Classes/Cache/Backend/RedisBackend.php
index fa844a51c48e..8bf584537f37 100644
--- a/typo3/sysext/core/Classes/Cache/Backend/RedisBackend.php
+++ b/typo3/sysext/core/Classes/Cache/Backend/RedisBackend.php
@@ -366,7 +366,7 @@ class RedisBackend extends AbstractBackend implements TaggableBackendInterface
             $storedEntry = $this->redis->get(self::IDENTIFIER_DATA_PREFIX . $entryIdentifier);
         }
         if ($this->compression && (string)$storedEntry !== '') {
-            $storedEntry = gzuncompress($storedEntry);
+            $storedEntry = gzuncompress((string)$storedEntry);
         }
         return $storedEntry;
     }
diff --git a/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php b/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php
index d2dbb371fbcf..72c17a101ffd 100644
--- a/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php
+++ b/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php
@@ -307,7 +307,7 @@ class SimpleFileBackend extends AbstractBackend implements PhpCapableBackendInte
         $directory = $this->cacheDirectory;
         if (is_link($directory)) {
             // Avoid attempting to rename the symlink see #87367
-            $directory = realpath($directory);
+            $directory = (string)realpath($directory);
         }
 
         if (is_dir($directory)) {
diff --git a/typo3/sysext/core/Classes/Cache/Backend/Typo3DatabaseBackend.php b/typo3/sysext/core/Classes/Cache/Backend/Typo3DatabaseBackend.php
index af80fc71d02e..a27b5c3c30ad 100644
--- a/typo3/sysext/core/Classes/Cache/Backend/Typo3DatabaseBackend.php
+++ b/typo3/sysext/core/Classes/Cache/Backend/Typo3DatabaseBackend.php
@@ -525,12 +525,12 @@ class Typo3DatabaseBackend extends AbstractBackend implements TaggableBackendInt
      */
     public function getTableDefinitions()
     {
-        $cacheTableSql = file_get_contents(
+        $cacheTableSql = (string)file_get_contents(
             ExtensionManagementUtility::extPath('core') .
             'Resources/Private/Sql/Cache/Backend/Typo3DatabaseBackendCache.sql'
         );
         $requiredTableStructures = str_replace('###CACHE_TABLE###', $this->cacheTable, $cacheTableSql) . LF . LF;
-        $tagsTableSql = file_get_contents(
+        $tagsTableSql = (string)file_get_contents(
             ExtensionManagementUtility::extPath('core') .
             'Resources/Private/Sql/Cache/Backend/Typo3DatabaseBackendTags.sql'
         );
diff --git a/typo3/sysext/core/Classes/Cache/CacheManager.php b/typo3/sysext/core/Classes/Cache/CacheManager.php
index ec34f469f28b..4f39f6d91373 100644
--- a/typo3/sysext/core/Classes/Cache/CacheManager.php
+++ b/typo3/sysext/core/Classes/Cache/CacheManager.php
@@ -88,7 +88,7 @@ class CacheManager implements SingletonInterface
      * If one of the options is not specified, the default value is assumed.
      * Existing cache configurations are preserved.
      *
-     * @param array $cacheConfigurations The cache configurations to set
+     * @param array<string, array> $cacheConfigurations The cache configurations to set
      * @throws \InvalidArgumentException If $cacheConfigurations is not an array
      */
     public function setCacheConfigurations(array $cacheConfigurations)
-- 
GitLab