updated php-archive library
This commit is contained in:
parent
e0dd796db5
commit
361134418d
|
@ -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": [],
|
||||
|
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -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.*"
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue