function ZipDownloader::extractWithZipArchive
extract $file to $path with ZipArchive
@phpstan-return PromiseInterface<void|null>
Parameters
string $file File to extract:
string $path Path where to extract file:
1 call to ZipDownloader::extractWithZipArchive()
- ZipDownloader::extractWithSystemUnzip in vendor/
composer/ composer/ src/ Composer/ Downloader/ ZipDownloader.php - extract $file to $path with "unzip" command
File
-
vendor/
composer/ composer/ src/ Composer/ Downloader/ ZipDownloader.php, line 208
Class
- ZipDownloader
- @author Jordi Boggiano <j.boggiano@seld.be>
Namespace
Composer\DownloaderCode
private function extractWithZipArchive(PackageInterface $package, string $file, string $path) : PromiseInterface {
$processError = null;
$zipArchive = $this->zipArchiveObject ?: new ZipArchive();
try {
if (!file_exists($file) || ($filesize = filesize($file)) === false || $filesize === 0) {
$retval = -1;
}
else {
$retval = $zipArchive->open($file);
}
if (true === $retval) {
$totalSize = 0;
$archiveSize = filesize($file);
$totalFiles = $zipArchive->count();
if ($totalFiles > 0) {
for ($i = 0; $i < min($totalFiles, 5); $i++) {
$stat = $zipArchive->statIndex(random_int(0, $totalFiles - 1));
if ($stat === false) {
continue;
}
$totalSize += $stat['size'];
if ($stat['size'] > $stat['comp_size'] * 200) {
throw new \RuntimeException('Invalid zip file with compression ratio >99% (possible zip bomb)');
}
}
if ($archiveSize !== false && $totalSize > $archiveSize * 100 && $totalSize > 50 * 1024 * 1024) {
throw new \RuntimeException('Invalid zip file with compression ratio >99% (possible zip bomb)');
}
}
$extractResult = $zipArchive->extractTo($path);
if (true === $extractResult) {
$zipArchive->close();
return \React\Promise\resolve(null);
}
$processError = new \RuntimeException(rtrim("There was an error extracting the ZIP file, it is either corrupted or using an invalid format.\n"));
}
else {
$processError = new \UnexpectedValueException(rtrim($this->getErrorMessage($retval, $file) . "\n"), $retval);
}
} catch (\ErrorException $e) {
$processError = new \RuntimeException('The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems): ' . $e->getMessage(), 0, $e);
} catch (\Throwable $e) {
$processError = $e;
}
throw $processError;
}