From 842cc4c6577c61b2a147ab8f466c0373d6347b10 Mon Sep 17 00:00:00 2001 From: Alies Lapatsin Date: Fri, 12 Sep 2025 10:47:19 +0200 Subject: [PATCH 1/2] Fix handling of additional INI directory files by checking if filenames are an array. Skip not existing dirs on uninstall command PHP_INI_SCAN_DIR may contain a non-existing directory in the list --- .../Ini/RemoveIniEntryWithFileGetContents.php | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/Installing/Ini/RemoveIniEntryWithFileGetContents.php b/src/Installing/Ini/RemoveIniEntryWithFileGetContents.php index ffed9c30..8fc5f766 100644 --- a/src/Installing/Ini/RemoveIniEntryWithFileGetContents.php +++ b/src/Installing/Ini/RemoveIniEntryWithFileGetContents.php @@ -18,6 +18,7 @@ use function file_exists; use function file_get_contents; use function in_array; +use function is_array; use function preg_replace; use function scandir; use function sprintf; @@ -39,24 +40,27 @@ public function __invoke(Package $package, TargetPlatform $targetPlatform, Outpu $additionalIniDirectory = $targetPlatform->phpBinaryPath->additionalIniDirectory(); if ($additionalIniDirectory !== null) { - $allIniFiles = array_merge( - array_map( - static function (string $path) use ($additionalIniDirectory): string { - return $additionalIniDirectory . DIRECTORY_SEPARATOR . $path; - }, - array_filter( - scandir($additionalIniDirectory), - static function (string $path) use ($additionalIniDirectory): bool { - if (in_array($path, ['.', '..'])) { - return false; - } - - return file_exists($additionalIniDirectory . DIRECTORY_SEPARATOR . $path); + $filenames = scandir($additionalIniDirectory); + if (is_array($filenames)) { + $allIniFiles = array_merge( + array_map( + static function (string $path) use ($additionalIniDirectory): string { + return $additionalIniDirectory . DIRECTORY_SEPARATOR . $path; }, + array_filter( + $filenames, + static function (string $path) use ($additionalIniDirectory): bool { + if (in_array($path, ['.', '..'])) { + return false; + } + + return file_exists($additionalIniDirectory . DIRECTORY_SEPARATOR . $path); + }, + ), ), - ), - $allIniFiles, - ); + $allIniFiles, + ); + } } // Make sure all symlinks are resolved From cd860a41597f245c3845319480b88abaab51150f Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Mon, 15 Sep 2025 19:30:57 +0100 Subject: [PATCH 2/2] Add test for additional INI path that does not exist --- .../Ini/RemoveIniEntryWithFileGetContents.php | 3 +- .../RemoveIniEntryWithFileGetContentsTest.php | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/Installing/Ini/RemoveIniEntryWithFileGetContents.php b/src/Installing/Ini/RemoveIniEntryWithFileGetContents.php index 8fc5f766..adee0753 100644 --- a/src/Installing/Ini/RemoveIniEntryWithFileGetContents.php +++ b/src/Installing/Ini/RemoveIniEntryWithFileGetContents.php @@ -19,6 +19,7 @@ use function file_get_contents; use function in_array; use function is_array; +use function is_dir; use function preg_replace; use function scandir; use function sprintf; @@ -39,7 +40,7 @@ public function __invoke(Package $package, TargetPlatform $targetPlatform, Outpu } $additionalIniDirectory = $targetPlatform->phpBinaryPath->additionalIniDirectory(); - if ($additionalIniDirectory !== null) { + if ($additionalIniDirectory !== null && file_exists($additionalIniDirectory) && is_dir($additionalIniDirectory)) { $filenames = scandir($additionalIniDirectory); if (is_array($filenames)) { $allIniFiles = array_merge( diff --git a/test/unit/Installing/Ini/RemoveIniEntryWithFileGetContentsTest.php b/test/unit/Installing/Ini/RemoveIniEntryWithFileGetContentsTest.php index e596825e..76259787 100644 --- a/test/unit/Installing/Ini/RemoveIniEntryWithFileGetContentsTest.php +++ b/test/unit/Installing/Ini/RemoveIniEntryWithFileGetContentsTest.php @@ -128,6 +128,46 @@ public function testRelevantIniFilesHaveExtensionRemoved(ExtensionType $extensio ); } + #[DataProvider('extensionTypeProvider')] + public function testNonExistentAdditionalIniDirectoryDoesNotCrash(ExtensionType $extensionType): void + { + $phpBinaryPath = $this->createMock(PhpBinaryPath::class); + $phpBinaryPath + ->method('loadedIniConfigurationFile') + ->willReturn(null); + $phpBinaryPath + ->method('additionalIniDirectory') + ->willReturn('/this/path/should/not/exist/for/testing'); + + $package = new Package( + $this->createMock(CompletePackageInterface::class), + $extensionType, + ExtensionName::normaliseFromString('foobar'), + 'foobar/foobar', + '1.2.3', + null, + ); + + $targetPlatform = new TargetPlatform( + OperatingSystem::NonWindows, + OperatingSystemFamily::Linux, + $phpBinaryPath, + Architecture::x86_64, + ThreadSafetyMode::ThreadSafe, + 1, + null, + ); + + self::assertSame( + [], + (new RemoveIniEntryWithFileGetContents())( + $package, + $targetPlatform, + $this->createMock(OutputInterface::class), + ), + ); + } + #[RequiresOperatingSystemFamily('Linux')] public function testSymlinkedIniFilesAreResolved(): void {