Release of v3.2.5
Add [AllowDynamicProperties] in the base view class for J5. Move the _prepareDocument above the display call in the base view class. Remove all backward compatibility issues, so JCB will not need the [Backward Compatibility] plugin to run. Added new import powers for custom import of spreadsheets. Move the setDocument and _prepareDocument above the display in the site view and custom admin view. Update the trashhelper layout to work in Joomla 5. Add AllowDynamicProperties (Joomla 4+5) to view class to allow Custom Dynamic Get methods to work without issues. Fix Save failed issue in dynamicGet. #1148. Move all [TEXT, EDITOR, TEXTAREA] fields from [NOT NULL] to [NULL]. Add the DateHelper class and improve the date methods. Add simple SessionHelper class. Add first classes for the new import engine. Improve the [VDM Registry] to be Joomla Registry Compatible. Move all registries to the [VDM Registry] class. Fix Checked Out to be null and not 0. (#1194). Fix created_by, modified_by, checked_out fields in the compiler of the SQL. (#1194). Update all core date fields in table class. (#1188). Update created_by, modified_by, checked_out fields in table class. Implementation of the decentralized Super-Power CORE repository network. (#1190). Fix the noticeboard to display Llewellyn's Joomla Social feed.
This commit is contained in:
22
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.editorconfig
vendored
Normal file
22
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.editorconfig
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
|
||||
[*.{yml,md,xml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{rst,php}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[composer.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[composer.lock]
|
||||
indent_style = space
|
||||
indent_size = 4
|
4
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.phive/phars.xml
vendored
Normal file
4
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.phive/phars.xml
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phive xmlns="https://phar.io/phive">
|
||||
<phar name="phpdocumentor" version="^3.3.1" installed="3.3.1" location="./tools/phpdocumentor" copy="false"/>
|
||||
</phive>
|
71
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.php-cs-fixer.dist.php
vendored
Normal file
71
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.php-cs-fixer.dist.php
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* PHP-CS-Fixer config for ZipStream-PHP
|
||||
* @author Nicolas CARPi <nico-git@deltablot.email>
|
||||
* @copyright 2022 Nicolas CARPi
|
||||
* @see https://github.com/maennchen/ZipStream-PHP
|
||||
* @license MIT
|
||||
* @package maennchen/ZipStream-PHP
|
||||
*/
|
||||
|
||||
use PhpCsFixer\Config;
|
||||
use PhpCsFixer\Finder;
|
||||
|
||||
$finder = Finder::create()
|
||||
->exclude('.github')
|
||||
->exclude('.phpdoc')
|
||||
->exclude('docs')
|
||||
->exclude('tools')
|
||||
->exclude('vendor')
|
||||
->in(__DIR__);
|
||||
|
||||
$config = new Config();
|
||||
return $config->setRules([
|
||||
'@PER' => true,
|
||||
'@PER:risky' => true,
|
||||
'@PHP82Migration' => true,
|
||||
'@PHPUnit84Migration:risky' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'class_attributes_separation' => true,
|
||||
'declare_strict_types' => true,
|
||||
'dir_constant' => true,
|
||||
'is_null' => true,
|
||||
'no_homoglyph_names' => true,
|
||||
'no_null_property_initialization' => true,
|
||||
'no_php4_constructor' => true,
|
||||
'no_unused_imports' => true,
|
||||
'no_useless_else' => true,
|
||||
'non_printable_character' => true,
|
||||
'ordered_imports' => true,
|
||||
'ordered_class_elements' => true,
|
||||
'php_unit_construct' => true,
|
||||
'pow_to_exponentiation' => true,
|
||||
'psr_autoloading' => true,
|
||||
'random_api_migration' => true,
|
||||
'return_assignment' => true,
|
||||
'self_accessor' => true,
|
||||
'semicolon_after_instruction' => true,
|
||||
'short_scalar_cast' => true,
|
||||
'simplified_null_return' => true,
|
||||
'single_blank_line_before_namespace' => true,
|
||||
'single_class_element_per_statement' => true,
|
||||
'single_line_comment_style' => true,
|
||||
'single_quote' => true,
|
||||
'space_after_semicolon' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'strict_param' => true,
|
||||
'ternary_operator_spaces' => true,
|
||||
'trailing_comma_in_multiline' => true,
|
||||
'trim_array_spaces' => true,
|
||||
'unary_operator_spaces' => true,
|
||||
'global_namespace_import' => [
|
||||
'import_classes' => true,
|
||||
'import_functions' => true,
|
||||
'import_constants' => true,
|
||||
],
|
||||
])
|
||||
->setFinder($finder)
|
||||
->setRiskyAllowed(true);
|
15
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.phpdoc/template/base.html.twig
vendored
Normal file
15
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.phpdoc/template/base.html.twig
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{% extends 'layout.html.twig' %}
|
||||
|
||||
{% set topMenu = {
|
||||
"menu": [
|
||||
{ "name": "Guides", "url": "https://maennchen.dev/ZipStream-PHP/guide/index.html"},
|
||||
{ "name": "API", "url": "https://maennchen.dev/ZipStream-PHP/classes/ZipStream-ZipStream.html"},
|
||||
{ "name": "Issues", "url": "https://github.com/maennchen/ZipStream-PHP/issues"},
|
||||
],
|
||||
"social": [
|
||||
{ "iconClass": "fab fa-github", "url": "https://github.com/maennchen/ZipStream-PHP"},
|
||||
{ "iconClass": "fas fa-envelope-open-text", "url": "https://github.com/maennchen/ZipStream-PHP/discussions"},
|
||||
{ "iconClass": "fas fa-money-bill", "url": "https://opencollective.com/zipstream"},
|
||||
]
|
||||
}
|
||||
%}
|
1
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.tool-versions
vendored
Normal file
1
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/.tool-versions
vendored
Normal file
@ -0,0 +1 @@
|
||||
php 8.2.5
|
24
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/LICENSE
vendored
Normal file
24
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/LICENSE
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2007-2009 Paul Duncan <pabs@pablotron.org>
|
||||
Copyright (C) 2014 Jonatan Männchen <jonatan@maennchen.ch>
|
||||
Copyright (C) 2014 Jesse G. Donat <donatj@gmail.com>
|
||||
Copyright (C) 2018 Nicolas CARPi <nicolas.carpi@curie.fr>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
183
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/README.md
vendored
Normal file
183
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/README.md
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
# ZipStream-PHP
|
||||
|
||||
[](https://github.com/maennchen/ZipStream-PHP/actions/workflows/branch_main.yml)
|
||||
[](https://coveralls.io/github/maennchen/ZipStream-PHP?branch=main)
|
||||
[](https://packagist.org/packages/maennchen/zipstream-php)
|
||||
[](https://packagist.org/packages/maennchen/zipstream-php)
|
||||
[](https://opencollective.com/zipstream) [](LICENSE)
|
||||
|
||||
## Unstable Branch
|
||||
|
||||
The `main` branch is not stable. Please see the
|
||||
[releases](https://github.com/maennchen/ZipStream-PHP/releases) for a stable
|
||||
version.
|
||||
|
||||
## Overview
|
||||
|
||||
A fast and simple streaming zip file downloader for PHP. Using this library will
|
||||
save you from having to write the Zip to disk. You can directly send it to the
|
||||
user, which is much faster. It can work with S3 buckets or any PSR7 Stream.
|
||||
|
||||
Please see the [LICENSE](LICENSE) file for licensing and warranty information.
|
||||
|
||||
## Installation
|
||||
|
||||
Simply add a dependency on maennchen/zipstream-php to your project's
|
||||
`composer.json` file if you use Composer to manage the dependencies of your
|
||||
project. Use following command to add the package to your project's dependencies:
|
||||
|
||||
```bash
|
||||
composer require maennchen/zipstream-php
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
For detailed instructions, please check the
|
||||
[Documentation](https://maennchen.github.io/ZipStream-PHP/).
|
||||
|
||||
```php
|
||||
// Autoload the dependencies
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
// create a new zipstream object
|
||||
$zip = new ZipStream\ZipStream(
|
||||
outputName: 'example.zip',
|
||||
|
||||
// enable output of HTTP headers
|
||||
sendHttpHeaders: true,
|
||||
);
|
||||
|
||||
// create a file named 'hello.txt'
|
||||
$zip->addFile(
|
||||
fileName: 'hello.txt',
|
||||
data: 'This is the contents of hello.txt',
|
||||
);
|
||||
|
||||
// add a file named 'some_image.jpg' from a local file 'path/to/image.jpg'
|
||||
$zip->addFileFromPath(
|
||||
fileName: 'some_image.jpg',
|
||||
path: 'path/to/image.jpg',
|
||||
);
|
||||
|
||||
// finish the zip stream
|
||||
$zip->finish();
|
||||
```
|
||||
|
||||
## Upgrade to version 3.0.0
|
||||
|
||||
### General
|
||||
|
||||
- Minimum PHP Version: `8.1`
|
||||
- Only 64bit Architecture is supported.
|
||||
- The class `ZipStream\Option\Method` has been replaced with the enum
|
||||
`ZipStream\CompressionMethod`.
|
||||
- Most clases have been flagged as `@internal` and should not be used from the
|
||||
outside.
|
||||
If you're using internal resources to extend this library, please open an
|
||||
issue so that a clean interface can be added & published.
|
||||
The externally available classes & enums are:
|
||||
- `ZipStream\CompressionMethod`
|
||||
- `ZipStream\Exception*`
|
||||
- `ZipStream\ZipStream`
|
||||
|
||||
### Archive Options
|
||||
|
||||
- The class `ZipStream\Option\Archive` has been replaced in favor of named
|
||||
arguments in the `ZipStream\ZipStream` constuctor.
|
||||
- The archive options `largeFileSize` & `largeFileMethod` has been removed. If
|
||||
you want different `compressionMethods` based on the file size, you'll have to
|
||||
implement this yourself.
|
||||
- The archive option `httpHeaderCallback` changed the type from `callable` to
|
||||
`Closure`.
|
||||
- The archive option `zeroHeader` has been replaced with the option
|
||||
`defaultEnableZeroHeader` and can be overridden for every file. Its default
|
||||
value changed from `false` to `true`.
|
||||
- The archive option `statFiles` was removed since the library no longer checks
|
||||
filesizes this way.
|
||||
- The archive option `deflateLevel` has been replaced with the option
|
||||
`defaultDeflateLevel` and can be overridden for every file.
|
||||
- The first argument (`name`) of the `ZipStream\ZipStream` constuctor has been
|
||||
replaced with the named argument `outputName`.
|
||||
- Headers are now also sent if the `outputName` is empty. If you do not want to
|
||||
automatically send http headers, set `sendHttpHeaders` to `false`.
|
||||
|
||||
### File Options
|
||||
|
||||
- The class `ZipStream\Option\File` has been replaced in favor of named
|
||||
arguments in the `ZipStream\ZipStream->addFile*` functions.
|
||||
- The file option `method` has been renamed to `compressionMethod`.
|
||||
- The file option `time` has been renamed to `lastModificationDateTime`.
|
||||
- The file option `size` has been renamed to `maxSize`.
|
||||
|
||||
## Upgrade to version 2.0.0
|
||||
|
||||
https://github.com/maennchen/ZipStream-PHP/tree/2.0.0#upgrade-to-version-200
|
||||
|
||||
## Upgrade to version 1.0.0
|
||||
|
||||
https://github.com/maennchen/ZipStream-PHP/tree/2.0.0#upgrade-to-version-100
|
||||
|
||||
## Contributing
|
||||
|
||||
ZipStream-PHP is a collaborative project. Please take a look at the
|
||||
[.github/CONTRIBUTING.md](.github/CONTRIBUTING.md) file.
|
||||
|
||||
## Version Support
|
||||
|
||||
Versions are supported according to the table below.
|
||||
|
||||
Please do not open any pull requests contradicting the current version support
|
||||
status.
|
||||
|
||||
Careful: Always check the `README` on `main` for up-to-date information.
|
||||
|
||||
| Version | New Features | Bugfixes | Security |
|
||||
|---------|--------------|----------|----------|
|
||||
| *3* | ✓ | ✓ | ✓ |
|
||||
| *2* | ✗ | ✓ | ✓ |
|
||||
| *1* | ✗ | ✗ | ✓ |
|
||||
| *0* | ✗ | ✗ | ✗ |
|
||||
|
||||
This library aligns itself with the PHP core support. New features and bugfixes
|
||||
will only target PHP versions according to their current status.
|
||||
|
||||
See: https://www.php.net/supported-versions.php
|
||||
|
||||
## About the Authors
|
||||
|
||||
- Paul Duncan <pabs@pablotron.org> - https://pablotron.org/
|
||||
- Jonatan Männchen <jonatan@maennchen.ch> - https://maennchen.dev
|
||||
- Jesse G. Donat <donatj@gmail.com> - https://donatstudios.com
|
||||
- Nicolas CARPi <nico-git@deltablot.email> - https://www.deltablot.com
|
||||
- Nik Barham <nik@brokencube.co.uk> - https://www.brokencube.co.uk
|
||||
|
||||
## Contributors
|
||||
|
||||
### Code Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute.
|
||||
[[Contribute](.github/CONTRIBUTING.md)].
|
||||
<a href="https://github.com/maennchen/ZipStream-PHP/graphs/contributors"><img src="https://opencollective.com/zipstream/contributors.svg?width=890&button=false" /></a>
|
||||
|
||||
### Financial Contributors
|
||||
|
||||
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/zipstream/contribute)]
|
||||
|
||||
#### Individuals
|
||||
|
||||
<a href="https://opencollective.com/zipstream"><img src="https://opencollective.com/zipstream/individuals.svg?width=890"></a>
|
||||
|
||||
#### Organizations
|
||||
|
||||
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/zipstream/contribute)]
|
||||
|
||||
<a href="https://opencollective.com/zipstream/organization/0/website"><img src="https://opencollective.com/zipstream/organization/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/zipstream/organization/1/website"><img src="https://opencollective.com/zipstream/organization/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/zipstream/organization/2/website"><img src="https://opencollective.com/zipstream/organization/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/zipstream/organization/3/website"><img src="https://opencollective.com/zipstream/organization/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/zipstream/organization/4/website"><img src="https://opencollective.com/zipstream/organization/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/zipstream/organization/5/website"><img src="https://opencollective.com/zipstream/organization/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/zipstream/organization/6/website"><img src="https://opencollective.com/zipstream/organization/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/zipstream/organization/7/website"><img src="https://opencollective.com/zipstream/organization/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/zipstream/organization/8/website"><img src="https://opencollective.com/zipstream/organization/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/zipstream/organization/9/website"><img src="https://opencollective.com/zipstream/organization/9/avatar.svg"></a>
|
88
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/composer.json
vendored
Normal file
88
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/composer.json
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
{
|
||||
"name": "maennchen/zipstream-php",
|
||||
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
|
||||
"keywords": ["zip", "stream"],
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [{
|
||||
"name": "Paul Duncan",
|
||||
"email": "pabs@pablotron.org"
|
||||
},
|
||||
{
|
||||
"name": "Jonatan Männchen",
|
||||
"email": "jonatan@maennchen.ch"
|
||||
},
|
||||
{
|
||||
"name": "Jesse Donat",
|
||||
"email": "donatj@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "András Kolesár",
|
||||
"email": "kolesar@kolesar.hu"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php-64bit": "^8.1",
|
||||
"ext-mbstring": "*",
|
||||
"ext-zlib": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"guzzlehttp/guzzle": "^7.5",
|
||||
"ext-zip": "*",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"php-coveralls/php-coveralls": "^2.5",
|
||||
"friendsofphp/php-cs-fixer": "^3.16",
|
||||
"vimeo/psalm": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/http-message": "^2.0",
|
||||
"guzzlehttp/psr7": "^2.4"
|
||||
},
|
||||
"scripts": {
|
||||
"format": "php-cs-fixer fix",
|
||||
"test": [
|
||||
"@test:unit",
|
||||
"@test:formatted",
|
||||
"@test:lint"
|
||||
],
|
||||
"test:unit": "phpunit --coverage-clover=coverage.clover.xml --coverage-html cov",
|
||||
"test:unit:slow": "@test:unit --group slow",
|
||||
"test:unit:fast": "@test:unit --exclude-group slow",
|
||||
"test:formatted": "@format --dry-run --stop-on-violation --using-cache=no",
|
||||
"test:lint": "psalm --stats --show-info=true --find-unused-psalm-suppress",
|
||||
"coverage:report": "php-coveralls --coverage_clover=coverage.clover.xml --json_path=coveralls-upload.json --insecure",
|
||||
"install:tools": "phive install --trust-gpg-keys 0x67F861C3D889C656",
|
||||
"docs:generate": "tools/phpdocumentor --sourcecode"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ZipStream\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": { "ZipStream\\Test\\": "test/" }
|
||||
},
|
||||
"archive": {
|
||||
"exclude": [
|
||||
"/composer.lock",
|
||||
"/docs",
|
||||
"/.gitattributes",
|
||||
"/.github",
|
||||
"/.gitignore",
|
||||
"/guides",
|
||||
"/.phive",
|
||||
"/.php-cs-fixer.cache",
|
||||
"/.php-cs-fixer.dist.php",
|
||||
"/.phpdoc",
|
||||
"/phpdoc.dist.xml",
|
||||
"/.phpunit.result.cache",
|
||||
"/phpunit.xml.dist",
|
||||
"/psalm.xml",
|
||||
"/test",
|
||||
"/tools",
|
||||
"/.tool-versions",
|
||||
"/vendor"
|
||||
]
|
||||
}
|
||||
}
|
47
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/ContentLength.rst
vendored
Normal file
47
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/ContentLength.rst
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
Adding Content-Length header
|
||||
=============
|
||||
|
||||
Adding a ``Content-Length`` header for ``ZipStream`` can be achieved by
|
||||
using the options ``SIMULATION_STRICT`` or ``SIMULATION_LAX`` in the
|
||||
``operationMode`` parameter.
|
||||
|
||||
In the ``SIMULATION_STRICT`` mode, ``ZipStream`` will not allow to calculate the
|
||||
size based on reading the whole file. ``SIMULATION_LAX`` will read the whole
|
||||
file if neccessary.
|
||||
|
||||
``SIMULATION_STRICT`` is therefore useful to make sure that the size can be
|
||||
calculated efficiently.
|
||||
|
||||
.. code-block:: php
|
||||
use ZipStream\OperationMode;
|
||||
use ZipStream\ZipStream;
|
||||
|
||||
$zip = new ZipStream(
|
||||
operationMode: OperationMode::SIMULATE_STRICT, // or SIMULATE_LAX
|
||||
defaultEnableZeroHeader: false,
|
||||
sendHttpHeaders: true,
|
||||
outputStream: $stream,
|
||||
);
|
||||
|
||||
// Normally add files
|
||||
$zip->addFile('sample.txt', 'Sample String Data');
|
||||
|
||||
// Use addFileFromCallback and exactSize if you want to defer opening of
|
||||
// the file resource
|
||||
$zip->addFileFromCallback(
|
||||
'sample.txt',
|
||||
exactSize: 18,
|
||||
callback: function () {
|
||||
return fopen('...');
|
||||
}
|
||||
);
|
||||
|
||||
// Read resulting file size
|
||||
$size = $zip->finish();
|
||||
|
||||
// Tell it to the browser
|
||||
header('Content-Length: '. $size);
|
||||
|
||||
// Execute the Simulation and stream the actual zip to the client
|
||||
$zip->executeSimulation();
|
||||
|
34
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/FlySystem.rst
vendored
Normal file
34
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/FlySystem.rst
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
Usage with FlySystem
|
||||
===============
|
||||
|
||||
For saving or uploading the generated zip, you can use the
|
||||
`Flysystem <https://flysystem.thephpleague.com>`_ package, and its many
|
||||
adapters.
|
||||
|
||||
For that you will need to provide another stream than the ``php://output``
|
||||
default one, and pass it to Flysystem ``putStream`` method.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Open Stream only once for read and write since it's a memory stream and
|
||||
// the content is lost when closing the stream / opening another one
|
||||
$tempStream = fopen('php://memory', 'w+');
|
||||
|
||||
// Create Zip Archive
|
||||
$zipStream = new ZipStream(
|
||||
outputStream: $tempStream,
|
||||
outputName: 'test.zip',
|
||||
);
|
||||
$zipStream->addFile('test.txt', 'text');
|
||||
$zipStream->finish();
|
||||
|
||||
// Store File
|
||||
// (see Flysystem documentation, and all its framework integration)
|
||||
// Can be any adapter (AWS, Google, Ftp, etc.)
|
||||
$adapter = new Local(__DIR__.'/path/to/folder');
|
||||
$filesystem = new Filesystem($adapter);
|
||||
|
||||
$filesystem->writeStream('test.zip', $tempStream)
|
||||
|
||||
// Close Stream
|
||||
fclose($tempStream);
|
16
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/Nginx.rst
vendored
Normal file
16
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/Nginx.rst
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
Usage with nginx
|
||||
=============
|
||||
|
||||
If you are using nginx as a webserver, it will try to buffer the response.
|
||||
So you'll want to disable this with a custom header:
|
||||
|
||||
.. code-block:: php
|
||||
header('X-Accel-Buffering: no');
|
||||
# or with the Response class from Symfony
|
||||
$response->headers->set('X-Accel-Buffering', 'no');
|
||||
|
||||
Alternatively, you can tweak the
|
||||
`fastcgi cache parameters <https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffers>`_
|
||||
within nginx config.
|
||||
|
||||
See `original issue <https://github.com/maennchen/ZipStream-PHP/issues/77>`_.
|
66
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/Options.rst
vendored
Normal file
66
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/Options.rst
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
Available options
|
||||
===============
|
||||
|
||||
Here is the full list of options available to you. You can also have a look at
|
||||
``src/ZipStream.php`` file.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use ZipStream\ZipStream;
|
||||
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
$zip = new ZipStream(
|
||||
// Define output stream
|
||||
// (argument is eiter a resource or implementing
|
||||
// `Psr\Http\Message\StreamInterface`)
|
||||
//
|
||||
// Setup with `psr/http-message` & `guzzlehttp/psr7` dependencies
|
||||
// required when using `Psr\Http\Message\StreamInterface`.
|
||||
outputStream: $filePointer,
|
||||
|
||||
// Set the deflate level (default is 6; use -1 to disable it)
|
||||
defaultDeflateLevel: 6,
|
||||
|
||||
// Add a comment to the zip file
|
||||
comment: 'This is a comment.',
|
||||
|
||||
// Send http headers (default is true)
|
||||
sendHttpHeaders: false,
|
||||
|
||||
// HTTP Content-Disposition.
|
||||
// Defaults to 'attachment', where FILENAME is the specified filename.
|
||||
// Note that this does nothing if you are not sending HTTP headers.
|
||||
contentDisposition: 'attachment',
|
||||
|
||||
// Output Name for HTTP Content-Disposition
|
||||
// Defaults to no name
|
||||
outputName: "example.zip",
|
||||
|
||||
// HTTP Content-Type.
|
||||
// Defaults to 'application/x-zip'.
|
||||
// Note that this does nothing if you are not sending HTTP headers.
|
||||
contentType: 'application/x-zip',
|
||||
|
||||
// Set the function called for setting headers.
|
||||
// Default is the `header()` of PHP
|
||||
httpHeaderCallback: header(...),
|
||||
|
||||
// Enable streaming files with single read where general purpose bit 3
|
||||
// indicates local file header contain zero values in crc and size
|
||||
// fields, these appear only after file contents in data descriptor
|
||||
// block.
|
||||
// Set to true if your input stream is remote
|
||||
// (used with addFileFromStream()).
|
||||
// Default is false.
|
||||
defaultEnableZeroHeader: false,
|
||||
|
||||
// Enable zip64 extension, allowing very large archives
|
||||
// (> 4Gb or file count > 64k)
|
||||
// Default is true
|
||||
enableZip64: true,
|
||||
|
||||
// Flush output buffer after every write
|
||||
// Default is false
|
||||
flushOutput: true,
|
||||
);
|
21
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/PSR7Streams.rst
vendored
Normal file
21
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/PSR7Streams.rst
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
Usage with PSR 7 Streams
|
||||
===============
|
||||
|
||||
PSR-7 streams are `standardized streams <https://www.php-fig.org/psr/psr-7/>`_.
|
||||
|
||||
ZipStream-PHP supports working with these streams with the function
|
||||
``addFileFromPsr7Stream``.
|
||||
|
||||
For all parameters of the function see the API documentation.
|
||||
|
||||
Example
|
||||
---------------
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$stream = $response->getBody();
|
||||
// add a file named 'streamfile.txt' from the content of the stream
|
||||
$zip->addFileFromPsr7Stream(
|
||||
fileName: 'streamfile.txt',
|
||||
stream: $stream,
|
||||
);
|
39
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/StreamOutput.rst
vendored
Normal file
39
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/StreamOutput.rst
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
Stream Output
|
||||
===============
|
||||
|
||||
Stream to S3 Bucket
|
||||
---------------
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Aws\S3\S3Client;
|
||||
use Aws\Credentials\CredentialProvider;
|
||||
use ZipStream\ZipStream;
|
||||
|
||||
$bucket = 'your bucket name';
|
||||
$client = new S3Client([
|
||||
'region' => 'your region',
|
||||
'version' => 'latest',
|
||||
'bucketName' => $bucket,
|
||||
'credentials' => CredentialProvider::defaultProvider(),
|
||||
]);
|
||||
$client->registerStreamWrapper();
|
||||
|
||||
$zipFile = fopen("s3://$bucket/example.zip", 'w');
|
||||
|
||||
$zip = new ZipStream(
|
||||
enableZip64: false,
|
||||
outputStream: $zipFile,
|
||||
);
|
||||
|
||||
$zip->addFile(
|
||||
fileName: 'file1.txt',
|
||||
data: 'File1 data',
|
||||
);
|
||||
$zip->addFile(
|
||||
fileName: 'file2.txt',
|
||||
data: 'File2 data',
|
||||
);
|
||||
$zip->finish();
|
||||
|
||||
fclose($zipFile);
|
130
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/Symfony.rst
vendored
Normal file
130
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/Symfony.rst
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
Usage with Symfony
|
||||
===============
|
||||
|
||||
Overview for using ZipStream in Symfony
|
||||
--------
|
||||
|
||||
Using ZipStream in Symfony requires use of Symfony's ``StreamedResponse`` when
|
||||
used in controller actions.
|
||||
|
||||
Wrap your call to the relevant ``ZipStream`` stream method (i.e. ``addFile``,
|
||||
``addFileFromPath``, ``addFileFromStream``) in Symfony's ``StreamedResponse``
|
||||
function passing in any required arguments for your use case.
|
||||
|
||||
Using Symfony's ``StreamedResponse`` will allow Symfony to stream output from
|
||||
ZipStream correctly to users' browsers and avoid a corrupted final zip landing
|
||||
on the users' end.
|
||||
|
||||
Example for using ``ZipStream`` in a controller action to zip stream files
|
||||
stored in an AWS S3 bucket by key:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Aws\S3\S3Client;
|
||||
use ZipStream;
|
||||
|
||||
//...
|
||||
|
||||
/**
|
||||
* @Route("/zipstream", name="zipstream")
|
||||
*/
|
||||
public function zipStreamAction()
|
||||
{
|
||||
// sample test file on s3
|
||||
$s3keys = array(
|
||||
"ziptestfolder/file1.txt"
|
||||
);
|
||||
|
||||
$s3Client = $this->get('app.amazon.s3'); //s3client service
|
||||
$s3Client->registerStreamWrapper(); //required
|
||||
|
||||
// using StreamedResponse to wrap ZipStream functionality
|
||||
// for files on AWS s3.
|
||||
$response = new StreamedResponse(function() use($s3keys, $s3Client)
|
||||
{
|
||||
// Define suitable options for ZipStream Archive.
|
||||
// this is needed to prevent issues with truncated zip files
|
||||
//initialise zipstream with output zip filename and options.
|
||||
$zip = new ZipStream\ZipStream(
|
||||
outputName: 'test.zip',
|
||||
defaultEnableZeroHeader: true,
|
||||
contentType: 'application/octet-stream',
|
||||
);
|
||||
|
||||
//loop keys - useful for multiple files
|
||||
foreach ($s3keys as $key) {
|
||||
// Get the file name in S3 key so we can save it to the zip
|
||||
//file using the same name.
|
||||
$fileName = basename($key);
|
||||
|
||||
// concatenate s3path.
|
||||
// replace with your bucket name or get from parameters file.
|
||||
$bucket = 'bucketname';
|
||||
$s3path = "s3://" . $bucket . "/" . $key;
|
||||
|
||||
//addFileFromStream
|
||||
if ($streamRead = fopen($s3path, 'r')) {
|
||||
$zip->addFileFromStream(
|
||||
fileName: $fileName,
|
||||
stream: $streamRead,
|
||||
);
|
||||
} else {
|
||||
die('Could not open stream for reading');
|
||||
}
|
||||
}
|
||||
|
||||
$zip->finish();
|
||||
|
||||
});
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
In the above example, files on AWS S3 are being streamed from S3 to the Symfon
|
||||
application via ``fopen`` call when the s3Client has ``registerStreamWrapper``
|
||||
applied. This stream is then passed to ``ZipStream`` via the
|
||||
``addFileFromStream`` function, which ZipStream then streams as a zip to the
|
||||
client browser via Symfony's ``StreamedResponse``. No Zip is created server
|
||||
side, which makes this approach a more efficient solution for streaming zips to
|
||||
the client browser especially for larger files.
|
||||
|
||||
For the above use case you will need to have installed
|
||||
`aws/aws-sdk-php-symfony <https://github.com/aws/aws-sdk-php-symfony>`_ to
|
||||
support accessing S3 objects in your Symfony web application. This is not
|
||||
required for locally stored files on you server you intend to stream via
|
||||
``ZipStream``.
|
||||
|
||||
See official Symfony documentation for details on
|
||||
`Symfony's StreamedResponse <https://symfony.com/doc/current/components/http_foundation.html#streaming-a-response>`_
|
||||
``Symfony\Component\HttpFoundation\StreamedResponse``.
|
||||
|
||||
Note from `S3 documentation <https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-stream-wrapper.html>`_:
|
||||
|
||||
Streams opened in "r" mode only allow data to be read from the stream, and
|
||||
are not seekable by default. This is so that data can be downloaded from
|
||||
Amazon S3 in a truly streaming manner, where previously read bytes do not
|
||||
need to be buffered into memory. If you need a stream to be seekable, you
|
||||
can pass seekable into the stream context options of a function.
|
||||
|
||||
Make sure to configure your S3 context correctly!
|
||||
|
||||
Uploading a file
|
||||
--------
|
||||
|
||||
You need to add correct permissions
|
||||
(see `#120 <https://github.com/maennchen/ZipStream-PHP/issues/120>`_)
|
||||
|
||||
**example code**
|
||||
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$path = "s3://{$adapter->getBucket()}/{$this->getArchivePath()}";
|
||||
|
||||
// the important bit
|
||||
$outputContext = stream_context_create([
|
||||
's3' => ['ACL' => 'public-read'],
|
||||
]);
|
||||
|
||||
fopen($path, 'w', null, $outputContext);
|
22
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/Varnish.rst
vendored
Normal file
22
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/Varnish.rst
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
Usage with Varnish
|
||||
=============
|
||||
|
||||
Serving a big zip with varnish in between can cause random stream close.
|
||||
This can be solved by adding attached code to the vcl file.
|
||||
|
||||
To avoid the problem, add the following to your varnish config file:
|
||||
|
||||
.. code-block::
|
||||
sub vcl_recv {
|
||||
# Varnish can’t intercept the discussion anymore
|
||||
# helps for streaming big zips
|
||||
if (req.url ~ "\.(tar|gz|zip|7z|exe)$") {
|
||||
return (pipe);
|
||||
}
|
||||
}
|
||||
# Varnish can’t intercept the discussion anymore
|
||||
# helps for streaming big zips
|
||||
sub vcl_pipe {
|
||||
set bereq.http.connection = "close";
|
||||
return (pipe);
|
||||
}
|
126
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/index.rst
vendored
Normal file
126
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/guides/index.rst
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
ZipStream PHP
|
||||
=============
|
||||
|
||||
A fast and simple streaming zip file downloader for PHP. Using this library will
|
||||
save you from having to write the Zip to disk. You can directly send it to the
|
||||
user, which is much faster. It can work with S3 buckets or any PSR7 Stream.
|
||||
|
||||
.. toctree::
|
||||
|
||||
index
|
||||
Symfony
|
||||
Options
|
||||
StreamOutput
|
||||
FlySystem
|
||||
PSR7Streams
|
||||
Nginx
|
||||
Varnish
|
||||
ContentLength
|
||||
|
||||
Installation
|
||||
---------------
|
||||
|
||||
Simply add a dependency on ``maennchen/zipstream-php`` to your project's
|
||||
``composer.json`` file if you use Composer to manage the dependencies of your
|
||||
project. Use following command to add the package to your project's
|
||||
dependencies:
|
||||
|
||||
.. code-block:: sh
|
||||
composer require maennchen/zipstream-php
|
||||
|
||||
If you want to use``addFileFromPsr7Stream```
|
||||
(``Psr\Http\Message\StreamInterface``) or use a stream instead of a
|
||||
``resource`` as ``outputStream``, the following dependencies must be installed
|
||||
as well:
|
||||
|
||||
.. code-block:: sh
|
||||
composer require psr/http-message guzzlehttp/psr7
|
||||
|
||||
If ``composer install`` yields the following error, your installation is missing
|
||||
the `mbstring extension <https://www.php.net/manual/en/book.mbstring.php>`_,
|
||||
either `install it <https://www.php.net/manual/en/mbstring.installation.php>`_
|
||||
or run the follwoing command:
|
||||
|
||||
.. code-block::
|
||||
Your requirements could not be resolved to an installable set of packages.
|
||||
|
||||
Problem 1
|
||||
- Root composer.json requires PHP extension ext-mbstring * but it is
|
||||
missing from your system. Install or enable PHP's mbstrings extension.
|
||||
|
||||
.. code-block:: sh
|
||||
composer require symfony/polyfill-mbstring
|
||||
|
||||
Usage Intro
|
||||
---------------
|
||||
|
||||
Here's a simple example:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Autoload the dependencies
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
// create a new zipstream object
|
||||
$zip = new ZipStream\ZipStream(
|
||||
outputName: 'example.zip',
|
||||
|
||||
// enable output of HTTP headers
|
||||
sendHttpHeaders: true,
|
||||
);
|
||||
|
||||
// create a file named 'hello.txt'
|
||||
$zip->addFile(
|
||||
fileName: 'hello.txt',
|
||||
data: 'This is the contents of hello.txt',
|
||||
);
|
||||
|
||||
// add a file named 'some_image.jpg' from a local file 'path/to/image.jpg'
|
||||
$zip->addFileFromPath(
|
||||
fileName: 'some_image.jpg',
|
||||
path: 'path/to/image.jpg',
|
||||
);
|
||||
|
||||
// add a file named 'goodbye.txt' from an open stream resource
|
||||
$filePointer = tmpfile();
|
||||
fwrite($filePointer, 'The quick brown fox jumped over the lazy dog.');
|
||||
rewind($filePointer);
|
||||
$zip->addFileFromStream(
|
||||
fileName: 'goodbye.txt',
|
||||
stream: $filePointer,
|
||||
);
|
||||
fclose($filePointer);
|
||||
|
||||
// add a file named 'streamfile.txt' from the body of a `guzzle` response
|
||||
// Setup with `psr/http-message` & `guzzlehttp/psr7` dependencies required.
|
||||
$zip->addFileFromPsr7Stream(
|
||||
fileName: 'streamfile.txt',
|
||||
stream: $response->getBody(),
|
||||
);
|
||||
|
||||
// finish the zip stream
|
||||
$zip->finish();
|
||||
|
||||
You can also add comments, modify file timestamps, and customize (or
|
||||
disable) the HTTP headers. It is also possible to specify the storage method
|
||||
when adding files, the current default storage method is ``DEFLATE``
|
||||
i.e files are stored with Compression mode 0x08.
|
||||
|
||||
Known Issues
|
||||
---------------
|
||||
|
||||
The native Mac OS archive extraction tool prior to macOS 10.15 might not open
|
||||
archives in some conditions. A workaround is to disable the Zip64 feature with
|
||||
the option ``enableZip64: false``. This limits the archive to 4 Gb and 64k files
|
||||
but will allow users on macOS 10.14 and below to open them without issue.
|
||||
See `#116 <https://github.com/maennchen/ZipStream-PHP/issues/146>`_.
|
||||
|
||||
The linux ``unzip`` utility might not handle properly unicode characters.
|
||||
It is recommended to extract with another tool like
|
||||
`7-zip <https://www.7-zip.org/>`_.
|
||||
See `#146 <https://github.com/maennchen/ZipStream-PHP/issues/146>`_.
|
||||
|
||||
It is the responsability of the client code to make sure that files are not
|
||||
saved with the same path, as it is not possible for the library to figure it out
|
||||
while streaming a zip.
|
||||
See `#154 <https://github.com/maennchen/ZipStream-PHP/issues/154>`_.
|
39
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/phpdoc.dist.xml
vendored
Normal file
39
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/phpdoc.dist.xml
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<phpdocumentor
|
||||
configVersion="3"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://www.phpdoc.org"
|
||||
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/phpDocumentor/phpDocumentor/master/data/xsd/phpdoc.xsd"
|
||||
>
|
||||
<title>💾 ZipStream-PHP</title>
|
||||
<paths>
|
||||
<output>docs</output>
|
||||
</paths>
|
||||
<version number="3.0.0">
|
||||
<folder>latest</folder>
|
||||
<api>
|
||||
<source dsn=".">
|
||||
<path>src</path>
|
||||
</source>
|
||||
<output>api</output>
|
||||
<ignore hidden="true" symlinks="true">
|
||||
<path>tests/**/*</path>
|
||||
<path>vendor/**/*</path>
|
||||
</ignore>
|
||||
<extensions>
|
||||
<extension>php</extension>
|
||||
</extensions>
|
||||
<visibility>public</visibility>
|
||||
<default-package-name>ZipStream</default-package-name>
|
||||
<include-source>true</include-source>
|
||||
</api>
|
||||
<guide>
|
||||
<source dsn=".">
|
||||
<path>guides</path>
|
||||
</source>
|
||||
<output>guide</output>
|
||||
</guide>
|
||||
</version>
|
||||
<setting name="guides.enabled" value="true"/>
|
||||
<template name="default" />
|
||||
</phpdocumentor>
|
15
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/phpunit.xml.dist
vendored
Normal file
15
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/phpunit.xml.dist
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="test/bootstrap.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd" cacheDirectory=".phpunit.cache">
|
||||
<coverage/>
|
||||
<testsuites>
|
||||
<testsuite name="Application">
|
||||
<directory>test</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<logging/>
|
||||
<source>
|
||||
<include>
|
||||
<directory suffix=".php">src</directory>
|
||||
</include>
|
||||
</source>
|
||||
</phpunit>
|
23
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/psalm.xml
vendored
Normal file
23
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/psalm.xml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
errorLevel="1"
|
||||
resolveFromConfigFile="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
findUnusedBaselineEntry="true"
|
||||
findUnusedCode="true"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
<issueHandlers>
|
||||
<!-- Turn off dead code warnings for externally called functions -->
|
||||
<PossiblyUnusedProperty errorLevel="suppress" />
|
||||
<PossiblyUnusedMethod errorLevel="suppress" />
|
||||
<PossiblyUnusedReturnValue errorLevel="suppress" />
|
||||
</issueHandlers>
|
||||
</psalm>
|
52
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/CentralDirectoryFileHeader.php
vendored
Normal file
52
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/CentralDirectoryFileHeader.php
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
106
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/CompressionMethod.php
vendored
Normal file
106
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/CompressionMethod.php
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
<?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;
|
||||
}
|
26
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/DataDescriptor.php
vendored
Normal file
26
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/DataDescriptor.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?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),
|
||||
);
|
||||
}
|
||||
}
|
35
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/EndOfCentralDirectory.php
vendored
Normal file
35
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/EndOfCentralDirectory.php
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
9
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Exception.php
vendored
Normal file
9
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Exception.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream;
|
||||
|
||||
abstract class Exception extends \Exception
|
||||
{
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
<?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.");
|
||||
}
|
||||
}
|
22
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Exception/FileNotFoundException.php
vendored
Normal file
22
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Exception/FileNotFoundException.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?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.");
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<?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.");
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
<?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.");
|
||||
}
|
||||
}
|
21
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Exception/OverflowException.php
vendored
Normal file
21
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Exception/OverflowException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?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.');
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?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.');
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<?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.');
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?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.');
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
420
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/File.php
vendored
Normal file
420
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/File.php
vendored
Normal file
@ -0,0 +1,420 @@
|
||||
<?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) {
|
||||
$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;
|
||||
|
||||
if (
|
||||
$this->isSimulation() &&
|
||||
$detectedSize > 0
|
||||
) {
|
||||
($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) {
|
||||
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 && $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;
|
||||
}
|
||||
}
|
89
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/GeneralPurposeBitFlag.php
vendored
Normal file
89
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/GeneralPurposeBitFlag.php
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
<?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;
|
||||
}
|
40
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/LocalFileHeader.php
vendored
Normal file
40
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/LocalFileHeader.php
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
35
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/OperationMode.php
vendored
Normal file
35
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/OperationMode.php
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<?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;
|
||||
}
|
57
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/PackField.php
vendored
Normal file
57
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/PackField.php
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
45
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Time.php
vendored
Normal file
45
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Time.php
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<?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' => $year,
|
||||
'mon' => $month,
|
||||
'mday' => $day,
|
||||
'hours' => $hour,
|
||||
'minutes' => $minute,
|
||||
'seconds' => $second
|
||||
] = getdate($dateTime->getTimestamp());
|
||||
|
||||
return
|
||||
($year << 25) |
|
||||
($month << 21) |
|
||||
($day << 16) |
|
||||
($hour << 11) |
|
||||
($minute << 5) |
|
||||
($second >> 1);
|
||||
}
|
||||
}
|
12
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Version.php
vendored
Normal file
12
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Version.php
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
<?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
|
||||
}
|
28
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Zip64/DataDescriptor.php
vendored
Normal file
28
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Zip64/DataDescriptor.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?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),
|
||||
);
|
||||
}
|
||||
}
|
43
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectory.php
vendored
Normal file
43
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Zip64/EndOfCentralDirectory.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?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),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?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),
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
864
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/ZipStream.php
vendored
Normal file
864
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/ZipStream.php
vendored
Normal file
@ -0,0 +1,864 @@
|
||||
<?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->addFileFormPath(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->addFile(
|
||||
* 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);
|
||||
}
|
||||
|
||||
if ($fileTime = filemtime($path)) {
|
||||
$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->addFileFromPsr7Stream(
|
||||
* 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->addFile(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) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
23
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Zs/ExtendedInformationExtraField.php
vendored
Normal file
23
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/src/Zs/ExtendedInformationExtraField.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?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),
|
||||
);
|
||||
}
|
||||
}
|
49
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/Assertions.php
vendored
Normal file
49
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/Assertions.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
trait Assertions
|
||||
{
|
||||
protected function assertFileContains(string $filePath, string $needle): void
|
||||
{
|
||||
$last = '';
|
||||
|
||||
$handle = fopen($filePath, 'r');
|
||||
while (!feof($handle)) {
|
||||
$line = fgets($handle, 1024);
|
||||
|
||||
if(str_contains($last . $line, $needle)) {
|
||||
fclose($handle);
|
||||
return;
|
||||
}
|
||||
|
||||
$last = $line;
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->fail("File {$filePath} must contain {$needle}");
|
||||
}
|
||||
|
||||
protected function assertFileDoesNotContain(string $filePath, string $needle): void
|
||||
{
|
||||
$last = '';
|
||||
|
||||
$handle = fopen($filePath, 'r');
|
||||
while (!feof($handle)) {
|
||||
$line = fgets($handle, 1024);
|
||||
|
||||
if(str_contains($last . $line, $needle)) {
|
||||
fclose($handle);
|
||||
|
||||
$this->fail("File {$filePath} must not contain {$needle}");
|
||||
}
|
||||
|
||||
$last = $line;
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
}
|
||||
}
|
60
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/CentralDirectoryFileHeaderTest.php
vendored
Normal file
60
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/CentralDirectoryFileHeaderTest.php
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\CentralDirectoryFileHeader;
|
||||
use ZipStream\CompressionMethod;
|
||||
|
||||
class CentralDirectoryFileHeaderTest extends TestCase
|
||||
{
|
||||
public function testSerializesCorrectly(): void
|
||||
{
|
||||
$dateTime = new DateTimeImmutable('2022-01-01 01:01:01Z');
|
||||
|
||||
$header = CentralDirectoryFileHeader::generate(
|
||||
versionMadeBy: 0x603,
|
||||
versionNeededToExtract: 0x002D,
|
||||
generalPurposeBitFlag: 0x2222,
|
||||
compressionMethod: CompressionMethod::DEFLATE,
|
||||
lastModificationDateTime: $dateTime,
|
||||
crc32: 0x11111111,
|
||||
compressedSize: 0x77777777,
|
||||
uncompressedSize: 0x99999999,
|
||||
fileName: 'test.png',
|
||||
extraField: 'some content',
|
||||
fileComment: 'some comment',
|
||||
diskNumberStart: 0,
|
||||
internalFileAttributes: 0,
|
||||
externalFileAttributes: 32,
|
||||
relativeOffsetOfLocalHeader: 0x1234,
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
bin2hex($header),
|
||||
'504b0102' . // 4 bytes; central file header signature
|
||||
'0306' . // 2 bytes; version made by
|
||||
'2d00' . // 2 bytes; version needed to extract
|
||||
'2222' . // 2 bytes; general purpose bit flag
|
||||
'0800' . // 2 bytes; compression method
|
||||
'2008' . // 2 bytes; last mod file time
|
||||
'2154' . // 2 bytes; last mod file date
|
||||
'11111111' . // 4 bytes; crc-32
|
||||
'77777777' . // 4 bytes; compressed size
|
||||
'99999999' . // 4 bytes; uncompressed size
|
||||
'0800' . // 2 bytes; file name length (n)
|
||||
'0c00' . // 2 bytes; extra field length (m)
|
||||
'0c00' . // 2 bytes; file comment length (o)
|
||||
'0000' . // 2 bytes; disk number start
|
||||
'0000' . // 2 bytes; internal file attributes
|
||||
'20000000' . // 4 bytes; external file attributes
|
||||
'34120000' . // 4 bytes; relative offset of local header
|
||||
'746573742e706e67' . // n bytes; file name
|
||||
'736f6d6520636f6e74656e74' . // m bytes; extra field
|
||||
'736f6d6520636f6d6d656e74' // o bytes; file comment
|
||||
);
|
||||
}
|
||||
}
|
26
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/DataDescriptorTest.php
vendored
Normal file
26
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/DataDescriptorTest.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\DataDescriptor;
|
||||
|
||||
class DataDescriptorTest extends TestCase
|
||||
{
|
||||
public function testSerializesCorrectly(): void
|
||||
{
|
||||
$this->assertSame(
|
||||
bin2hex(DataDescriptor::generate(
|
||||
crc32UncompressedData: 0x11111111,
|
||||
compressedSize: 0x77777777,
|
||||
uncompressedSize: 0x99999999,
|
||||
)),
|
||||
'504b0708' . // 4 bytes; Optional data descriptor signature = 0x08074b50
|
||||
'11111111' . // 4 bytes; CRC-32 of uncompressed data
|
||||
'77777777' . // 4 bytes; Compressed size
|
||||
'99999999' // 4 bytes; Uncompressed size
|
||||
);
|
||||
}
|
||||
}
|
35
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/EndOfCentralDirectoryTest.php
vendored
Normal file
35
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/EndOfCentralDirectoryTest.php
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\EndOfCentralDirectory;
|
||||
|
||||
class EndOfCentralDirectoryTest extends TestCase
|
||||
{
|
||||
public function testSerializesCorrectly(): void
|
||||
{
|
||||
$this->assertSame(
|
||||
bin2hex(EndOfCentralDirectory::generate(
|
||||
numberOfThisDisk: 0x00,
|
||||
numberOfTheDiskWithCentralDirectoryStart: 0x00,
|
||||
numberOfCentralDirectoryEntriesOnThisDisk: 0x10,
|
||||
numberOfCentralDirectoryEntries: 0x10,
|
||||
sizeOfCentralDirectory: 0x22,
|
||||
centralDirectoryStartOffsetOnDisk: 0x33,
|
||||
zipFileComment: 'foo',
|
||||
)),
|
||||
'504b0506' . // 4 bytes; end of central dir signature 0x06054b50
|
||||
'0000' . // 2 bytes; number of this disk
|
||||
'0000' . // 2 bytes; number of the disk with the start of the central directory
|
||||
'1000' . // 2 bytes; total number of entries in the central directory on this disk
|
||||
'1000' . // 2 bytes; total number of entries in the central directory
|
||||
'22000000' . // 4 bytes; size of the central directory
|
||||
'33000000' . // 4 bytes; offset of start of central directory with respect to the starting disk number
|
||||
'0300' . // 2 bytes; .ZIP file comment length
|
||||
bin2hex('foo')
|
||||
);
|
||||
}
|
||||
}
|
106
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/EndlessCycleStream.php
vendored
Normal file
106
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/EndlessCycleStream.php
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use RuntimeException;
|
||||
|
||||
class EndlessCycleStream implements StreamInterface
|
||||
{
|
||||
private int $offset = 0;
|
||||
|
||||
public function __construct(private readonly string $toRepeat = '0')
|
||||
{
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
throw new RuntimeException('Infinite Stream!');
|
||||
}
|
||||
|
||||
public function close(): void
|
||||
{
|
||||
$this->detach();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function detach()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public function getSize(): ?int
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function tell(): int
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
public function eof(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isSeekable(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function seek(int $offset, int $whence = SEEK_SET): void
|
||||
{
|
||||
switch($whence) {
|
||||
case SEEK_SET:
|
||||
$this->offset = $offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
$this->offset += $offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
throw new RuntimeException('Infinite Stream!');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->seek(0);
|
||||
}
|
||||
|
||||
public function isWritable(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function write(string $string): int
|
||||
{
|
||||
throw new RuntimeException('Not writeable');
|
||||
}
|
||||
|
||||
public function isReadable(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function read(int $length): string
|
||||
{
|
||||
$this->offset += $length;
|
||||
return substr(str_repeat($this->toRepeat, (int) ceil($length / strlen($this->toRepeat))), 0, $length);
|
||||
}
|
||||
|
||||
public function getContents(): string
|
||||
{
|
||||
throw new RuntimeException('Infinite Stream!');
|
||||
}
|
||||
|
||||
public function getMetadata(?string $key = null): array|null
|
||||
{
|
||||
return $key !== null ? null : [];
|
||||
}
|
||||
}
|
141
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/FaultInjectionResource.php
vendored
Normal file
141
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/FaultInjectionResource.php
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
class FaultInjectionResource
|
||||
{
|
||||
public const NAME = 'zipstream-php-test-broken-resource';
|
||||
|
||||
/** @var resource */
|
||||
public $context;
|
||||
|
||||
private array $injectFaults;
|
||||
|
||||
private string $mode;
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*/
|
||||
public static function getResource(array $injectFaults)
|
||||
{
|
||||
self::register();
|
||||
|
||||
return fopen(self::NAME . '://foobar', 'rw+', false, self::createStreamContext($injectFaults));
|
||||
}
|
||||
|
||||
public function stream_open(string $path, string $mode, int $options, string &$opened_path = null): bool
|
||||
{
|
||||
$options = stream_context_get_options($this->context);
|
||||
|
||||
if (!isset($options[self::NAME]['injectFaults'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->mode = $mode;
|
||||
$this->injectFaults = $options[self::NAME]['injectFaults'];
|
||||
|
||||
if ($this->shouldFail(__FUNCTION__)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function stream_write(string $data)
|
||||
{
|
||||
if ($this->shouldFail(__FUNCTION__)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function stream_seek(int $offset, int $whence): bool
|
||||
{
|
||||
if ($this->shouldFail(__FUNCTION__)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function stream_tell(): int
|
||||
{
|
||||
if ($this->shouldFail(__FUNCTION__)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function register(): void
|
||||
{
|
||||
if (!in_array(self::NAME, stream_get_wrappers(), true)) {
|
||||
stream_wrapper_register(self::NAME, __CLASS__);
|
||||
}
|
||||
}
|
||||
|
||||
public function stream_stat(): array
|
||||
{
|
||||
static $modeMap = [
|
||||
'r' => 33060,
|
||||
'rb' => 33060,
|
||||
'r+' => 33206,
|
||||
'w' => 33188,
|
||||
'wb' => 33188,
|
||||
];
|
||||
|
||||
return [
|
||||
'dev' => 0,
|
||||
'ino' => 0,
|
||||
'mode' => $modeMap[$this->mode],
|
||||
'nlink' => 0,
|
||||
'uid' => 0,
|
||||
'gid' => 0,
|
||||
'rdev' => 0,
|
||||
'size' => 0,
|
||||
'atime' => 0,
|
||||
'mtime' => 0,
|
||||
'ctime' => 0,
|
||||
'blksize' => 0,
|
||||
'blocks' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
public function url_stat(string $path, int $flags): array
|
||||
{
|
||||
return [
|
||||
'dev' => 0,
|
||||
'ino' => 0,
|
||||
'mode' => 0,
|
||||
'nlink' => 0,
|
||||
'uid' => 0,
|
||||
'gid' => 0,
|
||||
'rdev' => 0,
|
||||
'size' => 0,
|
||||
'atime' => 0,
|
||||
'mtime' => 0,
|
||||
'ctime' => 0,
|
||||
'blksize' => 0,
|
||||
'blocks' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
private static function createStreamContext(array $injectFaults)
|
||||
{
|
||||
return stream_context_create([
|
||||
self::NAME => ['injectFaults' => $injectFaults],
|
||||
]);
|
||||
}
|
||||
|
||||
private function shouldFail(string $function): bool
|
||||
{
|
||||
return in_array($function, $this->injectFaults, true);
|
||||
}
|
||||
}
|
47
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/LocalFileHeaderTest.php
vendored
Normal file
47
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/LocalFileHeaderTest.php
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\CompressionMethod;
|
||||
use ZipStream\LocalFileHeader;
|
||||
|
||||
class LocalFileHeaderTest extends TestCase
|
||||
{
|
||||
public function testSerializesCorrectly(): void
|
||||
{
|
||||
$dateTime = new DateTimeImmutable('2022-01-01 01:01:01Z');
|
||||
|
||||
$header = LocalFileHeader::generate(
|
||||
versionNeededToExtract: 0x002D,
|
||||
generalPurposeBitFlag: 0x2222,
|
||||
compressionMethod: CompressionMethod::DEFLATE,
|
||||
lastModificationDateTime: $dateTime,
|
||||
crc32UncompressedData: 0x11111111,
|
||||
compressedSize: 0x77777777,
|
||||
uncompressedSize: 0x99999999,
|
||||
fileName: 'test.png',
|
||||
extraField: 'some content'
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
bin2hex((string) $header),
|
||||
'504b0304' . // 4 bytes; Local file header signature
|
||||
'2d00' . // 2 bytes; Version needed to extract (minimum)
|
||||
'2222' . // 2 bytes; General purpose bit flag
|
||||
'0800' . // 2 bytes; Compression method; e.g. none = 0, DEFLATE = 8
|
||||
'2008' . // 2 bytes; File last modification time
|
||||
'2154' . // 2 bytes; File last modification date
|
||||
'11111111' . // 4 bytes; CRC-32 of uncompressed data
|
||||
'77777777' . // 4 bytes; Compressed size (or 0xffffffff for ZIP64)
|
||||
'99999999' . // 4 bytes; Uncompressed size (or 0xffffffff for ZIP64)
|
||||
'0800' . // 2 bytes; File name length (n)
|
||||
'0c00' . // 2 bytes; Extra field length (m)
|
||||
'746573742e706e67' . // n bytes; File name
|
||||
'736f6d6520636f6e74656e74' // m bytes; Extra field
|
||||
);
|
||||
}
|
||||
}
|
42
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/PackFieldTest.php
vendored
Normal file
42
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/PackFieldTest.php
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use RuntimeException;
|
||||
use ZipStream\PackField;
|
||||
|
||||
class PackFieldTest extends TestCase
|
||||
{
|
||||
public function testPacksFields(): void
|
||||
{
|
||||
$this->assertSame(
|
||||
bin2hex(PackField::pack(new PackField(format: 'v', value: 0x1122))),
|
||||
'2211',
|
||||
);
|
||||
}
|
||||
|
||||
public function testOverflow2(): void
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
PackField::pack(new PackField(format: 'v', value: 0xFFFFF));
|
||||
}
|
||||
|
||||
public function testOverflow4(): void
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
PackField::pack(new PackField(format: 'V', value: 0xFFFFFFFFF));
|
||||
}
|
||||
|
||||
public function testUnknownOperator(): void
|
||||
{
|
||||
$this->assertSame(
|
||||
bin2hex(PackField::pack(new PackField(format: 'a', value: 0x1122))),
|
||||
'34',
|
||||
);
|
||||
}
|
||||
}
|
160
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/ResourceStream.php
vendored
Normal file
160
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/ResourceStream.php
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ResourceStream implements StreamInterface
|
||||
{
|
||||
public function __construct(
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $stream
|
||||
) {
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->isSeekable()) {
|
||||
$this->seek(0);
|
||||
}
|
||||
return (string) stream_get_contents($this->stream);
|
||||
}
|
||||
|
||||
public function close(): void
|
||||
{
|
||||
$stream = $this->detach();
|
||||
if ($stream) {
|
||||
fclose($stream);
|
||||
}
|
||||
}
|
||||
|
||||
public function detach()
|
||||
{
|
||||
$result = $this->stream;
|
||||
// According to the interface, the stream is left in an unusable state;
|
||||
/** @psalm-suppress PossiblyNullPropertyAssignmentValue */
|
||||
$this->stream = null;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function seek(int $offset, int $whence = SEEK_SET): void
|
||||
{
|
||||
if (!$this->isSeekable()) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (fseek($this->stream, $offset, $whence) !== 0) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new RuntimeException();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
public function isSeekable(): bool
|
||||
{
|
||||
return (bool)$this->getMetadata('seekable');
|
||||
}
|
||||
|
||||
public function getMetadata(?string $key = null)
|
||||
{
|
||||
$metadata = stream_get_meta_data($this->stream);
|
||||
return $key !== null ? @$metadata[$key] : $metadata;
|
||||
}
|
||||
|
||||
public function getSize(): ?int
|
||||
{
|
||||
$stats = fstat($this->stream);
|
||||
return $stats['size'];
|
||||
}
|
||||
|
||||
public function tell(): int
|
||||
{
|
||||
$position = ftell($this->stream);
|
||||
if ($position === false) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new RuntimeException();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
return $position;
|
||||
}
|
||||
|
||||
public function eof(): bool
|
||||
{
|
||||
return feof($this->stream);
|
||||
}
|
||||
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->seek(0);
|
||||
}
|
||||
|
||||
public function write(string $string): int
|
||||
{
|
||||
if (!$this->isWritable()) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (fwrite($this->stream, $string) === false) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new RuntimeException();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
public function isWritable(): bool
|
||||
{
|
||||
$mode = $this->getMetadata('mode');
|
||||
if (!is_string($mode)) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new RuntimeException('Could not get stream mode from metadata!');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
return preg_match('/[waxc+]/', $mode) === 1;
|
||||
}
|
||||
|
||||
public function read(int $length): string
|
||||
{
|
||||
if (!$this->isReadable()) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
$result = fread($this->stream, $length);
|
||||
if ($result === false) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new RuntimeException();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function isReadable(): bool
|
||||
{
|
||||
$mode = $this->getMetadata('mode');
|
||||
if (!is_string($mode)) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new RuntimeException('Could not get stream mode from metadata!');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
return preg_match('/[r+]/', $mode) === 1;
|
||||
}
|
||||
|
||||
public function getContents(): string
|
||||
{
|
||||
if (!$this->isReadable()) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
$result = stream_get_contents($this->stream);
|
||||
if ($result === false) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new RuntimeException();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
35
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/TimeTest.php
vendored
Normal file
35
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/TimeTest.php
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\Exception\DosTimeOverflowException;
|
||||
use ZipStream\Time;
|
||||
|
||||
class TimeTest extends TestCase
|
||||
{
|
||||
public function testNormalDateToDosTime(): void
|
||||
{
|
||||
$this->assertSame(
|
||||
Time::dateTimeToDosTime(new DateTimeImmutable('2014-11-17T17:46:08Z')),
|
||||
1165069764
|
||||
);
|
||||
|
||||
// January 1 1980 - DOS Epoch.
|
||||
$this->assertSame(
|
||||
Time::dateTimeToDosTime(new DateTimeImmutable('1980-01-01T00:00:00+00:00')),
|
||||
2162688
|
||||
);
|
||||
}
|
||||
|
||||
public function testTooEarlyDateToDosTime(): void
|
||||
{
|
||||
$this->expectException(DosTimeOverflowException::class);
|
||||
|
||||
// January 1 1980 is the minimum DOS Epoch.
|
||||
Time::dateTimeToDosTime(new DateTimeImmutable('1970-01-01T00:00:00+00:00'));
|
||||
}
|
||||
}
|
135
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/Util.php
vendored
Normal file
135
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/Util.php
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test;
|
||||
|
||||
use function fgets;
|
||||
use function pclose;
|
||||
use function popen;
|
||||
use function preg_match;
|
||||
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
|
||||
use function strtolower;
|
||||
|
||||
use ZipArchive;
|
||||
|
||||
trait Util
|
||||
{
|
||||
protected function getTmpFileStream(): array
|
||||
{
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'zipstreamtest');
|
||||
$stream = fopen($tmp, 'wb+');
|
||||
|
||||
return [$tmp, $stream];
|
||||
}
|
||||
|
||||
protected function cmdExists(string $command): bool
|
||||
{
|
||||
if (strtolower(\substr(PHP_OS, 0, 3)) === 'win') {
|
||||
$fp = popen("where $command", 'r');
|
||||
$result = fgets($fp, 255);
|
||||
$exists = !preg_match('#Could not find files#', $result);
|
||||
pclose($fp);
|
||||
} else { // non-Windows
|
||||
$fp = popen("which $command", 'r');
|
||||
$result = fgets($fp, 255);
|
||||
$exists = !empty($result);
|
||||
pclose($fp);
|
||||
}
|
||||
|
||||
return $exists;
|
||||
}
|
||||
|
||||
protected function dumpZipContents(string $path): string
|
||||
{
|
||||
if (!$this->cmdExists('hexdump')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$output = [];
|
||||
|
||||
if (!exec("hexdump -C \"$path\" | head -n 50", $output)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return "\nHexdump:\n" . implode("\n", $output);
|
||||
}
|
||||
|
||||
protected function validateAndExtractZip(string $zipPath): string
|
||||
{
|
||||
$tmpDir = $this->getTmpDir();
|
||||
|
||||
$zipArchive = new ZipArchive();
|
||||
$result = $zipArchive->open($zipPath);
|
||||
|
||||
if ($result !== true) {
|
||||
$codeName = $this->zipArchiveOpenErrorCodeName($result);
|
||||
$debugInformation = $this->dumpZipContents($zipPath);
|
||||
|
||||
$this->fail("Failed to open {$zipPath}. Code: $result ($codeName)$debugInformation");
|
||||
|
||||
return $tmpDir;
|
||||
}
|
||||
|
||||
$this->assertSame(0, $zipArchive->status);
|
||||
$this->assertSame(0, $zipArchive->statusSys);
|
||||
|
||||
$zipArchive->extractTo($tmpDir);
|
||||
$zipArchive->close();
|
||||
|
||||
return $tmpDir;
|
||||
}
|
||||
|
||||
protected function zipArchiveOpenErrorCodeName(int $code): string
|
||||
{
|
||||
switch($code) {
|
||||
case ZipArchive::ER_EXISTS: return 'ER_EXISTS';
|
||||
case ZipArchive::ER_INCONS: return 'ER_INCONS';
|
||||
case ZipArchive::ER_INVAL: return 'ER_INVAL';
|
||||
case ZipArchive::ER_MEMORY: return 'ER_MEMORY';
|
||||
case ZipArchive::ER_NOENT: return 'ER_NOENT';
|
||||
case ZipArchive::ER_NOZIP: return 'ER_NOZIP';
|
||||
case ZipArchive::ER_OPEN: return 'ER_OPEN';
|
||||
case ZipArchive::ER_READ: return 'ER_READ';
|
||||
case ZipArchive::ER_SEEK: return 'ER_SEEK';
|
||||
default: return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
protected function getTmpDir(): string
|
||||
{
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'zipstreamtest');
|
||||
unlink($tmp);
|
||||
mkdir($tmp) or $this->fail('Failed to make directory');
|
||||
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getRecursiveFileList(string $path, bool $includeDirectories = false): array
|
||||
{
|
||||
$data = [];
|
||||
$path = (string)realpath($path);
|
||||
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
|
||||
|
||||
$pathLen = strlen($path);
|
||||
foreach ($files as $file) {
|
||||
$filePath = $file->getRealPath();
|
||||
|
||||
if (is_dir($filePath) && !$includeDirectories) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data[] = substr($filePath, $pathLen + 1);
|
||||
}
|
||||
|
||||
sort($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
28
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/Zip64/DataDescriptorTest.php
vendored
Normal file
28
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/Zip64/DataDescriptorTest.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test\Zip64;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\Zip64\DataDescriptor;
|
||||
|
||||
class DataDescriptorTest extends TestCase
|
||||
{
|
||||
public function testSerializesCorrectly(): void
|
||||
{
|
||||
$descriptor = DataDescriptor::generate(
|
||||
crc32UncompressedData: 0x11111111,
|
||||
compressedSize: (0x77777777 << 32) + 0x66666666,
|
||||
uncompressedSize: (0x99999999 << 32) + 0x88888888,
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
bin2hex($descriptor),
|
||||
'504b0708' . // 4 bytes; Optional data descriptor signature = 0x08074b50
|
||||
'11111111' . // 4 bytes; CRC-32 of uncompressed data
|
||||
'6666666677777777' . // 8 bytes; Compressed size
|
||||
'8888888899999999' // 8 bytes; Uncompressed size
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test\Zip64;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\Zip64\EndOfCentralDirectoryLocator;
|
||||
|
||||
class EndOfCentralDirectoryLocatorTest extends TestCase
|
||||
{
|
||||
public function testSerializesCorrectly(): void
|
||||
{
|
||||
$descriptor = EndOfCentralDirectoryLocator::generate(
|
||||
numberOfTheDiskWithZip64CentralDirectoryStart: 0x11111111,
|
||||
zip64centralDirectoryStartOffsetOnDisk: (0x22222222 << 32) + 0x33333333,
|
||||
totalNumberOfDisks: 0x44444444,
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
bin2hex($descriptor),
|
||||
'504b0607' . // 4 bytes; zip64 end of central dir locator signature - 0x07064b50
|
||||
'11111111' . // 4 bytes; number of the disk with the start of the zip64 end of central directory
|
||||
'3333333322222222' . // 28 bytes; relative offset of the zip64 end of central directory record
|
||||
'44444444' // 4 bytes;total number of disks
|
||||
);
|
||||
}
|
||||
}
|
41
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/Zip64/EndOfCentralDirectoryTest.php
vendored
Normal file
41
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/Zip64/EndOfCentralDirectoryTest.php
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test\Zip64;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\Zip64\EndOfCentralDirectory;
|
||||
|
||||
class EndOfCentralDirectoryTest extends TestCase
|
||||
{
|
||||
public function testSerializesCorrectly(): void
|
||||
{
|
||||
$descriptor = EndOfCentralDirectory::generate(
|
||||
versionMadeBy: 0x3333,
|
||||
versionNeededToExtract: 0x4444,
|
||||
numberOfThisDisk: 0x55555555,
|
||||
numberOfTheDiskWithCentralDirectoryStart: 0x66666666,
|
||||
numberOfCentralDirectoryEntriesOnThisDisk: (0x77777777 << 32) + 0x88888888,
|
||||
numberOfCentralDirectoryEntries: (0x99999999 << 32) + 0xAAAAAAAA,
|
||||
sizeOfCentralDirectory: (0xBBBBBBBB << 32) + 0xCCCCCCCC,
|
||||
centralDirectoryStartOffsetOnDisk: (0xDDDDDDDD << 32) + 0xEEEEEEEE,
|
||||
extensibleDataSector: 'foo',
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
bin2hex($descriptor),
|
||||
'504b0606' . // 4 bytes;zip64 end of central dir signature - 0x06064b50
|
||||
'2f00000000000000' . // 8 bytes; size of zip64 end of central directory record
|
||||
'3333' . // 2 bytes; version made by
|
||||
'4444' . // 2 bytes; version needed to extract
|
||||
'55555555' . // 4 bytes; number of this disk
|
||||
'66666666' . // 4 bytes; number of the disk with the start of the central directory
|
||||
'8888888877777777' . // 8 bytes; total number of entries in the central directory on this disk
|
||||
'aaaaaaaa99999999' . // 8 bytes; total number of entries in the central directory
|
||||
'ccccccccbbbbbbbb' . // 8 bytes; size of the central directory
|
||||
'eeeeeeeedddddddd' . // 8 bytes; offset of start of central directory with respect to the starting disk number
|
||||
bin2hex('foo')
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test\Zip64;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\Zip64\ExtendedInformationExtraField;
|
||||
|
||||
class ExtendedInformationExtraFieldTest extends TestCase
|
||||
{
|
||||
public function testSerializesCorrectly(): void
|
||||
{
|
||||
$extraField = ExtendedInformationExtraField::generate(
|
||||
originalSize: (0x77777777 << 32) + 0x66666666,
|
||||
compressedSize: (0x99999999 << 32) + 0x88888888,
|
||||
relativeHeaderOffset: (0x22222222 << 32) + 0x11111111,
|
||||
diskStartNumber: 0x33333333,
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
bin2hex($extraField),
|
||||
'0100' . // 2 bytes; Tag for this "extra" block type
|
||||
'1c00' . // 2 bytes; Size of this "extra" block
|
||||
'6666666677777777' . // 8 bytes; Original uncompressed file size
|
||||
'8888888899999999' . // 8 bytes; Size of compressed data
|
||||
'1111111122222222' . // 8 bytes; Offset of local header record
|
||||
'33333333' // 4 bytes; Number of the disk on which this file starts
|
||||
);
|
||||
}
|
||||
|
||||
public function testSerializesEmptyCorrectly(): void
|
||||
{
|
||||
$extraField = ExtendedInformationExtraField::generate();
|
||||
|
||||
$this->assertSame(
|
||||
bin2hex($extraField),
|
||||
'0100' . // 2 bytes; Tag for this "extra" block type
|
||||
'0000' // 2 bytes; Size of this "extra" block
|
||||
);
|
||||
}
|
||||
}
|
1284
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/ZipStreamTest.php
vendored
Normal file
1284
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/ZipStreamTest.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZipStream\Test\Zs;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipStream\Zs\ExtendedInformationExtraField;
|
||||
|
||||
class ExtendedInformationExtraFieldTest extends TestCase
|
||||
{
|
||||
public function testSerializesCorrectly(): void
|
||||
{
|
||||
$extraField = ExtendedInformationExtraField::generate();
|
||||
|
||||
$this->assertSame(
|
||||
bin2hex((string) $extraField),
|
||||
'5356' . // 2 bytes; Tag for this "extra" block type
|
||||
'0000' // 2 bytes; TODO: Document
|
||||
);
|
||||
}
|
||||
}
|
7
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/bootstrap.php
vendored
Normal file
7
libraries/phpspreadsheet/vendor/maennchen/zipstream-php/test/bootstrap.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
Reference in New Issue
Block a user