From: Tim Düsterhus Date: Fri, 11 May 2012 12:59:45 +0000 (+0200) Subject: Adding IArchive interface X-Git-Tag: 2.0.0_Beta_1~1028^2~11^2 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=a3f86ba7286d9260c499fc7bac2d6fde725d961a;p=GitHub%2FWoltLab%2FWCF.git Adding IArchive interface --- diff --git a/wcfsetup/install/files/lib/system/io/IArchive.class.php b/wcfsetup/install/files/lib/system/io/IArchive.class.php new file mode 100644 index 0000000000..259db55537 --- /dev/null +++ b/wcfsetup/install/files/lib/system/io/IArchive.class.php @@ -0,0 +1,52 @@ + + * @package com.woltlab.wcf + * @subpackage system.io + * @category Community Framework + */ +interface IArchive { + /** + * Returns an associative array with information + * about a specific file in the archive. + * + * @param mixed $index index or name of the requested file + * @return array + */ + public function getFileInfo($index); + + /** + * Extracts a specific file and returns the content as string. + * Returns false if extraction failed. + * + * @param mixed $index index or name of the requested file + * @return string content of the requested file + */ + public function extractToString($index); + + /** + * Extracts a specific file and writes it's content + * to the file specified with $destination. + * + * @param mixed $index index or name of the requested file + * @param string $destination + * @return boolean $success + */ + public function extract($index, $destination); + + /** + * Searchs a file in the tar archive + * and returns the numeric fileindex. + * Returns false if not found. + * + * @param string $filename + * @return integer index of the requested file + */ + public function getIndexByFilename($filename); +} diff --git a/wcfsetup/install/files/lib/system/io/Tar.class.php b/wcfsetup/install/files/lib/system/io/Tar.class.php index 0ef0b1006d..99a8fa0f60 100644 --- a/wcfsetup/install/files/lib/system/io/Tar.class.php +++ b/wcfsetup/install/files/lib/system/io/Tar.class.php @@ -21,7 +21,7 @@ use wcf\util\FileUtil; * @subpackage system.io * @category Community Framework */ -class Tar { +class Tar implements IArchive { /** * name of the archive * @var string @@ -309,7 +309,7 @@ class Tar { if (strlen($binaryData) != 512) { return false; } - + $header = array(); $checksum = 0; // First part of the header @@ -325,7 +325,7 @@ class Tar { for ($i = 156; $i < 512; $i++) { $checksum += ord(substr($binaryData, $i, 1)); } - + // Extract the values //$data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $binaryData); $data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix", $binaryData); diff --git a/wcfsetup/install/files/lib/system/io/Zip.class.php b/wcfsetup/install/files/lib/system/io/Zip.class.php index 26aa7b8c32..59b9a4810c 100644 --- a/wcfsetup/install/files/lib/system/io/Zip.class.php +++ b/wcfsetup/install/files/lib/system/io/Zip.class.php @@ -13,7 +13,7 @@ use wcf\util\FileUtil; * @subpackage system.io * @category Community Framework */ -class Zip extends File { +class Zip extends File implements IArchive { const LOCAL_FILE_SIGNATURE = "\x50\x4b\x03\x04"; const CENTRAL_DIRECTORY_SIGNATURE = "\x50\x4b\x01\x02"; const EOF_SIGNATURE = "\x50\x4b\x05\x06"; @@ -26,12 +26,9 @@ class Zip extends File { } /** - * Returns the offset for the given file and false of failure. - * - * @param string $filename file to search - * @return mixed + * @see wcf\system\io\IArchive::getIndexByFilename() */ - public function getOffsetByFilename($filename) { + public function getIndexByFilename($filename) { $this->jumpToCentralDirectory(); $centralDirectory = $this->readCentralDirectory(); @@ -39,6 +36,16 @@ class Zip extends File { return false; } + /** + * @see wcf\system\io\IArchive::getFileInfo() + */ + public function getFileInfo($offset) { + if (!is_int($offset)) $offset = $this->getIndexByFilename($offset); + + $info = $this->readFile($offset); + return $info['header']; + } + /** * Extracts all files to the given destination. * The directory-structure inside the .zip is preserved. @@ -53,36 +60,41 @@ class Zip extends File { $offset = $this->tell(); $file = $this->readFile(); $filename = $file['header']['filename']; - $this->extract($offset, $destination.dirname($filename)); + $this->extract($offset, $destination.$filename); } } /** - * Extracts the file at the given offset to a string. - * - * @param integer $offset The offset to extract - * @return string + * @see wcf\system\io\IArchive::extractToString() */ public function extractToString($offset) { - $file = $this->readFile($offset); + if (!is_int($offset)) $offset = $this->getIndexByFilename($offset); + + try { + $file = $this->readFile($offset); + } + catch (SystemException $e) { + return false; + } return $file['content']; } /** - * Extracts the file at the given offset to the given destination. - * The directory-structure inside the .zip is ignored. - * - * @param integer $offset The offset to extract - * @param string $destination Where to extract - * @param string $filename The filename. When not given the original filename is used + * @see wcf\system\io\IArchive::extract() */ - public function extract($offset, $destination, $filename = null) { - $file = $this->readFile($offset); - $filename = ($filename ?: $file['header']['filename']); + public function extract($offset, $destination) { + if (!is_int($offset)) $offset = $this->getIndexByFilename($offset); - FileUtil::makePath($destination); - $targetFile = new File(FileUtil::addTrailingSlash($destination).basename($filename)); + try { + $file = $this->readFile($offset); + } + catch (SystemException $e) { + return false; + } + + FileUtil::makePath(dirname($destination)); + $targetFile = new File($destination); $targetFile->write($file['content'], strlen($file['content'])); $targetFile->close(); @@ -98,9 +110,11 @@ class Zip extends File { } // check filesize - if (filesize(FileUtil::addTrailingSlash($destination).basename($filename)) != $file['header']['uncompressedSize']) { - throw new SystemException("Could not unzip file '".$file['header']['filename']."' to '".FileUtil::addTrailingSlash($destination).basename($filename)."'. Maybe disk quota exceeded in folder '".$destination."'."); + if (filesize($destination) != $file['header']['uncompressedSize']) { + throw new SystemException("Could not unzip file '".$file['header']['filename']."' to '".$destination."'. Maybe disk quota exceeded in folder '".dirname($destination)."'."); } + + return true; } /** @@ -125,6 +139,7 @@ class Zip extends File { */ public function readCentralDirectory($offset = null) { if ($offset === null) $offset = $this->tell(); + if ($offset === false) throw new SystemException('Invalid offset passed to readCentralDirectory'); $this->seek($offset); // check signature @@ -184,6 +199,7 @@ class Zip extends File { */ public function isFile($offset = null) { if ($offset === null) $offset = $this->tell(); + if ($offset === false) throw new SystemException('Invalid offset passed to isFile'); $oldOffset = $this->tell(); $this->seek($offset); @@ -201,6 +217,8 @@ class Zip extends File { */ public function skipFile($offset = null) { if ($offset === null) $offset = $this->tell(); + if (!is_int($offset)) $offset = $this->getIndexByFilename($offset); + if ($offset === false) throw new SystemException('Invalid offset passed to skipFile'); $this->seek($offset); // check signature @@ -229,6 +247,8 @@ class Zip extends File { */ public function readFile($offset = null) { if ($offset === null) $offset = $this->tell(); + if (!is_int($offset)) $offset = $this->getIndexByFilename($offset); + if ($offset === false) throw new SystemException('Invalid offset passed to readFile'); $this->seek($offset); // check signature