1
0
mirror of https://github.com/Ne-Lexa/php-zip.git synced 2025-08-17 20:52:59 +02:00

11 Commits

Author SHA1 Message Date
wapplay
ca068fa78f Merge branch 'hotfix/3.1.12' 2019-07-25 23:08:42 +03:00
wapplay
a84d2f9eff fix issue #39 2019-07-25 23:03:28 +03:00
Ne-Lexa
97db60a52d Merge pull request #36 from chrisgraham/develop
Fixed slightly confusing language regarding setPassword
2019-04-04 11:37:51 +03:00
Chris Graham
4134ca8daa Fixed slightly confusing language regarding setPassword 2019-04-02 16:53:33 -05:00
Ne-Lexa
e7528b2974 Merge tag '3.1.11' into develop
Tagging hotfix 3.1.11 3.1.11
2019-03-13 15:41:56 +03:00
Ne-Lexa
19e17fb730 Merge branch 'hotfix/3.1.11' 2019-03-13 15:41:56 +03:00
Ne-Lexa
d8f913ac67 removed nightly PHP (8.0-dev) from travis 2019-03-13 15:37:01 +03:00
Ne-Lexa
1d1c8559cd update travis config 2019-03-13 15:29:40 +03:00
Ne-Lexa
e1108f9a24 Added .gitattributes to exclude tests from the release version #34 2019-03-13 15:28:38 +03:00
Ne-Lexa
96d269b4ca Merge tag '3.1.10' into develop
Tagging hotfix 3.1.10 3.1.10
2019-03-13 15:16:08 +03:00
Ne-Lexa
4aa9711e00 Merge tag '3.1.9' into develop
Tagging version 3.1.9 3.1.9
2018-11-02 15:15:08 +03:00
6 changed files with 84 additions and 17 deletions

6
.gitattributes vendored Normal file
View 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

View File

@@ -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

View File

