From 640f75da8d10ee9688d2850e51c436ada234d8c7 Mon Sep 17 00:00:00 2001 From: the-djmaze <> Date: Tue, 18 Oct 2022 16:31:48 +0200 Subject: [PATCH] Workaround PHP `--disable-phar` aka Class 'PharData' not found #392 --- .../app/libraries/snappymail/repository.php | 9 +- .../v/0.0.0/app/libraries/snappymail/tar.php | 100 ++++++++++++++++++ .../app/libraries/snappymail/upgrade.php | 3 + 3 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 snappymail/v/0.0.0/app/libraries/snappymail/tar.php diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/repository.php b/snappymail/v/0.0.0/app/libraries/snappymail/repository.php index 432f5a8f4..d5de7d92b 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/repository.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/repository.php @@ -266,7 +266,12 @@ abstract class Repository } if ($sTmp) { - $oArchive = new \PharData($sTmp, 0, $sRealFile); + if (\class_exists('PharData')) { + $oArchive = new \PharData($sTmp, 0, $sRealFile); + } else { +// throw new \Exception('PHP Phar is disabled, you must enable it'); + $oArchive = new \SnappyMail\TAR($sTmp); + } if (!static::deletePackageDir($sId)) { throw new \Exception('Cannot remove previous plugin folder: '.$sId); } @@ -276,7 +281,7 @@ abstract class Repository $bResult = $oArchive->extractTo(\rtrim(APP_PLUGINS_PATH, '\\/')); } if (!$bResult) { - throw new \Exception('Cannot extract package files: '.$oArchive->getStatusString()); + throw new \Exception('Cannot extract package files'); } } } catch (\Throwable $e) { diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/tar.php b/snappymail/v/0.0.0/app/libraries/snappymail/tar.php new file mode 100644 index 000000000..77c5ee24e --- /dev/null +++ b/snappymail/v/0.0.0/app/libraries/snappymail/tar.php @@ -0,0 +1,100 @@ +filename = $filename; + $this->alias = $alias ?: $filename; + } + + /** + * @param $files array|string|null + */ + public function extractTo(string $directory, $files = null, bool $overwrite = false) : bool + { + if ($files) { + \trigger_error('$files parameter not yet supported'); + return false; + } + + $fp = \gzopen($this->filename, 'rb'); + if (!$fp) { + return false; + } + + \clearstatcache(false); + \clearstatcache(true); + while (!\gzeof($fp)) { + $data = \gzread($fp, 512); + if (\gzeof($fp) || !\trim($data)) { + break; + } + if (\strlen($data) !== 512) { + \trigger_error("{$this->alias} invalid header at offset " . \gztell($fp)); + return false; + } + $header = \unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8crc/a1type/a100linkname/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155path", $data); + if (!\strlen(\trim($header['filename']))) { + \trigger_error("{$this->alias} invalid entry filename at offset " . \gztell($fp)); + return false; + } + foreach ($header as $k => $v) { + $header[$k] = \in_array($k, self::dec) ? \octdec(\trim($v)) : \trim($v); + } + if ($header['crc'] > 0) { + $crc = 0; + for ($i = 0; $i < 148; ++$i) { $crc += \ord(\substr($data, $i, 1)); } + for ($i = 148; $i < 156; ++$i) { $crc += \ord(' '); } + for ($i = 156; $i < 512; ++$i) { $crc += \ord(\substr($data, $i, 1)); } + if ($header['crc'] !== $crc) { + \trigger_error("{$this->alias} checksum of '{$header['filename']}' incorrect"); + return false; + } + } + if (\preg_match('#(^|/)PaxHeader/#', $header['filename'])) { + } else if (\substr($header['filename'], -1) !== '/') { + $filename = ($header['path'] ? $header['path'] . '/' : '') . $header['filename']; + $filename = $directory . '/' . $filename; + $dir = \dirname($filename); + if (!\is_dir($dir) && !\mkdir($dir, 0777, true)) { + return false; + } + $target = \fopen($filename, 'wb'); + if (!$target) { + return false; + } + $bytes = $header['size']; + $blocksize = \ceil($bytes / 512) * 512; + $blocks = \ceil($blocksize / 8192); + while ($blocks--) { + $data = \gzread($fp, \min($blocksize, 8192)); + $length = \strlen($data); + if ($bytes < $length) { + $data = \substr($data, 0, $bytes); + } + \fwrite($target, $data); + $bytes -= $length; + $blocksize -= $length; + } + \fclose($target); + \chmod($filename, $header['mode']); + } else { + // Create directory +// \gzread($fp, $blocksize); + } + } + \gzclose($fp); + return true; + } +} diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/upgrade.php b/snappymail/v/0.0.0/app/libraries/snappymail/upgrade.php index 5d93c0518..9920ddff9 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/upgrade.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/upgrade.php @@ -165,6 +165,9 @@ abstract class Upgrade public static function backup() : string { + if (!\class_exists('PharData')) { + throw new \Exception('PHP Phar is disabled, you must enable it'); + } // $tar_destination = APP_DATA_FOLDER_PATH . APP_VERSION . '.tar'; $tar_destination = APP_DATA_FOLDER_PATH . 'backup-' . \date('YmdHis') . '.tar'; $tar = new \PharData($tar_destination);