mirror of
https://github.com/Ne-Lexa/php-zip.git
synced 2025-08-02 21:47:23 +02:00
Merge branch 'hotfix/3.1.7'
This commit is contained in:
@@ -144,8 +144,14 @@ class ZipInputStream implements ZipInputStreamInterface
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// .ZIP file comment (variable size)
|
// .ZIP file comment (variable size)
|
||||||
if (0 < $data['commentLength']) {
|
if ($data['commentLength'] > 0) {
|
||||||
$comment = fread($this->in, $data['commentLength']);
|
$comment = '';
|
||||||
|
$offset = 0;
|
||||||
|
while ($offset < $data['commentLength']) {
|
||||||
|
$read = min(8192 /* chunk size */, $data['commentLength'] - $offset);
|
||||||
|
$comment .= fread($this->in, $read);
|
||||||
|
$offset += $read;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->preamble = $endOfCentralDirRecordPos;
|
$this->preamble = $endOfCentralDirRecordPos;
|
||||||
$this->postamble = $size - ftell($this->in);
|
$this->postamble = $size - ftell($this->in);
|
||||||
@@ -314,7 +320,13 @@ class ZipInputStream implements ZipInputStreamInterface
|
|||||||
// $utf8 = ($data['gpbf'] & ZipEntry::GPBF_UTF8) !== 0;
|
// $utf8 = ($data['gpbf'] & ZipEntry::GPBF_UTF8) !== 0;
|
||||||
|
|
||||||
// See appendix D of PKWARE's ZIP File Format Specification.
|
// See appendix D of PKWARE's ZIP File Format Specification.
|
||||||
$name = fread($this->in, $data['fileLength']);
|
$name = '';
|
||||||
|
$offset = 0;
|
||||||
|
while ($offset < $data['fileLength']) {
|
||||||
|
$read = min(8192 /* chunk size */, $data['fileLength'] - $offset);
|
||||||
|
$name .= fread($this->in, $read);
|
||||||
|
$offset += $read;
|
||||||
|
}
|
||||||
|
|
||||||
$entry = new ZipSourceEntry($this);
|
$entry = new ZipSourceEntry($this);
|
||||||
$entry->setName($name);
|
$entry->setName($name);
|
||||||
@@ -329,10 +341,24 @@ class ZipInputStream implements ZipInputStreamInterface
|
|||||||
$entry->setExternalAttributes($data['rawExternalAttributes']);
|
$entry->setExternalAttributes($data['rawExternalAttributes']);
|
||||||
$entry->setOffset($data['lfhOff']); // must be unmapped!
|
$entry->setOffset($data['lfhOff']); // must be unmapped!
|
||||||
if ($data['extraLength'] > 0) {
|
if ($data['extraLength'] > 0) {
|
||||||
$entry->setExtra(fread($this->in, $data['extraLength']));
|
$extra = '';
|
||||||
|
$offset = 0;
|
||||||
|
while ($offset < $data['extraLength']) {
|
||||||
|
$read = min(8192 /* chunk size */, $data['extraLength'] - $offset);
|
||||||
|
$extra .= fread($this->in, $read);
|
||||||
|
$offset += $read;
|
||||||
|
}
|
||||||
|
$entry->setExtra($extra);
|
||||||
}
|
}
|
||||||
if ($data['commentLength'] > 0) {
|
if ($data['commentLength'] > 0) {
|
||||||
$entry->setComment(fread($this->in, $data['commentLength']));
|
$comment = '';
|
||||||
|
$offset = 0;
|
||||||
|
while ($offset < $data['commentLength']) {
|
||||||
|
$read = min(8192 /* chunk size */, $data['commentLength'] - $offset);
|
||||||
|
$comment .= fread($this->in, $read);
|
||||||
|
$offset += $read;
|
||||||
|
}
|
||||||
|
$entry->setComment($comment);
|
||||||
}
|
}
|
||||||
return $entry;
|
return $entry;
|
||||||
}
|
}
|
||||||
@@ -382,10 +408,14 @@ class ZipInputStream implements ZipInputStreamInterface
|
|||||||
// Get raw entry content
|
// Get raw entry content
|
||||||
$compressedSize = $entry->getCompressedSize();
|
$compressedSize = $entry->getCompressedSize();
|
||||||
$compressedSize = PHP_INT_SIZE === 4 ? sprintf('%u', $compressedSize) : $compressedSize;
|
$compressedSize = PHP_INT_SIZE === 4 ? sprintf('%u', $compressedSize) : $compressedSize;
|
||||||
|
$content = '';
|
||||||
if ($compressedSize > 0) {
|
if ($compressedSize > 0) {
|
||||||
$content = fread($this->in, $compressedSize);
|
$offset = 0;
|
||||||
} else {
|
while ($offset < $compressedSize) {
|
||||||
$content = '';
|
$read = min(8192 /* chunk size */, $compressedSize - $offset);
|
||||||
|
$content .= fread($this->in, $read);
|
||||||
|
$offset += $read;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$skipCheckCrc = false;
|
$skipCheckCrc = false;
|
||||||
@@ -453,6 +483,14 @@ class ZipInputStream implements ZipInputStreamInterface
|
|||||||
throw new ZipUnsupportMethodException($entry->getName() .
|
throw new ZipUnsupportMethodException($entry->getName() .
|
||||||
" (compression method " . $method . " is not supported)");
|
" (compression method " . $method . " is not supported)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($content === false) {
|
||||||
|
throw new ZipException(sprintf(
|
||||||
|
'Failed to get the contents of the zip entry "%s"',
|
||||||
|
$entry->getName()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if (!$skipCheckCrc) {
|
if (!$skipCheckCrc) {
|
||||||
$localCrc = crc32($content);
|
$localCrc = crc32($content);
|
||||||
$localCrc = PHP_INT_SIZE === 4 ? sprintf('%u', $localCrc) : $localCrc;
|
$localCrc = PHP_INT_SIZE === 4 ? sprintf('%u', $localCrc) : $localCrc;
|
||||||
@@ -498,7 +536,13 @@ class ZipInputStream implements ZipInputStreamInterface
|
|||||||
if ($sourceExtraLength > 0) {
|
if ($sourceExtraLength > 0) {
|
||||||
// read Local File Header extra fields
|
// read Local File Header extra fields
|
||||||
fseek($this->in, $pos + ZipEntry::LOCAL_FILE_HEADER_MIN_LEN + $nameLength, SEEK_SET);
|
fseek($this->in, $pos + ZipEntry::LOCAL_FILE_HEADER_MIN_LEN + $nameLength, SEEK_SET);
|
||||||
$extra = fread($this->in, $sourceExtraLength);
|
$extra = '';
|
||||||
|
$offset = 0;
|
||||||
|
while ($offset < $sourceExtraLength) {
|
||||||
|
$read = min(8192 /* chunk size */, $sourceExtraLength - $offset);
|
||||||
|
$extra .= fread($this->in, $read);
|
||||||
|
$offset += $read;
|
||||||
|
}
|
||||||
$extraFieldsCollection = ExtraFieldsFactory::createExtraFieldCollections($extra, $entry);
|
$extraFieldsCollection = ExtraFieldsFactory::createExtraFieldCollections($extra, $entry);
|
||||||
if (isset($extraFieldsCollection[ApkAlignmentExtraField::getHeaderId()]) && $this->zipModel->isZipAlign()) {
|
if (isset($extraFieldsCollection[ApkAlignmentExtraField::getHeaderId()]) && $this->zipModel->isZipAlign()) {
|
||||||
unset($extraFieldsCollection[ApkAlignmentExtraField::getHeaderId()]);
|
unset($extraFieldsCollection[ApkAlignmentExtraField::getHeaderId()]);
|
||||||
|
104
tests/PhpZip/Issue24Test.php
Normal file
104
tests/PhpZip/Issue24Test.php
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpZip;
|
||||||
|
|
||||||
|
use PhpZip\Exception\ZipException;
|
||||||
|
use PhpZip\Util\CryptoUtil;
|
||||||
|
|
||||||
|
class Issue24Test extends ZipTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This method is called before the first test of this test class is run.
|
||||||
|
*/
|
||||||
|
public static function setUpBeforeClass()
|
||||||
|
{
|
||||||
|
stream_wrapper_register("dummyfs", DummyFileSystemStream::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ZipException
|
||||||
|
*/
|
||||||
|
public function testDummyFS()
|
||||||
|
{
|
||||||
|
$fileContents = str_repeat(base64_encode(CryptoUtil::randomBytes(12000)), 100);
|
||||||
|
|
||||||
|
// create zip file
|
||||||
|
$zip = new ZipFile();
|
||||||
|
$zip->addFromString(
|
||||||
|
'file.txt',
|
||||||
|
$fileContents,
|
||||||
|
ZipFile::METHOD_DEFLATED
|
||||||
|
);
|
||||||
|
$zip->saveAsFile($this->outputFilename);
|
||||||
|
$zip->close();
|
||||||
|
|
||||||
|
$this->assertCorrectZipArchive($this->outputFilename);
|
||||||
|
|
||||||
|
$stream = fopen('dummyfs://localhost/' . $this->outputFilename, 'rb');
|
||||||
|
$this->assertNotFalse($stream);
|
||||||
|
$zip->openFromStream($stream);
|
||||||
|
$this->assertEquals($zip->getListFiles(), ['file.txt']);
|
||||||
|
$this->assertEquals($zip['file.txt'], $fileContents);
|
||||||
|
$zip->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to load using dummy stream
|
||||||
|
*/
|
||||||
|
class DummyFileSystemStream
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var resource
|
||||||
|
*/
|
||||||
|
private $fp;
|
||||||
|
|
||||||
|
function stream_open($path, $mode, $options, &$opened_path)
|
||||||
|
{
|
||||||
|
// echo "DummyFileSystemStream->stream_open($path, $mode, $options)" . PHP_EOL;
|
||||||
|
|
||||||
|
$parsedUrl = parse_url($path);
|
||||||
|
$path = $parsedUrl['path'];
|
||||||
|
$this->fp = fopen($path, $mode);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_read($count)
|
||||||
|
{
|
||||||
|
// echo "DummyFileSystemStream->stream_read($count)" . PHP_EOL;
|
||||||
|
$position = ftell($this->fp);
|
||||||
|
|
||||||
|
// echo "Loading chunk " . $position . " to " . ($position + $count - 1) . PHP_EOL;
|
||||||
|
$ret = fread($this->fp, $count);
|
||||||
|
|
||||||
|
// echo "String length: " . strlen($ret) . PHP_EOL;
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_tell()
|
||||||
|
{
|
||||||
|
// echo "DummyFileSystemStream->stream_tell()" . PHP_EOL;
|
||||||
|
return ftell($this->fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_eof()
|
||||||
|
{
|
||||||
|
// echo "DummyFileSystemStream->stream_eof()" . PHP_EOL;
|
||||||
|
$isfeof = feof($this->fp);
|
||||||
|
return $isfeof;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_seek($offset, $whence)
|
||||||
|
{
|
||||||
|
// echo "DummyFileSystemStream->stream_seek($offset, $whence)" . PHP_EOL;
|
||||||
|
fseek($this->fp, $offset, $whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_stat()
|
||||||
|
{
|
||||||
|
// echo "DummyFileSystemStream->stream_stat()" . PHP_EOL;
|
||||||
|
return fstat($this->fp);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user