@@ -567,7 +567,7 @@ $zipFile->rename($oldName, $newName);
```
<a name="Documentation-ZipFile-setCompressionLevel"></a> **ZipFile::setCompressionLevel** - set the compression level for all files in the archive.
> _Note that this method does not apply to entries that were added after this method was run._
> _Note that this method does not apply to entries that are added after this method is run._
By default, the compression level is -1 (`\PhpZip\ZipFile::LEVEL_DEFAULT_COMPRESSION`) or the compression level specified in the archive for Deflate compression.
@@ -671,7 +671,7 @@ $zipFile->setReadPasswordEntry($entryName, $password);
```
<a name="Documentation-ZipFile-setPassword"></a> **ZipFile::setPassword** - sets a new password for all files in the archive.
> _Note that this method does not apply to entries that were added after this method was run._
> _Note that this method does not apply to entries that are added after this method is run._
```php
$zipFile->setPassword($password);
```
@@ -691,7 +691,7 @@ $zipFile->setPasswordEntry($entryName, $password, $encryptionMethod);
```
<a name="Documentation-ZipFile-disableEncryption"></a> **ZipFile::disableEncryption** - disable encryption for all entries that are already in the archive.
> _Note that this method does not apply to entries that were added after this method was run._
> _Note that this method does not apply to entries that are added after this method is run._
```php
$zipFile->disableEncryption();
```

View File

@@ -225,4 +225,23 @@ class FilesUtil
}
return number_format($size) . " bytes";
}
/**
* Normalizes zip path.
*
* @param string $path Zip path
* @return string
*/
public static function normalizeZipPath($path)
{
return implode(
'/',
array_filter(
explode('/', (string)$path),
static function ($part) {
return $part !== '.' && $part !== '..';
}
)
);
}
}

View File

@@ -297,13 +297,13 @@ class ZipFile implements ZipFileInterface
public function extractTo($destination, $entries = null)
{
if (!file_exists($destination)) {
throw new ZipException("Destination " . $destination . " not found");
throw new ZipException(sprintf('Destination %s not found', $destination));
}
if (!is_dir($destination)) {
throw new ZipException("Destination is not directory");
throw new ZipException('Destination is not directory');
}
if (!is_writable($destination)) {
throw new ZipException("Destination is not writable directory");
throw new ZipException('Destination is not writable directory');
}
$zipEntries = $this->zipModel->getEntries();
@@ -315,18 +315,19 @@ class ZipFile implements ZipFileInterface
if (is_array($entries)) {
$entries = array_unique($entries);
$flipEntries = array_flip($entries);
$zipEntries = array_filter($zipEntries, function (ZipEntry $zipEntry) use ($flipEntries) {
$zipEntries = array_filter($zipEntries, static function (ZipEntry $zipEntry) use ($flipEntries) {
return isset($flipEntries[$zipEntry->getName()]);
});
}
}
foreach ($zipEntries as $entry) {
$file = $destination . DIRECTORY_SEPARATOR . $entry->getName();
$entryName = FilesUtil::normalizeZipPath($entry->getName());
$file = $destination . DIRECTORY_SEPARATOR . $entryName;
if ($entry->isDirectory()) {
if (!is_dir($file)) {
if (!mkdir($file, 0755, true)) {
throw new ZipException("Can not create dir " . $file);
if (!mkdir($file, 0755, true) && !is_dir($file)) {
throw new ZipException('Can not create dir ' . $file);
}
chmod($file, 0755);
touch($file, $entry->getTime());
@@ -335,8 +336,8 @@ class ZipFile implements ZipFileInterface
}
$dir = dirname($file);
if (!is_dir($dir)) {
if (!mkdir($dir, 0755, true)) {
throw new ZipException("Can not create dir " . $dir);
if (!mkdir($dir, 0755, true) && !is_dir($dir)) {
throw new ZipException('Can not create dir ' . $dir);
}
chmod($dir, 0755);
touch($dir, $entry->getTime());
@@ -1210,7 +1211,7 @@ class ZipFile implements ZipFileInterface
{
$filename = (string)$filename;
$tempFilename = $filename . '.temp' . uniqid();
$tempFilename = $filename . '.temp' . uniqid('', true);
if (!($handle = @fopen($tempFilename, 'w+b'))) {
throw new InvalidArgumentException("File " . $tempFilename . ' can not open from write.');
}
@@ -1256,7 +1257,7 @@ class ZipFile implements ZipFileInterface
{
$outputFilename = (string)$outputFilename;
if (empty($mimeType) || !is_string($mimeType) && !empty($outputFilename)) {
if (empty($mimeType) || (!is_string($mimeType) && !empty($outputFilename))) {
$ext = strtolower(pathinfo($outputFilename, PATHINFO_EXTENSION));
if (!empty($ext) && isset(self::$defaultMimeTypes[$ext])) {
@@ -1295,7 +1296,7 @@ class ZipFile implements ZipFileInterface
{
$outputFilename = (string)$outputFilename;
if (empty($mimeType) || !is_string($mimeType) && !empty($outputFilename)) {
if (empty($mimeType) || (!is_string($mimeType) && !empty($outputFilename))) {
$ext = strtolower(pathinfo($outputFilename, PATHINFO_EXTENSION));
if (!empty($ext) && isset(self::$defaultMimeTypes[$ext])) {

View File

@@ -0,0 +1,41 @@
<?php
namespace PhpZip;
/**
* Class ZipSlipVulnerabilityTest
*
* @package PhpZip
* @see https://github.com/Ne-Lexa/php-zip/issues/39 Issue#31
* @see https://snyk.io/research/zip-slip-vulnerability Zip Slip Vulnerability
*/
class ZipSlipVulnerabilityTest extends ZipTestCase
{
/**
* @throws Exception\ZipException
*/
public function testCreateSlipVulnerabilityFile()
{
$localFile = '../dir/./../../file.txt';
$zipFile = new ZipFile();
$zipFile->addFromString($localFile, 'contents');
self::assertContains($localFile, $zipFile->getListFiles());
$zipFile->close();
}
/**
* @throws Exception\ZipException
*/
public function testUnpack()
{
$this->assertTrue(mkdir($this->outputDirname, 0755, true));
$zipFile = new ZipFile();
$zipFile->addFromString('../dir/./../../file.txt', 'contents');
$zipFile->extractTo($this->outputDirname);
$zipFile->close();
$expectedExtractedFile = $this->outputDirname . '/dir/file.txt';
self::assertTrue(is_file($expectedExtractedFile));
}
}