mirror of
https://github.com/Ne-Lexa/php-zip.git
synced 2025-08-15 11:44:56 +02:00
Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
19e17fb730 | ||
|
d8f913ac67 | ||
|
1d1c8559cd | ||
|
e1108f9a24 | ||
|
53da7053ba | ||
|
e8745e0379 | ||
|
b3277fcc5c | ||
|
c9871c9f80 | ||
|
650fab4bad | ||
|
fd9750c4f3 | ||
|
e903642893 | ||
|
516d0c1e77 | ||
|
9934a860c1 | ||
|
c9f597308e | ||
|
837454ba7e | ||
|
680a9d92c1 | ||
|
04a92e7904 | ||
|
e4e3a7504e | ||
|
d8bb1be43b | ||
|
c163f0583e | ||
|
116a617744 | ||
|
e207086a75 |
6
.gitattributes
vendored
Normal file
6
.gitattributes
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
.gitattributes export-ignore
|
||||
.github export-ignore
|
||||
.gitignore export-ignore
|
||||
.travis.yml export-ignore
|
||||
phpunit.xml export-ignore
|
||||
tests export-ignore
|
23
.github/ISSUE_TEMPLATE/1_Bug_report.md
vendored
Normal file
23
.github/ISSUE_TEMPLATE/1_Bug_report.md
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
name: 🔴 Bug Report
|
||||
about: Report errors and problems
|
||||
|
||||
---
|
||||
|
||||
| Q | A
|
||||
| -----------------------------| ---
|
||||
| Library version(s) affected: | x.y.z
|
||||
| PHP version(s): | x.y.z
|
||||
| OS (with bit depth): | <!-- ex. Ubuntu 18.04 64-bit -->
|
||||
|
||||
**Description**
|
||||
<!-- A clear and concise description of the problem. -->
|
||||
|
||||
**How to reproduce**
|
||||
<!-- Code to reproduce the problem. -->
|
||||
|
||||
**Possible Solution**
|
||||
<!--- Optional: only if you have suggestions on a fix/reason for the bug -->
|
||||
|
||||
**Additional context**
|
||||
<!-- Optional: any other context about the problem: error messages, stack trace, zip files, etc. -->
|
12
.github/ISSUE_TEMPLATE/2_Feature_request.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/2_Feature_request.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
name: 🚀 Feature Request
|
||||
about: Ideas for new features and improvements
|
||||
|
||||
---
|
||||
|
||||
**Description**
|
||||
<!-- A clear and concise description of the new feature. -->
|
||||
|
||||
**Example**
|
||||
<!-- A simple example of the new feature in action (include PHP code)
|
||||
If the new feature changes an existing feature, include a simple before/after comparison. -->
|
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
| Q | A
|
||||
| ------------- | ---
|
||||
| Bug fix? | yes/no
|
||||
| New feature? | yes/no <!-- don't forget to update CHANGELOG.md file -->
|
||||
|
||||
<!--
|
||||
Write a short README entry for your feature/bugfix here (replace this comment block.)
|
||||
|
||||
Do NOT send pull request to `master` branch.
|
||||
Please send to `develop` branch instead.
|
||||
Any PR to `master` branch will NOT be merged.
|
||||
-->
|
@@ -5,7 +5,7 @@ php:
|
||||
- '7.0'
|
||||
- '7.1'
|
||||
- '7.2'
|
||||
- nightly
|
||||
- '7.3'
|
||||
|
||||
# cache vendor dirs
|
||||
cache:
|
||||
@@ -15,7 +15,7 @@ cache:
|
||||
|
||||
install:
|
||||
- travis_retry composer self-update && composer --version
|
||||
- travis_retry composer install --prefer-dist --no-interaction
|
||||
- travis_retry composer install --no-interaction
|
||||
|
||||
before_script:
|
||||
- sudo apt-get install p7zip-full
|
||||
|
@@ -148,7 +148,10 @@ class TraditionalPkwareEncryptionEngine implements ZipEncryptionEngine
|
||||
$checkByte = ($this->entry->getCrc() >> 24) & 0xff;
|
||||
}
|
||||
if ($byte !== $checkByte) {
|
||||
throw new ZipAuthenticationException("Bad password for entry " . $this->entry->getName());
|
||||
throw new ZipAuthenticationException(sprintf(
|
||||
'Invalid password for zip entry "%s"',
|
||||
$this->entry->getName()
|
||||
));
|
||||
}
|
||||
|
||||
$outputContent = "";
|
||||
|
@@ -41,7 +41,9 @@ class ZipNewEntry extends ZipAbstractEntry
|
||||
public function getEntryContent()
|
||||
{
|
||||
if (is_resource($this->content)) {
|
||||
rewind($this->content);
|
||||
if (stream_get_meta_data($this->content)['seekable']) {
|
||||
rewind($this->content);
|
||||
}
|
||||
return stream_get_contents($this->content);
|
||||
}
|
||||
return $this->content;
|
||||
|
@@ -25,14 +25,14 @@ class ZipNewFileEntry extends ZipAbstractEntry
|
||||
public function __construct($file)
|
||||
{
|
||||
parent::__construct();
|
||||
if ($file === null){
|
||||
if ($file === null) {
|
||||
throw new InvalidArgumentException("file is null");
|
||||
}
|
||||
$file = (string)$file;
|
||||
if (!is_file($file)){
|
||||
if (!is_file($file)) {
|
||||
throw new ZipException("File $file does not exist.");
|
||||
}
|
||||
if (!is_readable($file)){
|
||||
if (!is_readable($file)) {
|
||||
throw new ZipException("The '$file' file could not be read. Check permissions.");
|
||||
}
|
||||
$this->file = $file;
|
||||
@@ -45,9 +45,9 @@ class ZipNewFileEntry extends ZipAbstractEntry
|
||||
*/
|
||||
public function getEntryContent()
|
||||
{
|
||||
if (!is_file($this->file)){
|
||||
if (!is_file($this->file)) {
|
||||
throw new RuntimeException("File {$this->file} does not exist.");
|
||||
}
|
||||
return file_get_contents($this->file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ use PhpZip\Crypto\WinZipAesEngine;
|
||||
use PhpZip\Exception\Crc32Exception;
|
||||
use PhpZip\Exception\InvalidArgumentException;
|
||||
use PhpZip\Exception\RuntimeException;
|
||||
use PhpZip\Exception\ZipCryptoException;
|
||||
use PhpZip\Exception\ZipAuthenticationException;
|
||||
use PhpZip\Exception\ZipException;
|
||||
use PhpZip\Exception\ZipUnsupportMethodException;
|
||||
use PhpZip\Extra\ExtraFieldsCollection;
|
||||
@@ -144,8 +144,14 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
);
|
||||
}
|
||||
// .ZIP file comment (variable size)
|
||||
if (0 < $data['commentLength']) {
|
||||
$comment = fread($this->in, $data['commentLength']);
|
||||
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;
|
||||
}
|
||||
}
|
||||
$this->preamble = $endOfCentralDirRecordPos;
|
||||
$this->postamble = $size - ftell($this->in);
|
||||
@@ -314,7 +320,13 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
// $utf8 = ($data['gpbf'] & ZipEntry::GPBF_UTF8) !== 0;
|
||||
|
||||
// See appendix D of PKWARE's ZIP File Format Specification.
|
||||
$name = fread($this->in, $data['fileLength']);
|
||||
$name = '';
|
||||
$offset = 0;
|
||||
while ($offset < $data['fileLength']) {
|
||||
$read = min(8192 /* chunk size */, $data['fileLength'] - $offset);
|
||||
$name .= fread($this->in, $read);
|
||||
$offset += $read;
|
||||
}
|
||||
|
||||
$entry = new ZipSourceEntry($this);
|
||||
$entry->setName($name);
|
||||
@@ -329,10 +341,24 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
$entry->setExternalAttributes($data['rawExternalAttributes']);
|
||||
$entry->setOffset($data['lfhOff']); // must be unmapped!
|
||||
if ($data['extraLength'] > 0) {
|
||||
$entry->setExtra(fread($this->in, $data['extraLength']));
|
||||
$extra = '';
|
||||
$offset = 0;
|
||||
while ($offset < $data['extraLength']) {
|
||||
$read = min(8192 /* chunk size */, $data['extraLength'] - $offset);
|
||||
$extra .= fread($this->in, $read);
|
||||
$offset += $read;
|
||||
}
|
||||
$entry->setExtra($extra);
|
||||
}
|
||||
if ($data['commentLength'] > 0) {
|
||||
$entry->setComment(fread($this->in, $data['commentLength']));
|
||||
$comment = '';
|
||||
$offset = 0;
|
||||
while ($offset < $data['commentLength']) {
|
||||
$read = min(8192 /* chunk size */, $data['commentLength'] - $offset);
|
||||
$comment .= fread($this->in, $read);
|
||||
$offset += $read;
|
||||
}
|
||||
$entry->setComment($comment);
|
||||
}
|
||||
return $entry;
|
||||
}
|
||||
@@ -382,10 +408,14 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
// Get raw entry content
|
||||
$compressedSize = $entry->getCompressedSize();
|
||||
$compressedSize = PHP_INT_SIZE === 4 ? sprintf('%u', $compressedSize) : $compressedSize;
|
||||
$content = '';
|
||||
if ($compressedSize > 0) {
|
||||
$content = fread($this->in, $compressedSize);
|
||||
} else {
|
||||
$content = '';
|
||||
$offset = 0;
|
||||
while ($offset < $compressedSize) {
|
||||
$read = min(8192 /* chunk size */, $compressedSize - $offset);
|
||||
$content .= fread($this->in, $read);
|
||||
$offset += $read;
|
||||
}
|
||||
}
|
||||
|
||||
$skipCheckCrc = false;
|
||||
@@ -440,7 +470,7 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
case ZipFileInterface::METHOD_STORED:
|
||||
break;
|
||||
case ZipFileInterface::METHOD_DEFLATED:
|
||||
$content = gzinflate($content);
|
||||
$content = @gzinflate($content);
|
||||
break;
|
||||
case ZipFileInterface::METHOD_BZIP2:
|
||||
if (!extension_loaded('bz2')) {
|
||||
@@ -448,18 +478,38 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
}
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
$content = bzdecompress($content);
|
||||
if (is_int($content)) { // decompress error
|
||||
$content = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ZipUnsupportMethodException($entry->getName() .
|
||||
" (compression method " . $method . " is not supported)");
|
||||
}
|
||||
|
||||
if ($content === false) {
|
||||
if ($isEncrypted) {
|
||||
throw new ZipAuthenticationException(sprintf(
|
||||
'Invalid password for zip entry "%s"',
|
||||
$entry->getName()
|
||||
));
|
||||
}
|
||||
throw new ZipException(sprintf(
|
||||
'Failed to get the contents of the zip entry "%s"',
|
||||
$entry->getName()
|
||||
));
|
||||
}
|
||||
|
||||
if (!$skipCheckCrc) {
|
||||
$localCrc = crc32($content);
|
||||
$localCrc = PHP_INT_SIZE === 4 ? sprintf('%u', $localCrc) : $localCrc;
|
||||
$crc = PHP_INT_SIZE === 4 ? sprintf('%u', $entry->getCrc()) : $entry->getCrc();
|
||||
if ($crc != $localCrc) {
|
||||
if ($isEncrypted) {
|
||||
throw new ZipCryptoException("Wrong password");
|
||||
throw new ZipAuthenticationException(sprintf(
|
||||
'Invalid password for zip entry "%s"',
|
||||
$entry->getName()
|
||||
));
|
||||
}
|
||||
throw new Crc32Exception($entry->getName(), $crc, $localCrc);
|
||||
}
|
||||
@@ -498,7 +548,13 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
if ($sourceExtraLength > 0) {
|
||||
// read Local File Header extra fields
|
||||
fseek($this->in, $pos + ZipEntry::LOCAL_FILE_HEADER_MIN_LEN + $nameLength, SEEK_SET);
|
||||
$extra = fread($this->in, $sourceExtraLength);
|
||||
$extra = '';
|
||||
$offset = 0;
|
||||
while ($offset < $sourceExtraLength) {
|
||||
$read = min(8192 /* chunk size */, $sourceExtraLength - $offset);
|
||||
$extra .= fread($this->in, $read);
|
||||
$offset += $read;
|
||||
}
|
||||
$extraFieldsCollection = ExtraFieldsFactory::createExtraFieldCollections($extra, $entry);
|
||||
if (isset($extraFieldsCollection[ApkAlignmentExtraField::getHeaderId()]) && $this->zipModel->isZipAlign()) {
|
||||
unset($extraFieldsCollection[ApkAlignmentExtraField::getHeaderId()]);
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace PhpZip\Stream;
|
||||
|
||||
use PhpZip\Exception\ZipException;
|
||||
use PhpZip\Model\ZipEntry;
|
||||
use PhpZip\Model\ZipModel;
|
||||
|
||||
@@ -26,6 +27,7 @@ interface ZipInputStreamInterface
|
||||
/**
|
||||
* @param ZipEntry $entry
|
||||
* @return string
|
||||
* @throws ZipException
|
||||
*/
|
||||
public function readEntryContent(ZipEntry $entry);
|
||||
|
||||
|
@@ -562,7 +562,7 @@ class ZipFile implements ZipFileInterface
|
||||
throw new InvalidArgumentException('The input directory is not specified');
|
||||
}
|
||||
if (!is_dir($inputDir)) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $inputDir));
|
||||
throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $inputDir));
|
||||
}
|
||||
$inputDir = rtrim($inputDir, '/\\') . DIRECTORY_SEPARATOR;
|
||||
|
||||
@@ -594,7 +594,7 @@ class ZipFile implements ZipFileInterface
|
||||
throw new InvalidArgumentException('The input directory is not specified');
|
||||
}
|
||||
if (!is_dir($inputDir)) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $inputDir));
|
||||
throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $inputDir));
|
||||
}
|
||||
$inputDir = rtrim($inputDir, '/\\') . DIRECTORY_SEPARATOR;
|
||||
|
||||
@@ -713,7 +713,7 @@ class ZipFile implements ZipFileInterface
|
||||
throw new InvalidArgumentException('The input directory is not specified');
|
||||
}
|
||||
if (!is_dir($inputDir)) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $inputDir));
|
||||
throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $inputDir));
|
||||
}
|
||||
$globPattern = (string)$globPattern;
|
||||
if (empty($globPattern)) {
|
||||
@@ -813,7 +813,7 @@ class ZipFile implements ZipFileInterface
|
||||
throw new InvalidArgumentException('The input directory is not specified');
|
||||
}
|
||||
if (!is_dir($inputDir)) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $inputDir));
|
||||
throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $inputDir));
|
||||
}
|
||||
$inputDir = rtrim($inputDir, '/\\') . DIRECTORY_SEPARATOR;
|
||||
|
||||
|
104
tests/PhpZip/Issue24Test.php
Normal file
104
tests/PhpZip/Issue24Test.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace PhpZip;
|
||||
|
||||
use PhpZip\Exception\ZipException;
|
||||
use PhpZip\Util\CryptoUtil;
|
||||
|
||||
class Issue24Test extends ZipTestCase
|
||||
{
|
||||
/**
|
||||
* This method is called before the first test of this test class is run.
|
||||
*/
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
stream_wrapper_register("dummyfs", DummyFileSystemStream::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ZipException
|
||||
*/
|
||||
public function testDummyFS()
|
||||
{
|
||||
$fileContents = str_repeat(base64_encode(CryptoUtil::randomBytes(12000)), 100);
|
||||
|
||||
// create zip file
|
||||
$zip = new ZipFile();
|
||||
$zip->addFromString(
|
||||
'file.txt',
|
||||
$fileContents,
|
||||
ZipFile::METHOD_DEFLATED
|
||||
);
|
||||
$zip->saveAsFile($this->outputFilename);
|
||||
$zip->close();
|
||||
|
||||
$this->assertCorrectZipArchive($this->outputFilename);
|
||||
|
||||
$stream = fopen('dummyfs://localhost/' . $this->outputFilename, 'rb');
|
||||
$this->assertNotFalse($stream);
|
||||
$zip->openFromStream($stream);
|
||||
$this->assertEquals($zip->getListFiles(), ['file.txt']);
|
||||
$this->assertEquals($zip['file.txt'], $fileContents);
|
||||
$zip->close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to load using dummy stream
|
||||
*/
|
||||
class DummyFileSystemStream
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $fp;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_open($path, $mode, $options)" . PHP_EOL;
|
||||
|
||||
$parsedUrl = parse_url($path);
|
||||
$path = $parsedUrl['path'];
|
||||
$this->fp = fopen($path, $mode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_read($count)" . PHP_EOL;
|
||||
$position = ftell($this->fp);
|
||||
|
||||
// echo "Loading chunk " . $position . " to " . ($position + $count - 1) . PHP_EOL;
|
||||
$ret = fread($this->fp, $count);
|
||||
|
||||
// echo "String length: " . strlen($ret) . PHP_EOL;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_tell()" . PHP_EOL;
|
||||
return ftell($this->fp);
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_eof()" . PHP_EOL;
|
||||
$isfeof = feof($this->fp);
|
||||
return $isfeof;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_seek($offset, $whence)" . PHP_EOL;
|
||||
fseek($this->fp, $offset, $whence);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_stat()" . PHP_EOL;
|
||||
return fstat($this->fp);
|
||||
}
|
||||
}
|
@@ -101,7 +101,7 @@ class PhpZipExtResourceTest extends ZipTestCase
|
||||
* Bug #70752 (Depacking with wrong password leaves 0 length files)
|
||||
* @see https://github.com/php/php-src/blob/master/ext/zip/tests/bug70752.phpt
|
||||
* @expectedException \PhpZip\Exception\ZipAuthenticationException
|
||||
* @expectedExceptionMessage Bad password for entry bug70752.txt
|
||||
* @expectedExceptionMessage nvalid password for zip entry "bug70752.txt"
|
||||
* @throws ZipException
|
||||
*/
|
||||
public function testBug70752()
|
||||
|
@@ -15,7 +15,7 @@ class ZipAlignTest extends ZipTestCase
|
||||
*/
|
||||
public function testApkAlignedAndSetZipAlignAndReSave()
|
||||
{
|
||||
$filename = __DIR__ . '/resources/test.apk';
|
||||
$filename = __DIR__ . '/resources/apk.zip';
|
||||
|
||||
$this->assertCorrectZipArchive($filename);
|
||||
$result = $this->assertVerifyZipAlign($filename);
|
||||
|
@@ -22,7 +22,7 @@ class ZipEventTest extends ZipTestCase
|
||||
public function testBeforeSave()
|
||||
{
|
||||
$zipFile = new ZipFileExtended();
|
||||
$zipFile->openFile(__DIR__ . '/resources/test.apk');
|
||||
$zipFile->openFile(__DIR__ . '/resources/apk.zip');
|
||||
$this->assertTrue(isset($zipFile['META-INF/MANIFEST.MF']));
|
||||
$this->assertTrue(isset($zipFile['META-INF/CERT.SF']));
|
||||
$this->assertTrue(isset($zipFile['META-INF/CERT.RSA']));
|
||||
|
@@ -43,7 +43,7 @@ class ZipPasswordTest extends ZipFileAddDirTest
|
||||
$zipFile[$entryName];
|
||||
$this->fail("Expected Exception has not been raised.");
|
||||
} catch (ZipAuthenticationException $ae) {
|
||||
$this->assertContains('Bad password for entry', $ae->getMessage());
|
||||
$this->assertContains('Invalid password for zip entry', $ae->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
55
tests/PhpZip/ZipRemoteFileTest.php
Normal file
55
tests/PhpZip/ZipRemoteFileTest.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace PhpZip;
|
||||
|
||||
use PhpZip\Exception\ZipException;
|
||||
use PhpZip\Util\Iterator\IgnoreFilesFilterIterator;
|
||||
use PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator;
|
||||
|
||||
/**
|
||||
* Test add remote files to zip archive
|
||||
*/
|
||||
class ZipRemoteFileTest extends ZipTestCase
|
||||
{
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ZipException
|
||||
*/
|
||||
public function testAddRemoteFileFromStream()
|
||||
{
|
||||
$zipFile = new ZipFile();
|
||||
$outputZip = $this->outputFilename;
|
||||
$fileUrl = 'https://raw.githubusercontent.com/Ne-Lexa/php-zip/master/README.md';
|
||||
$fp = @fopen($fileUrl, 'rb', false, stream_context_create([
|
||||
'http' => [
|
||||
'timeout' => 3,
|
||||
]
|
||||
]));
|
||||
if ($fp === false) {
|
||||
self::markTestSkipped(sprintf(
|
||||
"Could not fetch remote file: %s",
|
||||
$fileUrl
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
$fileName = 'remote-file-from-http-stream.md';
|
||||
$zipFile->addFromStream($fp, $fileName);
|
||||
|
||||
$zipFile->saveAsFile($outputZip);
|
||||
$zipFile->close();
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->openFile($outputZip);
|
||||
$files = $zipFile->getListFiles();
|
||||
self::assertCount(1, $files);
|
||||
self::assertSame($fileName, $files[0]);
|
||||
$zipFile->close();
|
||||
}
|
||||
|
||||
}
|
@@ -10,7 +10,6 @@ use PhpZip\Util\FilesUtil;
|
||||
*/
|
||||
class ZipTestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -27,12 +26,10 @@ class ZipTestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$id = uniqid('phpzip');
|
||||
$id = uniqid('phpzip', true);
|
||||
$tempDir = sys_get_temp_dir() . '/phpunit-phpzip';
|
||||
if (!is_dir($tempDir)) {
|
||||
if (!mkdir($tempDir, 0755, true)) {
|
||||
throw new \RuntimeException("Dir " . $tempDir . " can't created");
|
||||
}
|
||||
if (!is_dir($tempDir) && !mkdir($tempDir, 0755, true) && !is_dir($tempDir)) {
|
||||
throw new \RuntimeException('Dir ' . $tempDir . " can't created");
|
||||
}
|
||||
$this->outputFilename = $tempDir . '/' . $id . '.zip';
|
||||
$this->outputDirname = $tempDir . '/' . $id;
|
||||
@@ -61,23 +58,23 @@ class ZipTestCase extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public static function assertCorrectZipArchive($filename, $password = null)
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR !== '\\' && `which unzip`) {
|
||||
$command = "unzip";
|
||||
if (self::existsProgram('unzip')) {
|
||||
$command = 'unzip';
|
||||
if ($password !== null) {
|
||||
$command .= " -P " . escapeshellarg($password);
|
||||
$command .= ' -P ' . escapeshellarg($password);
|
||||
}
|
||||
$command .= " -t " . escapeshellarg($filename);
|
||||
$command .= ' -t ' . escapeshellarg($filename);
|
||||
exec($command, $output, $returnCode);
|
||||
|
||||
$output = implode(PHP_EOL, $output);
|
||||
|
||||
if ($password !== null && $returnCode === 81) {
|
||||
if (`which 7z`) {
|
||||
if (self::existsProgram('7z')) {
|
||||
// WinZip 99-character limit
|
||||
// @see https://sourceforge.net/p/p7zip/discussion/383044/thread/c859a2f0/
|
||||
$password = substr($password, 0, 99);
|
||||
|
||||
$command = "7z t -p" . escapeshellarg($password) . " " . escapeshellarg($filename);
|
||||
$command = '7z t -p' . escapeshellarg($password) . ' ' . escapeshellarg($filename);
|
||||
exec($command, $output, $returnCode);
|
||||
/**
|
||||
* @var array $output
|
||||
@@ -100,6 +97,19 @@ class ZipTestCase extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $program
|
||||
* @return bool
|
||||
*/
|
||||
private static function existsProgram($program){
|
||||
if (DIRECTORY_SEPARATOR !== '\\') {
|
||||
exec('which ' . escapeshellarg($program), $output, $returnCode);
|
||||
return $returnCode === 0;
|
||||
}
|
||||
// false for Windows
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert correct empty zip archive.
|
||||
*
|
||||
@@ -107,15 +117,15 @@ class ZipTestCase extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public static function assertCorrectEmptyZip($filename)
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR !== '\\' && `which zipinfo`) {
|
||||
exec("zipinfo " . escapeshellarg($filename), $output, $returnCode);
|
||||
if (self::existsProgram('zipinfo')) {
|
||||
exec('zipinfo ' . escapeshellarg($filename), $output, $returnCode);
|
||||
|
||||
$output = implode(PHP_EOL, $output);
|
||||
|
||||
self::assertContains('Empty zipfile', $output);
|
||||
}
|
||||
$actualEmptyZipData = pack('VVVVVv', EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG, 0, 0, 0, 0, 0);
|
||||
self::assertEquals(file_get_contents($filename), $actualEmptyZipData);
|
||||
self::assertStringEqualsFile($filename, $actualEmptyZipData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,15 +135,15 @@ class ZipTestCase extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public static function assertVerifyZipAlign($filename, $showErrors = false)
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR !== '\\' && `which zipalign`) {
|
||||
exec("zipalign -c -v 4 " . escapeshellarg($filename), $output, $returnCode);
|
||||
if (self::existsProgram('zipalign')) {
|
||||
exec('zipalign -c -v 4 ' . escapeshellarg($filename), $output, $returnCode);
|
||||
if ($showErrors && $returnCode !== 0) {
|
||||
fwrite(STDERR, implode(PHP_EOL, $output));
|
||||
}
|
||||
return $returnCode === 0;
|
||||
} else {
|
||||
fwrite(STDERR, 'Can not find program "zipalign" for test' . PHP_EOL);
|
||||
return null;
|
||||
}
|
||||
|
||||
fwrite(STDERR, 'Can not find program "zipalign" for test' . PHP_EOL);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
BIN
tests/PhpZip/resources/apk.zip
Normal file
BIN
tests/PhpZip/resources/apk.zip
Normal file
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user