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
*/