From f44ae8fa36499ef33704518026362503989a2b74 Mon Sep 17 00:00:00 2001
From: Tomas Norre Mikkelsen <tomasnorre@gmail.com>
Date: Fri, 11 Nov 2022 08:15:43 +0100
Subject: [PATCH] [BUGFIX] CommandUtility::getCommand() results in error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

With PHP 8.1 the CommandUtility::getCommand() results in an
error:

Typed static property TYPO3\CMS\Core\Utility\CommandUtility::$paths
must not be accessed before initialization

This patch is to prevent this from happening

Resolves: #98950
Releases: main
Change-Id: I9fa88c65f25eebb7d2b2f989b875cb7bd85e60f8
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/76551
Tested-by: Oliver Klee <typo3-coding@oliverklee.de>
Reviewed-by: Oliver Klee <typo3-coding@oliverklee.de>
Tested-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: core-ci <typo3@b13.com>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
---
 Build/phpstan/phpstan-baseline.neon             |  5 -----
 .../core/Classes/Utility/CommandUtility.php     |  4 ++--
 .../Tests/Unit/Utility/CommandUtilityTest.php   | 17 +++++++++++++++++
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon
index 81605ce7f33a..3fb5cc7f61c3 100644
--- a/Build/phpstan/phpstan-baseline.neon
+++ b/Build/phpstan/phpstan-baseline.neon
@@ -1170,11 +1170,6 @@ parameters:
 			count: 1
 			path: ../../typo3/sysext/core/Classes/TypoScript/TemplateService.php
 
-		-
-			message: "#^If condition is always false\\.$#"
-			count: 1
-			path: ../../typo3/sysext/core/Classes/Utility/CommandUtility.php
-
 		-
 			message: "#^Call to an undefined method TYPO3\\\\CMS\\\\Core\\\\Cache\\\\Frontend\\\\FrontendInterface\\:\\:require\\(\\)\\.$#"
 			count: 3
diff --git a/typo3/sysext/core/Classes/Utility/CommandUtility.php b/typo3/sysext/core/Classes/Utility/CommandUtility.php
index 7a9e07f044f9..7df4338bd82b 100644
--- a/typo3/sysext/core/Classes/Utility/CommandUtility.php
+++ b/typo3/sysext/core/Classes/Utility/CommandUtility.php
@@ -73,9 +73,9 @@ class CommandUtility
      *
      * The key is a path. The value is either the same path, or false if the path is not valid.
      *
-     * @var array<string, string|false>
+     * @var array<string, string|false>|null
      */
-    protected static array $paths;
+    protected static ?array $paths = null;
 
     /**
      * Wrapper function for php exec function
diff --git a/typo3/sysext/core/Tests/Unit/Utility/CommandUtilityTest.php b/typo3/sysext/core/Tests/Unit/Utility/CommandUtilityTest.php
index 5715e17d8c02..ae29eb27fa12 100644
--- a/typo3/sysext/core/Tests/Unit/Utility/CommandUtilityTest.php
+++ b/typo3/sysext/core/Tests/Unit/Utility/CommandUtilityTest.php
@@ -203,4 +203,21 @@ class CommandUtilityTest extends UnitTestCase
         $actualQuoted = $commandUtilityMock->_call('unQuoteFilenames', $source);
         self::assertEquals($expectedQuoted, $actualQuoted);
     }
+
+    /**
+     * Test to ensure that, the error isn't happening
+     * Error: Typed static property TYPO3\CMS\Core\Utility\CommandUtility::$paths must not be
+     * accessed before initialization
+     *
+     * @test
+     */
+    public function getCommandWithPhpReturnsPathToPhpExecutable(): void
+    {
+        $commandUtilityMock = $this->getAccessibleMock(CommandUtility::class, ['dummy']);
+        $command = $commandUtilityMock->_call('getCommand', 'php');
+
+        self::assertIsString($command);
+        self::assertNotEmpty($command);
+        self::assertStringContainsString('php', $command);
+    }
 }
-- 
GitLab