1
0
mirror of https://github.com/Ne-Lexa/php-zip.git synced 2025-07-17 14:11:13 +02:00

Merge branch 'hotfix/3.1.12'

This commit is contained in:
wapplay
2019-07-25 23:08:42 +03:00
3 changed files with 73 additions and 12 deletions

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));
}
}