From 3d921b4c6998eaf2612e4a4f2f1538b8a8e88227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Gris?= Date: Tue, 30 Apr 2024 15:15:45 +0200 Subject: [PATCH] Fix(ZipTask): Preserve dir mtime PHP 7.4 compat --- src/Phing/Task/Ext/Archive/ZipTask.php | 52 +++++++++++++------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/Phing/Task/Ext/Archive/ZipTask.php b/src/Phing/Task/Ext/Archive/ZipTask.php index 4d1755ebe..151d6ecd1 100644 --- a/src/Phing/Task/Ext/Archive/ZipTask.php +++ b/src/Phing/Task/Ext/Archive/ZipTask.php @@ -74,35 +74,16 @@ class ZipTask extends MatchingTask * @var string $comment */ private $comment = ''; + private string $mtimeDummy; - /** - * Propagates the directory's mTime and permissions in the Zip archive if supported. - * - * @param \ZipArchive $zip The Zip archive - * @param File $f The File handle to the directory - * @param string $pathInZip The path of the directory in the Zip archive - * - * @throws IOException - */ - private static function fixDirAttributes($zip, $f, $pathInZip) - { - $indexInZip = $zip->locateName('/' === mb_substr($pathInZip, -1) ? $pathInZip : $pathInZip . '/'); - if (false !== $indexInZip) { - if (method_exists($zip, 'setMtimeIndex')) { // PHP >= 8.0.0, PECL zip >= 1.16.0 - $zip->setMtimeIndex($indexInZip, $f->lastModified()); - } - $filePerms = fileperms($f->getPath()); - if (false !== $filePerms) { // filePerms supported - $zip->setExternalAttributesIndex($indexInZip, \ZipArchive::OPSYS_DEFAULT, $filePerms << 16); - } - } - } /** * Removes all external attributes from the Zip archive. * * @param \ZipArchive $zip The Zip archive + * + * @return void */ - private static function clearExternalAttributes($zip) + private static function clearExternalAttributes(\ZipArchive $zip) { for ($i = 0, $count = $zip->count(); $i < $count; ++$i) { $zip->setExternalAttributesIndex($i, \ZipArchive::OPSYS_DOS, 0); @@ -267,6 +248,10 @@ public function main() $this->log("Building zip: " . $this->zipFile->__toString(), Project::MSG_INFO); + if (false === $this->mtimeDummy = tempnam(sys_get_temp_dir(), 'mtimeDummy')) { + throw new Exception('Could not create temp file'); + } + $zip = new ZipArchive(); $res = $zip->open($this->zipFile->getAbsolutePath(), ZipArchive::CREATE); @@ -288,6 +273,8 @@ public function main() } $zip->close(); + unlink($this->mtimeDummy); + } catch (IOException $ioe) { $msg = "Problem creating ZIP: " . $ioe->getMessage(); throw new BuildException($msg, $ioe, $this->getLocation()); @@ -356,8 +343,7 @@ private function addFilesetsToArchive($zip) if ($f->isDirectory()) { if ($pathInZip != '.') { - $zip->addEmptyDir($pathInZip); - static::fixDirAttributes($zip, $f, $pathInZip); + $this->addDirToZip($zip, $f->getAbsolutePath(), $pathInZip . '/'); } } else { $zip->addFile($f->getAbsolutePath(), $pathInZip); @@ -366,4 +352,20 @@ private function addFilesetsToArchive($zip) } } } + + /** + * @param \ZipArchive $zip + * @param string $dirPath + * @param string $entryName + * + * @return void + */ + private function addDirToZip(\ZipArchive $zip, string $dirPath, string $entryName) + { + touch($this->mtimeDummy, filemtime($dirPath)); // Save directory's mtime to dummmy + $zip->addFile($this->mtimeDummy, $entryName); // Add empty dummy as a directory + if (false !== $filePerms = fileperms($dirPath)) { // filePerms supported + $zip->setExternalAttributesName($entryName, \ZipArchive::OPSYS_UNIX, $filePerms << 16); + } + } }