diff options
Diffstat (limited to 'vendor/maennchen/zipstream-php/src')
27 files changed, 0 insertions, 2152 deletions
diff --git a/vendor/maennchen/zipstream-php/src/CentralDirectoryFileHeader.php b/vendor/maennchen/zipstream-php/src/CentralDirectoryFileHeader.php deleted file mode 100644 index ffcfc6e97..000000000 --- a/vendor/maennchen/zipstream-php/src/CentralDirectoryFileHeader.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -use DateTimeInterface; - -/** - * @internal - */ -abstract class CentralDirectoryFileHeader -{ - private const SIGNATURE = 0x02014b50; - - public static function generate( - int $versionMadeBy, - int $versionNeededToExtract, - int $generalPurposeBitFlag, - CompressionMethod $compressionMethod, - DateTimeInterface $lastModificationDateTime, - int $crc32, - int $compressedSize, - int $uncompressedSize, - string $fileName, - string $extraField, - string $fileComment, - int $diskNumberStart, - int $internalFileAttributes, - int $externalFileAttributes, - int $relativeOffsetOfLocalHeader, - ): string { - return PackField::pack( - new PackField(format: 'V', value: self::SIGNATURE), - new PackField(format: 'v', value: $versionMadeBy), - new PackField(format: 'v', value: $versionNeededToExtract), - new PackField(format: 'v', value: $generalPurposeBitFlag), - new PackField(format: 'v', value: $compressionMethod->value), - new PackField(format: 'V', value: Time::dateTimeToDosTime($lastModificationDateTime)), - new PackField(format: 'V', value: $crc32), - new PackField(format: 'V', value: $compressedSize), - new PackField(format: 'V', value: $uncompressedSize), - new PackField(format: 'v', value: strlen($fileName)), - new PackField(format: 'v', value: strlen($extraField)), - new PackField(format: 'v', value: strlen($fileComment)), - new PackField(format: 'v', value: $diskNumberStart), - new PackField(format: 'v', value: $internalFileAttributes), - new PackField(format: 'V', value: $externalFileAttributes), - new PackField(format: 'V', value: $relativeOffsetOfLocalHeader), - ) . $fileName . $extraField . $fileComment; - } -} diff --git a/vendor/maennchen/zipstream-php/src/CompressionMethod.php b/vendor/maennchen/zipstream-php/src/CompressionMethod.php deleted file mode 100644 index 51e436370..000000000 --- a/vendor/maennchen/zipstream-php/src/CompressionMethod.php +++ /dev/null @@ -1,106 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -enum CompressionMethod: int -{ - /** - * The file is stored (no compression) - */ - case STORE = 0x00; - - // 0x01: legacy algorithm - The file is Shrunk - // 0x02: legacy algorithm - The file is Reduced with compression factor 1 - // 0x03: legacy algorithm - The file is Reduced with compression factor 2 - // 0x04: legacy algorithm - The file is Reduced with compression factor 3 - // 0x05: legacy algorithm - The file is Reduced with compression factor 4 - // 0x06: legacy algorithm - The file is Imploded - // 0x07: Reserved for Tokenizing compression algorithm - - /** - * The file is Deflated - */ - case DEFLATE = 0x08; - - // /** - // * Enhanced Deflating using Deflate64(tm) - // */ - // case DEFLATE_64 = 0x09; - - // /** - // * PKWARE Data Compression Library Imploding (old IBM TERSE) - // */ - // case PKWARE = 0x0a; - - // // 0x0b: Reserved by PKWARE - - // /** - // * File is compressed using BZIP2 algorithm - // */ - // case BZIP2 = 0x0c; - - // // 0x0d: Reserved by PKWARE - - // /** - // * LZMA - // */ - // case LZMA = 0x0e; - - // // 0x0f: Reserved by PKWARE - - // /** - // * IBM z/OS CMPSC Compression - // */ - // case IBM_ZOS_CMPSC = 0x10; - - // // 0x11: Reserved by PKWARE - - // /** - // * File is compressed using IBM TERSE - // */ - // case IBM_TERSE = 0x12; - - // /** - // * IBM LZ77 z Architecture - // */ - // case IBM_LZ77 = 0x13; - - // // 0x14: deprecated (use method 93 for zstd) - - // /** - // * Zstandard (zstd) Compression - // */ - // case ZSTD = 0x5d; - - // /** - // * MP3 Compression - // */ - // case MP3 = 0x5e; - - // /** - // * XZ Compression - // */ - // case XZ = 0x5f; - - // /** - // * JPEG variant - // */ - // case JPEG = 0x60; - - // /** - // * WavPack compressed data - // */ - // case WAV_PACK = 0x61; - - // /** - // * PPMd version I, Rev 1 - // */ - // case PPMD_1_1 = 0x62; - - // /** - // * AE-x encryption marker - // */ - // case AE_X_ENCRYPTION = 0x63; -} diff --git a/vendor/maennchen/zipstream-php/src/DataDescriptor.php b/vendor/maennchen/zipstream-php/src/DataDescriptor.php deleted file mode 100644 index 04146190d..000000000 --- a/vendor/maennchen/zipstream-php/src/DataDescriptor.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -/** - * @internal - */ -abstract class DataDescriptor -{ - private const SIGNATURE = 0x08074b50; - - public static function generate( - int $crc32UncompressedData, - int $compressedSize, - int $uncompressedSize, - ): string { - return PackField::pack( - new PackField(format: 'V', value: self::SIGNATURE), - new PackField(format: 'V', value: $crc32UncompressedData), - new PackField(format: 'V', value: $compressedSize), - new PackField(format: 'V', value: $uncompressedSize), - ); - } -} diff --git a/vendor/maennchen/zipstream-php/src/EndOfCentralDirectory.php b/vendor/maennchen/zipstream-php/src/EndOfCentralDirectory.php deleted file mode 100644 index 4320addc3..000000000 --- a/vendor/maennchen/zipstream-php/src/EndOfCentralDirectory.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -/** - * @internal - */ -abstract class EndOfCentralDirectory -{ - private const SIGNATURE = 0x06054b50; - - public static function generate( - int $numberOfThisDisk, - int $numberOfTheDiskWithCentralDirectoryStart, - int $numberOfCentralDirectoryEntriesOnThisDisk, - int $numberOfCentralDirectoryEntries, - int $sizeOfCentralDirectory, - int $centralDirectoryStartOffsetOnDisk, - string $zipFileComment, - ): string { - /** @psalm-suppress MixedArgument */ - return PackField::pack( - new PackField(format: 'V', value: static::SIGNATURE), - new PackField(format: 'v', value: $numberOfThisDisk), - new PackField(format: 'v', value: $numberOfTheDiskWithCentralDirectoryStart), - new PackField(format: 'v', value: $numberOfCentralDirectoryEntriesOnThisDisk), - new PackField(format: 'v', value: $numberOfCentralDirectoryEntries), - new PackField(format: 'V', value: $sizeOfCentralDirectory), - new PackField(format: 'V', value: $centralDirectoryStartOffsetOnDisk), - new PackField(format: 'v', value: strlen($zipFileComment)), - ) . $zipFileComment; - } -} diff --git a/vendor/maennchen/zipstream-php/src/Exception.php b/vendor/maennchen/zipstream-php/src/Exception.php deleted file mode 100644 index 2e81e307b..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -abstract class Exception extends \Exception {} diff --git a/vendor/maennchen/zipstream-php/src/Exception/DosTimeOverflowException.php b/vendor/maennchen/zipstream-php/src/Exception/DosTimeOverflowException.php deleted file mode 100644 index b8d050808..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception/DosTimeOverflowException.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Exception; - -use DateTimeInterface; -use ZipStream\Exception; - -/** - * This Exception gets invoked if a file wasn't found - */ -class DosTimeOverflowException extends Exception -{ - /** - * @internal - */ - public function __construct( - public readonly DateTimeInterface $dateTime - ) { - parent::__construct('The date ' . $dateTime->format(DateTimeInterface::ATOM) . " can't be represented as DOS time / date."); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Exception/FileNotFoundException.php b/vendor/maennchen/zipstream-php/src/Exception/FileNotFoundException.php deleted file mode 100644 index 350a7bfe5..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception/FileNotFoundException.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Exception; - -use ZipStream\Exception; - -/** - * This Exception gets invoked if a file wasn't found - */ -class FileNotFoundException extends Exception -{ - /** - * @internal - */ - public function __construct( - public readonly string $path - ) { - parent::__construct("The file with the path $path wasn't found."); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Exception/FileNotReadableException.php b/vendor/maennchen/zipstream-php/src/Exception/FileNotReadableException.php deleted file mode 100644 index 93d0c6c64..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception/FileNotReadableException.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Exception; - -use ZipStream\Exception; - -/** - * This Exception gets invoked if a file wasn't found - */ -class FileNotReadableException extends Exception -{ - /** - * @internal - */ - public function __construct( - public readonly string $path - ) { - parent::__construct("The file with the path $path isn't readable."); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Exception/FileSizeIncorrectException.php b/vendor/maennchen/zipstream-php/src/Exception/FileSizeIncorrectException.php deleted file mode 100644 index 11f0b67b3..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception/FileSizeIncorrectException.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Exception; - -use ZipStream\Exception; - -/** - * This Exception gets invoked if a file is not as large as it was specified. - */ -class FileSizeIncorrectException extends Exception -{ - /** - * @internal - */ - public function __construct( - public readonly int $expectedSize, - public readonly int $actualSize - ) { - parent::__construct("File is {$actualSize} instead of {$expectedSize} bytes large. Adjust `exactSize` parameter."); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Exception/OverflowException.php b/vendor/maennchen/zipstream-php/src/Exception/OverflowException.php deleted file mode 100644 index 09bdafb28..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception/OverflowException.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Exception; - -use ZipStream\Exception; - -/** - * This Exception gets invoked if a counter value exceeds storage size - */ -class OverflowException extends Exception -{ - /** - * @internal - */ - public function __construct() - { - parent::__construct('File size exceeds limit of 32 bit integer. Please enable "zip64" option.'); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Exception/ResourceActionException.php b/vendor/maennchen/zipstream-php/src/Exception/ResourceActionException.php deleted file mode 100644 index cbd9b0bb9..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception/ResourceActionException.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Exception; - -use ZipStream\Exception; - -/** - * This Exception gets invoked if a resource like `fread` returns false - */ -class ResourceActionException extends Exception -{ - /** - * @var ?resource - */ - public $resource; - - /** - * @param resource $resource - */ - public function __construct( - public readonly string $function, - $resource = null, - ) { - $this->resource = $resource; - parent::__construct('Function ' . $function . 'failed on resource.'); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Exception/SimulationFileUnknownException.php b/vendor/maennchen/zipstream-php/src/Exception/SimulationFileUnknownException.php deleted file mode 100644 index 717c1aafe..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception/SimulationFileUnknownException.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Exception; - -use ZipStream\Exception; - -/** - * This Exception gets invoked if a strict simulation is executed and the file - * information can't be determined without reading the entire file. - */ -class SimulationFileUnknownException extends Exception -{ - public function __construct() - { - parent::__construct('The details of the strict simulation file could not be determined without reading the entire file.'); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Exception/StreamNotReadableException.php b/vendor/maennchen/zipstream-php/src/Exception/StreamNotReadableException.php deleted file mode 100644 index c1446735a..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception/StreamNotReadableException.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Exception; - -use ZipStream\Exception; - -/** - * This Exception gets invoked if a stream can't be read. - */ -class StreamNotReadableException extends Exception -{ - /** - * @internal - */ - public function __construct() - { - parent::__construct('The stream could not be read.'); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Exception/StreamNotSeekableException.php b/vendor/maennchen/zipstream-php/src/Exception/StreamNotSeekableException.php deleted file mode 100644 index 606f11f14..000000000 --- a/vendor/maennchen/zipstream-php/src/Exception/StreamNotSeekableException.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Exception; - -use ZipStream\Exception; - -/** - * This Exception gets invoked if a non seekable stream is - * provided and zero headers are disabled. - */ -class StreamNotSeekableException extends Exception -{ - /** - * @internal - */ - public function __construct() - { - parent::__construct('enableZeroHeader must be enable to add non seekable streams'); - } -} diff --git a/vendor/maennchen/zipstream-php/src/File.php b/vendor/maennchen/zipstream-php/src/File.php deleted file mode 100644 index 0462196e2..000000000 --- a/vendor/maennchen/zipstream-php/src/File.php +++ /dev/null @@ -1,420 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -use Closure; -use DateTimeInterface; -use DeflateContext; -use RuntimeException; -use ZipStream\Exception\FileSizeIncorrectException; -use ZipStream\Exception\OverflowException; -use ZipStream\Exception\ResourceActionException; -use ZipStream\Exception\SimulationFileUnknownException; -use ZipStream\Exception\StreamNotReadableException; -use ZipStream\Exception\StreamNotSeekableException; - -/** - * @internal - */ -class File -{ - private const CHUNKED_READ_BLOCK_SIZE = 0x1000000; - - private Version $version; - - private int $compressedSize = 0; - - private int $uncompressedSize = 0; - - private int $crc = 0; - - private int $generalPurposeBitFlag = 0; - - private readonly string $fileName; - - /** - * @var resource|null - */ - private $stream; - - /** - * @param Closure $dataCallback - * @psalm-param Closure(): resource $dataCallback - */ - public function __construct( - string $fileName, - private readonly Closure $dataCallback, - private readonly OperationMode $operationMode, - private readonly int $startOffset, - private readonly CompressionMethod $compressionMethod, - private readonly string $comment, - private readonly DateTimeInterface $lastModificationDateTime, - private readonly int $deflateLevel, - private readonly ?int $maxSize, - private readonly ?int $exactSize, - private readonly bool $enableZip64, - private readonly bool $enableZeroHeader, - private readonly Closure $send, - private readonly Closure $recordSentBytes, - ) { - $this->fileName = self::filterFilename($fileName); - $this->checkEncoding(); - - if ($this->enableZeroHeader) { - $this->generalPurposeBitFlag |= GeneralPurposeBitFlag::ZERO_HEADER; - } - - $this->version = $this->compressionMethod === CompressionMethod::DEFLATE ? Version::DEFLATE : Version::STORE; - } - - public function cloneSimulationExecution(): self - { - return new self( - $this->fileName, - $this->dataCallback, - OperationMode::NORMAL, - $this->startOffset, - $this->compressionMethod, - $this->comment, - $this->lastModificationDateTime, - $this->deflateLevel, - $this->maxSize, - $this->exactSize, - $this->enableZip64, - $this->enableZeroHeader, - $this->send, - $this->recordSentBytes, - ); - } - - public function process(): string - { - $forecastSize = $this->forecastSize(); - - if ($this->enableZeroHeader) { - // No calculation required - } elseif ($this->isSimulation() && $forecastSize !== null) { - $this->uncompressedSize = $forecastSize; - $this->compressedSize = $forecastSize; - } else { - $this->readStream(send: false); - if (rewind($this->unpackStream()) === false) { - throw new ResourceActionException('rewind', $this->unpackStream()); - } - } - - $this->addFileHeader(); - - $detectedSize = $forecastSize ?? ($this->compressedSize > 0 ? $this->compressedSize : null); - - if ( - $this->isSimulation() && - $detectedSize !== null - ) { - ($this->recordSentBytes)($detectedSize); - } else { - $this->readStream(send: true); - } - - $this->addFileFooter(); - return $this->getCdrFile(); - } - - /** - * @return resource - */ - private function unpackStream() - { - if ($this->stream) { - return $this->stream; - } - - if ($this->operationMode === OperationMode::SIMULATE_STRICT) { - throw new SimulationFileUnknownException(); - } - - $this->stream = ($this->dataCallback)(); - - if (!$this->enableZeroHeader && !stream_get_meta_data($this->stream)['seekable']) { - throw new StreamNotSeekableException(); - } - if (!( - str_contains(stream_get_meta_data($this->stream)['mode'], 'r') - || str_contains(stream_get_meta_data($this->stream)['mode'], 'w+') - || str_contains(stream_get_meta_data($this->stream)['mode'], 'a+') - || str_contains(stream_get_meta_data($this->stream)['mode'], 'x+') - || str_contains(stream_get_meta_data($this->stream)['mode'], 'c+') - )) { - throw new StreamNotReadableException(); - } - - return $this->stream; - } - - private function forecastSize(): ?int - { - if ($this->compressionMethod !== CompressionMethod::STORE) { - return null; - } - if ($this->exactSize !== null) { - return $this->exactSize; - } - $fstat = fstat($this->unpackStream()); - if (!$fstat || !array_key_exists('size', $fstat) || $fstat['size'] < 1) { - return null; - } - - if ($this->maxSize !== null && $this->maxSize < $fstat['size']) { - return $this->maxSize; - } - - return $fstat['size']; - } - - /** - * Create and send zip header for this file. - */ - private function addFileHeader(): void - { - $forceEnableZip64 = $this->enableZeroHeader && $this->enableZip64; - - $footer = $this->buildZip64ExtraBlock($forceEnableZip64); - - $zip64Enabled = $footer !== ''; - - if ($zip64Enabled) { - $this->version = Version::ZIP64; - } - - if ($this->generalPurposeBitFlag & GeneralPurposeBitFlag::EFS) { - // Put the tricky entry to - // force Linux unzip to lookup EFS flag. - $footer .= Zs\ExtendedInformationExtraField::generate(); - } - - $data = LocalFileHeader::generate( - versionNeededToExtract: $this->version->value, - generalPurposeBitFlag: $this->generalPurposeBitFlag, - compressionMethod: $this->compressionMethod, - lastModificationDateTime: $this->lastModificationDateTime, - crc32UncompressedData: $this->crc, - compressedSize: $zip64Enabled - ? 0xFFFFFFFF - : $this->compressedSize, - uncompressedSize: $zip64Enabled - ? 0xFFFFFFFF - : $this->uncompressedSize, - fileName: $this->fileName, - extraField: $footer, - ); - - - ($this->send)($data); - } - - /** - * Strip characters that are not legal in Windows filenames - * to prevent compatibility issues - */ - private static function filterFilename( - /** - * Unprocessed filename - */ - string $fileName - ): string { - // strip leading slashes from file name - // (fixes bug in windows archive viewer) - $fileName = ltrim($fileName, '/'); - - return str_replace(['\\', ':', '*', '?', '"', '<', '>', '|'], '_', $fileName); - } - - private function checkEncoding(): void - { - // Sets Bit 11: Language encoding flag (EFS). If this bit is set, - // the filename and comment fields for this file - // MUST be encoded using UTF-8. (see APPENDIX D) - if (mb_check_encoding($this->fileName, 'UTF-8') && - mb_check_encoding($this->comment, 'UTF-8')) { - $this->generalPurposeBitFlag |= GeneralPurposeBitFlag::EFS; - } - } - - private function buildZip64ExtraBlock(bool $force = false): string - { - $outputZip64ExtraBlock = false; - - $originalSize = null; - if ($force || $this->uncompressedSize > 0xFFFFFFFF) { - $outputZip64ExtraBlock = true; - $originalSize = $this->uncompressedSize; - } - - $compressedSize = null; - if ($force || $this->compressedSize > 0xFFFFFFFF) { - $outputZip64ExtraBlock = true; - $compressedSize = $this->compressedSize; - } - - // If this file will start over 4GB limit in ZIP file, - // CDR record will have to use Zip64 extension to describe offset - // to keep consistency we use the same value here - $relativeHeaderOffset = null; - if ($this->startOffset > 0xFFFFFFFF) { - $outputZip64ExtraBlock = true; - $relativeHeaderOffset = $this->startOffset; - } - - if (!$outputZip64ExtraBlock) { - return ''; - } - - if (!$this->enableZip64) { - throw new OverflowException(); - } - - return Zip64\ExtendedInformationExtraField::generate( - originalSize: $originalSize, - compressedSize: $compressedSize, - relativeHeaderOffset: $relativeHeaderOffset, - diskStartNumber: null, - ); - } - - private function addFileFooter(): void - { - if (($this->compressedSize > 0xFFFFFFFF || $this->uncompressedSize > 0xFFFFFFFF) && $this->version !== Version::ZIP64) { - throw new OverflowException(); - } - - if (!$this->enableZeroHeader) { - return; - } - - if ($this->version === Version::ZIP64) { - $footer = Zip64\DataDescriptor::generate( - crc32UncompressedData: $this->crc, - compressedSize: $this->compressedSize, - uncompressedSize: $this->uncompressedSize, - ); - } else { - $footer = DataDescriptor::generate( - crc32UncompressedData: $this->crc, - compressedSize: $this->compressedSize, - uncompressedSize: $this->uncompressedSize, - ); - } - - ($this->send)($footer); - } - - private function readStream(bool $send): void - { - $this->compressedSize = 0; - $this->uncompressedSize = 0; - $hash = hash_init('crc32b'); - - $deflate = $this->compressionInit(); - - while ( - !feof($this->unpackStream()) && - ($this->maxSize === null || $this->uncompressedSize < $this->maxSize) && - ($this->exactSize === null || $this->uncompressedSize < $this->exactSize) - ) { - $readLength = min( - ($this->maxSize ?? PHP_INT_MAX) - $this->uncompressedSize, - ($this->exactSize ?? PHP_INT_MAX) - $this->uncompressedSize, - self::CHUNKED_READ_BLOCK_SIZE - ); - - $data = fread($this->unpackStream(), $readLength); - - hash_update($hash, $data); - - $this->uncompressedSize += strlen($data); - - if ($deflate) { - $data = deflate_add( - $deflate, - $data, - feof($this->unpackStream()) ? ZLIB_FINISH : ZLIB_NO_FLUSH - ); - } - - $this->compressedSize += strlen($data); - - if ($send) { - ($this->send)($data); - } - } - - if ($this->exactSize !== null && $this->uncompressedSize !== $this->exactSize) { - throw new FileSizeIncorrectException(expectedSize: $this->exactSize, actualSize: $this->uncompressedSize); - } - - $this->crc = hexdec(hash_final($hash)); - } - - private function compressionInit(): ?DeflateContext - { - switch ($this->compressionMethod) { - case CompressionMethod::STORE: - // Noting to do - return null; - case CompressionMethod::DEFLATE: - $deflateContext = deflate_init( - ZLIB_ENCODING_RAW, - ['level' => $this->deflateLevel] - ); - - if (!$deflateContext) { - // @codeCoverageIgnoreStart - throw new RuntimeException("Can't initialize deflate context."); - // @codeCoverageIgnoreEnd - } - - // False positive, resource is no longer returned from this function - return $deflateContext; - default: - // @codeCoverageIgnoreStart - throw new RuntimeException('Unsupported Compression Method ' . print_r($this->compressionMethod, true)); - // @codeCoverageIgnoreEnd - } - } - - private function getCdrFile(): string - { - $footer = $this->buildZip64ExtraBlock(); - - return CentralDirectoryFileHeader::generate( - versionMadeBy: ZipStream::ZIP_VERSION_MADE_BY, - versionNeededToExtract: $this->version->value, - generalPurposeBitFlag: $this->generalPurposeBitFlag, - compressionMethod: $this->compressionMethod, - lastModificationDateTime: $this->lastModificationDateTime, - crc32: $this->crc, - compressedSize: $this->compressedSize > 0xFFFFFFFF - ? 0xFFFFFFFF - : $this->compressedSize, - uncompressedSize: $this->uncompressedSize > 0xFFFFFFFF - ? 0xFFFFFFFF - : $this->uncompressedSize, - fileName: $this->fileName, - extraField: $footer, - fileComment: $this->comment, - diskNumberStart: 0, - internalFileAttributes: 0, - externalFileAttributes: 32, - relativeOffsetOfLocalHeader: $this->startOffset > 0xFFFFFFFF - ? 0xFFFFFFFF - : $this->startOffset, - ); - } - - private function isSimulation(): bool - { - return $this->operationMode === OperationMode::SIMULATE_LAX || $this->operationMode === OperationMode::SIMULATE_STRICT; - } -} diff --git a/vendor/maennchen/zipstream-php/src/GeneralPurposeBitFlag.php b/vendor/maennchen/zipstream-php/src/GeneralPurposeBitFlag.php deleted file mode 100644 index 23a66d889..000000000 --- a/vendor/maennchen/zipstream-php/src/GeneralPurposeBitFlag.php +++ /dev/null @@ -1,89 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -/** - * @internal - */ -abstract class GeneralPurposeBitFlag -{ - /** - * If set, indicates that the file is encrypted. - */ - public const ENCRYPTED = 1 << 0; - - /** - * (For Methods 8 and 9 - Deflating) - * Normal (-en) compression option was used. - */ - public const DEFLATE_COMPRESSION_NORMAL = 0 << 1; - - /** - * (For Methods 8 and 9 - Deflating) - * Maximum (-exx/-ex) compression option was used. - */ - public const DEFLATE_COMPRESSION_MAXIMUM = 1 << 1; - - /** - * (For Methods 8 and 9 - Deflating) - * Fast (-ef) compression option was used. - */ - public const DEFLATE_COMPRESSION_FAST = 10 << 1; - - /** - * (For Methods 8 and 9 - Deflating) - * Super Fast (-es) compression option was used. - */ - public const DEFLATE_COMPRESSION_SUPERFAST = 11 << 1; - - /** - * If the compression method used was type 14, - * LZMA, then this bit, if set, indicates - * an end-of-stream (EOS) marker is used to - * mark the end of the compressed data stream. - * If clear, then an EOS marker is not present - * and the compressed data size must be known - * to extract. - */ - public const LZMA_EOS = 1 << 1; - - /** - * If this bit is set, the fields crc-32, compressed - * size and uncompressed size are set to zero in the - * local header. The correct values are put in the - * data descriptor immediately following the compressed - * data. - */ - public const ZERO_HEADER = 1 << 3; - - /** - * If this bit is set, this indicates that the file is - * compressed patched data. - */ - public const COMPRESSED_PATCHED_DATA = 1 << 5; - - /** - * Strong encryption. If this bit is set, you MUST - * set the version needed to extract value to at least - * 50 and you MUST also set bit 0. If AES encryption - * is used, the version needed to extract value MUST - * be at least 51. - */ - public const STRONG_ENCRYPTION = 1 << 6; - - /** - * Language encoding flag (EFS). If this bit is set, - * the filename and comment fields for this file - * MUST be encoded using UTF-8. - */ - public const EFS = 1 << 11; - - /** - * Set when encrypting the Central Directory to indicate - * selected data values in the Local Header are masked to - * hide their actual values. - */ - public const ENCRYPT_CENTRAL_DIRECTORY = 1 << 13; -} diff --git a/vendor/maennchen/zipstream-php/src/LocalFileHeader.php b/vendor/maennchen/zipstream-php/src/LocalFileHeader.php deleted file mode 100644 index e08b65610..000000000 --- a/vendor/maennchen/zipstream-php/src/LocalFileHeader.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -use DateTimeInterface; - -/** - * @internal - */ -abstract class LocalFileHeader -{ - private const SIGNATURE = 0x04034b50; - - public static function generate( - int $versionNeededToExtract, - int $generalPurposeBitFlag, - CompressionMethod $compressionMethod, - DateTimeInterface $lastModificationDateTime, - int $crc32UncompressedData, - int $compressedSize, - int $uncompressedSize, - string $fileName, - string $extraField, - ): string { - return PackField::pack( - new PackField(format: 'V', value: self::SIGNATURE), - new PackField(format: 'v', value: $versionNeededToExtract), - new PackField(format: 'v', value: $generalPurposeBitFlag), - new PackField(format: 'v', value: $compressionMethod->value), - new PackField(format: 'V', value: Time::dateTimeToDosTime($lastModificationDateTime)), - new PackField(format: 'V', value: $crc32UncompressedData), - new PackField(format: 'V', value: $compressedSize), - new PackField(format: 'V', value: $uncompressedSize), - new PackField(format: 'v', value: strlen($fileName)), - new PackField(format: 'v', value: strlen($extraField)), - ) . $fileName . $extraField; - } -} diff --git a/vendor/maennchen/zipstream-php/src/OperationMode.php b/vendor/maennchen/zipstream-php/src/OperationMode.php deleted file mode 100644 index dd650f070..000000000 --- a/vendor/maennchen/zipstream-php/src/OperationMode.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -/** - * ZipStream execution operation modes - */ -enum OperationMode -{ - /** - * Stream file into output stream - */ - case NORMAL; - - /** - * Simulate the zip to figure out the resulting file size - * - * This only supports entries where the file size is known beforehand and - * deflation is disabled. - */ - case SIMULATE_STRICT; - - /** - * Simulate the zip to figure out the resulting file size - * - * If the file size is not known beforehand or deflation is enabled, the - * entry streams will be read and rewound. - * - * If the entry does not support rewinding either, you will not be able to - * use the same stream in a later operation mode like `NORMAL`. - */ - case SIMULATE_LAX; -} diff --git a/vendor/maennchen/zipstream-php/src/PackField.php b/vendor/maennchen/zipstream-php/src/PackField.php deleted file mode 100644 index 892b4009a..000000000 --- a/vendor/maennchen/zipstream-php/src/PackField.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -use RuntimeException; - -/** - * @internal - * TODO: Make class readonly when requiring PHP 8.2 exclusively - */ -class PackField -{ - public const MAX_V = 0xFFFFFFFF; - - public const MAX_v = 0xFFFF; - - public function __construct( - public readonly string $format, - public readonly int|string $value - ) {} - - /** - * Create a format string and argument list for pack(), then call - * pack() and return the result. - */ - public static function pack(self ...$fields): string - { - $fmt = array_reduce($fields, function (string $acc, self $field) { - return $acc . $field->format; - }, ''); - - $args = array_map(function (self $field) { - switch ($field->format) { - case 'V': - if ($field->value > self::MAX_V) { - throw new RuntimeException(print_r($field->value, true) . ' is larger than 32 bits'); - } - break; - case 'v': - if ($field->value > self::MAX_v) { - throw new RuntimeException(print_r($field->value, true) . ' is larger than 16 bits'); - } - break; - case 'P': break; - default: - break; - } - - return $field->value; - }, $fields); - - return pack($fmt, ...$args); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Time.php b/vendor/maennchen/zipstream-php/src/Time.php deleted file mode 100644 index 1b4121ca9..000000000 --- a/vendor/maennchen/zipstream-php/src/Time.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -use DateInterval; -use DateTimeImmutable; -use DateTimeInterface; -use ZipStream\Exception\DosTimeOverflowException; - -/** - * @internal - */ -abstract class Time -{ - private const DOS_MINIMUM_DATE = '1980-01-01 00:00:00Z'; - - public static function dateTimeToDosTime(DateTimeInterface $dateTime): int - { - $dosMinimumDate = new DateTimeImmutable(self::DOS_MINIMUM_DATE); - - if ($dateTime->getTimestamp() < $dosMinimumDate->getTimestamp()) { - throw new DosTimeOverflowException(dateTime: $dateTime); - } - - $dateTime = DateTimeImmutable::createFromInterface($dateTime)->sub(new DateInterval('P1980Y')); - - [$year, $month, $day, $hour, $minute, $second] = explode(' ', $dateTime->format('Y n j G i s')); - - return - ((int) $year << 25) | - ((int) $month << 21) | - ((int) $day << 16) | - ((int) $hour << 11) | - ((int) $minute << 5) | - ((int) $second >> 1); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Version.php b/vendor/maennchen/zipstream-php/src/Version.php deleted file mode 100644 index c014f8a10..000000000 --- a/vendor/maennchen/zipstream-php/src/Version.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -enum Version: int -{ - case STORE = 0x000A; // 1.00 - case DEFLATE = 0x0014; // 2.00 - case ZIP64 = 0x002D; // 4.50 -} diff --git a/vendor/maennchen/zipstream-php/src/Zip64/DataDescriptor.php b/vendor/maennchen/zipstream-php/src/Zip64/DataDescriptor.php deleted file mode 100644 index 041c5579d..000000000 --- a/vendor/maennchen/zipstream-php/src/Zip64/DataDescriptor.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Zip64; - -use ZipStream\PackField; - -/** - * @internal - */ -abstract class DataDescriptor -{ - private const SIGNATURE = 0x08074b50; - - public static function generate( - int $crc32UncompressedData, - int $compressedSize, - int $uncompressedSize, - ): string { - return PackField::pack( - new PackField(format: 'V', value: self::SIGNATURE), - new PackField(format: 'V', value: $crc32UncompressedData), - new PackField(format: 'P', value: $compressedSize), - new PackField(format: 'P', value: $uncompressedSize), - ); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectory.php b/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectory.php deleted file mode 100644 index 08588e49c..000000000 --- a/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectory.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Zip64; - -use ZipStream\PackField; - -/** - * @internal - */ -abstract class EndOfCentralDirectory -{ - private const SIGNATURE = 0x06064b50; - - public static function generate( - int $versionMadeBy, - int $versionNeededToExtract, - int $numberOfThisDisk, - int $numberOfTheDiskWithCentralDirectoryStart, - int $numberOfCentralDirectoryEntriesOnThisDisk, - int $numberOfCentralDirectoryEntries, - int $sizeOfCentralDirectory, - int $centralDirectoryStartOffsetOnDisk, - string $extensibleDataSector, - ): string { - $recordSize = 44 + strlen($extensibleDataSector); // (length of block - 12) = 44; - - /** @psalm-suppress MixedArgument */ - return PackField::pack( - new PackField(format: 'V', value: static::SIGNATURE), - new PackField(format: 'P', value: $recordSize), - new PackField(format: 'v', value: $versionMadeBy), - new PackField(format: 'v', value: $versionNeededToExtract), - new PackField(format: 'V', value: $numberOfThisDisk), - new PackField(format: 'V', value: $numberOfTheDiskWithCentralDirectoryStart), - new PackField(format: 'P', value: $numberOfCentralDirectoryEntriesOnThisDisk), - new PackField(format: 'P', value: $numberOfCentralDirectoryEntries), - new PackField(format: 'P', value: $sizeOfCentralDirectory), - new PackField(format: 'P', value: $centralDirectoryStartOffsetOnDisk), - ) . $extensibleDataSector; - } -} diff --git a/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectoryLocator.php b/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectoryLocator.php deleted file mode 100644 index ef431c347..000000000 --- a/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectoryLocator.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Zip64; - -use ZipStream\PackField; - -/** - * @internal - */ -abstract class EndOfCentralDirectoryLocator -{ - private const SIGNATURE = 0x07064b50; - - public static function generate( - int $numberOfTheDiskWithZip64CentralDirectoryStart, - int $zip64centralDirectoryStartOffsetOnDisk, - int $totalNumberOfDisks, - ): string { - /** @psalm-suppress MixedArgument */ - return PackField::pack( - new PackField(format: 'V', value: static::SIGNATURE), - new PackField(format: 'V', value: $numberOfTheDiskWithZip64CentralDirectoryStart), - new PackField(format: 'P', value: $zip64centralDirectoryStartOffsetOnDisk), - new PackField(format: 'V', value: $totalNumberOfDisks), - ); - } -} diff --git a/vendor/maennchen/zipstream-php/src/Zip64/ExtendedInformationExtraField.php b/vendor/maennchen/zipstream-php/src/Zip64/ExtendedInformationExtraField.php deleted file mode 100644 index aaac51c83..000000000 --- a/vendor/maennchen/zipstream-php/src/Zip64/ExtendedInformationExtraField.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Zip64; - -use ZipStream\PackField; - -/** - * @internal - */ -abstract class ExtendedInformationExtraField -{ - private const TAG = 0x0001; - - public static function generate( - ?int $originalSize = null, - ?int $compressedSize = null, - ?int $relativeHeaderOffset = null, - ?int $diskStartNumber = null, - ): string { - return PackField::pack( - new PackField(format: 'v', value: self::TAG), - new PackField( - format: 'v', - value: ($originalSize === null ? 0 : 8) + - ($compressedSize === null ? 0 : 8) + - ($relativeHeaderOffset === null ? 0 : 8) + - ($diskStartNumber === null ? 0 : 4) - ), - ...($originalSize === null ? [] : [ - new PackField(format: 'P', value: $originalSize), - ]), - ...($compressedSize === null ? [] : [ - new PackField(format: 'P', value: $compressedSize), - ]), - ...($relativeHeaderOffset === null ? [] : [ - new PackField(format: 'P', value: $relativeHeaderOffset), - ]), - ...($diskStartNumber === null ? [] : [ - new PackField(format: 'V', value: $diskStartNumber), - ]), - ); - } -} diff --git a/vendor/maennchen/zipstream-php/src/ZipStream.php b/vendor/maennchen/zipstream-php/src/ZipStream.php deleted file mode 100644 index 3f4f481a8..000000000 --- a/vendor/maennchen/zipstream-php/src/ZipStream.php +++ /dev/null @@ -1,865 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream; - -use Closure; -use DateTimeImmutable; -use DateTimeInterface; -use GuzzleHttp\Psr7\StreamWrapper; -use Psr\Http\Message\StreamInterface; -use RuntimeException; -use ZipStream\Exception\FileNotFoundException; -use ZipStream\Exception\FileNotReadableException; -use ZipStream\Exception\OverflowException; -use ZipStream\Exception\ResourceActionException; - -/** - * Streamed, dynamically generated zip archives. - * - * ## Usage - * - * Streaming zip archives is a simple, three-step process: - * - * 1. Create the zip stream: - * - * ```php - * $zip = new ZipStream(outputName: 'example.zip'); - * ``` - * - * 2. Add one or more files to the archive: - * - * ```php - * // add first file - * $zip->addFile(fileName: 'world.txt', data: 'Hello World'); - * - * // add second file - * $zip->addFile(fileName: 'moon.txt', data: 'Hello Moon'); - * ``` - * - * 3. Finish the zip stream: - * - * ```php - * $zip->finish(); - * ``` - * - * You can also add an archive comment, add comments to individual files, - * and adjust the timestamp of files. See the API documentation for each - * method below for additional information. - * - * ## Example - * - * ```php - * // create a new zip stream object - * $zip = new ZipStream(outputName: 'some_files.zip'); - * - * // list of local files - * $files = array('foo.txt', 'bar.jpg'); - * - * // read and add each file to the archive - * foreach ($files as $path) - * $zip->addFileFromPath(fileName: $path, $path); - * - * // write archive footer to stream - * $zip->finish(); - * ``` - */ -class ZipStream -{ - /** - * This number corresponds to the ZIP version/OS used (2 bytes) - * From: https://www.iana.org/assignments/media-types/application/zip - * The upper byte (leftmost one) indicates the host system (OS) for the - * file. Software can use this information to determine - * the line record format for text files etc. The current - * mappings are: - * - * 0 - MS-DOS and OS/2 (F.A.T. file systems) - * 1 - Amiga 2 - VAX/VMS - * 3 - *nix 4 - VM/CMS - * 5 - Atari ST 6 - OS/2 H.P.F.S. - * 7 - Macintosh 8 - Z-System - * 9 - CP/M 10 thru 255 - unused - * - * The lower byte (rightmost one) indicates the version number of the - * software used to encode the file. The value/10 - * indicates the major version number, and the value - * mod 10 is the minor version number. - * Here we are using 6 for the OS, indicating OS/2 H.P.F.S. - * to prevent file permissions issues upon extract (see #84) - * 0x603 is 00000110 00000011 in binary, so 6 and 3 - * - * @internal - */ - public const ZIP_VERSION_MADE_BY = 0x603; - - private bool $ready = true; - - private int $offset = 0; - - /** - * @var string[] - */ - private array $centralDirectoryRecords = []; - - /** - * @var resource - */ - private $outputStream; - - private readonly Closure $httpHeaderCallback; - - /** - * @var File[] - */ - private array $recordedSimulation = []; - - /** - * Create a new ZipStream object. - * - * ##### Examples - * - * ```php - * // create a new zip file named 'foo.zip' - * $zip = new ZipStream(outputName: 'foo.zip'); - * - * // create a new zip file named 'bar.zip' with a comment - * $zip = new ZipStream( - * outputName: 'bar.zip', - * comment: 'this is a comment for the zip file.', - * ); - * ``` - * - * @param OperationMode $operationMode - * The mode can be used to switch between `NORMAL` and `SIMULATION_*` modes. - * For details see the `OperationMode` documentation. - * - * Default to `NORMAL`. - * - * @param string $comment - * Archive Level Comment - * - * @param StreamInterface|resource|null $outputStream - * Override the output of the archive to a different target. - * - * By default the archive is sent to `STDOUT`. - * - * @param CompressionMethod $defaultCompressionMethod - * How to handle file compression. Legal values are - * `CompressionMethod::DEFLATE` (the default), or - * `CompressionMethod::STORE`. `STORE` sends the file raw and is - * significantly faster, while `DEFLATE` compresses the file and - * is much, much slower. - * - * @param int $defaultDeflateLevel - * Default deflation level. Only relevant if `compressionMethod` - * is `DEFLATE`. - * - * See details of [`deflate_init`](https://www.php.net/manual/en/function.deflate-init.php#refsect1-function.deflate-init-parameters) - * - * @param bool $enableZip64 - * Enable Zip64 extension, supporting very large - * archives (any size > 4 GB or file count > 64k) - * - * @param bool $defaultEnableZeroHeader - * Enable streaming files with single read. - * - * When the zero header is set, the file is streamed into the output - * and the size & checksum are added at the end of the file. This is the - * fastest method and uses the least memory. Unfortunately not all - * ZIP clients fully support this and can lead to clients reporting - * the generated ZIP files as corrupted in combination with other - * circumstances. (Zip64 enabled, using UTF8 in comments / names etc.) - * - * When the zero header is not set, the length & checksum need to be - * defined before the file is actually added. To prevent loading all - * the data into memory, the data has to be read twice. If the data - * which is added is not seekable, this call will fail. - * - * @param bool $sendHttpHeaders - * Boolean indicating whether or not to send - * the HTTP headers for this file. - * - * @param ?Closure $httpHeaderCallback - * The method called to send HTTP headers - * - * @param string|null $outputName - * The name of the created archive. - * - * Only relevant if `$sendHttpHeaders = true`. - * - * @param string $contentDisposition - * HTTP Content-Disposition - * - * Only relevant if `sendHttpHeaders = true`. - * - * @param string $contentType - * HTTP Content Type - * - * Only relevant if `sendHttpHeaders = true`. - * - * @param bool $flushOutput - * Enable flush after every write to output stream. - * - * @return self - */ - public function __construct( - private OperationMode $operationMode = OperationMode::NORMAL, - private readonly string $comment = '', - $outputStream = null, - private readonly CompressionMethod $defaultCompressionMethod = CompressionMethod::DEFLATE, - private readonly int $defaultDeflateLevel = 6, - private readonly bool $enableZip64 = true, - private readonly bool $defaultEnableZeroHeader = true, - private bool $sendHttpHeaders = true, - ?Closure $httpHeaderCallback = null, - private readonly ?string $outputName = null, - private readonly string $contentDisposition = 'attachment', - private readonly string $contentType = 'application/x-zip', - private bool $flushOutput = false, - ) { - $this->outputStream = self::normalizeStream($outputStream); - $this->httpHeaderCallback = $httpHeaderCallback ?? header(...); - } - - /** - * Add a file to the archive. - * - * ##### File Options - * - * See {@see addFileFromPsr7Stream()} - * - * ##### Examples - * - * ```php - * // add a file named 'world.txt' - * $zip->addFile(fileName: 'world.txt', data: 'Hello World!'); - * - * // add a file named 'bar.jpg' with a comment and a last-modified - * // time of two hours ago - * $zip->addFile( - * fileName: 'bar.jpg', - * data: $data, - * comment: 'this is a comment about bar.jpg', - * lastModificationDateTime: new DateTime('2 hours ago'), - * ); - * ``` - * - * @param string $data - * - * contents of file - */ - public function addFile( - string $fileName, - string $data, - string $comment = '', - ?CompressionMethod $compressionMethod = null, - ?int $deflateLevel = null, - ?DateTimeInterface $lastModificationDateTime = null, - ?int $maxSize = null, - ?int $exactSize = null, - ?bool $enableZeroHeader = null, - ): void { - $this->addFileFromCallback( - fileName: $fileName, - callback: fn() => $data, - comment: $comment, - compressionMethod: $compressionMethod, - deflateLevel: $deflateLevel, - lastModificationDateTime: $lastModificationDateTime, - maxSize: $maxSize, - exactSize: $exactSize, - enableZeroHeader: $enableZeroHeader, - ); - } - - /** - * Add a file at path to the archive. - * - * ##### File Options - * - * See {@see addFileFromPsr7Stream()} - * - * ###### Examples - * - * ```php - * // add a file named 'foo.txt' from the local file '/tmp/foo.txt' - * $zip->addFileFromPath( - * fileName: 'foo.txt', - * path: '/tmp/foo.txt', - * ); - * - * // add a file named 'bigfile.rar' from the local file - * // '/usr/share/bigfile.rar' with a comment and a last-modified - * // time of two hours ago - * $zip->addFileFromPath( - * fileName: 'bigfile.rar', - * path: '/usr/share/bigfile.rar', - * comment: 'this is a comment about bigfile.rar', - * lastModificationDateTime: new DateTime('2 hours ago'), - * ); - * ``` - * - * @throws \ZipStream\Exception\FileNotFoundException - * @throws \ZipStream\Exception\FileNotReadableException - */ - public function addFileFromPath( - /** - * name of file in archive (including directory path). - */ - string $fileName, - - /** - * path to file on disk (note: paths should be encoded using - * UNIX-style forward slashes -- e.g '/path/to/some/file'). - */ - string $path, - string $comment = '', - ?CompressionMethod $compressionMethod = null, - ?int $deflateLevel = null, - ?DateTimeInterface $lastModificationDateTime = null, - ?int $maxSize = null, - ?int $exactSize = null, - ?bool $enableZeroHeader = null, - ): void { - if (!is_readable($path)) { - if (!file_exists($path)) { - throw new FileNotFoundException($path); - } - throw new FileNotReadableException($path); - } - - $fileTime = filemtime($path); - if ($fileTime !== false) { - $lastModificationDateTime ??= (new DateTimeImmutable())->setTimestamp($fileTime); - } - - $this->addFileFromCallback( - fileName: $fileName, - callback: function () use ($path) { - - $stream = fopen($path, 'rb'); - - if (!$stream) { - // @codeCoverageIgnoreStart - throw new ResourceActionException('fopen'); - // @codeCoverageIgnoreEnd - } - - return $stream; - }, - comment: $comment, - compressionMethod: $compressionMethod, - deflateLevel: $deflateLevel, - lastModificationDateTime: $lastModificationDateTime, - maxSize: $maxSize, - exactSize: $exactSize, - enableZeroHeader: $enableZeroHeader, - ); - } - - /** - * Add an open stream (resource) to the archive. - * - * ##### File Options - * - * See {@see addFileFromPsr7Stream()} - * - * ##### Examples - * - * ```php - * // create a temporary file stream and write text to it - * $filePointer = tmpfile(); - * fwrite($filePointer, 'The quick brown fox jumped over the lazy dog.'); - * - * // add a file named 'streamfile.txt' from the content of the stream - * $archive->addFileFromStream( - * fileName: 'streamfile.txt', - * stream: $filePointer, - * ); - * ``` - * - * @param resource $stream contents of file as a stream resource - */ - public function addFileFromStream( - string $fileName, - $stream, - string $comment = '', - ?CompressionMethod $compressionMethod = null, - ?int $deflateLevel = null, - ?DateTimeInterface $lastModificationDateTime = null, - ?int $maxSize = null, - ?int $exactSize = null, - ?bool $enableZeroHeader = null, - ): void { - $this->addFileFromCallback( - fileName: $fileName, - callback: fn() => $stream, - comment: $comment, - compressionMethod: $compressionMethod, - deflateLevel: $deflateLevel, - lastModificationDateTime: $lastModificationDateTime, - maxSize: $maxSize, - exactSize: $exactSize, - enableZeroHeader: $enableZeroHeader, - ); - } - - /** - * Add an open stream to the archive. - * - * ##### Examples - * - * ```php - * $stream = $response->getBody(); - * // add a file named 'streamfile.txt' from the content of the stream - * $archive->addFileFromPsr7Stream( - * fileName: 'streamfile.txt', - * stream: $stream, - * ); - * ``` - * - * @param string $fileName - * path of file in archive (including directory) - * - * @param StreamInterface $stream - * contents of file as a stream resource - * - * @param string $comment - * ZIP comment for this file - * - * @param ?CompressionMethod $compressionMethod - * Override `defaultCompressionMethod` - * - * See {@see __construct()} - * - * @param ?int $deflateLevel - * Override `defaultDeflateLevel` - * - * See {@see __construct()} - * - * @param ?DateTimeInterface $lastModificationDateTime - * Set last modification time of file. - * - * Default: `now` - * - * @param ?int $maxSize - * Only read `maxSize` bytes from file. - * - * The file is considered done when either reaching `EOF` - * or the `maxSize`. - * - * @param ?int $exactSize - * Read exactly `exactSize` bytes from file. - * If `EOF` is reached before reading `exactSize` bytes, an error will be - * thrown. The parameter allows for faster size calculations if the `stream` - * does not support `fstat` size or is slow and otherwise known beforehand. - * - * @param ?bool $enableZeroHeader - * Override `defaultEnableZeroHeader` - * - * See {@see __construct()} - */ - public function addFileFromPsr7Stream( - string $fileName, - StreamInterface $stream, - string $comment = '', - ?CompressionMethod $compressionMethod = null, - ?int $deflateLevel = null, - ?DateTimeInterface $lastModificationDateTime = null, - ?int $maxSize = null, - ?int $exactSize = null, - ?bool $enableZeroHeader = null, - ): void { - $this->addFileFromCallback( - fileName: $fileName, - callback: fn() => $stream, - comment: $comment, - compressionMethod: $compressionMethod, - deflateLevel: $deflateLevel, - lastModificationDateTime: $lastModificationDateTime, - maxSize: $maxSize, - exactSize: $exactSize, - enableZeroHeader: $enableZeroHeader, - ); - } - - /** - * Add a file based on a callback. - * - * This is useful when you want to simulate a lot of files without keeping - * all of the file handles open at the same time. - * - * ##### Examples - * - * ```php - * foreach($files as $name => $size) { - * $archive->addFileFromCallback( - * fileName: 'streamfile.txt', - * exactSize: $size, - * callback: function() use($name): Psr\Http\Message\StreamInterface { - * $response = download($name); - * return $response->getBody(); - * } - * ); - * } - * ``` - * - * @param string $fileName - * path of file in archive (including directory) - * - * @param Closure $callback - * @psalm-param Closure(): (resource|StreamInterface|string) $callback - * A callback to get the file contents in the shape of a PHP stream, - * a Psr StreamInterface implementation, or a string. - * - * @param string $comment - * ZIP comment for this file - * - * @param ?CompressionMethod $compressionMethod - * Override `defaultCompressionMethod` - * - * See {@see __construct()} - * - * @param ?int $deflateLevel - * Override `defaultDeflateLevel` - * - * See {@see __construct()} - * - * @param ?DateTimeInterface $lastModificationDateTime - * Set last modification time of file. - * - * Default: `now` - * - * @param ?int $maxSize - * Only read `maxSize` bytes from file. - * - * The file is considered done when either reaching `EOF` - * or the `maxSize`. - * - * @param ?int $exactSize - * Read exactly `exactSize` bytes from file. - * If `EOF` is reached before reading `exactSize` bytes, an error will be - * thrown. The parameter allows for faster size calculations if the `stream` - * does not support `fstat` size or is slow and otherwise known beforehand. - * - * @param ?bool $enableZeroHeader - * Override `defaultEnableZeroHeader` - * - * See {@see __construct()} - */ - public function addFileFromCallback( - string $fileName, - Closure $callback, - string $comment = '', - ?CompressionMethod $compressionMethod = null, - ?int $deflateLevel = null, - ?DateTimeInterface $lastModificationDateTime = null, - ?int $maxSize = null, - ?int $exactSize = null, - ?bool $enableZeroHeader = null, - ): void { - $file = new File( - dataCallback: function () use ($callback, $maxSize) { - $data = $callback(); - - if (is_resource($data)) { - return $data; - } - - if ($data instanceof StreamInterface) { - return StreamWrapper::getResource($data); - } - - - $stream = fopen('php://memory', 'rw+'); - if ($stream === false) { - // @codeCoverageIgnoreStart - throw new ResourceActionException('fopen'); - // @codeCoverageIgnoreEnd - } - if ($maxSize !== null && fwrite($stream, $data, $maxSize) === false) { - // @codeCoverageIgnoreStart - throw new ResourceActionException('fwrite', $stream); - // @codeCoverageIgnoreEnd - } elseif (fwrite($stream, $data) === false) { - // @codeCoverageIgnoreStart - throw new ResourceActionException('fwrite', $stream); - // @codeCoverageIgnoreEnd - } - if (rewind($stream) === false) { - // @codeCoverageIgnoreStart - throw new ResourceActionException('rewind', $stream); - // @codeCoverageIgnoreEnd - } - - return $stream; - - }, - send: $this->send(...), - recordSentBytes: $this->recordSentBytes(...), - operationMode: $this->operationMode, - fileName: $fileName, - startOffset: $this->offset, - compressionMethod: $compressionMethod ?? $this->defaultCompressionMethod, - comment: $comment, - deflateLevel: $deflateLevel ?? $this->defaultDeflateLevel, - lastModificationDateTime: $lastModificationDateTime ?? new DateTimeImmutable(), - maxSize: $maxSize, - exactSize: $exactSize, - enableZip64: $this->enableZip64, - enableZeroHeader: $enableZeroHeader ?? $this->defaultEnableZeroHeader, - ); - - if ($this->operationMode !== OperationMode::NORMAL) { - $this->recordedSimulation[] = $file; - } - - $this->centralDirectoryRecords[] = $file->process(); - } - - /** - * Add a directory to the archive. - * - * ##### File Options - * - * See {@see addFileFromPsr7Stream()} - * - * ##### Examples - * - * ```php - * // add a directory named 'world/' - * $zip->addDirectory(fileName: 'world/'); - * ``` - */ - public function addDirectory( - string $fileName, - string $comment = '', - ?DateTimeInterface $lastModificationDateTime = null, - ): void { - if (!str_ends_with($fileName, '/')) { - $fileName .= '/'; - } - - $this->addFile( - fileName: $fileName, - data: '', - comment: $comment, - compressionMethod: CompressionMethod::STORE, - deflateLevel: null, - lastModificationDateTime: $lastModificationDateTime, - maxSize: 0, - exactSize: 0, - enableZeroHeader: false, - ); - } - - /** - * Executes a previously calculated simulation. - * - * ##### Example - * - * ```php - * $zip = new ZipStream( - * outputName: 'foo.zip', - * operationMode: OperationMode::SIMULATE_STRICT, - * ); - * - * $zip->addFile('test.txt', 'Hello World'); - * - * $size = $zip->finish(); - * - * header('Content-Length: '. $size); - * - * $zip->executeSimulation(); - * ``` - */ - public function executeSimulation(): void - { - if ($this->operationMode !== OperationMode::NORMAL) { - throw new RuntimeException('Zip simulation is not finished.'); - } - - foreach ($this->recordedSimulation as $file) { - $this->centralDirectoryRecords[] = $file->cloneSimulationExecution()->process(); - } - - $this->finish(); - } - - /** - * Write zip footer to stream. - * - * The clase is left in an unusable state after `finish`. - * - * ##### Example - * - * ```php - * // write footer to stream - * $zip->finish(); - * ``` - */ - public function finish(): int - { - $centralDirectoryStartOffsetOnDisk = $this->offset; - $sizeOfCentralDirectory = 0; - - // add trailing cdr file records - foreach ($this->centralDirectoryRecords as $centralDirectoryRecord) { - $this->send($centralDirectoryRecord); - $sizeOfCentralDirectory += strlen($centralDirectoryRecord); - } - - // Add 64bit headers (if applicable) - if (count($this->centralDirectoryRecords) >= 0xFFFF || - $centralDirectoryStartOffsetOnDisk > 0xFFFFFFFF || - $sizeOfCentralDirectory > 0xFFFFFFFF) { - if (!$this->enableZip64) { - throw new OverflowException(); - } - - $this->send(Zip64\EndOfCentralDirectory::generate( - versionMadeBy: self::ZIP_VERSION_MADE_BY, - versionNeededToExtract: Version::ZIP64->value, - numberOfThisDisk: 0, - numberOfTheDiskWithCentralDirectoryStart: 0, - numberOfCentralDirectoryEntriesOnThisDisk: count($this->centralDirectoryRecords), - numberOfCentralDirectoryEntries: count($this->centralDirectoryRecords), - sizeOfCentralDirectory: $sizeOfCentralDirectory, - centralDirectoryStartOffsetOnDisk: $centralDirectoryStartOffsetOnDisk, - extensibleDataSector: '', - )); - - $this->send(Zip64\EndOfCentralDirectoryLocator::generate( - numberOfTheDiskWithZip64CentralDirectoryStart: 0x00, - zip64centralDirectoryStartOffsetOnDisk: $centralDirectoryStartOffsetOnDisk + $sizeOfCentralDirectory, - totalNumberOfDisks: 1, - )); - } - - // add trailing cdr eof record - $numberOfCentralDirectoryEntries = min(count($this->centralDirectoryRecords), 0xFFFF); - $this->send(EndOfCentralDirectory::generate( - numberOfThisDisk: 0x00, - numberOfTheDiskWithCentralDirectoryStart: 0x00, - numberOfCentralDirectoryEntriesOnThisDisk: $numberOfCentralDirectoryEntries, - numberOfCentralDirectoryEntries: $numberOfCentralDirectoryEntries, - sizeOfCentralDirectory: min($sizeOfCentralDirectory, 0xFFFFFFFF), - centralDirectoryStartOffsetOnDisk: min($centralDirectoryStartOffsetOnDisk, 0xFFFFFFFF), - zipFileComment: $this->comment, - )); - - $size = $this->offset; - - // The End - $this->clear(); - - return $size; - } - - /** - * @param StreamInterface|resource|null $outputStream - * @return resource - */ - private static function normalizeStream($outputStream) - { - if ($outputStream instanceof StreamInterface) { - return StreamWrapper::getResource($outputStream); - } - if (is_resource($outputStream)) { - return $outputStream; - } - return fopen('php://output', 'wb'); - } - - /** - * Record sent bytes - */ - private function recordSentBytes(int $sentBytes): void - { - $this->offset += $sentBytes; - } - - /** - * Send string, sending HTTP headers if necessary. - * Flush output after write if configure option is set. - */ - private function send(string $data): void - { - if (!$this->ready) { - throw new RuntimeException('Archive is already finished'); - } - - if ($this->operationMode === OperationMode::NORMAL && $this->sendHttpHeaders) { - $this->sendHttpHeaders(); - $this->sendHttpHeaders = false; - } - - $this->recordSentBytes(strlen($data)); - - if ($this->operationMode === OperationMode::NORMAL) { - if (fwrite($this->outputStream, $data) === false) { - throw new ResourceActionException('fwrite', $this->outputStream); - } - - if ($this->flushOutput) { - // flush output buffer if it is on and flushable - $status = ob_get_status(); - if (isset($status['flags']) && is_int($status['flags']) && ($status['flags'] & PHP_OUTPUT_HANDLER_FLUSHABLE)) { - ob_flush(); - } - - // Flush system buffers after flushing userspace output buffer - flush(); - } - } - } - - /** - * Send HTTP headers for this stream. - */ - private function sendHttpHeaders(): void - { - // grab content disposition - $disposition = $this->contentDisposition; - - if ($this->outputName !== null) { - // Various different browsers dislike various characters here. Strip them all for safety. - $safeOutput = trim(str_replace(['"', "'", '\\', ';', "\n", "\r"], '', $this->outputName)); - - // Check if we need to UTF-8 encode the filename - $urlencoded = rawurlencode($safeOutput); - $disposition .= "; filename*=UTF-8''{$urlencoded}"; - } - - $headers = [ - 'Content-Type' => $this->contentType, - 'Content-Disposition' => $disposition, - 'Pragma' => 'public', - 'Cache-Control' => 'public, must-revalidate', - 'Content-Transfer-Encoding' => 'binary', - ]; - - foreach ($headers as $key => $val) { - ($this->httpHeaderCallback)("$key: $val"); - } - } - - /** - * Clear all internal variables. Note that the stream object is not - * usable after this. - */ - private function clear(): void - { - $this->centralDirectoryRecords = []; - $this->offset = 0; - - if ($this->operationMode === OperationMode::NORMAL) { - $this->ready = false; - $this->recordedSimulation = []; - } else { - $this->operationMode = OperationMode::NORMAL; - } - } -} diff --git a/vendor/maennchen/zipstream-php/src/Zs/ExtendedInformationExtraField.php b/vendor/maennchen/zipstream-php/src/Zs/ExtendedInformationExtraField.php deleted file mode 100644 index bf621bc09..000000000 --- a/vendor/maennchen/zipstream-php/src/Zs/ExtendedInformationExtraField.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace ZipStream\Zs; - -use ZipStream\PackField; - -/** - * @internal - */ -abstract class ExtendedInformationExtraField -{ - private const TAG = 0x5653; - - public static function generate(): string - { - return PackField::pack( - new PackField(format: 'v', value: self::TAG), - new PackField(format: 'v', value: 0x0000), - ); - } -} |