mirror of
https://github.com/Ne-Lexa/php-zip.git
synced 2025-08-18 21:21:16 +02:00
Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
19e17fb730 | ||
|
d8f913ac67 | ||
|
1d1c8559cd | ||
|
e1108f9a24 | ||
|
53da7053ba | ||
|
e8745e0379 | ||
|
b3277fcc5c | ||
|
c9871c9f80 | ||
|
650fab4bad | ||
|
fd9750c4f3 | ||
|
e903642893 | ||
|
516d0c1e77 | ||
|
9934a860c1 | ||
|
c9f597308e | ||
|
837454ba7e | ||
|
04a92e7904 |
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
|
@@ -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;
|
||||
@@ -470,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')) {
|
||||
@@ -478,6 +478,9 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
}
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
$content = bzdecompress($content);
|
||||
if (is_int($content)) { // decompress error
|
||||
$content = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ZipUnsupportMethodException($entry->getName() .
|
||||
@@ -485,6 +488,12 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
}
|
||||
|
||||
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()
|
||||
@@ -497,7 +506,10 @@ class ZipInputStream implements ZipInputStreamInterface
|
||||
$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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -53,7 +53,7 @@ class DummyFileSystemStream
|
||||
*/
|
||||
private $fp;
|
||||
|
||||
function stream_open($path, $mode, $options, &$opened_path)
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_open($path, $mode, $options)" . PHP_EOL;
|
||||
|
||||
@@ -64,7 +64,7 @@ class DummyFileSystemStream
|
||||
return true;
|
||||
}
|
||||
|
||||
function stream_read($count)
|
||||
public function stream_read($count)
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_read($count)" . PHP_EOL;
|
||||
$position = ftell($this->fp);
|
||||
@@ -77,28 +77,28 @@ class DummyFileSystemStream
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function stream_tell()
|
||||
public function stream_tell()
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_tell()" . PHP_EOL;
|
||||
return ftell($this->fp);
|
||||
}
|
||||
|
||||
function stream_eof()
|
||||
public function stream_eof()
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_eof()" . PHP_EOL;
|
||||
$isfeof = feof($this->fp);
|
||||
return $isfeof;
|
||||
}
|
||||
|
||||
function stream_seek($offset, $whence)
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
// echo "DummyFileSystemStream->stream_seek($offset, $whence)" . PHP_EOL;
|
||||
fseek($this->fp, $offset, $whence);
|
||||
}
|
||||
|
||||
function stream_stat()
|
||||
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