package and depencies
This commit is contained in:
40
vendor/maennchen/zipstream-php/src/Bigint.php
vendored
40
vendor/maennchen/zipstream-php/src/Bigint.php
vendored
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream;
|
||||
@@ -22,22 +23,6 @@ class Bigint
|
||||
$this->fillBytes($value, 0, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the bytes field with int
|
||||
*
|
||||
* @param int $value
|
||||
* @param int $start
|
||||
* @param int $count
|
||||
* @return void
|
||||
*/
|
||||
protected function fillBytes(int $value, int $start, int $count): void
|
||||
{
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$this->bytes[$start + $i] = $i >= PHP_INT_SIZE ? 0 : $value & 0xFF;
|
||||
$value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance
|
||||
*
|
||||
@@ -58,7 +43,7 @@ class Bigint
|
||||
*/
|
||||
public static function fromLowHigh(int $low, int $high): self
|
||||
{
|
||||
$bigint = new Bigint();
|
||||
$bigint = new self();
|
||||
$bigint->fillBytes($low, 0, 4);
|
||||
$bigint->fillBytes($high, 4, 4);
|
||||
return $bigint;
|
||||
@@ -108,6 +93,7 @@ class Bigint
|
||||
/**
|
||||
* Check if is over 32
|
||||
*
|
||||
* @psalm-suppress ArgumentTypeCoercion
|
||||
* @param bool $force
|
||||
* @return bool
|
||||
*/
|
||||
@@ -149,7 +135,7 @@ class Bigint
|
||||
* @param Bigint $other
|
||||
* @return Bigint
|
||||
*/
|
||||
public function add(Bigint $other): Bigint
|
||||
public function add(self $other): self
|
||||
{
|
||||
$result = clone $this;
|
||||
$overflow = false;
|
||||
@@ -165,8 +151,24 @@ class Bigint
|
||||
}
|
||||
}
|
||||
if ($overflow) {
|
||||
throw new OverflowException;
|
||||
throw new OverflowException();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the bytes field with int
|
||||
*
|
||||
* @param int $value
|
||||
* @param int $start
|
||||
* @param int $count
|
||||
* @return void
|
||||
*/
|
||||
protected function fillBytes(int $value, int $start, int $count): void
|
||||
{
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$this->bytes[$start + $i] = $i >= PHP_INT_SIZE ? 0 : $value & 0xFF;
|
||||
$value >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
class DeflateStream extends Stream
|
||||
{
|
||||
protected $filter;
|
||||
|
||||
/**
|
||||
* @var Option\File
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Rewind stream
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rewind(): void
|
||||
public function __construct($stream)
|
||||
{
|
||||
// deflate filter needs to be removed before rewind
|
||||
if ($this->filter) {
|
||||
$this->removeDeflateFilter();
|
||||
$this->seek(0);
|
||||
$this->addDeflateFilter($this->options);
|
||||
} else {
|
||||
rewind($this->stream);
|
||||
}
|
||||
parent::__construct($stream);
|
||||
trigger_error('Class ' . __CLASS__ . ' is deprecated, delation will be handled internally instead', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the deflate filter
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeDeflateFilter(): void
|
||||
{
|
||||
if (!$this->filter) {
|
||||
return;
|
||||
}
|
||||
stream_filter_remove($this->filter);
|
||||
$this->filter = null;
|
||||
trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a deflate filter
|
||||
*
|
||||
* @param Option\File $options
|
||||
* @return void
|
||||
*/
|
||||
public function addDeflateFilter(Option\File $options): void
|
||||
{
|
||||
$this->options = $options;
|
||||
// parameter 4 for stream_filter_append expects array
|
||||
// so we convert the option object in an array
|
||||
$optionsArr = [
|
||||
'comment' => $options->getComment(),
|
||||
'method' => $options->getMethod(),
|
||||
'deflateLevel' => $options->getDeflateLevel(),
|
||||
'time' => $options->getTime()
|
||||
];
|
||||
$this->filter = stream_filter_append(
|
||||
$this->stream,
|
||||
'zlib.deflate',
|
||||
STREAM_FILTER_READ,
|
||||
$optionsArr
|
||||
);
|
||||
trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Exception;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Exception;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Exception;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Exception;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Exception;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Exception;
|
||||
|
||||
295
vendor/maennchen/zipstream-php/src/File.php
vendored
295
vendor/maennchen/zipstream-php/src/File.php
vendored
@@ -1,10 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream;
|
||||
|
||||
use HashContext;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use ZipStream\Exception\EncodingException;
|
||||
use ZipStream\Exception\FileNotFoundException;
|
||||
use ZipStream\Exception\FileNotReadableException;
|
||||
use ZipStream\Exception\OverflowException;
|
||||
@@ -14,13 +15,15 @@ use ZipStream\Option\Version;
|
||||
|
||||
class File
|
||||
{
|
||||
const HASH_ALGORITHM = 'crc32b';
|
||||
public const HASH_ALGORITHM = 'crc32b';
|
||||
|
||||
const BIT_ZERO_HEADER = 0x0008;
|
||||
const BIT_EFS_UTF8 = 0x0800;
|
||||
public const BIT_ZERO_HEADER = 0x0008;
|
||||
|
||||
const COMPUTE = 1;
|
||||
const SEND = 2;
|
||||
public const BIT_EFS_UTF8 = 0x0800;
|
||||
|
||||
public const COMPUTE = 1;
|
||||
|
||||
public const SEND = 2;
|
||||
|
||||
private const CHUNKED_READ_BLOCK_SIZE = 1048576;
|
||||
|
||||
@@ -38,6 +41,7 @@ class File
|
||||
* @var Bigint
|
||||
*/
|
||||
public $len;
|
||||
|
||||
/**
|
||||
* @var Bigint
|
||||
*/
|
||||
@@ -75,8 +79,9 @@ class File
|
||||
* @var resource
|
||||
*/
|
||||
private $deflate;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
* @var HashContext
|
||||
*/
|
||||
private $hash;
|
||||
|
||||
@@ -115,7 +120,7 @@ class File
|
||||
} else {
|
||||
$this->method = $this->zip->opt->getLargeFileMethod();
|
||||
|
||||
$stream = new DeflateStream(fopen($path, 'rb'));
|
||||
$stream = new Stream(fopen($path, 'rb'));
|
||||
$this->processStream($stream);
|
||||
$stream->close();
|
||||
}
|
||||
@@ -160,21 +165,17 @@ class File
|
||||
// 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($name, 'UTF-8') ||
|
||||
!mb_check_encoding($comment, 'UTF-8')) {
|
||||
throw new EncodingException(
|
||||
'File name and comment should use UTF-8 ' .
|
||||
'if one of them does not fit into ASCII range.'
|
||||
);
|
||||
if (mb_check_encoding($name, 'UTF-8') &&
|
||||
mb_check_encoding($comment, 'UTF-8')) {
|
||||
$this->bits |= self::BIT_EFS_UTF8;
|
||||
}
|
||||
$this->bits |= self::BIT_EFS_UTF8;
|
||||
}
|
||||
|
||||
if ($this->method->equals(Method::DEFLATE())) {
|
||||
$this->version = Version::DEFLATE();
|
||||
}
|
||||
|
||||
$force = (boolean)($this->bits & self::BIT_ZERO_HEADER) &&
|
||||
$force = (bool)($this->bits & self::BIT_ZERO_HEADER) &&
|
||||
$this->zip->opt->isEnableZip64();
|
||||
|
||||
$footer = $this->buildZip64ExtraBlock($force);
|
||||
@@ -226,83 +227,13 @@ class File
|
||||
return str_replace(['\\', ':', '*', '?', '"', '<', '>', '|'], '_', $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UNIX timestamp to a DOS timestamp.
|
||||
*
|
||||
* @param int $when
|
||||
* @return int DOS Timestamp
|
||||
*/
|
||||
final protected static function dosTime(int $when): int
|
||||
{
|
||||
// get date array for timestamp
|
||||
$d = getdate($when);
|
||||
|
||||
// set lower-bound on dates
|
||||
if ($d['year'] < 1980) {
|
||||
$d = array(
|
||||
'year' => 1980,
|
||||
'mon' => 1,
|
||||
'mday' => 1,
|
||||
'hours' => 0,
|
||||
'minutes' => 0,
|
||||
'seconds' => 0
|
||||
);
|
||||
}
|
||||
|
||||
// remove extra years from 1980
|
||||
$d['year'] -= 1980;
|
||||
|
||||
// return date string
|
||||
return
|
||||
($d['year'] << 25) |
|
||||
($d['mon'] << 21) |
|
||||
($d['mday'] << 16) |
|
||||
($d['hours'] << 11) |
|
||||
($d['minutes'] << 5) |
|
||||
($d['seconds'] >> 1);
|
||||
}
|
||||
|
||||
protected function buildZip64ExtraBlock(bool $force = false): string
|
||||
{
|
||||
|
||||
$fields = [];
|
||||
if ($this->len->isOver32($force)) {
|
||||
$fields[] = ['P', $this->len]; // Length of original data
|
||||
}
|
||||
|
||||
if ($this->len->isOver32($force)) {
|
||||
$fields[] = ['P', $this->zlen]; // Length of compressed data
|
||||
}
|
||||
|
||||
if ($this->ofs->isOver32()) {
|
||||
$fields[] = ['P', $this->ofs]; // Offset of local header record
|
||||
}
|
||||
|
||||
if (!empty($fields)) {
|
||||
if (!$this->zip->opt->isEnableZip64()) {
|
||||
throw new OverflowException();
|
||||
}
|
||||
|
||||
array_unshift(
|
||||
$fields,
|
||||
['v', 0x0001], // 64 bit extension
|
||||
['v', count($fields) * 8] // Length of data block
|
||||
);
|
||||
$this->version = Version::ZIP64();
|
||||
}
|
||||
|
||||
return ZipStream::packFields($fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and send data descriptor footer for this file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function addFileFooter(): void
|
||||
{
|
||||
|
||||
if ($this->bits & self::BIT_ZERO_HEADER) {
|
||||
// compressed and uncompressed size
|
||||
$sizeFormat = 'V';
|
||||
@@ -337,6 +268,130 @@ class File
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send CDR record for specified file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCdrFile(): string
|
||||
{
|
||||
$name = static::filterFilename($this->name);
|
||||
|
||||
// get attributes
|
||||
$comment = $this->opt->getComment();
|
||||
|
||||
// get dos timestamp
|
||||
$time = static::dosTime($this->opt->getTime()->getTimestamp());
|
||||
|
||||
$footer = $this->buildZip64ExtraBlock();
|
||||
|
||||
$fields = [
|
||||
['V', ZipStream::CDR_FILE_SIGNATURE], // Central file header signature
|
||||
['v', ZipStream::ZIP_VERSION_MADE_BY], // Made by version
|
||||
['v', $this->version->getValue()], // Extract by version
|
||||
['v', $this->bits], // General purpose bit flags - data descriptor flag set
|
||||
['v', $this->method->getValue()], // Compression method
|
||||
['V', $time], // Timestamp (DOS Format)
|
||||
['V', $this->crc], // CRC32
|
||||
['V', $this->zlen->getLowFF()], // Compressed Data Length
|
||||
['V', $this->len->getLowFF()], // Original Data Length
|
||||
['v', strlen($name)], // Length of filename
|
||||
['v', strlen($footer)], // Extra data len (see above)
|
||||
['v', strlen($comment)], // Length of comment
|
||||
['v', 0], // Disk number
|
||||
['v', 0], // Internal File Attributes
|
||||
['V', 32], // External File Attributes
|
||||
['V', $this->ofs->getLowFF()], // Relative offset of local header
|
||||
];
|
||||
|
||||
// pack fields, then append name and comment
|
||||
$header = ZipStream::packFields($fields);
|
||||
|
||||
return $header . $name . $footer . $comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Bigint
|
||||
*/
|
||||
public function getTotalLength(): Bigint
|
||||
{
|
||||
return $this->totalLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UNIX timestamp to a DOS timestamp.
|
||||
*
|
||||
* @param int $when
|
||||
* @return int DOS Timestamp
|
||||
*/
|
||||
final protected static function dosTime(int $when): int
|
||||
{
|
||||
// get date array for timestamp
|
||||
$d = getdate($when);
|
||||
|
||||
// set lower-bound on dates
|
||||
if ($d['year'] < 1980) {
|
||||
$d = [
|
||||
'year' => 1980,
|
||||
'mon' => 1,
|
||||
'mday' => 1,
|
||||
'hours' => 0,
|
||||
'minutes' => 0,
|
||||
'seconds' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
// remove extra years from 1980
|
||||
$d['year'] -= 1980;
|
||||
|
||||
// return date string
|
||||
return
|
||||
($d['year'] << 25) |
|
||||
($d['mon'] << 21) |
|
||||
($d['mday'] << 16) |
|
||||
($d['hours'] << 11) |
|
||||
($d['minutes'] << 5) |
|
||||
($d['seconds'] >> 1);
|
||||
}
|
||||
|
||||
protected function buildZip64ExtraBlock(bool $force = false): string
|
||||
{
|
||||
$fields = [];
|
||||
if ($this->len->isOver32($force)) {
|
||||
$fields[] = ['P', $this->len]; // Length of original data
|
||||
}
|
||||
|
||||
if ($this->len->isOver32($force)) {
|
||||
$fields[] = ['P', $this->zlen]; // Length of compressed data
|
||||
}
|
||||
|
||||
if ($this->ofs->isOver32()) {
|
||||
$fields[] = ['P', $this->ofs]; // Offset of local header record
|
||||
}
|
||||
|
||||
if (!empty($fields)) {
|
||||
if (!$this->zip->opt->isEnableZip64()) {
|
||||
throw new OverflowException();
|
||||
}
|
||||
|
||||
array_unshift(
|
||||
$fields,
|
||||
['v', 0x0001], // 64 bit extension
|
||||
['v', count($fields) * 8] // Length of data block
|
||||
);
|
||||
$this->version = Version::ZIP64();
|
||||
}
|
||||
|
||||
if ($this->bits & self::BIT_EFS_UTF8) {
|
||||
// Put the tricky entry to
|
||||
// force Linux unzip to lookup EFS flag.
|
||||
$fields[] = ['v', 0x5653]; // Choose 'ZS' for proprietary usage
|
||||
$fields[] = ['v', 0x0000]; // zero length
|
||||
}
|
||||
|
||||
return ZipStream::packFields($fields);
|
||||
}
|
||||
|
||||
protected function processStreamWithZeroHeader(StreamInterface $stream): void
|
||||
{
|
||||
$this->bits |= self::BIT_ZERO_HEADER;
|
||||
@@ -354,7 +409,7 @@ class File
|
||||
$data = $stream->read(self::CHUNKED_READ_BLOCK_SIZE);
|
||||
$total += strlen($data);
|
||||
if ($size > 0 && $total > $size) {
|
||||
$data = substr($data, 0 , strlen($data)-($total - $size));
|
||||
$data = substr($data, 0, strlen($data)-($total - $size));
|
||||
}
|
||||
$this->deflateData($stream, $data, $options);
|
||||
if ($options & self::SEND) {
|
||||
@@ -366,7 +421,8 @@ class File
|
||||
|
||||
protected function deflateInit(): void
|
||||
{
|
||||
$this->hash = hash_init(self::HASH_ALGORITHM);
|
||||
$hash = hash_init(self::HASH_ALGORITHM);
|
||||
$this->hash = $hash;
|
||||
if ($this->method->equals(Method::DEFLATE())) {
|
||||
$this->deflate = deflate_init(
|
||||
ZLIB_ENCODING_RAW,
|
||||
@@ -407,71 +463,8 @@ class File
|
||||
$this->readStream($stream, self::COMPUTE);
|
||||
$stream->rewind();
|
||||
|
||||
// incremental compression with deflate_add
|
||||
// makes this second read unnecessary
|
||||
// but it is only available from PHP 7.0
|
||||
if (!$this->deflate && $stream instanceof DeflateStream && $this->method->equals(Method::DEFLATE())) {
|
||||
$stream->addDeflateFilter($this->opt);
|
||||
$this->zlen = new Bigint();
|
||||
while (!$stream->eof()) {
|
||||
$data = $stream->read(self::CHUNKED_READ_BLOCK_SIZE);
|
||||
$this->zlen = $this->zlen->add(Bigint::init(strlen($data)));
|
||||
}
|
||||
$stream->rewind();
|
||||
}
|
||||
|
||||
$this->addFileHeader();
|
||||
$this->readStream($stream, self::SEND);
|
||||
$this->addFileFooter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send CDR record for specified file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCdrFile(): string
|
||||
{
|
||||
$name = static::filterFilename($this->name);
|
||||
|
||||
// get attributes
|
||||
$comment = $this->opt->getComment();
|
||||
|
||||
// get dos timestamp
|
||||
$time = static::dosTime($this->opt->getTime()->getTimestamp());
|
||||
|
||||
$footer = $this->buildZip64ExtraBlock();
|
||||
|
||||
$fields = [
|
||||
['V', ZipStream::CDR_FILE_SIGNATURE], // Central file header signature
|
||||
['v', ZipStream::ZIP_VERSION_MADE_BY], // Made by version
|
||||
['v', $this->version->getValue()], // Extract by version
|
||||
['v', $this->bits], // General purpose bit flags - data descriptor flag set
|
||||
['v', $this->method->getValue()], // Compression method
|
||||
['V', $time], // Timestamp (DOS Format)
|
||||
['V', $this->crc], // CRC32
|
||||
['V', $this->zlen->getLowFF()], // Compressed Data Length
|
||||
['V', $this->len->getLowFF()], // Original Data Length
|
||||
['v', strlen($name)], // Length of filename
|
||||
['v', strlen($footer)], // Extra data len (see above)
|
||||
['v', strlen($comment)], // Length of comment
|
||||
['v', 0], // Disk number
|
||||
['v', 0], // Internal File Attributes
|
||||
['V', 32], // External File Attributes
|
||||
['V', $this->ofs->getLowFF()] // Relative offset of local header
|
||||
];
|
||||
|
||||
// pack fields, then append name and comment
|
||||
$header = ZipStream::packFields($fields);
|
||||
|
||||
return $header . $name . $footer . $comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Bigint
|
||||
*/
|
||||
public function getTotalLength(): Bigint
|
||||
{
|
||||
return $this->totalLength;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Option;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
final class Archive
|
||||
{
|
||||
const DEFAULT_DEFLATE_LEVEL = 6;
|
||||
public const DEFAULT_DEFLATE_LEVEL = 6;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $comment = '';
|
||||
|
||||
/**
|
||||
* Size, in bytes, of the largest file to try
|
||||
* and load into memory (used by
|
||||
@@ -20,6 +25,7 @@ final class Archive
|
||||
* @var int
|
||||
*/
|
||||
private $largeFileSize = 20 * 1024 * 1024;
|
||||
|
||||
/**
|
||||
* How to handle large files. Legal values are
|
||||
* Method::STORE() (the default), or
|
||||
@@ -32,6 +38,7 @@ final class Archive
|
||||
* @var Method
|
||||
*/
|
||||
private $largeFileMethod;
|
||||
|
||||
/**
|
||||
* Boolean indicating whether or not to send
|
||||
* the HTTP headers for this file.
|
||||
@@ -39,12 +46,14 @@ final class Archive
|
||||
* @var bool
|
||||
*/
|
||||
private $sendHttpHeaders = false;
|
||||
|
||||
/**
|
||||
* The method called to send headers
|
||||
*
|
||||
* @var Callable
|
||||
*/
|
||||
private $httpHeaderCallback = 'header';
|
||||
|
||||
/**
|
||||
* Enable Zip64 extension, supporting very large
|
||||
* archives (any size > 4 GB or file count > 64k)
|
||||
@@ -52,6 +61,7 @@ final class Archive
|
||||
* @var bool
|
||||
*/
|
||||
private $enableZip64 = true;
|
||||
|
||||
/**
|
||||
* Enable streaming files with single read where
|
||||
* general purpose bit 3 indicates local file header
|
||||
@@ -62,6 +72,7 @@ final class Archive
|
||||
* @var bool
|
||||
*/
|
||||
private $zeroHeader = false;
|
||||
|
||||
/**
|
||||
* Enable reading file stat for determining file size.
|
||||
* When a 32-bit system reads file size that is
|
||||
@@ -75,11 +86,13 @@ final class Archive
|
||||
* @var bool
|
||||
*/
|
||||
private $statFiles = true;
|
||||
|
||||
/**
|
||||
* Enable flush after every write to output stream.
|
||||
* @var bool
|
||||
*/
|
||||
private $flushOutput = false;
|
||||
|
||||
/**
|
||||
* HTTP Content-Disposition. Defaults to
|
||||
* 'attachment', where
|
||||
@@ -91,6 +104,7 @@ final class Archive
|
||||
* @var string
|
||||
*/
|
||||
private $contentDisposition = 'attachment';
|
||||
|
||||
/**
|
||||
* Note that this does nothing if you are
|
||||
* not sending HTTP headers.
|
||||
@@ -98,13 +112,14 @@ final class Archive
|
||||
* @var string
|
||||
*/
|
||||
private $contentType = 'application/x-zip';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $deflateLevel = 6;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
* @var StreamInterface|resource
|
||||
*/
|
||||
private $outputStream;
|
||||
|
||||
@@ -157,12 +172,12 @@ final class Archive
|
||||
$this->sendHttpHeaders = $sendHttpHeaders;
|
||||
}
|
||||
|
||||
public function getHttpHeaderCallback(): Callable
|
||||
public function getHttpHeaderCallback(): callable
|
||||
{
|
||||
return $this->httpHeaderCallback;
|
||||
}
|
||||
|
||||
public function setHttpHeaderCallback(Callable $httpHeaderCallback): void
|
||||
public function setHttpHeaderCallback(callable $httpHeaderCallback): void
|
||||
{
|
||||
$this->httpHeaderCallback = $httpHeaderCallback;
|
||||
}
|
||||
@@ -228,7 +243,7 @@ final class Archive
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
* @return StreamInterface|resource
|
||||
*/
|
||||
public function getOutputStream()
|
||||
{
|
||||
@@ -236,7 +251,7 @@ final class Archive
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $outputStream
|
||||
* @param StreamInterface|resource $outputStream
|
||||
*/
|
||||
public function setOutputStream($outputStream): void
|
||||
{
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Option;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
|
||||
final class File
|
||||
{
|
||||
@@ -11,18 +13,22 @@ final class File
|
||||
* @var string
|
||||
*/
|
||||
private $comment = '';
|
||||
|
||||
/**
|
||||
* @var Method
|
||||
*/
|
||||
private $method;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $deflateLevel;
|
||||
|
||||
/**
|
||||
* @var DateTime
|
||||
* @var DateTimeInterface
|
||||
*/
|
||||
private $time;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
@@ -83,17 +89,17 @@ final class File
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
* @return DateTimeInterface
|
||||
*/
|
||||
public function getTime(): DateTime
|
||||
public function getTime(): DateTimeInterface
|
||||
{
|
||||
return $this->time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DateTime $time
|
||||
* @param DateTimeInterface $time
|
||||
*/
|
||||
public function setTime(DateTime $time): void
|
||||
public function setTime(DateTimeInterface $time): void
|
||||
{
|
||||
$this->time = $time;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Option;
|
||||
@@ -11,9 +12,12 @@ use MyCLabs\Enum\Enum;
|
||||
* @method static STORE(): Method
|
||||
* @method static DEFLATE(): Method
|
||||
* @psalm-immutable
|
||||
* @psalm-template int
|
||||
* @extends Enum<int>
|
||||
*/
|
||||
class Method extends Enum
|
||||
{
|
||||
const STORE = 0x00;
|
||||
const DEFLATE = 0x08;
|
||||
public const STORE = 0x00;
|
||||
|
||||
public const DEFLATE = 0x08;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Option;
|
||||
@@ -13,10 +14,14 @@ use MyCLabs\Enum\Enum;
|
||||
* @method static DEFLATE(): Version
|
||||
* @method static ZIP64(): Version
|
||||
* @psalm-immutable
|
||||
* @psalm-template int
|
||||
* @extends Enum<int>
|
||||
*/
|
||||
class Version extends Enum
|
||||
{
|
||||
const STORE = 0x000A; // 1.00
|
||||
const DEFLATE = 0x0014; // 2.00
|
||||
const ZIP64 = 0x002D; // 4.50
|
||||
public const STORE = 0x000A; // 1.00
|
||||
|
||||
public const DEFLATE = 0x0014; // 2.00
|
||||
|
||||
public const ZIP64 = 0x002D; // 4.50
|
||||
}
|
||||
|
||||
92
vendor/maennchen/zipstream-php/src/Stream.php
vendored
92
vendor/maennchen/zipstream-php/src/Stream.php
vendored
@@ -1,8 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream;
|
||||
|
||||
use function mb_strlen;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use RuntimeException;
|
||||
|
||||
@@ -22,6 +25,29 @@ class Stream implements StreamInterface
|
||||
$this->stream = $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all data from the stream into a string, from the beginning to end.
|
||||
*
|
||||
* This method MUST attempt to seek to the beginning of the stream before
|
||||
* reading data and read the stream until the end is reached.
|
||||
*
|
||||
* Warning: This could attempt to load a large amount of data into memory.
|
||||
*
|
||||
* This method MUST NOT raise an exception in order to conform with PHP's
|
||||
* string casting operations.
|
||||
*
|
||||
* @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
try {
|
||||
$this->seek(0);
|
||||
} catch (RuntimeException $e) {
|
||||
}
|
||||
return (string) stream_get_contents($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream and any underlying resources.
|
||||
*
|
||||
@@ -49,28 +75,6 @@ class Stream implements StreamInterface
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all data from the stream into a string, from the beginning to end.
|
||||
*
|
||||
* This method MUST attempt to seek to the beginning of the stream before
|
||||
* reading data and read the stream until the end is reached.
|
||||
*
|
||||
* Warning: This could attempt to load a large amount of data into memory.
|
||||
*
|
||||
* This method MUST NOT raise an exception in order to conform with PHP's
|
||||
* string casting operations.
|
||||
*
|
||||
* @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
try {
|
||||
$this->seek(0);
|
||||
} catch (\RuntimeException $e) {}
|
||||
return (string) stream_get_contents($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek to a position in the stream.
|
||||
*
|
||||
@@ -81,15 +85,15 @@ class Stream implements StreamInterface
|
||||
* PHP $whence values for `fseek()`. SEEK_SET: Set position equal to
|
||||
* offset bytes SEEK_CUR: Set position to current location plus offset
|
||||
* SEEK_END: Set position to end-of-stream plus offset.
|
||||
* @throws \RuntimeException on failure.
|
||||
* @throws RuntimeException on failure.
|
||||
*/
|
||||
public function seek($offset, $whence = SEEK_SET): void
|
||||
{
|
||||
if (!$this->isSeekable()) {
|
||||
throw new RuntimeException;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (fseek($this->stream, $offset, $whence) !== 0) {
|
||||
throw new RuntimeException;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,13 +140,13 @@ class Stream implements StreamInterface
|
||||
* Returns the current position of the file read/write pointer
|
||||
*
|
||||
* @return int Position of the file pointer
|
||||
* @throws \RuntimeException on error.
|
||||
* @throws RuntimeException on error.
|
||||
*/
|
||||
public function tell(): int
|
||||
{
|
||||
$position = ftell($this->stream);
|
||||
if ($position === false) {
|
||||
throw new RuntimeException;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
return $position;
|
||||
}
|
||||
@@ -165,7 +169,7 @@ class Stream implements StreamInterface
|
||||
*
|
||||
* @see seek()
|
||||
* @link http://www.php.net/manual/en/function.fseek.php
|
||||
* @throws \RuntimeException on failure.
|
||||
* @throws RuntimeException on failure.
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
@@ -177,17 +181,17 @@ class Stream implements StreamInterface
|
||||
*
|
||||
* @param string $string The string that is to be written.
|
||||
* @return int Returns the number of bytes written to the stream.
|
||||
* @throws \RuntimeException on failure.
|
||||
* @throws RuntimeException on failure.
|
||||
*/
|
||||
public function write($string): int
|
||||
{
|
||||
if (!$this->isWritable()) {
|
||||
throw new RuntimeException;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (fwrite($this->stream, $string) === false) {
|
||||
throw new RuntimeException;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
return \mb_strlen($string);
|
||||
return mb_strlen($string);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,7 +201,11 @@ class Stream implements StreamInterface
|
||||
*/
|
||||
public function isWritable(): bool
|
||||
{
|
||||
return preg_match('/[waxc+]/', $this->getMetadata('mode')) === 1;
|
||||
$mode = $this->getMetadata('mode');
|
||||
if (!is_string($mode)) {
|
||||
throw new RuntimeException('Could not get stream mode from metadata!');
|
||||
}
|
||||
return preg_match('/[waxc+]/', $mode) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,16 +216,16 @@ class Stream implements StreamInterface
|
||||
* call returns fewer bytes.
|
||||
* @return string Returns the data read from the stream, or an empty string
|
||||
* if no bytes are available.
|
||||
* @throws \RuntimeException if an error occurs.
|
||||
* @throws RuntimeException if an error occurs.
|
||||
*/
|
||||
public function read($length): string
|
||||
{
|
||||
if (!$this->isReadable()) {
|
||||
throw new RuntimeException;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
$result = fread($this->stream, $length);
|
||||
if ($result === false) {
|
||||
throw new RuntimeException;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -229,24 +237,28 @@ class Stream implements StreamInterface
|
||||
*/
|
||||
public function isReadable(): bool
|
||||
{
|
||||
return preg_match('/[r+]/', $this->getMetadata('mode')) === 1;
|
||||
$mode = $this->getMetadata('mode');
|
||||
if (!is_string($mode)) {
|
||||
throw new RuntimeException('Could not get stream mode from metadata!');
|
||||
}
|
||||
return preg_match('/[r+]/', $mode) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remaining contents in a string
|
||||
*
|
||||
* @return string
|
||||
* @throws \RuntimeException if unable to read or an error occurs while
|
||||
* @throws RuntimeException if unable to read or an error occurs while
|
||||
* reading.
|
||||
*/
|
||||
public function getContents(): string
|
||||
{
|
||||
if (!$this->isReadable()) {
|
||||
throw new RuntimeException;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
$result = stream_get_contents($this->stream);
|
||||
if ($result === false) {
|
||||
throw new RuntimeException;
|
||||
throw new RuntimeException();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
157
vendor/maennchen/zipstream-php/src/ZipStream.php
vendored
157
vendor/maennchen/zipstream-php/src/ZipStream.php
vendored
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream;
|
||||
@@ -80,19 +81,24 @@ class ZipStream
|
||||
* to prevent file permissions issues upon extract (see #84)
|
||||
* 0x603 is 00000110 00000011 in binary, so 6 and 3
|
||||
*/
|
||||
const ZIP_VERSION_MADE_BY = 0x603;
|
||||
public const ZIP_VERSION_MADE_BY = 0x603;
|
||||
|
||||
/**
|
||||
* The following signatures end with 0x4b50, which in ASCII is PK,
|
||||
* The following signatures end with 0x4b50, which in ASCII is PK,
|
||||
* the initials of the inventor Phil Katz.
|
||||
* See https://en.wikipedia.org/wiki/Zip_(file_format)#File_headers
|
||||
*/
|
||||
const FILE_HEADER_SIGNATURE = 0x04034b50;
|
||||
const CDR_FILE_SIGNATURE = 0x02014b50;
|
||||
const CDR_EOF_SIGNATURE = 0x06054b50;
|
||||
const DATA_DESCRIPTOR_SIGNATURE = 0x08074b50;
|
||||
const ZIP64_CDR_EOF_SIGNATURE = 0x06064b50;
|
||||
const ZIP64_CDR_LOCATOR_SIGNATURE = 0x07064b50;
|
||||
public const FILE_HEADER_SIGNATURE = 0x04034b50;
|
||||
|
||||
public const CDR_FILE_SIGNATURE = 0x02014b50;
|
||||
|
||||
public const CDR_EOF_SIGNATURE = 0x06054b50;
|
||||
|
||||
public const DATA_DESCRIPTOR_SIGNATURE = 0x08074b50;
|
||||
|
||||
public const ZIP64_CDR_EOF_SIGNATURE = 0x06064b50;
|
||||
|
||||
public const ZIP64_CDR_LOCATOR_SIGNATURE = 0x07064b50;
|
||||
|
||||
/**
|
||||
* Global Options
|
||||
@@ -293,7 +299,7 @@ class ZipStream
|
||||
$options->defaultTo($this->opt);
|
||||
|
||||
$file = new File($this, $name, $options);
|
||||
$file->processStream(new DeflateStream($stream));
|
||||
$file->processStream(new Stream($stream));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,12 +318,9 @@ class ZipStream
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* // create a temporary file stream and write text to it
|
||||
* $fp = tmpfile();
|
||||
* fwrite($fp, 'The quick brown fox jumped over the lazy dog.');
|
||||
*
|
||||
* $stream = $response->getBody();
|
||||
* // add a file named 'streamfile.txt' from the content of the stream
|
||||
* $x->addFileFromPsr7Stream('streamfile.txt', $fp);
|
||||
* $x->addFileFromPsr7Stream('streamfile.txt', $stream);
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -378,34 +381,6 @@ class ZipStream
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send ZIP64 CDR EOF (Central Directory Record End-of-File) record.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addCdr64Eof(): void
|
||||
{
|
||||
$num_files = count($this->files);
|
||||
$cdr_length = $this->cdr_ofs;
|
||||
$cdr_offset = $this->ofs;
|
||||
|
||||
$fields = [
|
||||
['V', static::ZIP64_CDR_EOF_SIGNATURE], // ZIP64 end of central file header signature
|
||||
['P', 44], // Length of data below this header (length of block - 12) = 44
|
||||
['v', static::ZIP_VERSION_MADE_BY], // Made by version
|
||||
['v', Version::ZIP64], // Extract by version
|
||||
['V', 0x00], // disk number
|
||||
['V', 0x00], // no of disks
|
||||
['P', $num_files], // no of entries on disk
|
||||
['P', $num_files], // no of entries in cdr
|
||||
['P', $cdr_length], // CDR size
|
||||
['P', $cdr_offset], // CDR offset
|
||||
];
|
||||
|
||||
$ret = static::packFields($fields);
|
||||
$this->send($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a format string and argument list for pack(), then call
|
||||
* pack() and return the result.
|
||||
@@ -459,7 +434,13 @@ class ZipStream
|
||||
}
|
||||
$this->need_headers = false;
|
||||
|
||||
fwrite($this->opt->getOutputStream(), $str);
|
||||
$outputStream = $this->opt->getOutputStream();
|
||||
|
||||
if ($outputStream instanceof StreamInterface) {
|
||||
$outputStream->write($str);
|
||||
} else {
|
||||
fwrite($outputStream, $str);
|
||||
}
|
||||
|
||||
if ($this->opt->isFlushOutput()) {
|
||||
// flush output buffer if it is on and flushable
|
||||
@@ -473,6 +454,62 @@ class ZipStream
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this file larger than large_file_size?
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function isLargeFile(string $path): bool
|
||||
{
|
||||
if (!$this->opt->isStatFiles()) {
|
||||
return false;
|
||||
}
|
||||
$stat = stat($path);
|
||||
return $stat['size'] > $this->opt->getLargeFileSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save file attributes for trailing CDR record.
|
||||
*
|
||||
* @param File $file
|
||||
* @return void
|
||||
*/
|
||||
public function addToCdr(File $file): void
|
||||
{
|
||||
$file->ofs = $this->ofs;
|
||||
$this->ofs = $this->ofs->add($file->getTotalLength());
|
||||
$this->files[] = $file->getCdrFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send ZIP64 CDR EOF (Central Directory Record End-of-File) record.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addCdr64Eof(): void
|
||||
{
|
||||
$num_files = count($this->files);
|
||||
$cdr_length = $this->cdr_ofs;
|
||||
$cdr_offset = $this->ofs;
|
||||
|
||||
$fields = [
|
||||
['V', static::ZIP64_CDR_EOF_SIGNATURE], // ZIP64 end of central file header signature
|
||||
['P', 44], // Length of data below this header (length of block - 12) = 44
|
||||
['v', static::ZIP_VERSION_MADE_BY], // Made by version
|
||||
['v', Version::ZIP64], // Extract by version
|
||||
['V', 0x00], // disk number
|
||||
['V', 0x00], // no of disks
|
||||
['P', $num_files], // no of entries on disk
|
||||
['P', $num_files], // no of entries in cdr
|
||||
['P', $cdr_length], // CDR size
|
||||
['P', $cdr_offset], // CDR offset
|
||||
];
|
||||
|
||||
$ret = static::packFields($fields);
|
||||
$this->send($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send HTTP headers for this stream.
|
||||
*
|
||||
@@ -492,13 +529,13 @@ class ZipStream
|
||||
$disposition .= "; filename*=UTF-8''{$urlencoded}";
|
||||
}
|
||||
|
||||
$headers = array(
|
||||
$headers = [
|
||||
'Content-Type' => $this->opt->getContentType(),
|
||||
'Content-Disposition' => $disposition,
|
||||
'Pragma' => 'public',
|
||||
'Cache-Control' => 'public, must-revalidate',
|
||||
'Content-Transfer-Encoding' => 'binary'
|
||||
);
|
||||
'Content-Transfer-Encoding' => 'binary',
|
||||
];
|
||||
|
||||
$call = $this->opt->getHttpHeaderCallback();
|
||||
foreach ($headers as $key => $val) {
|
||||
@@ -568,32 +605,4 @@ class ZipStream
|
||||
$this->cdr_ofs = new Bigint();
|
||||
$this->opt = new ArchiveOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this file larger than large_file_size?
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function isLargeFile(string $path): bool
|
||||
{
|
||||
if (!$this->opt->isStatFiles()) {
|
||||
return false;
|
||||
}
|
||||
$stat = stat($path);
|
||||
return $stat['size'] > $this->opt->getLargeFileSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save file attributes for trailing CDR record.
|
||||
*
|
||||
* @param File $file
|
||||
* @return void
|
||||
*/
|
||||
public function addToCdr(File $file): void
|
||||
{
|
||||
$file->ofs = $this->ofs;
|
||||
$this->ofs = $this->ofs->add($file->getTotalLength());
|
||||
$this->files[] = $file->getCdrFile();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user