1
0
mirror of https://github.com/Ne-Lexa/php-zip.git synced 2025-07-27 10:40:11 +02:00

refactoring zip64, add property softwareVersion, internal attrs, extracted os

This commit is contained in:
Ne-Lexa
2019-12-06 17:36:22 +03:00
parent e2c058840c
commit 95e3312e60
24 changed files with 821 additions and 626 deletions

View File

@@ -25,11 +25,6 @@
"ext-zlib": "*",
"psr/http-message": "^1.0"
},
"config": {
"platform": {
"php": "5.5"
}
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.7",
"zendframework/zend-diactoros": "^1.4"

View File

@@ -49,9 +49,9 @@ class WinZipAesEngine implements ZipEncryptionEngine
*
* @param string $content Input stream buffer
*
* @throws ZipCryptoException
* @throws ZipException
* @throws ZipAuthenticationException
* @throws ZipCryptoException
*
* @return string
*/

View File

@@ -4,7 +4,7 @@ namespace PhpZip\Extra\Fields;
use PhpZip\Exception\ZipException;
use PhpZip\Extra\ExtraField;
use PhpZip\ZipFileInterface;
use PhpZip\ZipFile;
/**
* WinZip AES Extra Field.
@@ -49,9 +49,9 @@ class WinZipAesEntryExtraField implements ExtraField
];
protected static $encryptionMethods = [
self::KEY_STRENGTH_128BIT => ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128,
self::KEY_STRENGTH_192BIT => ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192,
self::KEY_STRENGTH_256BIT => ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256,
self::KEY_STRENGTH_128BIT => ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128,
self::KEY_STRENGTH_192BIT => ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192,
self::KEY_STRENGTH_256BIT => ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256,
];
/**

View File

@@ -1,43 +0,0 @@
<?php
namespace PhpZip\Mapper;
/**
* Adds a offset value to the given position.
*
* @author Ne-Lexa alexey@nelexa.ru
* @license MIT
*/
class OffsetPositionMapper extends PositionMapper
{
/** @var int */
private $offset;
/**
* @param int $offset
*/
public function __construct($offset)
{
$this->offset = (int) $offset;
}
/**
* @param int $position
*
* @return int
*/
public function map($position)
{
return parent::map($position) + $this->offset;
}
/**
* @param int $position
*
* @return int
*/
public function unmap($position)
{
return parent::unmap($position) - $this->offset;
}
}

View File

@@ -1,32 +0,0 @@
<?php
namespace PhpZip\Mapper;
/**
* Maps a given position.
*
* @author Ne-Lexa alexey@nelexa.ru
* @license MIT
*/
class PositionMapper
{
/**
* @param int $position
*
* @return int
*/
public function map($position)
{
return $position;
}
/**
* @param int $position
*
* @return int
*/
public function unmap($position)
{
return $position;
}
}

View File

@@ -3,7 +3,7 @@
namespace PhpZip\Model;
/**
* Read End of Central Directory.
* End of Central Directory.
*
* @author Ne-Lexa alexey@nelexa.ru
* @license MIT
@@ -11,13 +11,13 @@ namespace PhpZip\Model;
class EndOfCentralDirectory
{
/** Zip64 End Of Central Directory Record. */
const ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIG = 0x06064B50;
const ZIP64_END_OF_CD_RECORD_SIG = 0x06064B50;
/** Zip64 End Of Central Directory Locator. */
const ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG = 0x07064B50;
const ZIP64_END_OF_CD_LOCATOR_SIG = 0x07064B50;
/** End Of Central Directory Record signature. */
const END_OF_CENTRAL_DIRECTORY_RECORD_SIG = 0x06054B50;
const END_OF_CD_SIG = 0x06054B50;
/**
* The minimum length of the End Of Central Directory Record.
@@ -49,7 +49,7 @@ class EndOfCentralDirectory
* end of central directory record 8
* total number of disks 4.
*/
const ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LEN = 20;
const ZIP64_END_OF_CD_LOCATOR_LEN = 20;
/**
* The minimum length of the Zip64 End Of Central Directory Record.
@@ -74,35 +74,45 @@ class EndOfCentralDirectory
*/
const ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_MIN_LEN = 56;
/** @var string|null the archive comment */
private $comment;
/** @var int */
/** @var int Count files. */
private $entryCount;
/** @var bool */
/** @var int Central Directory Offset. */
private $cdOffset;
/** @var int */
private $cdSize;
/** @var string|null The archive comment. */
private $comment;
/** @var bool Zip64 extension */
private $zip64;
/**
* EndOfCentralDirectory constructor.
*
* @param int $entryCount
* @param string|null $comment
* @param int $cdOffset
* @param int $cdSize
* @param bool $zip64
* @param mixed|null $comment
*/
public function __construct($entryCount, $comment, $zip64 = false)
public function __construct($entryCount, $cdOffset, $cdSize, $zip64, $comment = null)
{
$this->entryCount = $entryCount;
$this->comment = $comment;
$this->cdOffset = $cdOffset;
$this->cdSize = $cdSize;
$this->zip64 = $zip64;
$this->comment = $comment;
}
/**
* @return string|null
* @param string|null $comment
*/
public function getComment()
public function setComment($comment)
{
return $this->comment;
$this->comment = $comment;
}
/**
@@ -113,6 +123,30 @@ class EndOfCentralDirectory
return $this->entryCount;
}
/**
* @return int
*/
public function getCdOffset()
{
return $this->cdOffset;
}
/**
* @return int
*/
public function getCdSize()
{
return $this->cdSize;
}
/**
* @return string|null
*/
public function getComment()
{
return $this->comment;
}
/**
* @return bool
*/

View File

@@ -9,6 +9,8 @@ use PhpZip\Model\ZipEntry;
*
* @author Ne-Lexa alexey@nelexa.ru
* @license MIT
*
* @internal
*/
class OutputOffsetEntry
{

View File

@@ -10,7 +10,7 @@ use PhpZip\Extra\Fields\WinZipAesEntryExtraField;
use PhpZip\Model\ZipEntry;
use PhpZip\Util\DateTimeConverter;
use PhpZip\Util\StringUtil;
use PhpZip\ZipFileInterface;
use PhpZip\ZipFile;
/**
* Abstract ZIP entry.
@@ -26,16 +26,22 @@ abstract class ZipAbstractEntry implements ZipEntry
private $name;
/** @var int Made by platform */
private $platform = self::UNKNOWN;
private $createdOS = self::UNKNOWN;
/** @var int Extracted by platform */
private $extractedOS = self::UNKNOWN;
/** @var int */
private $versionNeededToExtract = 20;
private $softwareVersion = self::UNKNOWN;
/** @var int */
private $versionNeededToExtract = self::UNKNOWN;
/** @var int Compression method */
private $method = self::UNKNOWN;
/** @var int */
private $general = 0;
private $generalPurposeBitFlags = 0;
/** @var int Dos time */
private $dosTime = self::UNKNOWN;
@@ -49,11 +55,14 @@ abstract class ZipAbstractEntry implements ZipEntry
/** @var int Uncompressed size */
private $size = self::UNKNOWN;
/** @var int Internal attributes */
private $internalAttributes = 0;
/** @var int External attributes */
private $externalAttributes = 0;
/** @var int relative Offset Of Local File Header */
private $offset = self::UNKNOWN;
private $offset = 0;
/**
* Collections of Extra Fields.
@@ -73,17 +82,17 @@ abstract class ZipAbstractEntry implements ZipEntry
/**
* Encryption method.
*
* @see ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL
* @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128
* @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192
* @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256
* @see ZipFile::ENCRYPTION_METHOD_TRADITIONAL
* @see ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128
* @see ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192
* @see ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256
*
* @var int
*/
private $encryptionMethod = ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL;
private $encryptionMethod = ZipFile::ENCRYPTION_METHOD_TRADITIONAL;
/** @var int */
private $compressionLevel = ZipFileInterface::LEVEL_DEFAULT_COMPRESSION;
private $compressionLevel = ZipFile::LEVEL_DEFAULT_COMPRESSION;
/**
* ZipAbstractEntry constructor.
@@ -101,7 +110,9 @@ abstract class ZipAbstractEntry implements ZipEntry
public function setEntry(ZipEntry $entry)
{
$this->setName($entry->getName());
$this->setPlatform($entry->getPlatform());
$this->setSoftwareVersion($entry->getSoftwareVersion());
$this->setCreatedOS($entry->getCreatedOS());
$this->setExtractedOS($entry->getExtractedOS());
$this->setVersionNeededToExtract($entry->getVersionNeededToExtract());
$this->setMethod($entry->getMethod());
$this->setGeneralPurposeBitFlags($entry->getGeneralPurposeBitFlags());
@@ -109,6 +120,7 @@ abstract class ZipAbstractEntry implements ZipEntry
$this->setCrc($entry->getCrc());
$this->setCompressedSize($entry->getCompressedSize());
$this->setSize($entry->getSize());
$this->setInternalAttributes($entry->getInternalAttributes());
$this->setExternalAttributes($entry->getExternalAttributes());
$this->setOffset($entry->getOffset());
$this->setExtra($entry->getExtra());
@@ -163,20 +175,48 @@ abstract class ZipAbstractEntry implements ZipEntry
public function setGeneralPurposeBitFlag($mask, $bit)
{
if ($bit) {
$this->general |= $mask;
$this->generalPurposeBitFlags |= $mask;
} else {
$this->general &= ~$mask;
$this->generalPurposeBitFlags &= ~$mask;
}
return $this;
}
/**
* @return int platform
* @return int Get platform
*
* @deprecated Use {@see ZipEntry::getCreatedOS()}
*/
public function getPlatform()
{
return $this->platform;
@trigger_error('ZipEntry::getPlatform() is deprecated. Use ZipEntry::getCreatedOS()', \E_USER_DEPRECATED);
return $this->getCreatedOS();
}
/**
* @param int $platform
*
* @throws ZipException
*
* @return ZipEntry
*
* @deprecated Use {@see ZipEntry::setCreatedOS()}
*/
public function setPlatform($platform)
{
@trigger_error('ZipEntry::setPlatform() is deprecated. Use ZipEntry::setCreatedOS()', \E_USER_DEPRECATED);
return $this->setCreatedOS($platform);
}
/**
* @return int platform
*/
public function getCreatedOS()
{
return $this->createdOS;
}
/**
@@ -188,17 +228,64 @@ abstract class ZipAbstractEntry implements ZipEntry
*
* @return ZipEntry
*/
public function setPlatform($platform)
public function setCreatedOS($platform)
{
if ($platform !== self::UNKNOWN) {
$platform = (int) $platform;
if ($platform < 0x00 || $platform > 0xff) {
throw new ZipException('Platform out of range');
}
$this->platform = $platform;
} else {
$this->platform = 0; // ms-dos
$this->createdOS = $platform;
return $this;
}
/**
* @return int
*/
public function getExtractedOS()
{
return $this->extractedOS;
}
/**
* Set extracted OS.
*
* @param int $platform
*
* @throws ZipException
*
* @return ZipEntry
*/
public function setExtractedOS($platform)
{
$platform = (int) $platform;
if ($platform < 0x00 || $platform > 0xff) {
throw new ZipException('Platform out of range');
}
$this->extractedOS = $platform;
return $this;
}
/**
* @return int
*/
public function getSoftwareVersion()
{
return $this->softwareVersion;
}
/**
* @param int $softwareVersion
*
* @return ZipEntry
*/
public function setSoftwareVersion($softwareVersion)
{
$this->softwareVersion = (int) $softwareVersion;
return $this;
}
@@ -209,6 +296,24 @@ abstract class ZipAbstractEntry implements ZipEntry
*/
public function getVersionNeededToExtract()
{
if ($this->versionNeededToExtract === self::UNKNOWN) {
$method = $this->getMethod();
if ($method === self::METHOD_WINZIP_AES) {
return 51;
}
if ($method === ZipFile::METHOD_BZIP2) {
return 46;
}
if ($this->isZip64ExtensionsRequired()) {
return 45;
}
return $method === ZipFile::METHOD_DEFLATED || $this->isDirectory() ? 20 : 10;
}
return $this->versionNeededToExtract;
}
@@ -300,7 +405,7 @@ abstract class ZipAbstractEntry implements ZipEntry
*/
public function setOffset($offset)
{
$this->offset = $offset;
$this->offset = (int) $offset;
return $this;
}
@@ -312,7 +417,7 @@ abstract class ZipAbstractEntry implements ZipEntry
*/
public function getGeneralPurposeBitFlags()
{
return $this->general & 0xffff;
return $this->generalPurposeBitFlags & 0xffff;
}
/**
@@ -331,20 +436,20 @@ abstract class ZipAbstractEntry implements ZipEntry
if ($general < 0x0000 || $general > 0xffff) {
throw new ZipException('general out of range');
}
$this->general = $general;
$this->generalPurposeBitFlags = $general;
if ($this->method === ZipFileInterface::METHOD_DEFLATED) {
if ($this->method === ZipFile::METHOD_DEFLATED) {
$bit1 = $this->getGeneralPurposeBitFlag(self::GPBF_COMPRESSION_FLAG1);
$bit2 = $this->getGeneralPurposeBitFlag(self::GPBF_COMPRESSION_FLAG2);
if ($bit1 && !$bit2) {
$this->compressionLevel = ZipFileInterface::LEVEL_BEST_COMPRESSION;
$this->compressionLevel = ZipFile::LEVEL_BEST_COMPRESSION;
} elseif (!$bit1 && $bit2) {
$this->compressionLevel = ZipFileInterface::LEVEL_FAST;
$this->compressionLevel = ZipFile::LEVEL_FAST;
} elseif ($bit1 && $bit2) {
$this->compressionLevel = ZipFileInterface::LEVEL_SUPER_FAST;
$this->compressionLevel = ZipFile::LEVEL_SUPER_FAST;
} else {
$this->compressionLevel = ZipFileInterface::LEVEL_DEFAULT_COMPRESSION;
$this->compressionLevel = ZipFile::LEVEL_DEFAULT_COMPRESSION;
}
}
@@ -370,7 +475,7 @@ abstract class ZipAbstractEntry implements ZipEntry
*/
public function getGeneralPurposeBitFlag($mask)
{
return ($this->general & $mask) !== 0;
return ($this->generalPurposeBitFlags & $mask) !== 0;
}
/**
@@ -447,9 +552,9 @@ abstract class ZipAbstractEntry implements ZipEntry
}
switch ($method) {
case self::METHOD_WINZIP_AES:
case ZipFileInterface::METHOD_STORED:
case ZipFileInterface::METHOD_DEFLATED:
case ZipFileInterface::METHOD_BZIP2:
case ZipFile::METHOD_STORED:
case ZipFile::METHOD_DEFLATED:
case ZipFile::METHOD_BZIP2:
$this->method = $method;
break;
@@ -490,6 +595,8 @@ abstract class ZipAbstractEntry implements ZipEntry
* @param int $dosTime
*
* @throws ZipException
*
* @return ZipEntry
*/
public function setDosTime($dosTime)
{
@@ -499,6 +606,8 @@ abstract class ZipAbstractEntry implements ZipEntry
throw new ZipException('DosTime out of range');
}
$this->dosTime = $dosTime;
return $this;
}
/**
@@ -547,6 +656,30 @@ abstract class ZipAbstractEntry implements ZipEntry
return $this;
}
/**
* Sets the internal file attributes.
*
* @param int $attributes the internal file attributes
*
* @return ZipEntry
*/
public function setInternalAttributes($attributes)
{
$this->internalAttributes = (int) $attributes;
return $this;
}
/**
* Returns the internal file attributes.
*
* @return int the internal file attributes
*/
public function getInternalAttributes()
{
return $this->internalAttributes;
}
/**
* Returns true if and only if this ZIP entry represents a directory entry
* (i.e. end with '/').
@@ -589,10 +722,14 @@ abstract class ZipAbstractEntry implements ZipEntry
* @param string $data the byte array holding the serialized Extra Fields
*
* @throws ZipException if the serialized Extra Fields exceed 64 KB
*
* @return ZipEntry
*/
public function setExtra($data)
{
$this->extraFieldsCollection = ExtraFieldsFactory::createExtraFieldCollections($data, $this);
return $this;
}
/**
@@ -713,19 +850,19 @@ abstract class ZipAbstractEntry implements ZipEntry
*
* @return ZipEntry
*
* @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256
* @see ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL
* @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128
* @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192
* @see ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256
* @see ZipFile::ENCRYPTION_METHOD_TRADITIONAL
* @see ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128
* @see ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192
*/
public function setEncryptionMethod($encryptionMethod)
{
if ($encryptionMethod !== null) {
if (
$encryptionMethod !== ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL
&& $encryptionMethod !== ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128
&& $encryptionMethod !== ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192
&& $encryptionMethod !== ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256
$encryptionMethod !== ZipFile::ENCRYPTION_METHOD_TRADITIONAL
&& $encryptionMethod !== ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128
&& $encryptionMethod !== ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192
&& $encryptionMethod !== ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256
) {
throw new ZipException('Invalid encryption method');
}
@@ -748,14 +885,14 @@ abstract class ZipAbstractEntry implements ZipEntry
*
* @return ZipEntry
*/
public function setCompressionLevel($compressionLevel = ZipFileInterface::LEVEL_DEFAULT_COMPRESSION)
public function setCompressionLevel($compressionLevel = ZipFile::LEVEL_DEFAULT_COMPRESSION)
{
if ($compressionLevel < ZipFileInterface::LEVEL_DEFAULT_COMPRESSION ||
$compressionLevel > ZipFileInterface::LEVEL_BEST_COMPRESSION
if ($compressionLevel < ZipFile::LEVEL_DEFAULT_COMPRESSION ||
$compressionLevel > ZipFile::LEVEL_BEST_COMPRESSION
) {
throw new InvalidArgumentException(
'Invalid compression level. Minimum level ' .
ZipFileInterface::LEVEL_DEFAULT_COMPRESSION . '. Maximum level ' . ZipFileInterface::LEVEL_BEST_COMPRESSION
ZipFile::LEVEL_DEFAULT_COMPRESSION . '. Maximum level ' . ZipFile::LEVEL_BEST_COMPRESSION
);
}
$this->compressionLevel = $compressionLevel;

View File

@@ -10,6 +10,8 @@ use PhpZip\Exception\ZipException;
*
* @author Ne-Lexa alexey@nelexa.ru
* @license MIT
*
* @internal
*/
class ZipChangesEntry extends ZipAbstractEntry
{

View File

@@ -3,7 +3,6 @@
namespace PhpZip\Model\Entry;
use PhpZip\Exception\InvalidArgumentException;
use PhpZip\ZipFileInterface;
/**
* @author Ne-Lexa alexey@nelexa.ru
@@ -50,25 +49,6 @@ class ZipNewEntry extends ZipAbstractEntry
return $this->content;
}
/**
* Version needed to extract.
*
* @return int
*/
public function getVersionNeededToExtract()
{
$method = $this->getMethod();
return $method === self::METHOD_WINZIP_AES ? 51 :
(
$method === ZipFileInterface::METHOD_BZIP2 ? 46 :
(
$this->isZip64ExtensionsRequired() ? 45 :
($method === ZipFileInterface::METHOD_DEFLATED || $this->isDirectory() ? 20 : 10)
)
);
}
/**
* Clone extra fields.
*/

View File

@@ -4,7 +4,7 @@ namespace PhpZip\Model;
use PhpZip\Exception\ZipException;
use PhpZip\Extra\ExtraFieldsCollection;
use PhpZip\ZipFileInterface;
use PhpZip\ZipFile;
/**
* ZIP file entry.
@@ -16,9 +16,6 @@ use PhpZip\ZipFileInterface;
*/
interface ZipEntry
{
// Bit masks for initialized fields.
const BIT_EXTERNAL_ATTR = 128;
/** The unknown value for numeric properties. */
const UNKNOWN = -1;
@@ -118,11 +115,31 @@ interface ZipEntry
/**
* @return int Get platform
*
* @deprecated Use {@see ZipEntry::getCreatedOS()}
*/
public function getPlatform();
/**
* Set platform.
* @param int $platform
*
* @throws ZipException
*
* @return ZipEntry
*
* @deprecated Use {@see ZipEntry::setCreatedOS()}
*/
public function setPlatform($platform);
/**
* Returns created OS.
*
* @return int Get platform
*/
public function getCreatedOS();
/**
* Set created OS.
*
* @param int $platform
*
@@ -130,7 +147,35 @@ interface ZipEntry
*
* @return ZipEntry
*/
public function setPlatform($platform);
public function setCreatedOS($platform);
/**
* @return int
*/
public function getExtractedOS();
/**
* Set extracted OS.
*
* @param int $platform
*
* @throws ZipException
*
* @return ZipEntry
*/
public function setExtractedOS($platform);
/**
* @return int
*/
public function getSoftwareVersion();
/**
* @param int $softwareVersion
*
* @return ZipEntry
*/
public function setSoftwareVersion($softwareVersion);
/**
* Version needed to extract.
@@ -323,6 +368,8 @@ interface ZipEntry
* @param int $dosTime
*
* @throws ZipException
*
* @return ZipEntry
*/
public function setDosTime($dosTime);
@@ -333,6 +380,24 @@ interface ZipEntry
*/
public function getExternalAttributes();
/**
* Sets the internal file attributes.
*
* @param int $attributes the internal file attributes
*
* @throws ZipException
*
* @return ZipEntry
*/
public function setInternalAttributes($attributes);
/**
* Returns the internal file attributes.
*
* @return int the internal file attributes
*/
public function getInternalAttributes();
/**
* Sets the external file attributes.
*
@@ -368,6 +433,8 @@ interface ZipEntry
* @param string $data the byte array holding the serialized Extra Fields
*
* @throws ZipException if the serialized Extra Fields exceed 64 KB
*
* @return ZipEntry
*/
public function setExtra($data);
@@ -439,10 +506,10 @@ interface ZipEntry
*
* @return ZipEntry
*
* @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256
* @see ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL
* @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128
* @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192
* @see ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256
* @see ZipFile::ENCRYPTION_METHOD_TRADITIONAL
* @see ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128
* @see ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192
*/
public function setEncryptionMethod($encryptionMethod);
@@ -460,7 +527,7 @@ interface ZipEntry
*
* @return ZipEntry
*/
public function setCompressionLevel($compressionLevel = ZipFileInterface::LEVEL_DEFAULT_COMPRESSION);
public function setCompressionLevel($compressionLevel = ZipFile::LEVEL_DEFAULT_COMPRESSION);
/**
* @return int

View File

@@ -6,7 +6,7 @@ use PhpZip\Exception\ZipException;
use PhpZip\Extra\Fields\NtfsExtraField;
use PhpZip\Extra\Fields\WinZipAesEntryExtraField;
use PhpZip\Util\FilesUtil;
use PhpZip\ZipFileInterface;
use PhpZip\ZipFile;
/**
* Zip info.
@@ -132,7 +132,7 @@ class ZipInfo
private static $valuesCompressionMethod = [
ZipEntry::UNKNOWN => 'unknown',
ZipFileInterface::METHOD_STORED => 'no compression',
ZipFile::METHOD_STORED => 'no compression',
1 => 'shrink',
2 => 'reduce level 1',
3 => 'reduce level 2',
@@ -140,7 +140,7 @@ class ZipInfo
5 => 'reduce level 4',
6 => 'implode',
7 => 'reserved for Tokenizing compression algorithm',
ZipFileInterface::METHOD_DEFLATED => 'deflate',
ZipFile::METHOD_DEFLATED => 'deflate',
9 => 'deflate64',
10 => 'PKWARE Data Compression Library Imploding (old IBM TERSE)',
11 => 'reserved by PKWARE',
@@ -252,10 +252,10 @@ class ZipInfo
$attributes = str_repeat(' ', 12);
$externalAttributes = $entry->getExternalAttributes();
$xattr = (($externalAttributes >> 16) & 0xFFFF);
switch ($entry->getPlatform()) {
switch ($entry->getCreatedOS()) {
case self::MADE_BY_MS_DOS:
case self::MADE_BY_WINDOWS_NTFS:
if ($entry->getPlatform() !== self::MADE_BY_MS_DOS ||
if ($entry->getCreatedOS() !== self::MADE_BY_MS_DOS ||
($xattr & self::UNX_IRWXU) !==
(self::UNX_IRUSR |
(!($externalAttributes & 1) << 7) |
@@ -420,8 +420,8 @@ class ZipInfo
*/
public static function getPlatformName(ZipEntry $entry)
{
if (isset(self::$valuesMadeBy[$entry->getPlatform()])) {
return self::$valuesMadeBy[$entry->getPlatform()];
if (isset(self::$valuesMadeBy[$entry->getCreatedOS()])) {
return self::$valuesMadeBy[$entry->getCreatedOS()];
}
return 'unknown';

View File

@@ -7,7 +7,7 @@ use PhpZip\Exception\ZipEntryNotFoundException;
use PhpZip\Exception\ZipException;
use PhpZip\Model\Entry\ZipChangesEntry;
use PhpZip\Model\Entry\ZipSourceEntry;
use PhpZip\ZipFileInterface;
use PhpZip\ZipFile;
/**
* Zip Model.
@@ -203,8 +203,8 @@ class ZipModel implements \Countable
/**
* @param string|ZipEntry $entry
*
* @throws ZipException
* @throws ZipEntryNotFoundException
* @throws ZipException
*
* @return ZipChangesEntry|ZipEntry
*/
@@ -352,7 +352,7 @@ class ZipModel implements \Countable
/**
* @param int $encryptionMethod
*/
public function setEncryptionMethod($encryptionMethod = ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256)
public function setEncryptionMethod($encryptionMethod = ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256)
{
$this->matcher()->all()->setEncryptionMethod($encryptionMethod);
}

View File

@@ -14,15 +14,13 @@ use PhpZip\Extra\ExtraFieldsCollection;
use PhpZip\Extra\ExtraFieldsFactory;
use PhpZip\Extra\Fields\ApkAlignmentExtraField;
use PhpZip\Extra\Fields\WinZipAesEntryExtraField;
use PhpZip\Mapper\OffsetPositionMapper;
use PhpZip\Mapper\PositionMapper;
use PhpZip\Model\EndOfCentralDirectory;
use PhpZip\Model\Entry\ZipSourceEntry;
use PhpZip\Model\ZipEntry;
use PhpZip\Model\ZipModel;
use PhpZip\Util\PackUtil;
use PhpZip\Util\StringUtil;
use PhpZip\ZipFileInterface;
use PhpZip\ZipFile;
/**
* Read zip file.
@@ -35,15 +33,6 @@ class ZipInputStream implements ZipInputStreamInterface
/** @var resource */
protected $in;
/** @var PositionMapper */
protected $mapper;
/** @var int the number of bytes in the preamble of this ZIP file */
protected $preamble = 0;
/** @var int the number of bytes in the postamble of this ZIP file */
protected $postamble = 0;
/** @var ZipModel */
protected $zipModel;
@@ -58,7 +47,6 @@ class ZipInputStream implements ZipInputStreamInterface
throw new RuntimeException('$in must be resource');
}
$this->in = $in;
$this->mapper = new PositionMapper();
}
/**
@@ -95,8 +83,8 @@ class ZipInputStream implements ZipInputStreamInterface
if (
$signature !== ZipEntry::LOCAL_FILE_HEADER_SIG
&& $signature !== EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIG
&& $signature !== EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG
&& $signature !== EndOfCentralDirectory::ZIP64_END_OF_CD_RECORD_SIG
&& $signature !== EndOfCentralDirectory::END_OF_CD_SIG
) {
throw new ZipException(
'Expected Local File Header or (ZIP64) End Of Central Directory Record! Signature: ' . $signature
@@ -111,145 +99,179 @@ class ZipInputStream implements ZipInputStreamInterface
*/
protected function readEndOfCentralDirectory()
{
$comment = null;
// Search for End of central directory record.
$stats = fstat($this->in);
$size = $stats['size'];
$max = $size - EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_MIN_LEN;
$min = $max >= 0xffff ? $max - 0xffff : 0;
for ($endOfCentralDirRecordPos = $max; $endOfCentralDirRecordPos >= $min; $endOfCentralDirRecordPos--) {
fseek($this->in, $endOfCentralDirRecordPos, \SEEK_SET);
// end of central dir signature 4 bytes (0x06054b50)
if (unpack('V', fread($this->in, 4))[1] !== EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG) {
continue;
if (!$this->findEndOfCentralDirectory()) {
throw new ZipException('Invalid zip file. The end of the central directory could not be found.');
}
// number of this disk - 2 bytes
// number of the disk with the start of the
// central directory - 2 bytes
// total number of entries in the central
// directory on this disk - 2 bytes
// total number of entries in the central
// directory - 2 bytes
// size of the central directory - 4 bytes
// offset of start of central directory with
// respect to the starting disk number - 4 bytes
// ZIP file comment length - 2 bytes
$data = unpack(
'vdiskNo/vcdDiskNo/vcdEntriesDisk/vcdEntries/VcdSize/VcdPos/vcommentLength',
fread($this->in, 18)
$positionECD = ftell($this->in) - 4;
$buffer = fread($this->in, fstat($this->in)['size'] - $positionECD);
$unpack = unpack(
'vdiskNo/vcdDiskNo/vcdEntriesDisk/' .
'vcdEntries/VcdSize/VcdPos/vcommentLength',
substr($buffer, 0, 18)
);
if ($data['diskNo'] !== 0 || $data['cdDiskNo'] !== 0 || $data['cdEntriesDisk'] !== $data['cdEntries']) {
if (
$unpack['diskNo'] !== 0 ||
$unpack['cdDiskNo'] !== 0 ||
$unpack['cdEntriesDisk'] !== $unpack['cdEntries']
) {
throw new ZipException(
'ZIP file spanning/splitting is not supported!'
);
}
// .ZIP file comment (variable size)
if ($data['commentLength'] > 0) {
$comment = '';
$offset = 0;
// .ZIP file comment (variable sizeECD)
$comment = null;
while ($offset < $data['commentLength']) {
$read = min(8192 /* chunk size */, $data['commentLength'] - $offset);
$comment .= fread($this->in, $read);
$offset += $read;
if ($unpack['commentLength'] > 0) {
$comment = substr($buffer, 18, $unpack['commentLength']);
}
}
$this->preamble = $endOfCentralDirRecordPos;
$this->postamble = $size - ftell($this->in);
// Check for ZIP64 End Of Central Directory Locator.
$endOfCentralDirLocatorPos = $endOfCentralDirRecordPos - EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LEN;
fseek($this->in, $endOfCentralDirLocatorPos, \SEEK_SET);
// Check for ZIP64 End Of Central Directory Locator exists.
$zip64ECDLocatorPosition = $positionECD - EndOfCentralDirectory::ZIP64_END_OF_CD_LOCATOR_LEN;
fseek($this->in, $zip64ECDLocatorPosition);
// zip64 end of central dir locator
// signature 4 bytes (0x07064b50)
if (
$endOfCentralDirLocatorPos < 0 ||
ftell($this->in) === $size ||
unpack(
if ($zip64ECDLocatorPosition > 0 && unpack(
'V',
fread($this->in, 4)
)[1] !== EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG
) {
// Seek and check first CFH, probably requiring an offset mapper.
$offset = $endOfCentralDirRecordPos - $data['cdSize'];
fseek($this->in, $offset, \SEEK_SET);
$offset -= $data['cdPos'];
if ($offset !== 0) {
$this->mapper = new OffsetPositionMapper($offset);
}
$entryCount = $data['cdEntries'];
return new EndOfCentralDirectory($entryCount, $comment);
)[1] === EndOfCentralDirectory::ZIP64_END_OF_CD_LOCATOR_SIG) {
$positionECD = $this->findZip64ECDPosition();
$endCentralDirectory = $this->readZip64EndOfCentralDirectory($positionECD);
$endCentralDirectory->setComment($comment);
} else {
$endCentralDirectory = new EndOfCentralDirectory(
$unpack['cdEntries'],
$unpack['cdPos'],
$unpack['cdSize'],
false,
$comment
);
}
// number of the disk with the
// start of the zip64 end of
// central directory 4 bytes
$zip64EndOfCentralDirectoryRecordDisk = unpack('V', fread($this->in, 4))[1];
// relative offset of the zip64
// end of central directory record 8 bytes
$zip64EndOfCentralDirectoryRecordPos = PackUtil::unpackLongLE(fread($this->in, 8));
// total number of disks 4 bytes
return $endCentralDirectory;
}
/**
* @throws ZipException
*
* @return bool
*/
protected function findEndOfCentralDirectory()
{
$max = fstat($this->in)['size'] - EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_MIN_LEN;
if ($max < 0) {
throw new ZipException('Too short to be a zip file');
}
$min = $max >= 0xffff ? $max - 0xffff : 0;
// Search for End of central directory record.
for ($position = $max; $position >= $min; $position--) {
fseek($this->in, $position);
// end of central dir signature 4 bytes (0x06054b50)
if (unpack('V', fread($this->in, 4))[1] !== EndOfCentralDirectory::END_OF_CD_SIG) {
continue;
}
return true;
}
return false;
}
/**
* Read Zip64 end of central directory locator and returns
* Zip64 end of central directory position.
*
* number of the disk with the
* start of the zip64 end of
* central directory 4 bytes
* relative offset of the zip64
* end of central directory record 8 bytes
* total number of disks 4 bytes
*
* @throws ZipException
*
* @return int Zip64 End Of Central Directory position
*/
protected function findZip64ECDPosition()
{
$diskNo = unpack('V', fread($this->in, 4))[1];
$zip64ECDPos = PackUtil::unpackLongLE(fread($this->in, 8));
$totalDisks = unpack('V', fread($this->in, 4))[1];
if ($zip64EndOfCentralDirectoryRecordDisk !== 0 || $totalDisks !== 1) {
if ($diskNo !== 0 || $totalDisks > 1) {
throw new ZipException('ZIP file spanning/splitting is not supported!');
}
fseek($this->in, $zip64EndOfCentralDirectoryRecordPos, \SEEK_SET);
// zip64 end of central dir
// signature 4 bytes (0x06064b50)
$zip64EndOfCentralDirSig = unpack('V', fread($this->in, 4))[1];
if ($zip64EndOfCentralDirSig !== EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIG) {
return $zip64ECDPos;
}
/**
* Read zip64 end of central directory locator and zip64 end
* of central directory record.
*
* zip64 end of central dir
* signature 4 bytes (0x06064b50)
* size of zip64 end of central
* directory record 8 bytes
* version made by 2 bytes
* version needed to extract 2 bytes
* number of this disk 4 bytes
* number of the disk with the
* start of the central directory 4 bytes
* total number of entries in the
* central directory on this disk 8 bytes
* total number of entries in the
* central directory 8 bytes
* size of the central directory 8 bytes
* offset of start of central
* directory with respect to
* the starting disk number 8 bytes
* zip64 extensible data sector (variable size)
*
* @param int $zip64ECDPosition
*
* @throws ZipException
*
* @return EndOfCentralDirectory
*/
protected function readZip64EndOfCentralDirectory($zip64ECDPosition)
{
fseek($this->in, $zip64ECDPosition);
$buffer = fread($this->in, 56 /* zip64 end of cd rec length */);
if (unpack('V', $buffer)[1] !== EndOfCentralDirectory::ZIP64_END_OF_CD_RECORD_SIG) {
throw new ZipException('Expected ZIP64 End Of Central Directory Record!');
}
// size of zip64 end of central
// directory record 8 bytes
// version made by 2 bytes
// version needed to extract 2 bytes
fseek($this->in, 12, \SEEK_CUR);
// number of this disk 4 bytes
$diskNo = unpack('V', fread($this->in, 4))[1];
// number of the disk with the
// start of the central directory 4 bytes
$cdDiskNo = unpack('V', fread($this->in, 4))[1];
// total number of entries in the
// central directory on this disk 8 bytes
$cdEntriesDisk = PackUtil::unpackLongLE(fread($this->in, 8));
// total number of entries in the
// central directory 8 bytes
$cdEntries = PackUtil::unpackLongLE(fread($this->in, 8));
if ($diskNo !== 0 || $cdDiskNo !== 0 || $cdEntriesDisk !== $cdEntries) {
$data = unpack(
'VdiskNo/VcdDiskNo',
substr($buffer, 16)
);
$cdEntriesDisk = PackUtil::unpackLongLE(substr($buffer, 24, 8));
$entryCount = PackUtil::unpackLongLE(substr($buffer, 32, 8));
$cdSize = PackUtil::unpackLongLE(substr($buffer, 40, 8));
$cdPos = PackUtil::unpackLongLE(substr($buffer, 48, 8));
if ($data['diskNo'] !== 0 || $data['cdDiskNo'] !== 0 || $entryCount !== $cdEntriesDisk) {
throw new ZipException('ZIP file spanning/splitting is not supported!');
}
if ($cdEntries < 0 || $cdEntries > 0x7fffffff) {
if ($entryCount < 0 || $entryCount > 0x7fffffff) {
throw new ZipException('Total Number Of Entries In The Central Directory out of range!');
}
// size of the central directory 8 bytes
fseek($this->in, 8, \SEEK_CUR);
// offset of start of central
// directory with respect to
// the starting disk number 8 bytes
$cdPos = PackUtil::unpackLongLE(fread($this->in, 8));
// zip64 extensible data sector (variable size)
fseek($this->in, $cdPos, \SEEK_SET);
$this->preamble = $zip64EndOfCentralDirectoryRecordPos;
$entryCount = $cdEntries;
$zip64 = true;
return new EndOfCentralDirectory($entryCount, $comment, $zip64);
}
// Start recovering file entries from min.
$this->preamble = $min;
$this->postamble = $size - $min;
// skip zip64 extensible data sector (variable sizeEndCD)
return new EndOfCentralDirectory(0, $comment);
return new EndOfCentralDirectory(
$entryCount,
$cdPos,
$cdSize,
true
);
}
/**
@@ -268,122 +290,108 @@ class ZipInputStream implements ZipInputStreamInterface
*/
protected function mountCentralDirectory(EndOfCentralDirectory $endOfCentralDirectory)
{
$numEntries = $endOfCentralDirectory->getEntryCount();
$entries = [];
for (; $numEntries > 0; $numEntries--) {
$entry = $this->readEntry();
// Re-load virtual offset after ZIP64 Extended Information
// Extra Field may have been parsed, map it to the real
// offset and conditionally update the preamble size from it.
$lfhOff = $this->mapper->map($entry->getOffset());
fseek($this->in, $endOfCentralDirectory->getCdOffset());
if ($lfhOff < $this->preamble) {
$this->preamble = $lfhOff;
if (!($cdStream = fopen('php://temp', 'w+b'))) {
throw new ZipException('Temp resource can not open from write');
}
stream_copy_to_stream($this->in, $cdStream, $endOfCentralDirectory->getCdSize());
rewind($cdStream);
for ($numEntries = $endOfCentralDirectory->getEntryCount(); $numEntries > 0; $numEntries--) {
$entry = $this->readCentralDirectoryEntry($cdStream);
$entries[$entry->getName()] = $entry;
}
if (($numEntries % 0x10000) !== 0) {
throw new ZipException(
'Expected ' . abs($numEntries) .
($numEntries > 0 ? ' more' : ' less') .
' entries in the Central Directory!'
);
}
if ($this->preamble + $this->postamble >= fstat($this->in)['size']) {
$this->checkZipFileSignature();
}
fclose($cdStream);
return $entries;
}
/**
* Read central directory entry.
*
* central file header signature 4 bytes (0x02014b50)
* version made by 2 bytes
* version needed to extract 2 bytes
* general purpose bit flag 2 bytes
* compression method 2 bytes
* last mod file time 2 bytes
* last mod file date 2 bytes
* crc-32 4 bytes
* compressed size 4 bytes
* uncompressed size 4 bytes
* file name length 2 bytes
* extra field length 2 bytes
* file comment length 2 bytes
* disk number start 2 bytes
* internal file attributes 2 bytes
* external file attributes 4 bytes
* relative offset of local header 4 bytes
*
* file name (variable size)
* extra field (variable size)
* file comment (variable size)
*
* @param resource $stream
*
* @throws ZipException
*
* @return ZipEntry
*/
public function readEntry()
public function readCentralDirectoryEntry($stream)
{
// central file header signature 4 bytes (0x02014b50)
$fileHeaderSig = unpack('V', fread($this->in, 4))[1];
if ($fileHeaderSig !== ZipOutputStreamInterface::CENTRAL_FILE_HEADER_SIG) {
throw new InvalidArgumentException('Corrupt zip file. Can not read zip entry.');
if (unpack('V', fread($stream, 4))[1] !== ZipOutputStreamInterface::CENTRAL_FILE_HEADER_SIG) {
throw new ZipException('Corrupt zip file. Cannot read central dir entry.');
}
// version made by 2 bytes
// version needed to extract 2 bytes
// general purpose bit flag 2 bytes
// compression method 2 bytes
// last mod file time 2 bytes
// last mod file date 2 bytes
// crc-32 4 bytes
// compressed size 4 bytes
// uncompressed size 4 bytes
// file name length 2 bytes
// extra field length 2 bytes
// file comment length 2 bytes
// disk number start 2 bytes
// internal file attributes 2 bytes
// external file attributes 4 bytes
// relative offset of local header 4 bytes
$data = unpack(
'vversionMadeBy/vversionNeededToExtract/vgpbf/' .
'vrawMethod/VrawTime/VrawCrc/VrawCompressedSize/' .
'VrawSize/vfileLength/vextraLength/vcommentLength/' .
'VrawInternalAttributes/VrawExternalAttributes/VlfhOff',
fread($this->in, 42)
'vversionMadeBy/vversionNeededToExtract/' .
'vgeneralPurposeBitFlag/vcompressionMethod/' .
'VlastModFile/Vcrc/VcompressedSize/' .
'VuncompressedSize/vfileNameLength/vextraFieldLength/' .
'vfileCommentLength/vdiskNumberStart/vinternalFileAttributes/' .
'VexternalFileAttributes/VoffsetLocalHeader',
fread($stream, 42)
);
// $utf8 = ($data['gpbf'] & ZipEntry::GPBF_UTF8) !== 0;
$createdOS = ($data['versionMadeBy'] & 0xFF00) >> 8;
$softwareVersion = $data['versionMadeBy'] & 0x00FF;
// See appendix D of PKWARE's ZIP File Format Specification.
$name = '';
$offset = 0;
$extractOS = ($data['versionNeededToExtract'] & 0xFF00) >> 8;
$extractVersion = $data['versionNeededToExtract'] & 0x00FF;
while ($offset < $data['fileLength']) {
$read = min(8192 /* chunk size */, $data['fileLength'] - $offset);
$name .= fread($this->in, $read);
$offset += $read;
$name = fread($stream, $data['fileNameLength']);
$extra = '';
if ($data['extraFieldLength'] > 0) {
$extra = fread($stream, $data['extraFieldLength']);
}
$comment = null;
if ($data['fileCommentLength'] > 0) {
$comment = fread($stream, $data['fileCommentLength']);
}
$entry = new ZipSourceEntry($this);
$entry->setName($name);
$entry->setVersionNeededToExtract($data['versionNeededToExtract']);
$entry->setPlatform($data['versionMadeBy'] >> 8);
$entry->setMethod($data['rawMethod']);
$entry->setGeneralPurposeBitFlags($data['gpbf']);
$entry->setDosTime($data['rawTime']);
$entry->setCrc($data['rawCrc']);
$entry->setCompressedSize($data['rawCompressedSize']);
$entry->setSize($data['rawSize']);
$entry->setExternalAttributes($data['rawExternalAttributes']);
$entry->setOffset($data['lfhOff']); // must be unmapped!
if ($data['extraLength'] > 0) {
$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) {
$comment = '';
$offset = 0;
while ($offset < $data['commentLength']) {
$read = min(8192 /* chunk size */, $data['commentLength'] - $offset);
$comment .= fread($this->in, $read);
$offset += $read;
}
$entry->setCreatedOS($createdOS);
$entry->setSoftwareVersion($softwareVersion);
$entry->setVersionNeededToExtract($extractVersion);
$entry->setExtractedOS($extractOS);
$entry->setMethod($data['compressionMethod']);
$entry->setGeneralPurposeBitFlags($data['generalPurposeBitFlag']);
$entry->setDosTime($data['lastModFile']);
$entry->setCrc($data['crc']);
$entry->setCompressedSize($data['compressedSize']);
$entry->setSize($data['uncompressedSize']);
$entry->setInternalAttributes($data['internalFileAttributes']);
$entry->setExternalAttributes($data['externalFileAttributes']);
$entry->setOffset($data['offsetLocalHeader']);
$entry->setComment($comment);
}
$entry->setExtra($extra);
return $entry;
}
@@ -410,9 +418,8 @@ class ZipInputStream implements ZipInputStreamInterface
throw new ZipException('Can not password from entry ' . $entry->getName());
}
$pos = $entry->getOffset();
$startPos = $pos = $entry->getOffset();
$startPos = $pos = $this->mapper->map($pos);
fseek($this->in, $startPos);
// local file header signature 4 bytes (0x04034b50)
@@ -465,7 +472,7 @@ class ZipInputStream implements ZipInputStreamInterface
// Traditional PKWARE Decryption
$zipCryptoEngine = new TraditionalPkwareEncryptionEngine($entry);
$content = $zipCryptoEngine->decrypt($content);
$entry->setEncryptionMethod(ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
$entry->setEncryptionMethod(ZipFile::ENCRYPTION_METHOD_TRADITIONAL);
}
if (!$skipCheckCrc) {
@@ -500,15 +507,15 @@ class ZipInputStream implements ZipInputStreamInterface
}
switch ($method) {
case ZipFileInterface::METHOD_STORED:
case ZipFile::METHOD_STORED:
break;
case ZipFileInterface::METHOD_DEFLATED:
case ZipFile::METHOD_DEFLATED:
/** @noinspection PhpUsageOfSilenceOperatorInspection */
$content = @gzinflate($content);
break;
case ZipFileInterface::METHOD_BZIP2:
case ZipFile::METHOD_BZIP2:
if (!\extension_loaded('bz2')) {
throw new ZipException('Extension bzip2 not install');
}
@@ -589,8 +596,6 @@ class ZipInputStream implements ZipInputStreamInterface
throw new ZipException(sprintf('Missing local header offset for entry %s', $entry->getName()));
}
$pos = $this->mapper->map($pos);
$nameLength = \strlen($entry->getName());
fseek($this->in, $pos + ZipEntry::LOCAL_FILE_HEADER_MIN_LEN - 2, \SEEK_SET);
@@ -625,7 +630,7 @@ class ZipInputStream implements ZipInputStreamInterface
if (
$this->zipModel->isZipAlign() &&
!$entry->isEncrypted() &&
$entry->getMethod() === ZipFileInterface::METHOD_STORED
$entry->getMethod() === ZipFile::METHOD_STORED
) {
if (StringUtil::endsWith($entry->getName(), '.so')) {
$dataAlignmentMultiple = ApkAlignmentExtraField::ANDROID_COMMON_PAGE_ALIGNMENT_BYTES;
@@ -688,7 +693,6 @@ class ZipInputStream implements ZipInputStreamInterface
public function copyEntryData(ZipEntry $entry, ZipOutputStreamInterface $out)
{
$offset = $entry->getOffset();
$offset = $this->mapper->map($offset);
$nameLength = \strlen($entry->getName());
fseek($this->in, $offset + ZipEntry::LOCAL_FILE_HEADER_MIN_LEN - 2, \SEEK_SET);

View File

@@ -20,9 +20,15 @@ interface ZipInputStreamInterface
public function readZip();
/**
* Read central directory entry.
*
* @param resource $stream
*
* @throws ZipException
*
* @return ZipEntry
*/
public function readEntry();
public function readCentralDirectoryEntry($stream);
/**
* @param ZipEntry $entry

View File

@@ -19,7 +19,7 @@ use PhpZip\Model\ZipEntry;
use PhpZip\Model\ZipModel;
use PhpZip\Util\PackUtil;
use PhpZip\Util\StringUtil;
use PhpZip\ZipFileInterface;
use PhpZip\ZipFile;
/**
* Write zip file.
@@ -97,7 +97,7 @@ class ZipOutputStream implements ZipOutputStreamInterface
if (
$this->zipModel->isZipAlign() &&
!$entry->isEncrypted() &&
$entry->getMethod() === ZipFileInterface::METHOD_STORED
$entry->getMethod() === ZipFile::METHOD_STORED
) {
$dataAlignmentMultiple = $this->zipModel->getZipAlign();
@@ -144,7 +144,7 @@ class ZipOutputStream implements ZipOutputStreamInterface
// local file header signature 4 bytes (0x04034b50)
ZipEntry::LOCAL_FILE_HEADER_SIG,
// version needed to extract 2 bytes
$entry->getVersionNeededToExtract(),
($entry->getExtractedOS() << 8) | $entry->getVersionNeededToExtract(),
// general purpose bit flag 2 bytes
$entry->getGeneralPurposeBitFlags(),
// compression method 2 bytes
@@ -221,8 +221,12 @@ class ZipOutputStream implements ZipOutputStreamInterface
*/
protected function entryCommitChangesAndReturnContent(ZipEntry $entry)
{
if ($entry->getPlatform() === ZipEntry::UNKNOWN) {
$entry->setPlatform(ZipEntry::PLATFORM_UNIX);
if ($entry->getCreatedOS() === ZipEntry::UNKNOWN) {
$entry->setCreatedOS(ZipEntry::PLATFORM_UNIX);
}
if ($entry->getExtractedOS() === ZipEntry::UNKNOWN) {
$entry->setExtractedOS(ZipEntry::PLATFORM_UNIX);
}
if ($entry->getTime() === ZipEntry::UNKNOWN) {
@@ -265,16 +269,15 @@ class ZipOutputStream implements ZipOutputStreamInterface
}
switch ($method) {
case ZipFileInterface::METHOD_STORED:
case ZipFile::METHOD_STORED:
break;
case ZipFileInterface::METHOD_DEFLATED:
case ZipFile::METHOD_DEFLATED:
$entryContent = gzdeflate($entryContent, $entry->getCompressionLevel());
break;
case ZipFileInterface::METHOD_BZIP2:
$compressionLevel = $entry->getCompressionLevel(
) === ZipFileInterface::LEVEL_DEFAULT_COMPRESSION ?
case ZipFile::METHOD_BZIP2:
$compressionLevel = $entry->getCompressionLevel() === ZipFile::LEVEL_DEFAULT_COMPRESSION ?
ZipEntry::LEVEL_DEFAULT_BZIP2_COMPRESSION :
$entry->getCompressionLevel();
/** @noinspection PhpComposerExtensionStubsInspection */
@@ -294,19 +297,19 @@ class ZipOutputStream implements ZipOutputStreamInterface
throw new ZipException($entry->getName() . ' (unsupported compression method ' . $method . ')');
}
if ($method === ZipFileInterface::METHOD_DEFLATED) {
if ($method === ZipFile::METHOD_DEFLATED) {
$bit1 = false;
$bit2 = false;
switch ($entry->getCompressionLevel()) {
case ZipFileInterface::LEVEL_BEST_COMPRESSION:
case ZipFile::LEVEL_BEST_COMPRESSION:
$bit1 = true;
break;
case ZipFileInterface::LEVEL_FAST:
case ZipFile::LEVEL_FAST:
$bit2 = true;
break;
case ZipFileInterface::LEVEL_SUPER_FAST:
case ZipFile::LEVEL_SUPER_FAST:
$bit1 = true;
$bit2 = true;
break;
@@ -320,9 +323,9 @@ class ZipOutputStream implements ZipOutputStreamInterface
if (\in_array(
$entry->getEncryptionMethod(),
[
ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128,
ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192,
ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256,
ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128,
ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192,
ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256,
],
true
)) {
@@ -334,7 +337,7 @@ class ZipOutputStream implements ZipOutputStreamInterface
$field->setMethod($method);
$size = $entry->getSize();
if ($size >= 20 && $method !== ZipFileInterface::METHOD_BZIP2) {
if ($size >= 20 && $method !== ZipFile::METHOD_BZIP2) {
$field->setVendorVersion(WinZipAesEntryExtraField::VV_AE_1);
} else {
$field->setVendorVersion(WinZipAesEntryExtraField::VV_AE_2);
@@ -345,7 +348,7 @@ class ZipOutputStream implements ZipOutputStreamInterface
$winZipAesEngine = new WinZipAesEngine($entry);
$entryContent = $winZipAesEngine->encrypt($entryContent);
} elseif ($entry->getEncryptionMethod() === ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL) {
} elseif ($entry->getEncryptionMethod() === ZipFile::ENCRYPTION_METHOD_TRADITIONAL) {
$zipCryptoEngine = new TraditionalPkwareEncryptionEngine($entry);
$entryContent = $zipCryptoEngine->encrypt($entryContent);
}
@@ -382,11 +385,11 @@ class ZipOutputStream implements ZipOutputStreamInterface
$entryContent = gzdeflate($content, $entry->getCompressionLevel());
if (\strlen($entryContent) < \strlen($content)) {
$entry->setMethod(ZipFileInterface::METHOD_DEFLATED);
$entry->setMethod(ZipFile::METHOD_DEFLATED);
return $entryContent;
}
$entry->setMethod(ZipFileInterface::METHOD_STORED);
$entry->setMethod(ZipFile::METHOD_STORED);
}
return $content;
@@ -418,9 +421,9 @@ class ZipOutputStream implements ZipOutputStreamInterface
// central file header signature 4 bytes (0x02014b50)
self::CENTRAL_FILE_HEADER_SIG,
// version made by 2 bytes
($entry->getPlatform() << 8) | 63,
($entry->getCreatedOS() << 8) | $entry->getSoftwareVersion(),
// version needed to extract 2 bytes
$entry->getVersionNeededToExtract(),
($entry->getExtractedOS() << 8) | $entry->getVersionNeededToExtract(),
// general purpose bit flag 2 bytes
$entry->getGeneralPurposeBitFlags(),
// compression method 2 bytes
@@ -442,7 +445,7 @@ class ZipOutputStream implements ZipOutputStreamInterface
// disk number start 2 bytes
0,
// internal file attributes 2 bytes
0,
$entry->getInternalAttributes(),
// external file attributes 4 bytes
$entry->getExternalAttributes(),
// relative offset of local header 4 bytes
@@ -468,75 +471,99 @@ class ZipOutputStream implements ZipOutputStreamInterface
*/
protected function writeEndOfCentralDirectoryRecord($centralDirectoryOffset)
{
$centralDirectoryOffset = (int) $centralDirectoryOffset;
$centralDirectoryEntriesCount = \count($this->zipModel);
$cdEntriesCount = \count($this->zipModel);
$position = ftell($this->out);
$centralDirectorySize = $position - $centralDirectoryOffset;
$centralDirectoryEntriesZip64 = $centralDirectoryEntriesCount > 0xffff;
$centralDirectorySizeZip64 = $centralDirectorySize > 0xffffffff;
$centralDirectoryOffsetZip64 = $centralDirectoryOffset > 0xffffffff;
$centralDirectoryEntries16 = $centralDirectoryEntriesZip64 ? 0xffff : $centralDirectoryEntriesCount;
$centralDirectorySize32 = $centralDirectorySizeZip64 ? 0xffffffff : $centralDirectorySize;
$centralDirectoryOffset32 = $centralDirectoryOffsetZip64 ? 0xffffffff : $centralDirectoryOffset;
$zip64 // ZIP64 extensions?
= $centralDirectoryEntriesZip64
|| $centralDirectorySizeZip64
|| $centralDirectoryOffsetZip64;
if ($zip64) {
// [zip64 end of central directory record]
// relative offset of the zip64 end of central directory record
$zip64EndOfCentralDirectoryOffset = $position;
// zip64 end of central dir
$cdEntriesZip64 = $cdEntriesCount > 0xFFFF;
$cdSizeZip64 = $centralDirectorySize > 0xFFFFFFFF;
$cdOffsetZip64 = $centralDirectoryOffset > 0xFFFFFFFF;
$zip64Required = $cdEntriesZip64 || $cdSizeZip64 || $cdOffsetZip64;
if ($zip64Required) {
$zip64EndOfCentralDirectoryOffset = ftell($this->out);
// find max software version, version needed to extract and most common platform
list($softwareVersion, $versionNeededToExtract) = array_reduce(
$this->zipModel->getEntries(),
static function (array $carry, ZipEntry $entry) {
$carry[0] = max($carry[0], $entry->getSoftwareVersion() & 0xFF);
$carry[1] = max($carry[1], $entry->getVersionNeededToExtract() & 0xFF);
return $carry;
},
[10 /* simple file min ver */, 45 /* zip64 ext min ver */]
);
$createdOS = $extractedOS = ZipEntry::PLATFORM_FAT;
$versionMadeBy = ($createdOS << 8) | max($softwareVersion, 45 /* zip64 ext min ver */);
$versionExtractedBy = ($extractedOS << 8) | max($versionNeededToExtract, 45 /* zip64 ext min ver */);
// signature 4 bytes (0x06064b50)
fwrite($this->out, pack('V', EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIG));
fwrite($this->out, pack('V', EndOfCentralDirectory::ZIP64_END_OF_CD_RECORD_SIG));
// size of zip64 end of central
// directory record 8 bytes
fwrite($this->out, PackUtil::packLongLE(44));
fwrite(
$this->out,
PackUtil::packLongLE(EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_MIN_LEN - 12)
);
pack(
'vvVV',
// version made by 2 bytes
$versionMadeBy & 0xFFFF,
// version needed to extract 2 bytes
// due to potential use of BZIP2 compression
$versionExtractedBy & 0xFFFF,
// number of this disk 4 bytes
0,
// number of the disk with the
// start of the central directory 4 bytes
fwrite($this->out, pack('vvVV', 63, 46, 0, 0));
0
)
);
// total number of entries in the
// central directory on this disk 8 bytes
fwrite($this->out, PackUtil::packLongLE($centralDirectoryEntriesCount));
fwrite($this->out, PackUtil::packLongLE($cdEntriesCount));
// total number of entries in the
// central directory 8 bytes
fwrite($this->out, PackUtil::packLongLE($centralDirectoryEntriesCount));
fwrite($this->out, PackUtil::packLongLE($cdEntriesCount));
// size of the central directory 8 bytes
fwrite($this->out, PackUtil::packLongLE($centralDirectorySize));
// offset of start of central
// directory with respect to
// the starting disk number 8 bytes
fwrite($this->out, PackUtil::packLongLE($centralDirectoryOffset));
// zip64 extensible data sector (variable size)
// [zip64 end of central directory locator]
// write zip64 end of central directory locator
fwrite(
$this->out,
pack(
'VV',
// zip64 end of central dir locator
// signature 4 bytes (0x07064b50)
EndOfCentralDirectory::ZIP64_END_OF_CD_LOCATOR_SIG,
// number of the disk with the
// start of the zip64 end of
// central directory 4 bytes
fwrite($this->out, pack('VV', EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG, 0));
0
)
);
// relative offset of the zip64
// end of central directory record 8 bytes
fwrite($this->out, PackUtil::packLongLE($zip64EndOfCentralDirectoryOffset));
// total number of disks 4 bytes
fwrite($this->out, pack('V', 1));
}
$comment = $this->zipModel->getArchiveComment();
$commentLength = \strlen($comment);
$commentLength = $comment !== null ? \strlen($comment) : 0;
fwrite(
$this->out,
pack(
'VvvvvVVv',
// end of central dir signature 4 bytes (0x06054b50)
EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG,
EndOfCentralDirectory::END_OF_CD_SIG,
// number of this disk 2 bytes
0,
// number of the disk with the
@@ -544,16 +571,16 @@ class ZipOutputStream implements ZipOutputStreamInterface
0,
// total number of entries in the
// central directory on this disk 2 bytes
$centralDirectoryEntries16,
$cdEntriesZip64 ? 0xFFFF : $cdEntriesCount,
// total number of entries in
// the central directory 2 bytes
$centralDirectoryEntries16,
$cdEntriesZip64 ? 0xFFFF : $cdEntriesCount,
// size of the central directory 4 bytes
$centralDirectorySize32,
$cdSizeZip64 ? 0xFFFFFFFF : $centralDirectorySize,
// offset of start of central
// directory with respect to
// the starting disk number 4 bytes
$centralDirectoryOffset32,
$cdOffsetZip64 ? 0xFFFFFFFF : $centralDirectoryOffset,
// .ZIP file comment length 2 bytes
$commentLength
)

View File

@@ -234,8 +234,8 @@ class ZipFile implements ZipFileInterface
* @param string $entryName
* @param string|null $comment
*
* @throws ZipEntryNotFoundException
* @throws ZipException
* @throws ZipEntryNotFoundException
*
* @return ZipFileInterface
*/
@@ -277,8 +277,8 @@ class ZipFile implements ZipFileInterface
*
* @param string|ZipEntry $entryName
*
* @throws ZipException
* @throws ZipEntryNotFoundException
* @throws ZipException
*
* @return ZipInfo
*/
@@ -398,9 +398,9 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addFromString($localName, $contents, $compressionMethod = null)
{
@@ -454,9 +454,9 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addFile($filename, $localName = null, $compressionMethod = null)
{
@@ -520,9 +520,9 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addFromStream($stream, $localName, $compressionMethod = null)
{
@@ -655,9 +655,9 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addDirRecursive($inputDir, $localPath = '/', $compressionMethod = null)
{
@@ -693,9 +693,9 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addFilesFromIterator(
\Iterator $iterator,
@@ -1091,10 +1091,10 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @see ZipFileInterface::LEVEL_DEFAULT_COMPRESSION
* @see ZipFileInterface::LEVEL_SUPER_FAST
* @see ZipFileInterface::LEVEL_FAST
* @see ZipFileInterface::LEVEL_BEST_COMPRESSION
* @see ZipFile::LEVEL_DEFAULT_COMPRESSION
* @see ZipFile::LEVEL_SUPER_FAST
* @see ZipFile::LEVEL_FAST
* @see ZipFile::LEVEL_BEST_COMPRESSION
*/
public function setCompressionLevel($compressionLevel = self::LEVEL_DEFAULT_COMPRESSION)
{
@@ -1123,16 +1123,16 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @see ZipFileInterface::LEVEL_DEFAULT_COMPRESSION
* @see ZipFileInterface::LEVEL_SUPER_FAST
* @see ZipFileInterface::LEVEL_FAST
* @see ZipFileInterface::LEVEL_BEST_COMPRESSION
* @see ZipFile::LEVEL_DEFAULT_COMPRESSION
* @see ZipFile::LEVEL_SUPER_FAST
* @see ZipFile::LEVEL_FAST
* @see ZipFile::LEVEL_BEST_COMPRESSION
*/
public function setCompressionLevelEntry($entryName, $compressionLevel)
{
if ($compressionLevel !== null) {
if ($compressionLevel < ZipFileInterface::LEVEL_DEFAULT_COMPRESSION ||
$compressionLevel > ZipFileInterface::LEVEL_BEST_COMPRESSION
if ($compressionLevel < self::LEVEL_DEFAULT_COMPRESSION ||
$compressionLevel > self::LEVEL_BEST_COMPRESSION
) {
throw new InvalidArgumentException(
'Invalid compression level. Minimum level ' .
@@ -1158,9 +1158,9 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function setCompressionMethodEntry($entryName, $compressionMethod)
{
@@ -1204,7 +1204,7 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @deprecated using ZipFileInterface::setReadPassword()
* @deprecated using ZipFile::setReadPassword()
*/
public function withReadPassword($password)
{
@@ -1254,7 +1254,7 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @deprecated using ZipFileInterface::setPassword()
* @deprecated using ZipFile::setPassword()
*/
public function withNewPassword($password, $encryptionMethod = self::ENCRYPTION_METHOD_WINZIP_AES_256)
{
@@ -1311,7 +1311,7 @@ class ZipFile implements ZipFileInterface
*
* @return ZipFileInterface
*
* @deprecated using ZipFileInterface::disableEncryption()
* @deprecated using ZipFile::disableEncryption()
*/
public function withoutPassword()
{

View File

@@ -233,9 +233,9 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addFromString($localName, $contents, $compressionMethod = null);
@@ -250,9 +250,9 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addFile($filename, $localName = null, $compressionMethod = null);
@@ -267,9 +267,9 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addFromStream($stream, $localName, $compressionMethod = null);
@@ -306,9 +306,9 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addDirRecursive($inputDir, $localPath = '/', $compressionMethod = null);
@@ -323,9 +323,9 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function addFilesFromIterator(\Iterator $iterator, $localPath = '/', $compressionMethod = null);
@@ -456,10 +456,10 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @see ZipFileInterface::LEVEL_SUPER_FAST
* @see ZipFileInterface::LEVEL_FAST
* @see ZipFileInterface::LEVEL_BEST_COMPRESSION
* @see ZipFileInterface::LEVEL_DEFAULT_COMPRESSION
* @see ZipFile::LEVEL_SUPER_FAST
* @see ZipFile::LEVEL_FAST
* @see ZipFile::LEVEL_BEST_COMPRESSION
* @see ZipFile::LEVEL_DEFAULT_COMPRESSION
*/
public function setCompressionLevel($compressionLevel = self::LEVEL_DEFAULT_COMPRESSION);
@@ -471,10 +471,10 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @see ZipFileInterface::LEVEL_DEFAULT_COMPRESSION
* @see ZipFileInterface::LEVEL_SUPER_FAST
* @see ZipFileInterface::LEVEL_FAST
* @see ZipFileInterface::LEVEL_BEST_COMPRESSION
* @see ZipFile::LEVEL_DEFAULT_COMPRESSION
* @see ZipFile::LEVEL_SUPER_FAST
* @see ZipFile::LEVEL_FAST
* @see ZipFile::LEVEL_BEST_COMPRESSION
*/
public function setCompressionLevelEntry($entryName, $compressionLevel);
@@ -486,9 +486,9 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @see ZipFileInterface::METHOD_STORED
* @see ZipFileInterface::METHOD_DEFLATED
* @see ZipFileInterface::METHOD_BZIP2
* @see ZipFile::METHOD_STORED
* @see ZipFile::METHOD_DEFLATED
* @see ZipFile::METHOD_BZIP2
*/
public function setCompressionMethodEntry($entryName, $compressionMethod);
@@ -510,7 +510,7 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @deprecated using ZipFileInterface::setReadPassword()
* @deprecated using ZipFile::setReadPassword()
*/
public function withReadPassword($password);
@@ -541,7 +541,7 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @deprecated using ZipFileInterface::setPassword()
* @deprecated using ZipFile::setPassword()
*/
public function withNewPassword($password, $encryptionMethod = self::ENCRYPTION_METHOD_WINZIP_AES_256);
@@ -571,7 +571,7 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
*
* @return ZipFileInterface
*
* @deprecated using ZipFileInterface::disableEncryption()
* @deprecated using ZipFile::disableEncryption()
*/
public function withoutPassword();

View File

@@ -127,7 +127,10 @@ class PhpZipExtResourceTest extends ZipTestCase
public function testBug70752()
{
if (\PHP_INT_SIZE === 4) { // php 32 bit
$this->setExpectedException(RuntimeException::class, 'Traditional PKWARE Encryption is not supported in 32-bit PHP.');
$this->setExpectedException(
RuntimeException::class,
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
);
} else { // php 64 bit
$this->setExpectedException(
ZipAuthenticationException::class,
@@ -163,19 +166,11 @@ class PhpZipExtResourceTest extends ZipTestCase
*/
public function testPecl12414()
{
$filename = __DIR__ . '/php-zip-ext-test-resources/pecl12414.zip';
$this->setExpectedException(ZipException::class, 'Corrupt zip file. Cannot read central dir entry.');
$entryName = 'MYLOGOV2.GFX';
$filename = __DIR__ . '/php-zip-ext-test-resources/pecl12414.zip';
$zipFile = new ZipFile();
$zipFile->openFile($filename);
$info = $zipFile->getEntryInfo($entryName);
static::assertTrue($info->getSize() > 0);
$contents = $zipFile[$entryName];
static::assertSame(\strlen($contents), $info->getSize());
$zipFile->close();
}
}

View File

@@ -54,7 +54,7 @@ class ZipAlignTest extends ZipTestCase
$zipFile->addFromString(
'entry' . $i . '.txt',
CryptoUtil::randomBytes(mt_rand(100, 4096)),
ZipFileInterface::METHOD_STORED
ZipFile::METHOD_STORED
);
}
$zipFile->saveAsFile($this->outputFilename);
@@ -95,7 +95,7 @@ class ZipAlignTest extends ZipTestCase
$zipFile->addFromString(
'entry' . $i . '.txt',
CryptoUtil::randomBytes(mt_rand(100, 4096)),
ZipFileInterface::METHOD_STORED
ZipFile::METHOD_STORED
);
}
$zipFile->setZipAlign(4);
@@ -123,7 +123,7 @@ class ZipAlignTest extends ZipTestCase
$zipFile->addFromString(
'entry' . $i . '.txt',
CryptoUtil::randomBytes(mt_rand(100, 4096)),
ZipFileInterface::METHOD_STORED
ZipFile::METHOD_STORED
);
}
$zipFile->saveAsFile($this->outputFilename);
@@ -149,8 +149,8 @@ class ZipAlignTest extends ZipTestCase
'entry_new_' . ($isStored ? 'stored' : 'deflated') . '_' . $i . '.txt',
CryptoUtil::randomBytes(mt_rand(100, 4096)),
$isStored ?
ZipFileInterface::METHOD_STORED :
ZipFileInterface::METHOD_DEFLATED
ZipFile::METHOD_STORED :
ZipFile::METHOD_DEFLATED
);
}
$zipFile->setZipAlign(4);

View File

@@ -909,12 +909,12 @@ class ZipFileTest extends ZipTestCase
$entries = [
'1' => [
'data' => CryptoUtil::randomBytes(255),
'method' => ZipFileInterface::METHOD_STORED,
'method' => ZipFile::METHOD_STORED,
'expected' => 'No compression',
],
'2' => [
'data' => CryptoUtil::randomBytes(255),
'method' => ZipFileInterface::METHOD_DEFLATED,
'method' => ZipFile::METHOD_DEFLATED,
'expected' => 'Deflate',
],
];
@@ -922,7 +922,7 @@ class ZipFileTest extends ZipTestCase
if (\extension_loaded('bz2')) {
$entries['3'] = [
'data' => CryptoUtil::randomBytes(255),
'method' => ZipFileInterface::METHOD_BZIP2,
'method' => ZipFile::METHOD_BZIP2,
'expected' => 'Bzip2',
];
}
@@ -938,7 +938,7 @@ class ZipFileTest extends ZipTestCase
static::assertCorrectZipArchive($this->outputFilename);
$zipFile->openFile($this->outputFilename);
$zipFile->setCompressionLevel(ZipFileInterface::LEVEL_BEST_COMPRESSION);
$zipFile->setCompressionLevel(ZipFile::LEVEL_BEST_COMPRESSION);
$zipAllInfo = $zipFile->getAllInfo();
foreach ($zipAllInfo as $entryName => $info) {
@@ -1693,14 +1693,14 @@ class ZipFileTest extends ZipTestCase
$files['file' . $i . '.txt'] = CryptoUtil::randomBytes(255);
}
$methods = [ZipFileInterface::METHOD_STORED, ZipFileInterface::METHOD_DEFLATED];
$methods = [ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED];
if (\extension_loaded('bz2')) {
$methods[] = ZipFileInterface::METHOD_BZIP2;
$methods[] = ZipFile::METHOD_BZIP2;
}
$zipFile = new ZipFile();
$zipFile->setCompressionLevel(ZipFileInterface::LEVEL_BEST_SPEED);
$zipFile->setCompressionLevel(ZipFile::LEVEL_BEST_SPEED);
foreach ($files as $entryName => $content) {
$zipFile->addFromString($entryName, $content, $methods[array_rand($methods)]);
@@ -1985,14 +1985,14 @@ class ZipFileTest extends ZipTestCase
{
$zipFile = new ZipFile();
$zipFile
->addFromString('file', 'content', ZipFileInterface::METHOD_DEFLATED)
->setCompressionLevelEntry('file', ZipFileInterface::LEVEL_BEST_COMPRESSION)
->addFromString('file2', 'content', ZipFileInterface::METHOD_DEFLATED)
->setCompressionLevelEntry('file2', ZipFileInterface::LEVEL_FAST)
->addFromString('file3', 'content', ZipFileInterface::METHOD_DEFLATED)
->setCompressionLevelEntry('file3', ZipFileInterface::LEVEL_SUPER_FAST)
->addFromString('file4', 'content', ZipFileInterface::METHOD_DEFLATED)
->setCompressionLevelEntry('file4', ZipFileInterface::LEVEL_DEFAULT_COMPRESSION)
->addFromString('file', 'content', ZipFile::METHOD_DEFLATED)
->setCompressionLevelEntry('file', ZipFile::LEVEL_BEST_COMPRESSION)
->addFromString('file2', 'content', ZipFile::METHOD_DEFLATED)
->setCompressionLevelEntry('file2', ZipFile::LEVEL_FAST)
->addFromString('file3', 'content', ZipFile::METHOD_DEFLATED)
->setCompressionLevelEntry('file3', ZipFile::LEVEL_SUPER_FAST)
->addFromString('file4', 'content', ZipFile::METHOD_DEFLATED)
->setCompressionLevelEntry('file4', ZipFile::LEVEL_DEFAULT_COMPRESSION)
->saveAsFile($this->outputFilename)
->close()
;
@@ -2003,22 +2003,22 @@ class ZipFileTest extends ZipTestCase
static::assertSame(
$zipFile->getEntryInfo('file')
->getCompressionLevel(),
ZipFileInterface::LEVEL_BEST_COMPRESSION
ZipFile::LEVEL_BEST_COMPRESSION
);
static::assertSame(
$zipFile->getEntryInfo('file2')
->getCompressionLevel(),
ZipFileInterface::LEVEL_FAST
ZipFile::LEVEL_FAST
);
static::assertSame(
$zipFile->getEntryInfo('file3')
->getCompressionLevel(),
ZipFileInterface::LEVEL_SUPER_FAST
ZipFile::LEVEL_SUPER_FAST
);
static::assertSame(
$zipFile->getEntryInfo('file4')
->getCompressionLevel(),
ZipFileInterface::LEVEL_DEFAULT_COMPRESSION
ZipFile::LEVEL_DEFAULT_COMPRESSION
);
$zipFile->close();
}
@@ -2054,10 +2054,10 @@ class ZipFileTest extends ZipTestCase
{
$zipFile = new ZipFile();
for ($i = 0; $i < 10; $i++) {
$zipFile->addFromString('file' . $i, 'content', ZipFileInterface::METHOD_DEFLATED);
$zipFile->addFromString('file' . $i, 'content', ZipFile::METHOD_DEFLATED);
}
$zipFile
->setCompressionLevel(ZipFileInterface::LEVEL_BEST_SPEED)
->setCompressionLevel(ZipFile::LEVEL_BEST_SPEED)
->saveAsFile($this->outputFilename)
->close()
;
@@ -2069,7 +2069,7 @@ class ZipFileTest extends ZipTestCase
array_walk(
$infoList,
function (ZipInfo $zipInfo) {
$this->assertSame($zipInfo->getCompressionLevel(), ZipFileInterface::LEVEL_BEST_SPEED);
$this->assertSame($zipInfo->getCompressionLevel(), ZipFile::LEVEL_BEST_SPEED);
}
);
$zipFile->close();
@@ -2082,13 +2082,13 @@ class ZipFileTest extends ZipTestCase
public function testCompressionMethodEntry()
{
$zipFile = new ZipFile();
$zipFile->addFromString('file', 'content', ZipFileInterface::METHOD_STORED);
$zipFile->addFromString('file', 'content', ZipFile::METHOD_STORED);
$zipFile->saveAsFile($this->outputFilename);
$zipFile->close();
$zipFile->openFile($this->outputFilename);
static::assertSame($zipFile->getEntryInfo('file')->getMethodName(), 'No compression');
$zipFile->setCompressionMethodEntry('file', ZipFileInterface::METHOD_DEFLATED);
$zipFile->setCompressionMethodEntry('file', ZipFile::METHOD_DEFLATED);
static::assertSame($zipFile->getEntryInfo('file')->getMethodName(), 'Deflate');
$zipFile->rewrite();
@@ -2103,7 +2103,7 @@ class ZipFileTest extends ZipTestCase
$this->setExpectedException(ZipUnsupportMethodException::class, 'Unsupported method');
$zipFile = new ZipFile();
$zipFile->addFromString('file', 'content', ZipFileInterface::METHOD_STORED);
$zipFile->addFromString('file', 'content', ZipFile::METHOD_STORED);
$zipFile->setCompressionMethodEntry('file', 99);
}

View File

@@ -38,8 +38,16 @@ class ZipMatcherTest extends TestCase
$matcher->match('~^[2][1-5]|[3][6-9]|40$~s');
static::assertCount(10, $matcher);
$actualMatches = [
'21', '22', '23', '24', '25',
'36', '37', '38', '39', '40',
'21',
'22',
'23',
'24',
'25',
'36',
'37',
'38',
'39',
'40',
];
static::assertSame($matcher->getMatches(), $actualMatches);
$matcher->setPassword('qwerty');

View File

@@ -22,11 +22,15 @@ class ZipPasswordTest extends ZipFileAddDirTest
* Test archive password.
*
* @throws ZipException
* @noinspection PhpRedundantCatchClauseInspection
*/
public function testSetPassword()
{
if (\PHP_INT_SIZE === 4) { // php 32 bit
$this->setExpectedException(RuntimeException::class, 'Traditional PKWARE Encryption is not supported in 32-bit PHP.');
$this->setExpectedException(
RuntimeException::class,
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
);
}
$password = base64_encode(CryptoUtil::randomBytes(100));
@@ -35,7 +39,7 @@ class ZipPasswordTest extends ZipFileAddDirTest
// create encryption password with ZipCrypto
$zipFile = new ZipFile();
$zipFile->addDir(__DIR__);
$zipFile->setPassword($password, ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
$zipFile->setPassword($password, ZipFile::ENCRYPTION_METHOD_TRADITIONAL);
$zipFile->saveAsFile($this->outputFilename);
$zipFile->close();
@@ -66,7 +70,7 @@ class ZipPasswordTest extends ZipFileAddDirTest
}
// change encryption method to WinZip Aes and update file
$zipFile->setPassword($password, ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES);
$zipFile->setPassword($password, ZipFile::ENCRYPTION_METHOD_WINZIP_AES);
$zipFile->saveAsFile($this->outputFilename);
$zipFile->close();
@@ -121,14 +125,17 @@ class ZipPasswordTest extends ZipFileAddDirTest
public function testTraditionalEncryption()
{
if (\PHP_INT_SIZE === 4) { // php 32 bit
$this->setExpectedException(RuntimeException::class, 'Traditional PKWARE Encryption is not supported in 32-bit PHP.');
$this->setExpectedException(
RuntimeException::class,
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
);
}
$password = base64_encode(CryptoUtil::randomBytes(50));
$zip = new ZipFile();
$zip->addDirRecursive($this->outputDirname);
$zip->setPassword($password, ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
$zip->setPassword($password, ZipFile::ENCRYPTION_METHOD_TRADITIONAL);
$zip->saveAsFile($this->outputFilename);
$zip->close();
@@ -187,10 +194,10 @@ class ZipPasswordTest extends ZipFileAddDirTest
public function winZipKeyStrengthProvider()
{
return [
[ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128, 128],
[ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192, 192],
[ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES, 256],
[ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256, 256],
[ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128, 128],
[ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192, 192],
[ZipFile::ENCRYPTION_METHOD_WINZIP_AES, 256],
[ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256, 256],
];
}
@@ -201,7 +208,10 @@ class ZipPasswordTest extends ZipFileAddDirTest
public function testEncryptionEntries()
{
if (\PHP_INT_SIZE === 4) { // php 32 bit
$this->setExpectedException(RuntimeException::class, 'Traditional PKWARE Encryption is not supported in 32-bit PHP.');
$this->setExpectedException(
RuntimeException::class,
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
);
}
$password1 = '353442434235424234';
@@ -209,8 +219,8 @@ class ZipPasswordTest extends ZipFileAddDirTest
$zip = new ZipFile();
$zip->addDir($this->outputDirname);
$zip->setPasswordEntry('.hidden', $password1, ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
$zip->setPasswordEntry('text file.txt', $password2, ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES);
$zip->setPasswordEntry('.hidden', $password1, ZipFile::ENCRYPTION_METHOD_TRADITIONAL);
$zip->setPasswordEntry('text file.txt', $password2, ZipFile::ENCRYPTION_METHOD_WINZIP_AES);
$zip->saveAsFile($this->outputFilename);
$zip->close();
@@ -248,7 +258,10 @@ class ZipPasswordTest extends ZipFileAddDirTest
public function testEncryptionEntriesWithDefaultPassword()
{
if (\PHP_INT_SIZE === 4) { // php 32 bit
$this->setExpectedException(RuntimeException::class, 'Traditional PKWARE Encryption is not supported in 32-bit PHP.');
$this->setExpectedException(
RuntimeException::class,
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
);
}
$password1 = '353442434235424234';
@@ -258,8 +271,8 @@ class ZipPasswordTest extends ZipFileAddDirTest
$zip = new ZipFile();
$zip->addDir($this->outputDirname);
$zip->setPassword($defaultPassword);
$zip->setPasswordEntry('.hidden', $password1, ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
$zip->setPasswordEntry('text file.txt', $password2, ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES);
$zip->setPasswordEntry('.hidden', $password1, ZipFile::ENCRYPTION_METHOD_TRADITIONAL);
$zip->setPasswordEntry('text file.txt', $password2, ZipFile::ENCRYPTION_METHOD_WINZIP_AES);
$zip->saveAsFile($this->outputFilename);
$zip->close();
@@ -350,7 +363,7 @@ class ZipPasswordTest extends ZipFileAddDirTest
$this->setExpectedException(ZipException::class, 'Invalid encryption method');
$zipFile = new ZipFile();
$zipFile->addFromString('file', 'content', ZipFileInterface::METHOD_STORED);
$zipFile->addFromString('file', 'content', ZipFile::METHOD_STORED);
$zipFile->setPasswordEntry('file', 'pass', 99);
}

View File

@@ -129,7 +129,7 @@ abstract class ZipTestCase extends TestCase
static::assertContains('Empty zipfile', $output);
}
$actualEmptyZipData = pack('VVVVVv', EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG, 0, 0, 0, 0, 0);
$actualEmptyZipData = pack('VVVVVv', EndOfCentralDirectory::END_OF_CD_SIG, 0, 0, 0, 0, 0);
static::assertStringEqualsFile($filename, $actualEmptyZipData);
}