From e44b2d88727913e757c8b431f95fd828c530e26e Mon Sep 17 00:00:00 2001 From: Philipp Scheit Date: Tue, 25 Feb 2025 12:45:57 +0100 Subject: [PATCH] ZipArchiver: treat backslaches in folder names on Unix (#12327) --- src/Composer/Package/Archiver/ZipArchiver.php | 19 +++++++++++-------- .../Test/Package/Archiver/ZipArchiverTest.php | 11 +++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Composer/Package/Archiver/ZipArchiver.php b/src/Composer/Package/Archiver/ZipArchiver.php index 5ab5bd55b..54ca20a41 100644 --- a/src/Composer/Package/Archiver/ZipArchiver.php +++ b/src/Composer/Package/Archiver/ZipArchiver.php @@ -12,8 +12,9 @@ namespace Composer\Package\Archiver; -use ZipArchive; use Composer\Util\Filesystem; +use Composer\Util\Platform; +use ZipArchive; /** * @author Jan Prieser @@ -44,15 +45,17 @@ class ZipArchiver implements ArchiverInterface $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters); foreach ($files as $file) { /** @var \Symfony\Component\Finder\SplFileInfo $file */ - $filepath = strtr($file->getPath()."/".$file->getFilename(), '\\', '/'); - $localname = $filepath; - if (strpos($localname, $sources . '/') === 0) { - $localname = substr($localname, strlen($sources . '/')); + $filepath = $file->getPathname(); + $relativePath = $file->getRelativePathname(); + + if (Platform::isWindows()) { + $relativePath = strtr($relativePath, '\\', '/'); } + if ($file->isDir()) { - $zip->addEmptyDir($localname); + $zip->addEmptyDir($relativePath); } else { - $zip->addFile($filepath, $localname); + $zip->addFile($filepath, $relativePath); } /** @@ -64,7 +67,7 @@ class ZipArchiver implements ArchiverInterface /** * Ensure to preserve the permission umasks for the filepath in the archive. */ - $zip->setExternalAttributesName($localname, ZipArchive::OPSYS_UNIX, $perms << 16); + $zip->setExternalAttributesName($relativePath, ZipArchive::OPSYS_UNIX, $perms << 16); } } if ($zip->close()) { diff --git a/tests/Composer/Test/Package/Archiver/ZipArchiverTest.php b/tests/Composer/Test/Package/Archiver/ZipArchiverTest.php index 80c7bb95e..915c193fd 100644 --- a/tests/Composer/Test/Package/Archiver/ZipArchiverTest.php +++ b/tests/Composer/Test/Package/Archiver/ZipArchiverTest.php @@ -37,6 +37,17 @@ class ZipArchiverTest extends ArchiverTestCase ]; } + public function testFolderWithBackslashes(): void + { + if (Platform::isWindows()) { + $this->markTestSkipped('Folder names cannot contain backslashes on Windows.'); + } + + $this->testZipArchive([ + 'folder\with\backslashes/README.md' => '# doc', + ]); + } + /** * @param array $files */