1
0
mirror of https://github.com/Ne-Lexa/php-zip.git synced 2025-10-25 12:06:12 +02:00

minor fixes, ZipEntry tests

This commit is contained in:
wapplay
2020-01-06 11:53:17 +03:00
parent 70bb598fa6
commit a16b0e7c15
21 changed files with 1906 additions and 141 deletions

View File

@@ -31,9 +31,9 @@ use PhpZip\Util\StringUtil;
/**
* ZIP file entry.
*
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
* @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
*
* @author Ne-Lexa alexey@nelexa.ru
* @author Ne-Lexa alexey@nelexa.ru
* @license MIT
*/
class ZipEntry
@@ -152,11 +152,12 @@ class ZipEntry
/**
* ZipEntry constructor.
*
* @param string $name Entry name
* @param string $name Entry name
* @param string|null $charset DOS charset
*/
public function __construct($name)
public function __construct($name, $charset = null)
{
$this->setName($name);
$this->setName($name, $charset);
$this->cdExtraFields = new ExtraFieldsCollection();
$this->localExtraFields = new ExtraFieldsCollection();
@@ -185,6 +186,7 @@ class ZipEntry
* @return ZipEntry
*
* @internal
*
* @noinspection PhpTooManyParametersInspection
*/
public static function create(
@@ -229,11 +231,12 @@ class ZipEntry
/**
* Set entry name.
*
* @param string $name New entry name
* @param string $name New entry name
* @param string|null $charset
*
* @return ZipEntry
*/
private function setName($name)
private function setName($name, $charset = null)
{
if ($name === null) {
throw new InvalidArgumentException('zip entry name is null');
@@ -252,13 +255,24 @@ class ZipEntry
throw new InvalidArgumentException('Illegal zip entry name parameter');
}
if (!StringUtil::isASCII($name)) {
$this->setCharset($charset);
if ($this->charset === null && !StringUtil::isASCII($name)) {
$this->enableUtf8Name(true);
}
$this->name = $name;
$this->isDirectory = ($length = \strlen($name)) >= 1 && $name[$length - 1] === '/';
$this->externalAttributes = $this->isDirectory ? DosAttrs::DOS_DIRECTORY : DosAttrs::DOS_ARCHIVE;
if ($this->extractVersion !== self::UNKNOWN) {
$this->extractVersion = max(
$this->extractVersion,
$this->isDirectory ?
ZipVersion::v20_DEFLATED_FOLDER_ZIPCRYPTO :
ZipVersion::v10_DEFAULT_MIN
);
}
return $this;
}
@@ -291,6 +305,8 @@ class ZipEntry
* @param string $newName New entry name
*
* @return ZipEntry new {@see ZipEntry} object with new name
*
* @internal
*/
public function rename($newName)
{
@@ -314,6 +330,8 @@ class ZipEntry
/**
* @return ZipData|null
*
* @internal
*/
public function getData()
{
@@ -322,6 +340,8 @@ class ZipEntry
/**
* @param ZipData|null $data
*
* @internal
*/
public function setData($data)
{
@@ -458,7 +478,7 @@ class ZipEntry
return ZipVersion::v51_ENCR_AES_RC2_CORRECT;
}
if ($this->getCompressionMethod() === ZipCompressionMethod::BZIP2) {
if ($this->compressionMethod === ZipCompressionMethod::BZIP2) {
return ZipVersion::v46_BZIP2;
}
@@ -466,9 +486,15 @@ class ZipEntry
return ZipVersion::v45_ZIP64_EXT;
}
return $this->getCompressionMethod() === ZipCompressionMethod::DEFLATED || $this->isDirectory() ?
ZipVersion::v20_DEFLATED_FOLDER_ZIPCRYPTO :
ZipVersion::v10_DEFAULT_MIN;
if (
$this->compressionMethod === ZipCompressionMethod::DEFLATED ||
$this->isDirectory ||
$this->encryptionMethod === ZipEncryptionMethod::PKWARE
) {
return ZipVersion::v20_DEFLATED_FOLDER_ZIPCRYPTO;
}
return ZipVersion::v10_DEFAULT_MIN;
}
return $this->extractVersion;
@@ -520,9 +546,16 @@ class ZipEntry
* @param int $compressedSize the Compressed Size
*
* @return ZipEntry
*
* @internal
*/
public function setCompressedSize($compressedSize)
{
$compressedSize = (int) $compressedSize;
if ($compressedSize < self::UNKNOWN) {
throw new InvalidArgumentException('Compressed size < ' . self::UNKNOWN);
}
$this->compressedSize = $compressedSize;
return $this;
@@ -550,6 +583,8 @@ class ZipEntry
* @return ZipEntry
*
* @deprecated Use {@see ZipEntry::setUncompressedSize()}
*
* @internal
*/
public function setSize($size)
{
@@ -574,9 +609,16 @@ class ZipEntry
* @param int $uncompressedSize the (Uncompressed) Size
*
* @return ZipEntry
*
* @internal
*/
public function setUncompressedSize($uncompressedSize)
{
$uncompressedSize = (int) $uncompressedSize;
if ($uncompressedSize < self::UNKNOWN) {
throw new InvalidArgumentException('Uncompressed size < ' . self::UNKNOWN);
}
$this->uncompressedSize = $uncompressedSize;
return $this;
@@ -596,10 +638,17 @@ class ZipEntry
* @param int $localHeaderOffset
*
* @return ZipEntry
*
* @internal
*/
public function setLocalHeaderOffset($localHeaderOffset)
{
$this->localHeaderOffset = (int) $localHeaderOffset;
$localHeaderOffset = (int) $localHeaderOffset;
if ($localHeaderOffset < 0) {
throw new InvalidArgumentException('Negative $localHeaderOffset');
}
$this->localHeaderOffset = $localHeaderOffset;
return $this;
}
@@ -627,6 +676,8 @@ class ZipEntry
* @return ZipEntry
*
* @deprecated Use {@see ZipEntry::setLocalHeaderOffset()}
*
* @internal
*/
public function setOffset($offset)
{
@@ -645,24 +696,26 @@ class ZipEntry
*/
public function getGeneralPurposeBitFlags()
{
return $this->generalPurposeBitFlags & 0xffff;
return $this->generalPurposeBitFlags;
}
/**
* Sets the General Purpose Bit Flags.
*
* @param mixed $general
* @param int $gpbf general purpose bit flags
*
* @return ZipEntry
*
* @var int general
* @internal
*/
public function setGeneralPurposeBitFlags($general)
public function setGeneralPurposeBitFlags($gpbf)
{
if ($general < 0x0000 || $general > 0xffff) {
throw new InvalidArgumentException('general out of range');
$gpbf = (int) $gpbf;
if ($gpbf < 0x0000 || $gpbf > 0xffff) {
throw new InvalidArgumentException('general purpose bit flags out of range');
}
$this->generalPurposeBitFlags = $general;
$this->generalPurposeBitFlags = $gpbf;
$this->updateCompressionLevel();
return $this;
@@ -710,7 +763,7 @@ class ZipEntry
*/
private function isSetGeneralBitFlag($mask)
{
return ($this->generalPurposeBitFlags & $mask) !== 0;
return ($this->generalPurposeBitFlags & $mask) === $mask;
}
/**
@@ -775,7 +828,9 @@ class ZipEntry
{
$this->setEncrypted(false);
$this->removeExtraField(WinZipAesExtraField::HEADER_ID);
$this->encryptionMethod = ZipEncryptionMethod::NONE;
$this->password = null;
$this->extractVersion = self::UNKNOWN;
return $this;
}
@@ -858,7 +913,9 @@ class ZipEntry
*/
public function setCompressionMethod($compressionMethod)
{
if (($compressionMethod < 0x0000 || $compressionMethod > 0xffff) && $compressionMethod !== self::UNKNOWN) {
$compressionMethod = (int) $compressionMethod;
if ($compressionMethod < 0x0000 || $compressionMethod > 0xffff) {
throw new InvalidArgumentException('method out of range: ' . $compressionMethod);
}
@@ -866,6 +923,7 @@ class ZipEntry
$this->compressionMethod = $compressionMethod;
$this->updateCompressionLevel();
$this->extractVersion = self::UNKNOWN;
return $this;
}
@@ -881,7 +939,7 @@ class ZipEntry
return self::UNKNOWN;
}
return DateTimeConverter::toUnixTimestamp($this->getDosTime());
return DateTimeConverter::msDosToUnix($this->getDosTime());
}
/**
@@ -922,10 +980,8 @@ class ZipEntry
*/
public function setTime($unixTimestamp)
{
$known = $unixTimestamp !== self::UNKNOWN;
if ($known) {
$this->dosTime = DateTimeConverter::toDosTime($unixTimestamp);
if ($unixTimestamp !== self::UNKNOWN) {
$this->setDosTime(DateTimeConverter::unixToMsDos($unixTimestamp));
} else {
$this->dosTime = 0;
}
@@ -954,6 +1010,11 @@ class ZipEntry
{
$this->externalAttributes = (int) $externalAttributes;
if ($externalAttributes < 0x00000000 || $externalAttributes > 0xffffffff) {
throw new InvalidArgumentException('external attributes out of range: ' . $externalAttributes);
}
$this->externalAttributes = $externalAttributes;
return $this;
}
@@ -970,13 +1031,18 @@ class ZipEntry
/**
* Sets the internal file attributes.
*
* @param int $attributes the internal file attributes
* @param int $internalAttributes the internal file attributes
*
* @return ZipEntry
*/
public function setInternalAttributes($attributes)
public function setInternalAttributes($internalAttributes)
{
$this->internalAttributes = (int) $attributes;
$internalAttributes = (int) $internalAttributes;
if ($internalAttributes < 0x0000 || $internalAttributes > 0xffff) {
throw new InvalidArgumentException('internal attributes out of range');
}
$this->internalAttributes = $internalAttributes;
return $this;
}
@@ -1094,6 +1160,31 @@ class ZipEntry
$this->localExtraFields->remove($headerId);
}
/**
* @param ZipExtraField $zipExtraField
*/
public function addExtraField(ZipExtraField $zipExtraField)
{
$this->addLocalExtraField($zipExtraField);
$this->addCdExtraField($zipExtraField);
}
/**
* @param ZipExtraField $zipExtraField
*/
public function addLocalExtraField(ZipExtraField $zipExtraField)
{
$this->localExtraFields->add($zipExtraField);
}
/**
* @param ZipExtraField $zipExtraField
*/
public function addCdExtraField(ZipExtraField $zipExtraField)
{
$this->cdExtraFields->add($zipExtraField);
}
/**
* Returns comment entry.
*
@@ -1116,11 +1207,11 @@ class ZipEntry
if ($comment !== null) {
$commentLength = \strlen($comment);
if ($commentLength < 0x0000 || $commentLength > 0xffff) {
if ($commentLength > 0xffff) {
throw new InvalidArgumentException('Comment too long');
}
if (!StringUtil::isASCII($comment)) {
if ($this->charset === null && !StringUtil::isASCII($comment)) {
$this->enableUtf8Name(true);
}
}
@@ -1153,6 +1244,8 @@ class ZipEntry
* @param int $crc
*
* @return ZipEntry
*
* @internal
*/
public function setCrc($crc)
{
@@ -1180,15 +1273,19 @@ class ZipEntry
public function setPassword($password, $encryptionMethod = null)
{
if (!$this->isDirectory) {
if ($encryptionMethod !== null) {
$this->setEncryptionMethod($encryptionMethod);
}
if ($password === null || $password === '') {
$this->password = null;
$this->disableEncryption();
} else {
$this->password = (string) $password;
if ($encryptionMethod === null && $this->encryptionMethod === ZipEncryptionMethod::NONE) {
$encryptionMethod = ZipEncryptionMethod::WINZIP_AES_256;
}
if ($encryptionMethod !== null) {
$this->setEncryptionMethod($encryptionMethod);
}
$this->setEncrypted(true);
}
}
@@ -1228,6 +1325,7 @@ class ZipEntry
$this->encryptionMethod = $encryptionMethod;
$this->setEncrypted($this->encryptionMethod !== ZipEncryptionMethod::NONE);
$this->extractVersion = self::UNKNOWN;
return $this;
}
@@ -1329,18 +1427,21 @@ class ZipEntry
*/
public function getUnixMode()
{
/** @var AsiExtraField|null $asiExtraField */
$asiExtraField = $this->getExtraField(AsiExtraField::HEADER_ID);
if ($asiExtraField !== null) {
return $asiExtraField->getMode();
}
$mode = 0;
if ($this->createdOS === ZipPlatform::OS_UNIX) {
return ($this->externalAttributes >> 16) & 0xFFFF;
$mode = ($this->externalAttributes >> 16) & 0xFFFF;
} elseif ($this->hasExtraField(AsiExtraField::HEADER_ID)) {
/** @var AsiExtraField $asiExtraField */
$asiExtraField = $this->getExtraField(AsiExtraField::HEADER_ID);
$mode = $asiExtraField->getMode();
}
return $this->isDirectory ? 040755 : 0100664;
if ($mode > 0) {
return $mode;
}
return $this->isDirectory ? 040755 : 0100644;
}
/**
@@ -1351,8 +1452,8 @@ class ZipEntry
*/
public function isZip64ExtensionsRequired()
{
return $this->compressedSize >= ZipConstants::ZIP64_MAGIC
|| $this->uncompressedSize >= ZipConstants::ZIP64_MAGIC;
return $this->compressedSize > ZipConstants::ZIP64_MAGIC
|| $this->uncompressedSize > ZipConstants::ZIP64_MAGIC;
}
/**