1
0
mirror of https://github.com/Ne-Lexa/php-zip.git synced 2025-08-16 12:14:37 +02:00

5 Commits
3.0.0 ... 3.0.2

Author SHA1 Message Date
wapplay-home-linux
810b7ca741 Merge branch 'hotfix/3.0.2' 2017-10-30 23:32:11 +03:00
wapplay-home-linux
115dfd3b52 some bugs fixed for php 32-bit 2017-10-30 23:31:39 +03:00
Ne-Lexa
183274d6da remove build on hhvm 2017-06-19 00:44:00 +03:00
Ne-Lexa
f99c0278fd Merge branch 'hotfix/3.0.1' 2017-03-15 19:03:17 +03:00
Ne-Lexa
1b065c4cca fix incorrect time in archive 2017-03-15 19:03:04 +03:00
10 changed files with 103 additions and 55 deletions

View File

@@ -4,7 +4,6 @@ php:
- '5.6' - '5.6'
- '7.0' - '7.0'
- '7.1' - '7.1'
- hhvm
- nightly - nightly
# cache vendor dirs # cache vendor dirs

View File

@@ -24,7 +24,7 @@
], ],
"minimum-stability": "stable", "minimum-stability": "stable",
"require": { "require": {
"php-64bit": "^5.5 || ^7.0" "php": "^5.5 || ^7.0"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

View File

@@ -155,12 +155,12 @@ class TraditionalPkwareEncryptionEngine implements CryptoEngine
if ($this->entry->getGeneralPurposeBitFlag(ZipEntry::GPBF_DATA_DESCRIPTOR)) { if ($this->entry->getGeneralPurposeBitFlag(ZipEntry::GPBF_DATA_DESCRIPTOR)) {
// compare against the file type from extended local headers // compare against the file type from extended local headers
$checkByte = ($this->entry->getTime() >> 8) & 0xff; $checkByte = ($this->entry->getDosTime() >> 8) & 0xff;
} else { } else {
// compare against the CRC otherwise // compare against the CRC otherwise
$checkByte = ($this->entry->getCrc() >> 24) & 0xff; $checkByte = ($this->entry->getCrc() >> 24) & 0xff;
} }
if ($headerBytes[11] !== $checkByte) { if ($byte !== $checkByte) {
throw new ZipAuthenticationException("Bad password for entry " . $this->entry->getName()); throw new ZipAuthenticationException("Bad password for entry " . $this->entry->getName());
} }
@@ -192,9 +192,9 @@ class TraditionalPkwareEncryptionEngine implements CryptoEngine
*/ */
public function encrypt($data) public function encrypt($data)
{ {
$crc = ($this->entry->isDataDescriptorRequired() ? $crc = $this->entry->isDataDescriptorRequired() ?
($this->entry->getTime() & 0x0000ffff) << 16 : ($this->entry->getDosTime() & 0x0000ffff) << 16 :
$this->entry->getCrc()); $this->entry->getCrc();
$headerBytes = CryptoUtil::randomBytes(self::STD_DEC_HDR_SIZE); $headerBytes = CryptoUtil::randomBytes(self::STD_DEC_HDR_SIZE);
// Initialize again since the generated bytes were encrypted. // Initialize again since the generated bytes were encrypted.

View File

@@ -166,6 +166,18 @@ class CentralDirectory
return $this->entries[$entryName]; return $this->entries[$entryName];
} }
/**
* @param string $entryName
* @return ZipEntry
* @throws ZipNotFoundEntry
*/
public function getModifiedEntry($entryName){
if (!isset($this->modifiedEntries[$entryName])) {
throw new ZipNotFoundEntry('Zip modified entry ' . $entryName . ' not found');
}
return $this->modifiedEntries[$entryName];
}
/** /**
* @return EndOfCentralDirectory * @return EndOfCentralDirectory
*/ */
@@ -420,7 +432,7 @@ class CentralDirectory
// compression method 2 bytes // compression method 2 bytes
$entry->getMethod(), $entry->getMethod(),
// last mod file datetime 4 bytes // last mod file datetime 4 bytes
$entry->getTime(), $entry->getDosTime(),
// crc-32 4 bytes // crc-32 4 bytes
$entry->getCrc(), $entry->getCrc(),
// compressed size 4 bytes // compressed size 4 bytes

View File

@@ -1,4 +1,5 @@
<?php <?php
namespace PhpZip\Model\Entry; namespace PhpZip\Model\Entry;
use PhpZip\Exception\InvalidArgumentException; use PhpZip\Exception\InvalidArgumentException;
@@ -257,6 +258,7 @@ abstract class ZipAbstractEntry implements ZipEntry
public function setCompressedSize($compressedSize) public function setCompressedSize($compressedSize)
{ {
if (self::UNKNOWN != $compressedSize) { if (self::UNKNOWN != $compressedSize) {
$compressedSize = sprintf('%u', $compressedSize);
if (0 > $compressedSize || $compressedSize > 0x7fffffffffffffff) { if (0 > $compressedSize || $compressedSize > 0x7fffffffffffffff) {
throw new ZipException("Compressed size out of range - " . $this->name); throw new ZipException("Compressed size out of range - " . $this->name);
} }
@@ -285,6 +287,7 @@ abstract class ZipAbstractEntry implements ZipEntry
public function setSize($size) public function setSize($size)
{ {
if (self::UNKNOWN != $size) { if (self::UNKNOWN != $size) {
$size = sprintf('%u', $size);
if (0 > $size || $size > 0x7fffffffffffffff) { if (0 > $size || $size > 0x7fffffffffffffff) {
throw new ZipException("Uncompressed Size out of range - " . $this->name); throw new ZipException("Uncompressed Size out of range - " . $this->name);
} }
@@ -310,6 +313,7 @@ abstract class ZipAbstractEntry implements ZipEntry
*/ */
public function setOffset($offset) public function setOffset($offset)
{ {
$offset = sprintf('%u', $offset);
if (0 > $offset || $offset > 0x7fffffffffffffff) { if (0 > $offset || $offset > 0x7fffffffffffffff) {
throw new ZipException("Offset out of range - " . $this->name); throw new ZipException("Offset out of range - " . $this->name);
} }
@@ -485,7 +489,7 @@ abstract class ZipAbstractEntry implements ZipEntry
if (!$this->isInit(self::BIT_DATE_TIME)) { if (!$this->isInit(self::BIT_DATE_TIME)) {
return self::UNKNOWN; return self::UNKNOWN;
} }
return DateTimeConverter::toUnixTimestamp($this->dosTime & 0xffffffff); return DateTimeConverter::toUnixTimestamp($this->getDosTime());
} }
/** /**
@@ -506,6 +510,31 @@ abstract class ZipAbstractEntry implements ZipEntry
return $this; return $this;
} }
/**
* Get Dos Time
*
* @return int
*/
public function getDosTime()
{
return $this->dosTime & 0xffffffff;
}
/**
* Set Dos Time
* @param int $dosTime
* @throws ZipException
*/
public function setDosTime($dosTime)
{
$dosTime = sprintf('%u', $dosTime);
if (0x00000000 > $dosTime || $dosTime > 0xffffffff) {
throw new ZipException('DosTime out of range');
}
$this->dosTime = $dosTime;
$this->setInit(self::BIT_DATE_TIME, true);
}
/** /**
* Returns the external file attributes. * Returns the external file attributes.
* *
@@ -530,6 +559,7 @@ abstract class ZipAbstractEntry implements ZipEntry
{ {
$known = self::UNKNOWN != $externalAttributes; $known = self::UNKNOWN != $externalAttributes;
if ($known) { if ($known) {
$externalAttributes = sprintf('%u', $externalAttributes);
if (0x00000000 > $externalAttributes || $externalAttributes > 0xffffffff) { if (0x00000000 > $externalAttributes || $externalAttributes > 0xffffffff) {
throw new ZipException("external file attributes out of range - " . $this->name); throw new ZipException("external file attributes out of range - " . $this->name);
} }
@@ -823,6 +853,7 @@ abstract class ZipAbstractEntry implements ZipEntry
*/ */
public function setCrc($crc) public function setCrc($crc)
{ {
$crc = sprintf('%u', $crc);
if (0x00000000 > $crc || $crc > 0xffffffff) { if (0x00000000 > $crc || $crc > 0xffffffff) {
throw new ZipException("CRC-32 out of range - " . $this->name); throw new ZipException("CRC-32 out of range - " . $this->name);
} }

View File

@@ -218,7 +218,7 @@ abstract class ZipNewEntry extends ZipAbstractEntry
$this->getMethod(), $this->getMethod(),
// last mod file time 2 bytes // last mod file time 2 bytes
// last mod file date 2 bytes // last mod file date 2 bytes
$this->getTime(), $this->getDosTime(),
// crc-32 4 bytes // crc-32 4 bytes
$dd ? 0 : $this->getCrc(), $dd ? 0 : $this->getCrc(),
// compressed size 4 bytes // compressed size 4 bytes
@@ -258,7 +258,7 @@ abstract class ZipNewEntry extends ZipAbstractEntry
} else { } else {
fwrite($outputStream, pack('VV', $this->getCompressedSize(), $this->getSize())); fwrite($outputStream, pack('VV', $this->getCompressedSize(), $this->getSize()));
} }
} elseif ($this->getCompressedSize() !== $compressedSize) { } elseif ($this->getCompressedSize() != $compressedSize) {
throw new ZipException($this->getName() throw new ZipException($this->getName()
. " (expected compressed entry size of " . " (expected compressed entry size of "
. $this->getCompressedSize() . " bytes, but is actually " . $compressedSize . " bytes)"); . $this->getCompressedSize() . " bytes, but is actually " . $compressedSize . " bytes)");

View File

@@ -96,7 +96,7 @@ class ZipReadEntry extends ZipAbstractEntry
$this->setPlatform($data['versionMadeBy'] >> 8); $this->setPlatform($data['versionMadeBy'] >> 8);
$this->setGeneralPurposeBitFlags($data['gpbf']); $this->setGeneralPurposeBitFlags($data['gpbf']);
$this->setMethod($data['rawMethod']); $this->setMethod($data['rawMethod']);
$this->setTime($data['rawTime']); $this->setDosTime($data['rawTime']);
$this->setCrc($data['rawCrc']); $this->setCrc($data['rawCrc']);
$this->setCompressedSize($data['rawCompressedSize']); $this->setCompressedSize($data['rawCompressedSize']);
$this->setSize($data['rawSize']); $this->setSize($data['rawSize']);
@@ -282,7 +282,7 @@ class ZipReadEntry extends ZipAbstractEntry
$this->getMethod(), $this->getMethod(),
// last mod file time 2 bytes // last mod file time 2 bytes
// last mod file date 2 bytes // last mod file date 2 bytes
$this->getTime(), $this->getDosTime(),
// crc-32 4 bytes // crc-32 4 bytes
$dd ? 0 : $this->getCrc(), $dd ? 0 : $this->getCrc(),
// compressed size 4 bytes // compressed size 4 bytes

View File

@@ -281,6 +281,20 @@ interface ZipEntry
*/ */
public function setTime($unixTimestamp); public function setTime($unixTimestamp);
/**
* Get Dos Time
*
* @return int
*/
public function getDosTime();
/**
* Set Dos Time
* @param int $dosTime
* @throws ZipException
*/
public function setDosTime($dosTime);
/** /**
* Returns the external file attributes. * Returns the external file attributes.
* *

View File

@@ -461,6 +461,9 @@ class ZipFile implements \Countable, \ArrayAccess, \Iterator
$localName = basename($filename); $localName = basename($filename);
} }
$this->addFromStream($handle, $localName, $compressionMethod); $this->addFromStream($handle, $localName, $compressionMethod);
$this->centralDirectory
->getModifiedEntry($localName)
->setTime(filemtime($filename));
return $this; return $this;
} }

View File

@@ -447,7 +447,8 @@ class ZipFileTest extends ZipTestCase
$zipFile->close(); $zipFile->close();
} }
public function testDeleteNewEntry(){ public function testDeleteNewEntry()
{
$zipFile = new ZipFile(); $zipFile = new ZipFile();
$zipFile['entry1'] = ''; $zipFile['entry1'] = '';
$zipFile['entry2'] = ''; $zipFile['entry2'] = '';
@@ -466,7 +467,8 @@ class ZipFileTest extends ZipTestCase
* @expectedException \PhpZip\Exception\ZipNotFoundEntry * @expectedException \PhpZip\Exception\ZipNotFoundEntry
* @expectedExceptionMessage Not found entry entry * @expectedExceptionMessage Not found entry entry
*/ */
public function testDeleteFromNameNotFoundEntry(){ public function testDeleteFromNameNotFoundEntry()
{
$zipFile = new ZipFile(); $zipFile = new ZipFile();
$zipFile->deleteFromName('entry'); $zipFile->deleteFromName('entry');
} }
@@ -790,17 +792,19 @@ class ZipFileTest extends ZipTestCase
* @expectedException \PhpZip\Exception\InvalidArgumentException * @expectedException \PhpZip\Exception\InvalidArgumentException
* @expectedExceptionMessage Invalid compression level. Minimum level -1. Maximum level 9 * @expectedExceptionMessage Invalid compression level. Minimum level -1. Maximum level 9
*/ */
public function testSetInvalidCompressionLevel(){ public function testSetInvalidCompressionLevel()
{
$zipFile = new ZipFile(); $zipFile = new ZipFile();
$zipFile->setCompressionLevel(-2); $zipFile->setCompressionLevel(-2);
} }
/** /**
/** * /**
* @expectedException \PhpZip\Exception\InvalidArgumentException * @expectedException \PhpZip\Exception\InvalidArgumentException
* @expectedExceptionMessage Invalid compression level. Minimum level -1. Maximum level 9 * @expectedExceptionMessage Invalid compression level. Minimum level -1. Maximum level 9
*/ */
public function testSetInvalidCompressionLevel2(){ public function testSetInvalidCompressionLevel2()
{
$zipFile = new ZipFile(); $zipFile = new ZipFile();
$zipFile->setCompressionLevel(10); $zipFile->setCompressionLevel(10);
} }
@@ -817,11 +821,6 @@ class ZipFileTest extends ZipTestCase
'test empty/dir' => null, 'test empty/dir' => null,
]; ];
$extractPath = sys_get_temp_dir() . '/zipExtract' . uniqid();
if (!is_dir($extractPath)) {
mkdir($extractPath, 0755, true);
}
$zipFile = new ZipFile(); $zipFile = new ZipFile();
foreach ($entries as $entryName => $value) { foreach ($entries as $entryName => $value) {
if ($value === null) { if ($value === null) {
@@ -833,10 +832,12 @@ class ZipFileTest extends ZipTestCase
$zipFile->saveAsFile($this->outputFilename); $zipFile->saveAsFile($this->outputFilename);
$zipFile->close(); $zipFile->close();
self::assertTrue(mkdir($this->outputDirname, 0755, true));
$zipFile->openFile($this->outputFilename); $zipFile->openFile($this->outputFilename);
$zipFile->extractTo($extractPath); $zipFile->extractTo($this->outputDirname);
foreach ($entries as $entryName => $value) { foreach ($entries as $entryName => $value) {
$fullExtractedFilename = $extractPath . DIRECTORY_SEPARATOR . $entryName; $fullExtractedFilename = $this->outputDirname . DIRECTORY_SEPARATOR . $entryName;
if ($value === null) { if ($value === null) {
self::assertTrue(is_dir($fullExtractedFilename)); self::assertTrue(is_dir($fullExtractedFilename));
self::assertTrue(FilesUtil::isEmptyDir($fullExtractedFilename)); self::assertTrue(FilesUtil::isEmptyDir($fullExtractedFilename));
@@ -847,8 +848,6 @@ class ZipFileTest extends ZipTestCase
} }
} }
$zipFile->close(); $zipFile->close();
FilesUtil::removeDir($extractPath);
} }
/** /**
@@ -876,11 +875,7 @@ class ZipFileTest extends ZipTestCase
'test empty/dir2/' 'test empty/dir2/'
]; ];
$extractPath = sys_get_temp_dir() . '/zipExtractTest'; self::assertTrue(mkdir($this->outputDirname, 0755, true));
if (is_dir($extractPath)) {
FilesUtil::removeDir($extractPath);
}
self::assertTrue(mkdir($extractPath, 0755, true));
$zipFile = new ZipFile(); $zipFile = new ZipFile();
$zipFile->addAll($entries); $zipFile->addAll($entries);
@@ -888,10 +883,10 @@ class ZipFileTest extends ZipTestCase
$zipFile->close(); $zipFile->close();
$zipFile->openFile($this->outputFilename); $zipFile->openFile($this->outputFilename);
$zipFile->extractTo($extractPath, $extractEntries); $zipFile->extractTo($this->outputDirname, $extractEntries);
foreach ($entries as $entryName => $value) { foreach ($entries as $entryName => $value) {
$fullExtractFilename = $extractPath . DIRECTORY_SEPARATOR . $entryName; $fullExtractFilename = $this->outputDirname . DIRECTORY_SEPARATOR . $entryName;
if (in_array($entryName, $extractEntries)) { if (in_array($entryName, $extractEntries)) {
if ($value === null) { if ($value === null) {
self::assertTrue(is_dir($fullExtractFilename)); self::assertTrue(is_dir($fullExtractFilename));
@@ -909,12 +904,11 @@ class ZipFileTest extends ZipTestCase
} }
} }
} }
self::assertFalse(is_file($extractPath . DIRECTORY_SEPARATOR . 'test/test/test.txt')); self::assertFalse(is_file($this->outputDirname . DIRECTORY_SEPARATOR . 'test/test/test.txt'));
$zipFile->extractTo($extractPath, 'test/test/test.txt'); $zipFile->extractTo($this->outputDirname, 'test/test/test.txt');
self::assertTrue(is_file($extractPath . DIRECTORY_SEPARATOR . 'test/test/test.txt')); self::assertTrue(is_file($this->outputDirname . DIRECTORY_SEPARATOR . 'test/test/test.txt'));
$zipFile->close(); $zipFile->close();
FilesUtil::removeDir($extractPath);
} }
/** /**
@@ -958,15 +952,11 @@ class ZipFileTest extends ZipTestCase
$zipFile->saveAsFile($this->outputFilename); $zipFile->saveAsFile($this->outputFilename);
$zipFile->close(); $zipFile->close();
$extractPath = sys_get_temp_dir() . '/zipExtractTest'; self::assertTrue(mkdir($this->outputDirname, 0444, true));
if (is_dir($extractPath)) { self::assertTrue(chmod($this->outputDirname, 0444));
FilesUtil::removeDir($extractPath);
}
self::assertTrue(mkdir($extractPath, 0444, true));
self::assertTrue(chmod($extractPath, 0444));
$zipFile->openFile($this->outputFilename); $zipFile->openFile($this->outputFilename);
$zipFile->extractTo($extractPath); $zipFile->extractTo($this->outputDirname);
} }
/** /**
@@ -1059,7 +1049,8 @@ class ZipFileTest extends ZipTestCase
* @expectedException \PhpZip\Exception\ZipException * @expectedException \PhpZip\Exception\ZipException
* @expectedExceptionMessage Invalid encryption method * @expectedExceptionMessage Invalid encryption method
*/ */
public function testSetEncryptionMethodInvalid(){ public function testSetEncryptionMethodInvalid()
{
$zipFile = new ZipFile(); $zipFile = new ZipFile();
$encryptionMethod = 9999; $encryptionMethod = 9999;
$zipFile->withNewPassword('pass', $encryptionMethod); $zipFile->withNewPassword('pass', $encryptionMethod);
@@ -1539,14 +1530,10 @@ class ZipFileTest extends ZipTestCase
*/ */
public function testSaveAsFileNotWritable() public function testSaveAsFileNotWritable()
{ {
$this->outputFilename = sys_get_temp_dir() . '/zipExtractTest'; self::assertTrue(mkdir($this->outputDirname, 0444, true));
if (is_dir($this->outputFilename)) { self::assertTrue(chmod($this->outputDirname, 0444));
FilesUtil::removeDir($this->outputFilename);
}
self::assertTrue(mkdir($this->outputFilename, 0444, true));
self::assertTrue(chmod($this->outputFilename, 0444));
$this->outputFilename .= '/' . uniqid() . '.zip'; $this->outputFilename = $this->outputDirname . DIRECTORY_SEPARATOR . basename($this->outputFilename);
$zipFile = new ZipFile(); $zipFile = new ZipFile();
$zipFile->saveAsFile($this->outputFilename); $zipFile->saveAsFile($this->outputFilename);
@@ -1699,7 +1686,8 @@ class ZipFileTest extends ZipTestCase
* @expectedException \PhpZip\Exception\ZipNotFoundEntry * @expectedException \PhpZip\Exception\ZipNotFoundEntry
* @expectedExceptionMessage Zip entry bad entry name not found * @expectedExceptionMessage Zip entry bad entry name not found
*/ */
public function testNotFoundEntry(){ public function testNotFoundEntry()
{
$zipFile = new ZipFile(); $zipFile = new ZipFile();
$zipFile['bad entry name']; $zipFile['bad entry name'];
} }
@@ -1761,7 +1749,8 @@ class ZipFileTest extends ZipTestCase
* @expectedException \PhpZip\Exception\ZipException * @expectedException \PhpZip\Exception\ZipException
* @expectedExceptionMessage input stream is null * @expectedExceptionMessage input stream is null
*/ */
public function testRewriteNullStream(){ public function testRewriteNullStream()
{
$zipFile = new ZipFile(); $zipFile = new ZipFile();
$zipFile->rewrite(); $zipFile->rewrite();
} }