diff --git a/composer.lock b/composer.lock index 5b87863544edfc9ddb941dcde40d94cfb9cb168d..aa48f8b219c8617fba708be8cbc009f336b72ab7 100644 --- a/composer.lock +++ b/composer.lock @@ -254,16 +254,16 @@ }, { "name": "splitbrain/php-archive", - "version": "1.0.7", + "version": "1.0.8", "source": { "type": "git", "url": "https://github.com/splitbrain/php-archive.git", - "reference": "c075304b44c4aadff0718af445e86bf730f331ff" + "reference": "6b1c1746fa0a6f9f68f0bc832892ddeda8db905c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/splitbrain/php-archive/zipball/c075304b44c4aadff0718af445e86bf730f331ff", - "reference": "c075304b44c4aadff0718af445e86bf730f331ff", + "url": "https://api.github.com/repos/splitbrain/php-archive/zipball/6b1c1746fa0a6f9f68f0bc832892ddeda8db905c", + "reference": "6b1c1746fa0a6f9f68f0bc832892ddeda8db905c", "shasum": "" }, "require": { @@ -272,6 +272,10 @@ "require-dev": { "phpunit/phpunit": "4.5.*" }, + "suggest": { + "ext-iconv": "Used for proper filename encode handling", + "ext-mbstring": "Can be used alternatively for handling filename encoding" + }, "type": "library", "autoload": { "psr-4": { @@ -297,7 +301,7 @@ "unzip", "zip" ], - "time": "2015-08-12T13:24:34+00:00" + "time": "2017-03-19T09:10:53+00:00" } ], "packages-dev": [], diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 9f6ff74a2f94b2ebdbf1cb15f22b9333859e0bd9..fa67e52b90f96704681110c7c842e7d1a2a94d6e 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,53 +1,4 @@ [ - { - "name": "splitbrain/php-archive", - "version": "1.0.7", - "version_normalized": "1.0.7.0", - "source": { - "type": "git", - "url": "https://github.com/splitbrain/php-archive.git", - "reference": "c075304b44c4aadff0718af445e86bf730f331ff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/splitbrain/php-archive/zipball/c075304b44c4aadff0718af445e86bf730f331ff", - "reference": "c075304b44c4aadff0718af445e86bf730f331ff", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "4.5.*" - }, - "time": "2015-08-12T13:24:34+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "splitbrain\\PHPArchive\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andreas Gohr", - "email": "andi@splitbrain.org" - } - ], - "description": "Pure-PHP implementation to read and write TAR and ZIP archives", - "keywords": [ - "archive", - "extract", - "tar", - "unpack", - "unzip", - "zip" - ] - }, { "name": "easybook/geshi", "version": "v1.0.8.18", @@ -301,5 +252,58 @@ "pseudorandom", "random" ] + }, + { + "name": "splitbrain/php-archive", + "version": "1.0.8", + "version_normalized": "1.0.8.0", + "source": { + "type": "git", + "url": "https://github.com/splitbrain/php-archive.git", + "reference": "6b1c1746fa0a6f9f68f0bc832892ddeda8db905c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/splitbrain/php-archive/zipball/6b1c1746fa0a6f9f68f0bc832892ddeda8db905c", + "reference": "6b1c1746fa0a6f9f68f0bc832892ddeda8db905c", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.5.*" + }, + "suggest": { + "ext-iconv": "Used for proper filename encode handling", + "ext-mbstring": "Can be used alternatively for handling filename encoding" + }, + "time": "2017-03-19T09:10:53+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "splitbrain\\PHPArchive\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Gohr", + "email": "andi@splitbrain.org" + } + ], + "description": "Pure-PHP implementation to read and write TAR and ZIP archives", + "keywords": [ + "archive", + "extract", + "tar", + "unpack", + "unzip", + "zip" + ] } ] diff --git a/vendor/splitbrain/php-archive/composer.json b/vendor/splitbrain/php-archive/composer.json index 5ad41a8c4544df3dbb7e8bd12ec0c9c8ae56ec01..36c649769129fcdf4930f1c25f4da9e0c98712ac 100644 --- a/vendor/splitbrain/php-archive/composer.json +++ b/vendor/splitbrain/php-archive/composer.json @@ -14,6 +14,11 @@ "php": ">=5.3.0" }, + "suggest": { + "ext-iconv": "Used for proper filename encode handling", + "ext-mbstring": "Can be used alternatively for handling filename encoding" + }, + "require-dev": { "phpunit/phpunit": "4.5.*" }, diff --git a/vendor/splitbrain/php-archive/src/FileInfo.php b/vendor/splitbrain/php-archive/src/FileInfo.php index 612f924c34668e02c0d0d3aa6bd9c09804a66909..99f60c0fe1df7ddd5445a44da0bf88bf61937e7c 100644 --- a/vendor/splitbrain/php-archive/src/FileInfo.php +++ b/vendor/splitbrain/php-archive/src/FileInfo.php @@ -74,10 +74,11 @@ class FileInfo } /** - * @return int + * @return int the filesize. always 0 for directories */ public function getSize() { + if($this->isdir) return 0; return $this->size; } diff --git a/vendor/splitbrain/php-archive/src/Tar.php b/vendor/splitbrain/php-archive/src/Tar.php index e29c7d5a63ba4ba4f960fc749877a0494bf078bd..f9d7bfbc094a4c5e78ab15028f40bde918107a08 100644 --- a/vendor/splitbrain/php-archive/src/Tar.php +++ b/vendor/splitbrain/php-archive/src/Tar.php @@ -230,9 +230,10 @@ class Tar extends Archive /** * Add a file to the current TAR archive using an existing file in the filesystem * - * @param string $file path to the original file + * @param string $file path to the original file * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data, empty to take from original - * @throws ArchiveIOException + * @throws ArchiveCorruptedException when the file changes while reading it, the archive will be corrupt and should be deleted + * @throws ArchiveIOException there was trouble reading the given file, it was not added */ public function addFile($file, $fileinfo = '') { @@ -253,8 +254,10 @@ class Tar extends Archive $this->writeFileHeader($fileinfo); // write data + $read = 0; while (!feof($fp)) { $data = fread($fp, 512); + $read += strlen($data); if ($data === false) { break; } @@ -265,6 +268,11 @@ class Tar extends Archive $this->writebytes($packed); } fclose($fp); + + if($read != $fileinfo->getSize()) { + $this->close(); + throw new ArchiveCorruptedException("The size of $file changed while reading, archive corrupted. read $read expected ".$fileinfo->getSize()); + } } /** @@ -573,7 +581,7 @@ class Tar extends Archive // Handle Long-Link entries from GNU Tar if ($return['typeflag'] == 'L') { // following data block(s) is the filename - $filename = trim($this->readbytes(ceil($header['size'] / 512) * 512)); + $filename = trim($this->readbytes(ceil($return['size'] / 512) * 512)); // next block is the real header $block = $this->readbytes(512); $return = $this->parseHeader($block); diff --git a/vendor/splitbrain/php-archive/src/Zip.php b/vendor/splitbrain/php-archive/src/Zip.php index 1bc1ac1b7b24415b879608e70e4d6a03a17b4f72..272a9027b0d0731b880f75cf12f77525db0189d1 100644 --- a/vendor/splitbrain/php-archive/src/Zip.php +++ b/vendor/splitbrain/php-archive/src/Zip.php @@ -272,7 +272,7 @@ class Zip extends Archive * Add a file to the current archive using an existing file in the filesystem * * @param string $file path to the original file - * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data, empty to take from original + * @param string|FileInfo $fileinfo either the name to use in archive (string) or a FileInfo oject with all meta data, empty to take from original * @throws ArchiveIOException */ public function addFile($file, $fileinfo = '') @@ -295,7 +295,7 @@ class Zip extends Archive } /** - * Add a file to the current TAR archive using the given $data as content + * Add a file to the current Zip archive using the given $data as content * * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data * @param string $data binary content of the file to add @@ -495,8 +495,10 @@ class Zip extends Archive if ($header['extra_len'] != 0) { $header['extra'] = fread($this->fh, $header['extra_len']); + $header['extradata'] = $this->parseExtra($header['extra']); } else { $header['extra'] = ''; + $header['extradata'] = array(); } if ($header['comment_len'] != 0) { @@ -536,8 +538,10 @@ class Zip extends Archive $header['filename'] = fread($this->fh, $data['filename_len']); if ($data['extra_len'] != 0) { $header['extra'] = fread($this->fh, $data['extra_len']); + $header['extradata'] = array_merge($header['extradata'], $this->parseExtra($header['extra'])); } else { $header['extra'] = ''; + $header['extradata'] = array(); } $header['compression'] = $data['compression']; @@ -559,6 +563,35 @@ class Zip extends Archive return $header; } + /** + * Parse the extra headers into fields + * + * @param string $header + * @return array + */ + protected function parseExtra($header) + { + $extra = array(); + // parse all extra fields as raw values + while (strlen($header) !== 0) { + $set = unpack('vid/vlen', $header); + $header = substr($header, 4); + $value = substr($header, 0, $set['len']); + $header = substr($header, $set['len']); + $extra[$set['id']] = $value; + } + + // handle known ones + if(isset($extra[0x6375])) { + $extra['utf8comment'] = substr($extra[0x7075], 5); // strip version and crc + } + if(isset($extra[0x7075])) { + $extra['utf8path'] = substr($extra[0x7075], 5); // strip version and crc + } + + return $extra; + } + /** * Create fileinfo object from header data * @@ -568,15 +601,75 @@ class Zip extends Archive protected function header2fileinfo($header) { $fileinfo = new FileInfo(); - $fileinfo->setPath($header['filename']); $fileinfo->setSize($header['size']); $fileinfo->setCompressedSize($header['compressed_size']); $fileinfo->setMtime($header['mtime']); $fileinfo->setComment($header['comment']); $fileinfo->setIsdir($header['external'] == 0x41FF0010 || $header['external'] == 16); + + if(isset($header['extradata']['utf8path'])) { + $fileinfo->setPath($header['extradata']['utf8path']); + } else { + $fileinfo->setPath($this->cpToUtf8($header['filename'])); + } + + if(isset($header['extradata']['utf8comment'])) { + $fileinfo->setComment($header['extradata']['utf8comment']); + } else { + $fileinfo->setComment($this->cpToUtf8($header['comment'])); + } + return $fileinfo; } + /** + * Convert the given CP437 encoded string to UTF-8 + * + * Tries iconv with the correct encoding first, falls back to mbstring with CP850 which is + * similar enough. CP437 seems not to be available in mbstring. Lastly falls back to keeping the + * string as is, which is still better than nothing. + * + * @param $string + * @return string + */ + protected function cpToUtf8($string) + { + if (function_exists('iconv')) { + return iconv('CP437', 'UTF-8', $string); + } elseif (function_exists('mb_convert_encoding')) { + return mb_convert_encoding($string, 'UTF-8', 'CP850'); + } else { + return $string; + } + } + + /** + * Convert the given UTF-8 encoded string to CP437 + * + * Same caveats as for cpToUtf8() apply + * + * @param $string + * @return string + */ + protected function utf8ToCp($string) + { + // try iconv first + if (function_exists('iconv')) { + $conv = @iconv('UTF-8', 'CP437//IGNORE', $string); + if($conv) return $conv; // it worked + } + + // still here? iconv failed to convert the string. Try another method + // see http://php.net/manual/en/function.iconv.php#108643 + + if (function_exists('mb_convert_encoding')) { + return mb_convert_encoding($string, 'CP850', 'UTF-8'); + } else { + return $string; + } + } + + /** * Write to the open filepointer or memory * @@ -684,6 +777,8 @@ class Zip extends Archive $comp = $comp ? 8 : 0; $dtime = dechex($this->makeDosTime($ts)); + list($name, $extra) = $this->encodeFilename($name); + $header = "\x50\x4b\x01\x02"; // central file header signature $header .= pack('v', 14); // version made by - VFAT $header .= pack('v', 20); // version needed to extract - 2.0 @@ -700,13 +795,14 @@ class Zip extends Archive $header .= pack('V', $clen); // compressed size $header .= pack('V', $len); // uncompressed size $header .= pack('v', strlen($name)); // file name length - $header .= pack('v', 0); // extra field length + $header .= pack('v', strlen($extra)); // extra field length $header .= pack('v', 0); // file comment length $header .= pack('v', 0); // disk number start $header .= pack('v', 0); // internal file attributes $header .= pack('V', 0); // external file attributes @todo was 0x32!? $header .= pack('V', $offset); // relative offset of local header $header .= $name; // file name + $header .= $extra; // extra (utf-8 filename) return $header; } @@ -728,6 +824,8 @@ class Zip extends Archive $comp = $comp ? 8 : 0; $dtime = dechex($this->makeDosTime($ts)); + list($name, $extra) = $this->encodeFilename($name); + $header = "\x50\x4b\x03\x04"; // local file header signature $header .= pack('v', 20); // version needed to extract - 2.0 $header .= pack('v', 0); // general purpose flag - no flags set @@ -743,8 +841,37 @@ class Zip extends Archive $header .= pack('V', $clen); // compressed size $header .= pack('V', $len); // uncompressed size $header .= pack('v', strlen($name)); // file name length - $header .= pack('v', 0); // extra field length - $header .= $name; + $header .= pack('v', strlen($extra)); // extra field length + $header .= $name; // file name + $header .= $extra; // extra (utf-8 filename) return $header; } + + /** + * Returns an allowed filename and an extra field header + * + * When encoding stuff outside the 7bit ASCII range it needs to be placed in a separate + * extra field + * + * @param $original + * @return array($filename, $extra) + */ + protected function encodeFilename($original) + { + $cp437 = $this->utf8ToCp($original); + if ($cp437 === $original) { + return array($original, ''); + } + + $extra = pack( + 'vvCV', + 0x7075, // tag + strlen($original) + 5, // length of file + version + crc + 1, // version + crc32($original) // crc + ); + $extra .= $original; + + return array($cp437, $extra); + } }