mirror of
https://github.com/Ne-Lexa/php-zip.git
synced 2025-01-17 07:18:14 +01:00
parent
7283fc3402
commit
584784c119
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1,8 +1,7 @@
|
||||
.gitattributes export-ignore
|
||||
.github export-ignore
|
||||
.gitignore export-ignore
|
||||
.php_cs export-ignore
|
||||
.travis.yml export-ignore
|
||||
.php-cs-fixer.php export-ignore
|
||||
bootstrap.php export-ignore
|
||||
phpunit.xml export-ignore
|
||||
tests export-ignore
|
||||
|
130
.github/workflows/build.yml
vendored
Normal file
130
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: PHP ${{ matrix.php }} Test on ${{ matrix.os }}
|
||||
|
||||
env:
|
||||
extensions: bz2, dom, iconv, fileinfo, openssl, xml, zlib, gd
|
||||
key: cache-v1
|
||||
PHPUNIT_COVERAGE: 0
|
||||
PHP_INI: date.timezone='UTC', memory_limit=-1, opcache.enable=1, opcache.enable_cli=1
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
- macos-latest
|
||||
php:
|
||||
- '7.1'
|
||||
- '7.2'
|
||||
- '7.3'
|
||||
- '7.4'
|
||||
- '8.0'
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
|
||||
-
|
||||
name: Install linux dependencies
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: sudo apt-get install unzip p7zip-full zipalign
|
||||
|
||||
-
|
||||
name: Install windows dependencies
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: choco install zip unzip 7zip
|
||||
|
||||
-
|
||||
name: Install macos dependencies
|
||||
if: matrix.os == 'macos-latest'
|
||||
run: brew install zip unzip p7zip
|
||||
|
||||
-
|
||||
name: Disable JIT for PHP 8 on Linux and Mac
|
||||
if: (matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest') && matrix.php == '8.0'
|
||||
run: echo "PHP_INI=\"${PHP_INI}, opcache.jit=0, opcache.jit_buffer_size=0\"" >> $GITHUB_ENV
|
||||
|
||||
-
|
||||
name: Disable JIT for PHP 8 on Windows
|
||||
if: matrix.os == 'windows-latest' && matrix.php == '8.0'
|
||||
run: echo "PHP_INI=\"$PHP_INI, opcache.jit=0, opcache.jit_buffer_size=0\"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
|
||||
-
|
||||
name: Install PHP with extensions
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: ${{ env.extensions }}
|
||||
coverage: pcov
|
||||
ini-values: ${{ env.PHP_INI }}
|
||||
tools: composer:v2, cs2pr
|
||||
|
||||
-
|
||||
name: Determine composer cache directory on Linux or MacOS
|
||||
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
|
||||
run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
|
||||
|
||||
-
|
||||
name: Determine composer cache directory on Windows
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: echo "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
|
||||
-
|
||||
name: Set coverage args
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.php == '7.4'
|
||||
run: echo "PHPUNIT_COVERAGE=1" >> $GITHUB_ENV
|
||||
|
||||
-
|
||||
name: Cache composer dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ env.COMPOSER_CACHE_DIR }}
|
||||
key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: php${{ matrix.php }}-composer-
|
||||
|
||||
-
|
||||
name: Check PHP Version
|
||||
run: php -v
|
||||
|
||||
-
|
||||
name: Check Composer Version
|
||||
run: composer -V
|
||||
|
||||
-
|
||||
name: Check PHP Extensions
|
||||
run: php -m
|
||||
|
||||
-
|
||||
name: Validate composer.json and composer.lock
|
||||
run: composer validate
|
||||
|
||||
-
|
||||
name: Install dependencies with composer
|
||||
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
|
||||
|
||||
-
|
||||
name: Run tests with phpunit
|
||||
if: env.PHPUNIT_COVERAGE == 0
|
||||
run: vendor/bin/phpunit -v --testsuite "all_tests" --group small,medium,large
|
||||
|
||||
-
|
||||
name: Run tests with phpunit and coverage
|
||||
if: env.PHPUNIT_COVERAGE == 1
|
||||
run: vendor/bin/phpunit -v --coverage-clover=coverage.clover --testsuite "all_tests" --group small,medium,large
|
||||
|
||||
-
|
||||
name: Upload code coverage scrutinizer
|
||||
if: env.PHPUNIT_COVERAGE == 1
|
||||
run: |
|
||||
wget https://scrutinizer-ci.com/ocular.phar
|
||||
php ocular.phar code-coverage:upload --format=php-clover coverage.clover
|
@ -1,16 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* PHP Code Style Fixer (config created for version 2.16.4 (Yellow Bird)).
|
||||
* PHP Code Style Fixer (config created for version 3.0.0 (Constitution)).
|
||||
*
|
||||
* Use one of the following console commands to just see the
|
||||
* changes that will be made.
|
||||
* - `php-cs-fixer fix --config='.php_cs' --diff-format udiff --dry-run`
|
||||
* - `php '.php_cs'`
|
||||
* - `php-cs-fixer fix --config='.php-cs-fixer.php' --dry-run`
|
||||
* - `php '.php-cs-fixer.php'`
|
||||
*
|
||||
* Use one of the following console commands to fix PHP code:
|
||||
* - `php-cs-fixer fix --config='.php_cs' --diff-format udiff`
|
||||
* - `php '.php_cs' --force`
|
||||
* - `php-cs-fixer fix --config='.php-cs-fixer.php'
|
||||
* - `php '.php-cs-fixer.php' --force`
|
||||
*
|
||||
* @see https://cs.symfony.com/
|
||||
*/
|
||||
@ -24,6 +26,14 @@ $rules = [
|
||||
// Each element of an array must be indented exactly once.
|
||||
'array_indentation' => true,
|
||||
|
||||
/*
|
||||
* Converts simple usages of `array_push($x, $y);` to `$x[] = $y;`.
|
||||
*
|
||||
* Risky!
|
||||
* Risky when the function `array_push` is overridden.
|
||||
*/
|
||||
'array_push' => true,
|
||||
|
||||
// PHP arrays should be declared using the configured syntax.
|
||||
'array_syntax' => [
|
||||
'syntax' => 'short',
|
||||
@ -51,23 +61,7 @@ $rules = [
|
||||
'blank_line_after_opening_tag' => true,
|
||||
|
||||
// An empty line feed must precede any configured statement.
|
||||
'blank_line_before_statement' => [
|
||||
'statements' => [
|
||||
'continue',
|
||||
'declare',
|
||||
'return',
|
||||
'throw',
|
||||
'try',
|
||||
'case',
|
||||
'die',
|
||||
'exit',
|
||||
'do',
|
||||
'foreach',
|
||||
'goto',
|
||||
'if',
|
||||
'while',
|
||||
],
|
||||
],
|
||||
'blank_line_before_statement' => true,
|
||||
|
||||
/*
|
||||
* The body of each structure MUST be enclosed by braces. Braces
|
||||
@ -82,8 +76,8 @@ $rules = [
|
||||
'cast_spaces' => true,
|
||||
|
||||
/*
|
||||
* Class, trait and interface elements must be separated with one
|
||||
* blank line.
|
||||
* Class, trait and interface elements must be separated with one or
|
||||
* none blank line.
|
||||
*/
|
||||
'class_attributes_separation' => true,
|
||||
|
||||
@ -98,6 +92,9 @@ $rules = [
|
||||
// Converts `::class` keywords to FQCN strings.
|
||||
'class_keyword_remove' => false,
|
||||
|
||||
// Namespace must not contain spacing, comments or PHPDoc.
|
||||
'clean_namespace' => true,
|
||||
|
||||
// Using `isset($var) &&` multiple times should be done in one call.
|
||||
'combine_consecutive_issets' => true,
|
||||
|
||||
@ -111,7 +108,7 @@ $rules = [
|
||||
* Risky!
|
||||
* Risky when the function `dirname` is overridden.
|
||||
*/
|
||||
'combine_nested_dirname' => false,
|
||||
'combine_nested_dirname' => true,
|
||||
|
||||
/*
|
||||
* Comments with annotation should be docblock when used on
|
||||
@ -132,7 +129,7 @@ $rules = [
|
||||
*
|
||||
* Rule is applied only in a PHP 7.1+ environment.
|
||||
*/
|
||||
'compact_nullable_typehint' => false,
|
||||
'compact_nullable_typehint' => true,
|
||||
|
||||
// Concatenation should be spaced according configuration.
|
||||
'concat_space' => [
|
||||
@ -181,7 +178,9 @@ $rules = [
|
||||
* Doctrine annotations must use configured operator for assignment
|
||||
* in arrays.
|
||||
*/
|
||||
'doctrine_annotation_array_assignment' => true,
|
||||
'doctrine_annotation_array_assignment' => [
|
||||
'operator' => ':',
|
||||
],
|
||||
|
||||
/*
|
||||
* Doctrine annotations without arguments must use the configured
|
||||
@ -200,7 +199,15 @@ $rules = [
|
||||
* space around named arguments assignment operator; there must be
|
||||
* one space around array assignment operator.
|
||||
*/
|
||||
'doctrine_annotation_spaces' => true,
|
||||
'doctrine_annotation_spaces' => [
|
||||
'before_array_assignments_colon' => false,
|
||||
],
|
||||
|
||||
/*
|
||||
* Replaces short-echo `<?=` with long format `<?php echo`/`<?php
|
||||
* print` syntax, or vice-versa.
|
||||
*/
|
||||
'echo_tag_syntax' => true,
|
||||
|
||||
/*
|
||||
* The keyword `elseif` should be used instead of `else if` so that
|
||||
@ -270,7 +277,7 @@ $rules = [
|
||||
* Add curly braces to indirect variables to make them clear to
|
||||
* understand. Requires PHP >= 7.0.
|
||||
*/
|
||||
'explicit_indirect_variable' => false,
|
||||
'explicit_indirect_variable' => true,
|
||||
|
||||
/*
|
||||
* Converts implicit variables into explicit ones in double-quoted
|
||||
@ -332,9 +339,6 @@ $rules = [
|
||||
*/
|
||||
'final_public_method_for_abstract_class' => false,
|
||||
|
||||
// Converts `static` access to `self` access in `final` classes.
|
||||
'final_static_access' => true,
|
||||
|
||||
/*
|
||||
* Order the flags in `fopen` calls, `b` and `t` must be last.
|
||||
*
|
||||
@ -377,15 +381,7 @@ $rules = [
|
||||
* Risky when any of the configured functions to replace are
|
||||
* overridden.
|
||||
*/
|
||||
'function_to_constant' => [
|
||||
'functions' => [
|
||||
'get_class',
|
||||
'php_sapi_name',
|
||||
'phpversion',
|
||||
'pi',
|
||||
'get_called_class',
|
||||
],
|
||||
],
|
||||
'function_to_constant' => true,
|
||||
|
||||
// Ensure single space between function's argument and its typehint.
|
||||
'function_typehint_space' => true,
|
||||
@ -393,6 +389,13 @@ $rules = [
|
||||
// Configured annotations should be omitted from PHPDoc.
|
||||
'general_phpdoc_annotation_remove' => true,
|
||||
|
||||
// Renames PHPDoc tags.
|
||||
'general_phpdoc_tag_rename' => [
|
||||
'replacements' => [
|
||||
'inheritDocs' => 'inheritDoc',
|
||||
],
|
||||
],
|
||||
|
||||
// Imports or fully qualifies global classes/functions/constants.
|
||||
'global_namespace_import' => [
|
||||
'import_constants' => false,
|
||||
@ -400,6 +403,9 @@ $rules = [
|
||||
'import_classes' => false,
|
||||
],
|
||||
|
||||
// There MUST be group use for the same namespaces.
|
||||
'group_import' => false,
|
||||
|
||||
// Add, replace or remove header comment.
|
||||
'header_comment' => false,
|
||||
|
||||
@ -444,6 +450,9 @@ $rules = [
|
||||
*/
|
||||
'is_null' => true,
|
||||
|
||||
// Lambda must not import variables it doesn't use.
|
||||
'lambda_not_used_import' => true,
|
||||
|
||||
// All PHP files must use same line ending.
|
||||
'line_ending' => true,
|
||||
|
||||
@ -589,6 +598,9 @@ $rules = [
|
||||
],
|
||||
],
|
||||
|
||||
// Master language constructs shall be used instead of aliases.
|
||||
'no_alias_language_construct_call' => true,
|
||||
|
||||
// Replace control structure alternative syntax to use braces.
|
||||
'no_alternative_syntax' => true,
|
||||
|
||||
@ -630,30 +642,14 @@ $rules = [
|
||||
// There should not be empty PHPDoc blocks.
|
||||
'no_empty_phpdoc' => true,
|
||||
|
||||
// Remove useless semicolon statements.
|
||||
// Remove useless (semicolon) statements.
|
||||
'no_empty_statement' => true,
|
||||
|
||||
/*
|
||||
* Removes extra blank lines and/or blank lines following
|
||||
* configuration.
|
||||
*/
|
||||
'no_extra_blank_lines' => [
|
||||
'tokens' => [
|
||||
'extra',
|
||||
'case',
|
||||
'continue',
|
||||
'default',
|
||||
'curly_brace_block',
|
||||
'parenthesis_brace_block',
|
||||
'return',
|
||||
'square_brace_block',
|
||||
'use',
|
||||
'throw',
|
||||
'use_trait',
|
||||
'useTrait',
|
||||
'switch',
|
||||
],
|
||||
],
|
||||
'no_extra_blank_lines' => true,
|
||||
|
||||
/*
|
||||
* Replace accidental usage of homoglyphs (non ascii characters) in
|
||||
@ -701,9 +697,6 @@ $rules = [
|
||||
*/
|
||||
'no_short_bool_cast' => true,
|
||||
|
||||
// Replace short-echo `<?=` with long format `<?php echo` syntax.
|
||||
'no_short_echo_tag' => false,
|
||||
|
||||
// Single-line whitespace before closing semicolon are prohibited.
|
||||
'no_singleline_whitespace_before_semicolons' => true,
|
||||
|
||||
@ -743,14 +736,36 @@ $rules = [
|
||||
// There MUST be no trailing spaces inside comment or PHPDoc.
|
||||
'no_trailing_whitespace_in_comment' => true,
|
||||
|
||||
/*
|
||||
* There must be no trailing whitespace in strings.
|
||||
*
|
||||
* Risky!
|
||||
* Changing the whitespaces in strings might affect string
|
||||
* comparisons and outputs.
|
||||
*/
|
||||
'no_trailing_whitespace_in_string' => false,
|
||||
|
||||
// Removes unneeded parentheses around control statements.
|
||||
'no_unneeded_control_parentheses' => true,
|
||||
'no_unneeded_control_parentheses' => [
|
||||
'statements' => [
|
||||
'break',
|
||||
'clone',
|
||||
'continue',
|
||||
'echo_print',
|
||||
'return',
|
||||
'switch_case',
|
||||
'yield',
|
||||
'yield_from',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
* Removes unneeded curly braces that are superfluous and aren't
|
||||
* part of a control structure's body.
|
||||
*/
|
||||
'no_unneeded_curly_braces' => true,
|
||||
'no_unneeded_curly_braces' => [
|
||||
'namespaces' => true,
|
||||
],
|
||||
|
||||
/*
|
||||
* A `final` class must not have `final` methods and `private`
|
||||
@ -779,12 +794,14 @@ $rules = [
|
||||
* Properties should be set to `null` instead of using `unset`.
|
||||
*
|
||||
* Risky!
|
||||
* Changing variables to `null` instead of unsetting them will mean
|
||||
* they still show up when looping over class variables. With PHP
|
||||
* 7.4, this rule might introduce `null` assignments to property
|
||||
* whose type declaration does not allow it.
|
||||
* Risky when relying on attributes to be removed using `unset`
|
||||
* rather than be set to `null`. Changing variables to `null`
|
||||
* instead of unsetting means these still show up when looping over
|
||||
* class variables and reference properties remain unbroken. With
|
||||
* PHP 7.4, this rule might introduce `null` assignments to
|
||||
* properties whose type declaration does not allow it.
|
||||
*/
|
||||
'no_unset_on_property' => false,
|
||||
'no_unset_on_property' => true,
|
||||
|
||||
// Unused `use` statements must be removed.
|
||||
'no_unused_imports' => true,
|
||||
@ -798,6 +815,14 @@ $rules = [
|
||||
*/
|
||||
'no_useless_return' => true,
|
||||
|
||||
/*
|
||||
* There must be no `sprintf` calls with only the first argument.
|
||||
*
|
||||
* Risky!
|
||||
* Risky when if the `sprintf` function is overridden.
|
||||
*/
|
||||
'no_useless_sprintf' => true,
|
||||
|
||||
/*
|
||||
* In array declaration, there MUST NOT be a whitespace before each
|
||||
* comma.
|
||||
@ -837,13 +862,33 @@ $rules = [
|
||||
'nullable_type_declaration_for_default_null_value' => false,
|
||||
|
||||
/*
|
||||
* There should not be space before or after object
|
||||
* `T_OBJECT_OPERATOR` `->`.
|
||||
* There should not be space before or after object operators `->`
|
||||
* and `?->`.
|
||||
*/
|
||||
'object_operator_without_whitespace' => true,
|
||||
|
||||
/*
|
||||
* Operators - when multiline - must always be at the beginning or
|
||||
* at the end of the line.
|
||||
*/
|
||||
'operator_linebreak' => true,
|
||||
|
||||
// Orders the elements of classes/interfaces/traits.
|
||||
'ordered_class_elements' => false,
|
||||
'ordered_class_elements' => [
|
||||
'order' => [
|
||||
'use_trait',
|
||||
'constant_public',
|
||||
'constant_protected',
|
||||
'constant_private',
|
||||
'property_public',
|
||||
'property_protected',
|
||||
'property_private',
|
||||
'construct',
|
||||
'destruct',
|
||||
'magic',
|
||||
'phpunit',
|
||||
],
|
||||
],
|
||||
|
||||
// Ordering `use` statements.
|
||||
'ordered_imports' => [
|
||||
@ -866,6 +911,14 @@ $rules = [
|
||||
*/
|
||||
'ordered_interfaces' => false,
|
||||
|
||||
/*
|
||||
* Trait `use` statements must be sorted alphabetically.
|
||||
*
|
||||
* Risky!
|
||||
* Risky when depending on order of the imports.
|
||||
*/
|
||||
'ordered_traits' => false,
|
||||
|
||||
/*
|
||||
* PHPUnit assertion method calls like `->assertSame(true, $foo)`
|
||||
* should be written with dedicated method like
|
||||
@ -885,9 +938,7 @@ $rules = [
|
||||
* Fixer could be risky if one is overriding PHPUnit's native
|
||||
* methods.
|
||||
*/
|
||||
'php_unit_dedicate_assert' => [
|
||||
'target' => '3.5',
|
||||
],
|
||||
'php_unit_dedicate_assert' => true,
|
||||
|
||||
/*
|
||||
* PHPUnit assertions like `assertIsArray` should be used over
|
||||
@ -897,7 +948,7 @@ $rules = [
|
||||
* Risky when PHPUnit methods are overridden or when project has
|
||||
* PHPUnit incompatibilities.
|
||||
*/
|
||||
'php_unit_dedicate_assert_internal_type' => false,
|
||||
'php_unit_dedicate_assert_internal_type' => true,
|
||||
|
||||
/*
|
||||
* Usages of `->setExpectedException*` methods MUST be replaced by
|
||||
@ -907,7 +958,9 @@ $rules = [
|
||||
* Risky when PHPUnit classes are overridden or not accessible, or
|
||||
* when project has PHPUnit incompatibilities.
|
||||
*/
|
||||
'php_unit_expectation' => false,
|
||||
'php_unit_expectation' => [
|
||||
'target' => '5.6',
|
||||
],
|
||||
|
||||
// PHPUnit annotations should be a FQCNs including a root namespace.
|
||||
'php_unit_fqcn_annotation' => true,
|
||||
@ -930,7 +983,7 @@ $rules = [
|
||||
* Risky when PHPUnit classes are overridden or not accessible, or
|
||||
* when project has PHPUnit incompatibilities.
|
||||
*/
|
||||
'php_unit_mock' => false,
|
||||
'php_unit_mock' => true,
|
||||
|
||||
/*
|
||||
* Usage of PHPUnit's mock e.g. `->will($this->returnValue(..))`
|
||||
@ -941,7 +994,7 @@ $rules = [
|
||||
* Risky when PHPUnit classes are overridden or not accessible, or
|
||||
* when project has PHPUnit incompatibilities.
|
||||
*/
|
||||
'php_unit_mock_short_will_return' => false,
|
||||
'php_unit_mock_short_will_return' => true,
|
||||
|
||||
/*
|
||||
* PHPUnit classes MUST be used in namespaced version, e.g.
|
||||
@ -962,9 +1015,7 @@ $rules = [
|
||||
* Risky when PHPUnit classes are overridden or not accessible, or
|
||||
* when project has PHPUnit incompatibilities.
|
||||
*/
|
||||
'php_unit_namespaced' => [
|
||||
'target' => '4.8',
|
||||
],
|
||||
'php_unit_namespaced' => true,
|
||||
|
||||
/*
|
||||
* Usages of `@expectedException*` annotations MUST be replaced by
|
||||
@ -978,9 +1029,6 @@ $rules = [
|
||||
'target' => 'newest',
|
||||
],
|
||||
|
||||
// Order `@covers` annotation of PHPUnit tests.
|
||||
'php_unit_ordered_covers' => true,
|
||||
|
||||
/*
|
||||
* Changes the visibility of the `setUp()` and `tearDown()`
|
||||
* functions of PHPUnit to `protected`, to match the PHPUnit
|
||||
@ -1047,18 +1095,7 @@ $rules = [
|
||||
* All items of the given phpdoc tags must be either left-aligned or
|
||||
* (by default) aligned vertically.
|
||||
*/
|
||||
'phpdoc_align' => [
|
||||
'tags' => [
|
||||
'return',
|
||||
'throws',
|
||||
'type',
|
||||
'var',
|
||||
'property',
|
||||
'method',
|
||||
'param',
|
||||
],
|
||||
'align' => 'vertical',
|
||||
],
|
||||
'phpdoc_align' => true,
|
||||
|
||||
// PHPDoc annotation descriptions should not be a sentence.
|
||||
'phpdoc_annotation_without_dot' => true,
|
||||
@ -1069,8 +1106,8 @@ $rules = [
|
||||
*/
|
||||
'phpdoc_indent' => true,
|
||||
|
||||
// Fix PHPDoc inline tags, make `@inheritdoc` always inline.
|
||||
'phpdoc_inline_tag' => true,
|
||||
// Fixes PHPDoc inline tags.
|
||||
'phpdoc_inline_tag_normalizer' => true,
|
||||
|
||||
/*
|
||||
* Changes doc blocks from single to multi line, or reversed. Works
|
||||
@ -1110,6 +1147,17 @@ $rules = [
|
||||
*/
|
||||
'phpdoc_order' => true,
|
||||
|
||||
// Order phpdoc tags by value.
|
||||
'phpdoc_order_by_value' => [
|
||||
'annotations' => [
|
||||
'covers',
|
||||
'method',
|
||||
'property',
|
||||
'property-read',
|
||||
'property-write',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
* The type of `@return` annotations of methods returning a
|
||||
* reference to itself must the configured one.
|
||||
@ -1139,6 +1187,16 @@ $rules = [
|
||||
*/
|
||||
'phpdoc_summary' => true,
|
||||
|
||||
// Fixes casing of PHPDoc tags.
|
||||
'phpdoc_tag_casing' => true,
|
||||
|
||||
// Forces PHPDoc tags to be either regular annotations or inline.
|
||||
'phpdoc_tag_type' => [
|
||||
'tags' => [
|
||||
'inheritDoc' => 'inline',
|
||||
],
|
||||
],
|
||||
|
||||
// Docblocks should only be used on structural elements.
|
||||
'phpdoc_to_comment' => false,
|
||||
|
||||
@ -1155,6 +1213,19 @@ $rules = [
|
||||
*/
|
||||
'phpdoc_to_param_type' => false,
|
||||
|
||||
/*
|
||||
* EXPERIMENTAL: Takes `@var` annotation of non-mixed types and
|
||||
* adjusts accordingly the property signature. Requires PHP >= 7.4.
|
||||
*
|
||||
* Risky!
|
||||
* This rule is EXPERIMENTAL and [1] is not covered with backward
|
||||
* compatibility promise. [2] `@var` annotation is mandatory for the
|
||||
* fixer to make changes, signatures of properties without it (no
|
||||
* docblock) will not be fixed. [3] Manual actions might be required
|
||||
* for newly typed properties that are read before initialization.
|
||||
*/
|
||||
'phpdoc_to_property_type' => false,
|
||||
|
||||
/*
|
||||
* EXPERIMENTAL: Takes `@return` annotation of non-mixed types and
|
||||
* adjusts accordingly the function signature. Requires PHP >= 7.0.
|
||||
@ -1164,8 +1235,7 @@ $rules = [
|
||||
* compatibility promise. [2] `@return` annotation is mandatory for
|
||||
* the fixer to make changes, signatures of methods without it (no
|
||||
* docblock, inheritdocs) will not be fixed. [3] Manual actions are
|
||||
* required if inherited signatures are not properly documented. [4]
|
||||
* `@inheritdocs` support is under construction.
|
||||
* required if inherited signatures are not properly documented.
|
||||
*/
|
||||
'phpdoc_to_return_type' => false,
|
||||
|
||||
@ -1208,7 +1278,7 @@ $rules = [
|
||||
* Risky!
|
||||
* Risky when the function `pow` is overridden.
|
||||
*/
|
||||
'pow_to_exponentiation' => false,
|
||||
'pow_to_exponentiation' => true,
|
||||
|
||||
/*
|
||||
* Converts `protected` variables and methods to `private` where
|
||||
@ -1225,16 +1295,7 @@ $rules = [
|
||||
* This fixer may change your class name, which will break the code
|
||||
* that depends on the old name.
|
||||
*/
|
||||
'psr0' => false,
|
||||
|
||||
/*
|
||||
* Class names should match the file name.
|
||||
*
|
||||
* Risky!
|
||||
* This fixer may change your class name, which will break the code
|
||||
* that depends on the old name.
|
||||
*/
|
||||
'psr4' => true,
|
||||
'psr_autoloading' => false,
|
||||
|
||||
/*
|
||||
* Replaces `rand`, `srand`, `getrandmax` functions calls with their
|
||||
@ -1245,12 +1306,23 @@ $rules = [
|
||||
*/
|
||||
'random_api_migration' => [
|
||||
'replacements' => [
|
||||
'getrandmax' => 'mt_getrandmax',
|
||||
'rand' => 'mt_rand',
|
||||
'srand' => 'mt_srand',
|
||||
'mt_rand' => 'random_int',
|
||||
'rand' => 'random_int',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
* Callables must be called without using `call_user_func*` when
|
||||
* possible.
|
||||
*
|
||||
* Risky!
|
||||
* Risky when the `call_user_func` or `call_user_func_array`
|
||||
* function is overridden or when are used in constructions that
|
||||
* should be avoided, like `call_user_func_array('foo', ['bar' =>
|
||||
* 'baz'])` or `call_user_func($foo, $foo = 'bar')`.
|
||||
*/
|
||||
'regular_callable_call' => true,
|
||||
|
||||
/*
|
||||
* Local, dynamic and directly referenced variables should not be
|
||||
* assigned and directly returned by a function or method.
|
||||
@ -1263,7 +1335,7 @@ $rules = [
|
||||
*
|
||||
* Rule is applied only in a PHP 7+ environment.
|
||||
*/
|
||||
'return_type_declaration' => false,
|
||||
'return_type_declaration' => true,
|
||||
|
||||
/*
|
||||
* Inside class or interface element `self` should be preferred to
|
||||
@ -1309,6 +1381,12 @@ $rules = [
|
||||
*/
|
||||
'simple_to_complex_string_variable' => true,
|
||||
|
||||
/*
|
||||
* Simplify `if` control structures that return the boolean result
|
||||
* of their condition.
|
||||
*/
|
||||
'simplified_if_return' => true,
|
||||
|
||||
/*
|
||||
* A return statement wishing to return `void` should not return
|
||||
* `null`.
|
||||
@ -1356,6 +1434,9 @@ $rules = [
|
||||
'strings_containing_single_quote_chars' => false,
|
||||
],
|
||||
|
||||
// Ensures a single space after language constructs.
|
||||
'single_space_after_construct' => true,
|
||||
|
||||
// Each trait `use` must be done as single statement.
|
||||
'single_trait_insert_per_statement' => true,
|
||||
|
||||
@ -1414,17 +1495,32 @@ $rules = [
|
||||
// Removes extra spaces between colon and case value.
|
||||
'switch_case_space' => true,
|
||||
|
||||
// Switch case must not be ended with `continue` but with `break`.
|
||||
'switch_continue_to_break' => true,
|
||||
|
||||
// Standardize spaces around ternary operator.
|
||||
'ternary_operator_spaces' => true,
|
||||
|
||||
/*
|
||||
* Use the Elvis operator `?:` where possible.
|
||||
*
|
||||
* Risky!
|
||||
* Risky when relying on functions called on both sides of the `?`
|
||||
* operator.
|
||||
*/
|
||||
'ternary_to_elvis_operator' => true,
|
||||
|
||||
/*
|
||||
* Use `null` coalescing operator `??` where possible. Requires PHP
|
||||
* >= 7.0.
|
||||
*/
|
||||
'ternary_to_null_coalescing' => false,
|
||||
'ternary_to_null_coalescing' => true,
|
||||
|
||||
// PHP multi-line arrays should have a trailing comma.
|
||||
'trailing_comma_in_multiline_array' => true,
|
||||
/*
|
||||
* Multi-line arrays, arguments list and parameters list must have a
|
||||
* trailing comma.
|
||||
*/
|
||||
'trailing_comma_in_multiline' => true,
|
||||
|
||||
/*
|
||||
* Arrays should be formatted like function/method arguments,
|
||||
@ -1435,12 +1531,27 @@ $rules = [
|
||||
// Unary operators should be placed adjacent to their operands.
|
||||
'unary_operator_spaces' => true,
|
||||
|
||||
/*
|
||||
* Anonymous functions with one-liner return statement must use
|
||||
* arrow functions.
|
||||
*
|
||||
* Risky!
|
||||
* Risky when using `isset()` on outside variables that are not
|
||||
* imported with `use ()`.
|
||||
*/
|
||||
'use_arrow_functions' => false,
|
||||
|
||||
/*
|
||||
* Visibility MUST be declared on all properties and methods;
|
||||
* `abstract` and `final` MUST be declared before the visibility;
|
||||
* `static` MUST be declared after the visibility.
|
||||
*/
|
||||
'visibility_required' => true,
|
||||
'visibility_required' => [
|
||||
'elements' => [
|
||||
'method',
|
||||
'property',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
* Add `void` return type to functions with missing or empty return
|
||||
@ -1459,8 +1570,10 @@ $rules = [
|
||||
'whitespace_after_comma_in_array' => true,
|
||||
|
||||
/*
|
||||
* Write conditions in Yoda style (`true`), non-Yoda style (`false`)
|
||||
* or ignore those conditions (`null`) based on configuration.
|
||||
* Write conditions in Yoda style (`true`), non-Yoda style
|
||||
* (`['equal' => false, 'identical' => false, 'less_and_greater' =>
|
||||
* false]`) or ignore those conditions (`null`) based on
|
||||
* configuration.
|
||||
*/
|
||||
'yoda_style' => [
|
||||
'equal' => false,
|
||||
@ -1477,7 +1590,7 @@ if (\PHP_SAPI === 'cli' && !class_exists(\PhpCsFixer\Config::class)) {
|
||||
}
|
||||
$dryRun = !in_array('--force', $_SERVER['argv'], true);
|
||||
|
||||
$command = escapeshellarg($binFixer) . ' fix --config ' . escapeshellarg(__FILE__) . ' --diff-format udiff --ansi -vv';
|
||||
$command = escapeshellarg($binFixer) . ' fix --config ' . escapeshellarg(__FILE__) . ' --diff --ansi -vv';
|
||||
|
||||
if ($dryRun) {
|
||||
$command .= ' --dry-run';
|
||||
@ -1498,13 +1611,14 @@ if (\PHP_SAPI === 'cli' && !class_exists(\PhpCsFixer\Config::class)) {
|
||||
exit($returnCode);
|
||||
}
|
||||
|
||||
return \PhpCsFixer\Config::create()
|
||||
return (new \PhpCsFixer\Config())
|
||||
->setUsingCache(true)
|
||||
->setCacheFile(__DIR__ . '/.php_cs.cache')
|
||||
->setCacheFile(__DIR__ . '/.php-cs-fixer.cache')
|
||||
->setRules($rules)
|
||||
->setRiskyAllowed(true)
|
||||
->setFinder(
|
||||
\PhpCsFixer\Finder::create()
|
||||
->ignoreUnreadableDirs()
|
||||
->in(__DIR__)
|
||||
)
|
||||
;
|
20
README.RU.md
20
README.RU.md
@ -1,16 +1,22 @@
|
||||
`PhpZip`
|
||||
========
|
||||
<h1 align="center"><img src="logo.svg" alt="PhpZip" width="250" height="51"></h1>
|
||||
|
||||
`PhpZip` - php библиотека для продвинутой работы с ZIP-архивами.
|
||||
|
||||
[![Build Status](https://travis-ci.org/Ne-Lexa/php-zip.svg?branch=master)](https://travis-ci.org/Ne-Lexa/php-zip)
|
||||
[![Packagist Version](https://img.shields.io/packagist/v/nelexa/zip.svg)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Packagist Downloads](https://img.shields.io/packagist/dt/nelexa/zip.svg?color=%23ff007f)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Code Coverage](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/?branch=master)
|
||||
[![Latest Stable Version](https://poser.pugx.org/nelexa/zip/v/stable)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Total Downloads](https://poser.pugx.org/nelexa/zip/downloads)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Minimum PHP Version](http://img.shields.io/badge/php-%3E%3D%205.5-8892BF.svg)](https://php.net/)
|
||||
[![License](https://poser.pugx.org/nelexa/zip/license)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Build Status](https://github.com/Ne-Lexa/php-zip/workflows/build/badge.svg)](https://github.com/Ne-Lexa/php-zip/actions)
|
||||
[![License](https://img.shields.io/packagist/l/nelexa/zip.svg)](https://github.com/Ne-Lexa/php-zip/blob/master/LICENSE)
|
||||
|
||||
[English Documentation](README.md)
|
||||
|
||||
### Версии и зависимости
|
||||
| Версия | PHP | Документация |
|
||||
| --------------- | ------------ | ----------------------------------------------------------------------------- |
|
||||
| ^4.0 (master) | ^7.4 \| ^8.0 | [Документация v4.0](https://github.com/Ne-Lexa/php-zip/blob/master/README.md) |
|
||||
| 3.4.* | ^7.1 \| ^8.0 | текущая документация |
|
||||
| 3.0.* - 3.3.* | ^5.5 \| ^7.0 | [Документация v3.3](https://github.com/Ne-Lexa/php-zip/blob/3.3.3/README.md) |
|
||||
|
||||
Содержание
|
||||
----------
|
||||
- [Функционал](#Features)
|
||||
|
20
README.md
20
README.md
@ -1,16 +1,22 @@
|
||||
`PhpZip`
|
||||
========
|
||||
<h1 align="center"><img src="logo.svg" alt="PhpZip" width="250" height="51"></h1>
|
||||
|
||||
`PhpZip` is a php-library for extended work with ZIP-archives.
|
||||
|
||||
[![Build Status](https://travis-ci.org/Ne-Lexa/php-zip.svg?branch=master)](https://travis-ci.org/Ne-Lexa/php-zip)
|
||||
[![Packagist Version](https://img.shields.io/packagist/v/nelexa/zip.svg)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Packagist Downloads](https://img.shields.io/packagist/dt/nelexa/zip.svg?color=%23ff007f)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Code Coverage](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Ne-Lexa/php-zip/?branch=master)
|
||||
[![Latest Stable Version](https://poser.pugx.org/nelexa/zip/v/stable)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Total Downloads](https://poser.pugx.org/nelexa/zip/downloads)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Minimum PHP Version](http://img.shields.io/badge/php-%3E%3D%205.5-8892BF.svg)](https://php.net/)
|
||||
[![License](https://poser.pugx.org/nelexa/zip/license)](https://packagist.org/packages/nelexa/zip)
|
||||
[![Build Status](https://github.com/Ne-Lexa/php-zip/workflows/build/badge.svg)](https://github.com/Ne-Lexa/php-zip/actions)
|
||||
[![License](https://img.shields.io/packagist/l/nelexa/zip.svg)](https://github.com/Ne-Lexa/php-zip/blob/master/LICENSE)
|
||||
|
||||
[Russian Documentation](README.RU.md)
|
||||
|
||||
### Versions & Dependencies
|
||||
| Version | PHP | Documentation |
|
||||
| --------------- | ------------ | --------------------------------------------------------------------- |
|
||||
| ^4.0 (master) | ^7.4 \| ^8.0 | [Docs v4.0](https://github.com/Ne-Lexa/php-zip/blob/master/README.md) |
|
||||
| 3.4.* | ^7.1 \| ^8.0 | current docs |
|
||||
| 3.0.* - 3.3.* | ^5.5 \| ^7.0 | [Docs v3.3](https://github.com/Ne-Lexa/php-zip/blob/3.3.3/README.md) |
|
||||
|
||||
Table of contents
|
||||
-----------------
|
||||
- [Features](#Features)
|
||||
|
@ -1,6 +0,0 @@
|
||||
<?php
|
||||
|
||||
// see https://stackoverflow.com/questions/33299149/phpstorm-8-and-phpunit-problems-with-runinseparateprocess/37174348#37174348
|
||||
if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
|
||||
define('PHPUNIT_COMPOSER_INSTALL', __DIR__ . '/vendor/autoload.php');
|
||||
}
|
@ -21,11 +21,10 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.5.9 || ^7.0",
|
||||
"php": "^7.1.3 | ^8.0",
|
||||
"ext-zlib": "*",
|
||||
"psr/http-message": "^1.0",
|
||||
"paragonie/random_compat": "*",
|
||||
"symfony/finder": "^3.0|^4.0|^5.0"
|
||||
"symfony/finder": "^3.0 | ^4.0 | ^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-bz2": "*",
|
||||
@ -33,8 +32,9 @@
|
||||
"ext-fileinfo": "*",
|
||||
"ext-xml": "*",
|
||||
"guzzlehttp/psr7": "^1.6",
|
||||
"phpunit/phpunit": "^4.8|^5.7",
|
||||
"symfony/var-dumper": "^3.0|^4.0|^5.0"
|
||||
"phpunit/phpunit": "^7.5.20 | ^8.5.15 | ^9.5.4",
|
||||
"symfony/var-dumper": "^3.0 | ^4.0 | ^5.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@ -47,14 +47,18 @@
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"ext-openssl": "Needed to support encrypt zip entries or use ext-mcrypt",
|
||||
"ext-mcrypt": "Needed to support encrypt zip entries or use ext-openssl",
|
||||
"ext-openssl": "Needed to support encrypt zip entries",
|
||||
"ext-bz2": "Needed to support BZIP2 compression",
|
||||
"ext-fileinfo": "Needed to get mime-type file"
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"scripts": {
|
||||
"php:fix": "php .php_cs --force",
|
||||
"php:fix:debug": "php .php_cs"
|
||||
"php:fix": "php .php-cs-fixer.php --force",
|
||||
"php:fix:debug": "php .php-cs-fixer.php"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.1.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
logo.svg
Normal file
1
logo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 22 KiB |
@ -1,10 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/7.5/phpunit.xsd"
|
||||
colors="true"
|
||||
bootstrap="bootstrap.php">
|
||||
bootstrap="vendor/autoload.php">
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1"/>
|
||||
</php>
|
||||
|
@ -56,9 +56,8 @@ final class ZipCompressionMethod
|
||||
*/
|
||||
public static function getCompressionMethodName($value)
|
||||
{
|
||||
return isset(self::$ZIP_COMPRESSION_METHODS[$value]) ?
|
||||
self::$ZIP_COMPRESSION_METHODS[$value] :
|
||||
'Unknown Method';
|
||||
return self::$ZIP_COMPRESSION_METHODS[$value]
|
||||
?? 'Unknown Method';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,9 +41,8 @@ final class ZipEncryptionMethod
|
||||
{
|
||||
$value = (int) $value;
|
||||
|
||||
return isset(self::$ENCRYPTION_METHODS[$value]) ?
|
||||
self::$ENCRYPTION_METHODS[$value] :
|
||||
'Unknown Encryption Method';
|
||||
return self::$ENCRYPTION_METHODS[$value]
|
||||
?? 'Unknown Encryption Method';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,6 +48,6 @@ final class ZipPlatform
|
||||
*/
|
||||
public static function getPlatformName($platform)
|
||||
{
|
||||
return isset(self::$platforms[$platform]) ? self::$platforms[$platform] : 'Unknown';
|
||||
return self::$platforms[$platform] ?? 'Unknown';
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +328,7 @@ class PKCryptContext
|
||||
}
|
||||
|
||||
if ($byte !== $checkByte) {
|
||||
throw new ZipAuthenticationException(sprintf('Invalid password'));
|
||||
throw new ZipAuthenticationException('Invalid password');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,9 +66,9 @@ class PKEncryptionStreamFilter extends \php_user_filter
|
||||
// init keys
|
||||
$this->context = new PKCryptContext($password);
|
||||
|
||||
$crc = $entry->isDataDescriptorRequired() || $entry->getCrc() === ZipEntry::UNKNOWN ?
|
||||
($entry->getDosTime() & 0x0000ffff) << 16 :
|
||||
$entry->getCrc();
|
||||
$crc = $entry->isDataDescriptorRequired() || $entry->getCrc() === ZipEntry::UNKNOWN
|
||||
? ($entry->getDosTime() & 0x0000ffff) << 16
|
||||
: $entry->getCrc();
|
||||
|
||||
try {
|
||||
$headerBytes = random_bytes(PKCryptContext::STD_DEC_HDR_SIZE);
|
||||
|
@ -60,9 +60,9 @@ class WinZipAesDecryptionStreamFilter extends \php_user_filter
|
||||
$this->entry = $this->params['entry'];
|
||||
|
||||
if (
|
||||
$this->entry->getPassword() === null ||
|
||||
!$this->entry->isEncrypted() ||
|
||||
!$this->entry->hasExtraField(WinZipAesExtraField::HEADER_ID)
|
||||
$this->entry->getPassword() === null
|
||||
|| !$this->entry->isEncrypted()
|
||||
|| !$this->entry->hasExtraField(WinZipAesExtraField::HEADER_ID)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@ -156,8 +156,8 @@ class WinZipAesDecryptionStreamFilter extends \php_user_filter
|
||||
$this->encBlockPosition += $offset;
|
||||
|
||||
if (
|
||||
$this->encBlockPosition === $this->encBlockLength &&
|
||||
\strlen($this->buffer) === WinZipAesContext::FOOTER_SIZE
|
||||
$this->encBlockPosition === $this->encBlockLength
|
||||
&& \strlen($this->buffer) === WinZipAesContext::FOOTER_SIZE
|
||||
) {
|
||||
$this->authenticationCode = $this->buffer;
|
||||
$this->buffer = '';
|
||||
|
@ -53,9 +53,9 @@ class WinZipAesEncryptionStreamFilter extends \php_user_filter
|
||||
$this->entry = $this->params['entry'];
|
||||
|
||||
if (
|
||||
$this->entry->getPassword() === null ||
|
||||
!$this->entry->isEncrypted() ||
|
||||
!$this->entry->hasExtraField(WinZipAesExtraField::HEADER_ID)
|
||||
$this->entry->getPassword() === null
|
||||
|| !$this->entry->isEncrypted()
|
||||
|| !$this->entry->hasExtraField(WinZipAesExtraField::HEADER_ID)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
@ -87,27 +87,11 @@ class ResponseStream implements StreamInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stream metadata as an associative array or retrieve a specific key.
|
||||
*
|
||||
* The keys returned are identical to the keys returned from PHP's
|
||||
* stream_get_meta_data() function.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.stream-get-meta-data.php
|
||||
*
|
||||
* @param string $key specific metadata to retrieve
|
||||
*
|
||||
* @return array|mixed|null Returns an associative array if no key is
|
||||
* provided. Returns a specific key value if a key is provided and the
|
||||
* value is found, or null if the key is not found.
|
||||
* Closes the stream when the destructed.
|
||||
*/
|
||||
public function getMetadata($key = null)
|
||||
public function __destruct()
|
||||
{
|
||||
if (!$this->stream) {
|
||||
return $key ? null : [];
|
||||
}
|
||||
$meta = stream_get_meta_data($this->stream);
|
||||
|
||||
return isset($meta[$key]) ? $meta[$key] : null;
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,6 +119,30 @@ class ResponseStream implements StreamInterface
|
||||
return (string) stream_get_contents($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stream metadata as an associative array or retrieve a specific key.
|
||||
*
|
||||
* The keys returned are identical to the keys returned from PHP's
|
||||
* stream_get_meta_data() function.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.stream-get-meta-data.php
|
||||
*
|
||||
* @param string $key specific metadata to retrieve
|
||||
*
|
||||
* @return array|mixed|null Returns an associative array if no key is
|
||||
* provided. Returns a specific key value if a key is provided and the
|
||||
* value is found, or null if the key is not found.
|
||||
*/
|
||||
public function getMetadata($key = null)
|
||||
{
|
||||
if (!$this->stream) {
|
||||
return $key ? null : [];
|
||||
}
|
||||
$meta = stream_get_meta_data($this->stream);
|
||||
|
||||
return $meta[$key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek to the beginning of the stream.
|
||||
*
|
||||
@ -163,7 +171,7 @@ class ResponseStream implements StreamInterface
|
||||
}
|
||||
|
||||
if (!$this->stream) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
// Clear the stat cache if the stream has a URI
|
||||
if ($this->uri !== null) {
|
||||
@ -176,8 +184,6 @@ class ResponseStream implements StreamInterface
|
||||
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -297,14 +303,6 @@ class ResponseStream implements StreamInterface
|
||||
return $this->stream ? stream_get_contents($this->stream) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream when the destructed.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream and any underlying resources.
|
||||
*/
|
||||
|
@ -59,7 +59,7 @@ class ZipReader
|
||||
}
|
||||
$meta = stream_get_meta_data($inStream);
|
||||
|
||||
$wrapperType = isset($meta['wrapper_type']) ? $meta['wrapper_type'] : 'Unknown';
|
||||
$wrapperType = $meta['wrapper_type'] ?? 'Unknown';
|
||||
$supportStreamWrapperTypes = ['plainfile', 'PHP', 'user-space'];
|
||||
|
||||
if (!\in_array($wrapperType, $supportStreamWrapperTypes, true)) {
|
||||
@ -72,10 +72,10 @@ class ZipReader
|
||||
}
|
||||
|
||||
if (
|
||||
$wrapperType === 'plainfile' &&
|
||||
(
|
||||
$meta['stream_type'] === 'dir' ||
|
||||
(isset($meta['uri']) && is_dir($meta['uri']))
|
||||
$wrapperType === 'plainfile'
|
||||
&& (
|
||||
$meta['stream_type'] === 'dir'
|
||||
|| (isset($meta['uri']) && is_dir($meta['uri']))
|
||||
)
|
||||
) {
|
||||
throw new InvalidArgumentException('Directory stream not supported');
|
||||
@ -94,6 +94,11 @@ class ZipReader
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@ -162,15 +167,15 @@ class ZipReader
|
||||
$buffer = fread($this->inStream, $sizeECD);
|
||||
|
||||
$unpack = unpack(
|
||||
'vdiskNo/vcdDiskNo/vcdEntriesDisk/' .
|
||||
'vcdEntries/VcdSize/VcdPos/vcommentLength',
|
||||
'vdiskNo/vcdDiskNo/vcdEntriesDisk/'
|
||||
. 'vcdEntries/VcdSize/VcdPos/vcommentLength',
|
||||
substr($buffer, 0, 18)
|
||||
);
|
||||
|
||||
if (
|
||||
$unpack['diskNo'] !== 0 ||
|
||||
$unpack['cdDiskNo'] !== 0 ||
|
||||
$unpack['cdEntriesDisk'] !== $unpack['cdEntries']
|
||||
$unpack['diskNo'] !== 0
|
||||
|| $unpack['cdDiskNo'] !== 0
|
||||
|| $unpack['cdEntriesDisk'] !== $unpack['cdEntries']
|
||||
) {
|
||||
throw new ZipException(
|
||||
'ZIP file spanning/splitting is not supported!'
|
||||
@ -375,8 +380,8 @@ class ZipReader
|
||||
$unicodePath = str_replace('\\', '/', $unicodePath);
|
||||
|
||||
if (
|
||||
$unicodePath !== '' &&
|
||||
substr_count($entryName, '/') === substr_count($unicodePath, '/')
|
||||
$unicodePath !== ''
|
||||
&& substr_count($entryName, '/') === substr_count($unicodePath, '/')
|
||||
) {
|
||||
$entryName = $unicodePath;
|
||||
}
|
||||
@ -427,12 +432,12 @@ class ZipReader
|
||||
}
|
||||
|
||||
$unpack = unpack(
|
||||
'vversionMadeBy/vversionNeededToExtract/' .
|
||||
'vgeneralPurposeBitFlag/vcompressionMethod/' .
|
||||
'VlastModFile/Vcrc/VcompressedSize/' .
|
||||
'VuncompressedSize/vfileNameLength/vextraFieldLength/' .
|
||||
'vfileCommentLength/vdiskNumberStart/vinternalFileAttributes/' .
|
||||
'VexternalFileAttributes/VoffsetLocalHeader',
|
||||
'vversionMadeBy/vversionNeededToExtract/'
|
||||
. 'vgeneralPurposeBitFlag/vcompressionMethod/'
|
||||
. 'VlastModFile/Vcrc/VcompressedSize/'
|
||||
. 'VuncompressedSize/vfileNameLength/vextraFieldLength/'
|
||||
. 'vfileCommentLength/vdiskNumberStart/vinternalFileAttributes/'
|
||||
. 'VexternalFileAttributes/VoffsetLocalHeader',
|
||||
fread($stream, 42)
|
||||
);
|
||||
|
||||
@ -523,9 +528,9 @@ class ZipReader
|
||||
*/
|
||||
protected function parseExtraFields($buffer, ZipEntry $zipEntry, $local = false)
|
||||
{
|
||||
$collection = $local ?
|
||||
$zipEntry->getLocalExtraFields() :
|
||||
$zipEntry->getCdExtraFields();
|
||||
$collection = $local
|
||||
? $zipEntry->getLocalExtraFields()
|
||||
: $zipEntry->getCdExtraFields();
|
||||
|
||||
if (!empty($buffer)) {
|
||||
$pos = 0;
|
||||
@ -548,9 +553,9 @@ class ZipReader
|
||||
try {
|
||||
if ($className !== null) {
|
||||
try {
|
||||
$extraField = $local ?
|
||||
\call_user_func([$className, 'unpackLocalFileData'], $bufferData, $zipEntry) :
|
||||
\call_user_func([$className, 'unpackCentralDirData'], $bufferData, $zipEntry);
|
||||
$extraField = $local
|
||||
? \call_user_func([$className, 'unpackLocalFileData'], $bufferData, $zipEntry)
|
||||
: \call_user_func([$className, 'unpackCentralDirData'], $bufferData, $zipEntry);
|
||||
} catch (\Throwable $e) {
|
||||
// skip errors while parsing invalid data
|
||||
continue;
|
||||
@ -890,9 +895,4 @@ class ZipReader
|
||||
fclose($this->inStream);
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
}
|
||||
|
@ -105,8 +105,8 @@ class ZipWriter
|
||||
$entry->enableDataDescriptor(true);
|
||||
}
|
||||
|
||||
$dd = $entry->isDataDescriptorRequired() ||
|
||||
$entry->isDataDescriptorEnabled();
|
||||
$dd = $entry->isDataDescriptorRequired()
|
||||
|| $entry->isDataDescriptorEnabled();
|
||||
|
||||
$compressedSize = $entry->getCompressedSize();
|
||||
$uncompressedSize = $entry->getUncompressedSize();
|
||||
@ -232,20 +232,20 @@ class ZipWriter
|
||||
|
||||
$offset = ftell($outStream);
|
||||
|
||||
$dataMinStartOffset =
|
||||
$offset +
|
||||
ZipConstants::LFH_FILENAME_POS +
|
||||
$extraLength +
|
||||
$nameLength;
|
||||
$dataMinStartOffset
|
||||
= $offset
|
||||
+ ZipConstants::LFH_FILENAME_POS
|
||||
+ $extraLength
|
||||
+ $nameLength;
|
||||
|
||||
$padding =
|
||||
($multiple - ($dataMinStartOffset % $multiple))
|
||||
$padding
|
||||
= ($multiple - ($dataMinStartOffset % $multiple))
|
||||
% $multiple;
|
||||
|
||||
if ($padding > 0) {
|
||||
$dataMinStartOffset += ApkAlignmentExtraField::MIN_SIZE;
|
||||
$padding =
|
||||
($multiple - ($dataMinStartOffset % $multiple))
|
||||
$padding
|
||||
= ($multiple - ($dataMinStartOffset % $multiple))
|
||||
% $multiple;
|
||||
|
||||
$entry->getLocalExtraFields()->add(
|
||||
@ -268,9 +268,9 @@ class ZipWriter
|
||||
protected function getExtraFieldsContents(ZipEntry $entry, $local)
|
||||
{
|
||||
$local = (bool) $local;
|
||||
$collection = $local ?
|
||||
$entry->getLocalExtraFields() :
|
||||
$entry->getCdExtraFields();
|
||||
$collection = $local
|
||||
? $entry->getLocalExtraFields()
|
||||
: $entry->getCdExtraFields();
|
||||
$extraData = '';
|
||||
|
||||
foreach ($collection as $extraField) {
|
||||
@ -490,6 +490,7 @@ class ZipWriter
|
||||
))) {
|
||||
throw new \RuntimeException('Could not append filter "zlib.deflate" to out stream');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ZipCompressionMethod::BZIP2:
|
||||
@ -501,6 +502,7 @@ class ZipWriter
|
||||
))) {
|
||||
throw new \RuntimeException('Could not append filter "bzip2.compress" to out stream');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ZipCompressionMethod::STORED:
|
||||
@ -585,14 +587,14 @@ class ZipWriter
|
||||
);
|
||||
|
||||
if (
|
||||
$entry->isZip64ExtensionsRequired() ||
|
||||
$entry->getLocalExtraFields()->has(Zip64ExtraField::HEADER_ID)
|
||||
$entry->isZip64ExtensionsRequired()
|
||||
|| $entry->getLocalExtraFields()->has(Zip64ExtraField::HEADER_ID)
|
||||
) {
|
||||
$dd =
|
||||
$dd
|
||||
// compressed size 8 bytes
|
||||
PackUtil::packLongLE($entry->getCompressedSize()) .
|
||||
= PackUtil::packLongLE($entry->getCompressedSize())
|
||||
// uncompressed size 8 bytes
|
||||
PackUtil::packLongLE($entry->getUncompressedSize());
|
||||
. PackUtil::packLongLE($entry->getUncompressedSize());
|
||||
} else {
|
||||
$dd = pack(
|
||||
'VV',
|
||||
@ -635,9 +637,9 @@ class ZipWriter
|
||||
$entry->getCdExtraFields()->remove(Zip64ExtraField::HEADER_ID);
|
||||
|
||||
if (
|
||||
$localHeaderOffset > ZipConstants::ZIP64_MAGIC ||
|
||||
$compressedSize > ZipConstants::ZIP64_MAGIC ||
|
||||
$uncompressedSize > ZipConstants::ZIP64_MAGIC
|
||||
$localHeaderOffset > ZipConstants::ZIP64_MAGIC
|
||||
|| $compressedSize > ZipConstants::ZIP64_MAGIC
|
||||
|| $uncompressedSize > ZipConstants::ZIP64_MAGIC
|
||||
) {
|
||||
$zip64ExtraField = new Zip64ExtraField();
|
||||
|
||||
@ -814,16 +816,16 @@ class ZipWriter
|
||||
$outStream,
|
||||
// total number of entries in the
|
||||
// central directory on this disk 8 bytes
|
||||
PackUtil::packLongLE($cdEntriesCount) .
|
||||
PackUtil::packLongLE($cdEntriesCount)
|
||||
// total number of entries in the
|
||||
// central directory 8 bytes
|
||||
PackUtil::packLongLE($cdEntriesCount) .
|
||||
. PackUtil::packLongLE($cdEntriesCount)
|
||||
// size of the central directory 8 bytes
|
||||
PackUtil::packLongLE($centralDirectorySize) .
|
||||
. PackUtil::packLongLE($centralDirectorySize)
|
||||
// offset of start of central
|
||||
// directory with respect to
|
||||
// the starting disk number 8 bytes
|
||||
PackUtil::packLongLE($centralDirectoryOffset)
|
||||
. PackUtil::packLongLE($centralDirectoryOffset)
|
||||
);
|
||||
|
||||
// write zip64 end of central directory locator
|
||||
@ -838,12 +840,12 @@ class ZipWriter
|
||||
// start of the zip64 end of
|
||||
// central directory 4 bytes
|
||||
0
|
||||
) .
|
||||
)
|
||||
// relative offset of the zip64
|
||||
// end of central directory record 8 bytes
|
||||
PackUtil::packLongLE($zip64EndOfCentralDirectoryOffset) .
|
||||
. PackUtil::packLongLE($zip64EndOfCentralDirectoryOffset)
|
||||
// total number of disks 4 bytes
|
||||
pack('V', 1)
|
||||
. pack('V', 1)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -51,10 +51,44 @@ class ZipNewData implements ZipData
|
||||
}
|
||||
|
||||
$resourceId = (int) $this->stream;
|
||||
self::$guardClonedStream[$resourceId] =
|
||||
isset(self::$guardClonedStream[$resourceId]) ?
|
||||
self::$guardClonedStream[$resourceId] + 1 :
|
||||
0;
|
||||
self::$guardClonedStream[$resourceId]
|
||||
= isset(self::$guardClonedStream[$resourceId])
|
||||
? self::$guardClonedStream[$resourceId] + 1
|
||||
: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The stream will be closed when closing the zip archive.
|
||||
*
|
||||
* The method implements protection against closing the stream of the cloned object.
|
||||
*
|
||||
* @see ZipFile::close()
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$resourceId = (int) $this->stream;
|
||||
|
||||
if (isset(self::$guardClonedStream[$resourceId]) && self::$guardClonedStream[$resourceId] > 0) {
|
||||
self::$guardClonedStream[$resourceId]--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (\is_resource($this->stream)) {
|
||||
fclose($this->stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://php.net/manual/en/language.oop5.cloning.php
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$resourceId = (int) $this->stream;
|
||||
self::$guardClonedStream[$resourceId]
|
||||
= isset(self::$guardClonedStream[$resourceId])
|
||||
? self::$guardClonedStream[$resourceId] + 1
|
||||
: 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,38 +129,4 @@ class ZipNewData implements ZipData
|
||||
rewind($stream);
|
||||
stream_copy_to_stream($stream, $outStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://php.net/manual/en/language.oop5.cloning.php
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$resourceId = (int) $this->stream;
|
||||
self::$guardClonedStream[$resourceId] =
|
||||
isset(self::$guardClonedStream[$resourceId]) ?
|
||||
self::$guardClonedStream[$resourceId] + 1 :
|
||||
1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The stream will be closed when closing the zip archive.
|
||||
*
|
||||
* The method implements protection against closing the stream of the cloned object.
|
||||
*
|
||||
* @see ZipFile::close()
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$resourceId = (int) $this->stream;
|
||||
|
||||
if (isset(self::$guardClonedStream[$resourceId]) && self::$guardClonedStream[$resourceId] > 0) {
|
||||
self::$guardClonedStream[$resourceId]--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (\is_resource($this->stream)) {
|
||||
fclose($this->stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +47,16 @@ class ZipSourceFileData implements ZipData
|
||||
$this->uncompressedSize = $zipEntry->getUncompressedSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (\is_resource($this->stream)) {
|
||||
fclose($this->stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZipEntry $entry
|
||||
*
|
||||
@ -54,14 +64,14 @@ class ZipSourceFileData implements ZipData
|
||||
*/
|
||||
public function hasRecompressData(ZipEntry $entry)
|
||||
{
|
||||
return $this->sourceEntry->getCompressionLevel() !== $entry->getCompressionLevel() ||
|
||||
$this->sourceEntry->getCompressionMethod() !== $entry->getCompressionMethod() ||
|
||||
$this->sourceEntry->isEncrypted() !== $entry->isEncrypted() ||
|
||||
$this->sourceEntry->getEncryptionMethod() !== $entry->getEncryptionMethod() ||
|
||||
$this->sourceEntry->getPassword() !== $entry->getPassword() ||
|
||||
$this->sourceEntry->getCompressedSize() !== $entry->getCompressedSize() ||
|
||||
$this->sourceEntry->getUncompressedSize() !== $entry->getUncompressedSize() ||
|
||||
$this->sourceEntry->getCrc() !== $entry->getCrc();
|
||||
return $this->sourceEntry->getCompressionLevel() !== $entry->getCompressionLevel()
|
||||
|| $this->sourceEntry->getCompressionMethod() !== $entry->getCompressionMethod()
|
||||
|| $this->sourceEntry->isEncrypted() !== $entry->isEncrypted()
|
||||
|| $this->sourceEntry->getEncryptionMethod() !== $entry->getEncryptionMethod()
|
||||
|| $this->sourceEntry->getPassword() !== $entry->getPassword()
|
||||
|| $this->sourceEntry->getCompressedSize() !== $entry->getCompressedSize()
|
||||
|| $this->sourceEntry->getUncompressedSize() !== $entry->getUncompressedSize()
|
||||
|| $this->sourceEntry->getCrc() !== $entry->getCrc();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,14 +169,4 @@ class ZipSourceFileData implements ZipData
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (\is_resource($this->stream)) {
|
||||
fclose($this->stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,30 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
||||
*/
|
||||
protected $collection = [];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$formats = [];
|
||||
|
||||
foreach ($this->collection as $key => $value) {
|
||||
$formats[] = (string) $value;
|
||||
}
|
||||
|
||||
return implode("\n", $formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* If clone extra fields.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this->collection as $k => $v) {
|
||||
$this->collection[$k] = clone $v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of Extra Fields in this collection.
|
||||
*
|
||||
@ -41,7 +65,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
||||
{
|
||||
$this->validateHeaderId($headerId);
|
||||
|
||||
return isset($this->collection[$headerId]) ? $this->collection[$headerId] : null;
|
||||
return $this->collection[$headerId] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,8 +152,6 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
||||
|
||||
return $ef;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,7 +179,7 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->collection[$offset]) ? $this->collection[$offset] : null;
|
||||
return $this->collection[$offset] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -249,28 +271,4 @@ class ExtraFieldsCollection implements \ArrayAccess, \Countable, \Iterator
|
||||
{
|
||||
$this->collection = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$formats = [];
|
||||
|
||||
foreach ($this->collection as $key => $value) {
|
||||
$formats[] = (string) $value;
|
||||
}
|
||||
|
||||
return implode("\n", $formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* If clone extra fields.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this->collection as $k => $v) {
|
||||
$this->collection[$k] = clone $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,8 +116,8 @@ abstract class AbstractUnicodeExtraField implements ZipExtraField
|
||||
'CV',
|
||||
self::DEFAULT_VERSION,
|
||||
$this->crc32
|
||||
) .
|
||||
$this->unicodeValue;
|
||||
)
|
||||
. $this->unicodeValue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,6 +50,19 @@ class ApkAlignmentExtraField implements ZipExtraField
|
||||
$this->padding = $padding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf(
|
||||
'0x%04x APK Alignment: Multiple=%d Padding=%d',
|
||||
self::HEADER_ID,
|
||||
$this->multiple,
|
||||
$this->padding
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
@ -160,17 +173,4 @@ class ApkAlignmentExtraField implements ZipExtraField
|
||||
{
|
||||
return $this->packLocalFileData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf(
|
||||
'0x%04x APK Alignment: Multiple=%d Padding=%d',
|
||||
self::HEADER_ID,
|
||||
$this->multiple,
|
||||
$this->padding
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,21 @@ class AsiExtraField implements ZipExtraField
|
||||
$this->link = $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf(
|
||||
'0x%04x ASI: Mode=%o UID=%d GID=%d Link="%s',
|
||||
self::HEADER_ID,
|
||||
$this->mode,
|
||||
$this->uid,
|
||||
$this->gid,
|
||||
$this->link
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
@ -284,19 +299,4 @@ class AsiExtraField implements ZipExtraField
|
||||
{
|
||||
$this->gid = (int) $gid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf(
|
||||
'0x%04x ASI: Mode=%o UID=%d GID=%d Link="%s',
|
||||
self::HEADER_ID,
|
||||
$this->mode,
|
||||
$this->uid,
|
||||
$this->gid,
|
||||
$this->link
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -116,6 +116,32 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
||||
$this->createTime = $createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [self::HEADER_ID];
|
||||
$format = '0x%04x ExtendedTimestamp:';
|
||||
|
||||
if ($this->modifyTime !== null) {
|
||||
$format .= ' Modify:[%s]';
|
||||
$args[] = date(\DATE_W3C, $this->modifyTime);
|
||||
}
|
||||
|
||||
if ($this->accessTime !== null) {
|
||||
$format .= ' Access:[%s]';
|
||||
$args[] = date(\DATE_W3C, $this->accessTime);
|
||||
}
|
||||
|
||||
if ($this->createTime !== null) {
|
||||
$format .= ' Create:[%s]';
|
||||
$args[] = date(\DATE_W3C, $this->createTime);
|
||||
}
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $modifyTime
|
||||
* @param int|null $accessTime
|
||||
@ -414,33 +440,7 @@ class ExtendedTimestampExtraField implements ZipExtraField
|
||||
try {
|
||||
return $timestamp !== null ? new \DateTimeImmutable('@' . $timestamp) : null;
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [self::HEADER_ID];
|
||||
$format = '0x%04x ExtendedTimestamp:';
|
||||
|
||||
if ($this->modifyTime !== null) {
|
||||
$format .= ' Modify:[%s]';
|
||||
$args[] = date(\DATE_W3C, $this->modifyTime);
|
||||
}
|
||||
|
||||
if ($this->accessTime !== null) {
|
||||
$format .= ' Access:[%s]';
|
||||
$args[] = date(\DATE_W3C, $this->accessTime);
|
||||
}
|
||||
|
||||
if ($this->createTime !== null) {
|
||||
$format .= ' Create:[%s]';
|
||||
$args[] = date(\DATE_W3C, $this->createTime);
|
||||
}
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,14 @@ class JarMarkerExtraField implements ZipExtraField
|
||||
/** @var int Header id. */
|
||||
const HEADER_ID = 0xCAFE;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('0x%04x Jar Marker', self::HEADER_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZipContainer $container
|
||||
*/
|
||||
@ -107,12 +115,4 @@ class JarMarkerExtraField implements ZipExtraField
|
||||
{
|
||||
return self::unpackLocalFileData($buffer, $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('0x%04x Jar Marker', self::HEADER_ID);
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,19 @@ class NewUnixExtraField implements ZipExtraField
|
||||
$this->gid = (int) $gid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf(
|
||||
'0x%04x NewUnix: UID=%d GID=%d',
|
||||
self::HEADER_ID,
|
||||
$this->uid,
|
||||
$this->gid
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
@ -221,17 +234,4 @@ class NewUnixExtraField implements ZipExtraField
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf(
|
||||
'0x%04x NewUnix: UID=%d GID=%d',
|
||||
self::HEADER_ID,
|
||||
$this->uid,
|
||||
$this->gid
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,32 @@ class NtfsExtraField implements ZipExtraField
|
||||
$this->createNtfsTime = (int) $createNtfsTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [self::HEADER_ID];
|
||||
$format = '0x%04x NtfsExtra:';
|
||||
|
||||
if ($this->modifyNtfsTime !== 0) {
|
||||
$format .= ' Modify:[%s]';
|
||||
$args[] = $this->getModifyDateTime()->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
if ($this->accessNtfsTime !== 0) {
|
||||
$format .= ' Access:[%s]';
|
||||
$args[] = $this->getAccessDateTime()->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
if ($this->createNtfsTime !== 0) {
|
||||
$format .= ' Create:[%s]';
|
||||
$args[] = $this->getCreateDateTime()->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTimeInterface $modifyDateTime
|
||||
* @param \DateTimeInterface $accessDateTime
|
||||
@ -310,30 +336,4 @@ class NtfsExtraField implements ZipExtraField
|
||||
|
||||
return $dateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [self::HEADER_ID];
|
||||
$format = '0x%04x NtfsExtra:';
|
||||
|
||||
if ($this->modifyNtfsTime !== 0) {
|
||||
$format .= ' Modify:[%s]';
|
||||
$args[] = $this->getModifyDateTime()->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
if ($this->accessNtfsTime !== 0) {
|
||||
$format .= ' Access:[%s]';
|
||||
$args[] = $this->getAccessDateTime()->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
if ($this->createNtfsTime !== 0) {
|
||||
$format .= ' Create:[%s]';
|
||||
$args[] = $this->getCreateDateTime()->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +84,37 @@ class OldUnixExtraField implements ZipExtraField
|
||||
$this->gid = $gid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [self::HEADER_ID];
|
||||
$format = '0x%04x OldUnix:';
|
||||
|
||||
if (($modifyTime = $this->getModifyDateTime()) !== null) {
|
||||
$format .= ' Modify:[%s]';
|
||||
$args[] = $modifyTime->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
if (($accessTime = $this->getAccessDateTime()) !== null) {
|
||||
$format .= ' Access:[%s]';
|
||||
$args[] = $accessTime->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
if ($this->uid !== null) {
|
||||
$format .= ' UID=%d';
|
||||
$args[] = $this->uid;
|
||||
}
|
||||
|
||||
if ($this->gid !== null) {
|
||||
$format .= ' GID=%d';
|
||||
$args[] = $this->gid;
|
||||
}
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
@ -226,10 +257,10 @@ class OldUnixExtraField implements ZipExtraField
|
||||
public function getAccessDateTime()
|
||||
{
|
||||
try {
|
||||
return $this->accessTime === null ? null :
|
||||
new \DateTimeImmutable('@' . $this->accessTime);
|
||||
return $this->accessTime === null ? null
|
||||
: new \DateTimeImmutable('@' . $this->accessTime);
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,10 +286,10 @@ class OldUnixExtraField implements ZipExtraField
|
||||
public function getModifyDateTime()
|
||||
{
|
||||
try {
|
||||
return $this->modifyTime === null ? null :
|
||||
new \DateTimeImmutable('@' . $this->modifyTime);
|
||||
return $this->modifyTime === null ? null
|
||||
: new \DateTimeImmutable('@' . $this->modifyTime);
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,35 +324,4 @@ class OldUnixExtraField implements ZipExtraField
|
||||
{
|
||||
$this->gid = $gid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [self::HEADER_ID];
|
||||
$format = '0x%04x OldUnix:';
|
||||
|
||||
if (($modifyTime = $this->getModifyDateTime()) !== null) {
|
||||
$format .= ' Modify:[%s]';
|
||||
$args[] = $modifyTime->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
if (($accessTime = $this->getAccessDateTime()) !== null) {
|
||||
$format .= ' Access:[%s]';
|
||||
$args[] = $accessTime->format(\DATE_ATOM);
|
||||
}
|
||||
|
||||
if ($this->uid !== null) {
|
||||
$format .= ' UID=%d';
|
||||
$args[] = $this->uid;
|
||||
}
|
||||
|
||||
if ($this->gid !== null) {
|
||||
$format .= ' GID=%d';
|
||||
$args[] = $this->gid;
|
||||
}
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
}
|
||||
|
@ -50,18 +50,6 @@ class UnicodeCommentExtraField extends AbstractUnicodeExtraField
|
||||
{
|
||||
const HEADER_ID = 0x6375;
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
* which must be constant during the life cycle of this object.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeaderId()
|
||||
{
|
||||
return self::HEADER_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -73,4 +61,16 @@ class UnicodeCommentExtraField extends AbstractUnicodeExtraField
|
||||
$this->getUnicodeValue()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
* which must be constant during the life cycle of this object.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeaderId()
|
||||
{
|
||||
return self::HEADER_ID;
|
||||
}
|
||||
}
|
||||
|
@ -51,18 +51,6 @@ class UnicodePathExtraField extends AbstractUnicodeExtraField
|
||||
{
|
||||
const HEADER_ID = 0x7075;
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
* which must be constant during the life cycle of this object.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeaderId()
|
||||
{
|
||||
return self::HEADER_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -74,4 +62,16 @@ class UnicodePathExtraField extends AbstractUnicodeExtraField
|
||||
$this->getUnicodeValue()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
* which must be constant during the life cycle of this object.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeaderId()
|
||||
{
|
||||
return self::HEADER_ID;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,17 @@ class UnrecognizedExtraField implements ZipExtraField
|
||||
$this->data = (string) $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [$this->headerId, $this->data];
|
||||
$format = '0x%04x Unrecognized Extra Field: "%s"';
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $headerId
|
||||
*/
|
||||
@ -72,7 +83,7 @@ class UnrecognizedExtraField implements ZipExtraField
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function packLocalFileData()
|
||||
{
|
||||
@ -80,7 +91,7 @@ class UnrecognizedExtraField implements ZipExtraField
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function packCentralDirData()
|
||||
{
|
||||
@ -102,15 +113,4 @@ class UnrecognizedExtraField implements ZipExtraField
|
||||
{
|
||||
$this->data = (string) $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [$this->headerId, $this->data];
|
||||
$format = '0x%04x Unrecognized Extra Field: "%s"';
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,20 @@ class WinZipAesExtraField implements ZipExtraField
|
||||
$this->setCompressionMethod($compressionMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf(
|
||||
'0x%04x WINZIP AES: VendorVersion=%d KeyStrength=0x%02x CompressionMethod=%s',
|
||||
__CLASS__,
|
||||
$this->vendorVersion,
|
||||
$this->keyStrength,
|
||||
$this->compressionMethod
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZipEntry $entry
|
||||
*
|
||||
@ -118,11 +132,11 @@ class WinZipAesExtraField implements ZipExtraField
|
||||
//
|
||||
// https://www.winzip.com/win/en/aes_info.html
|
||||
$vendorVersion = (
|
||||
$entry->getUncompressedSize() < 20 ||
|
||||
$entry->getCompressionMethod() === ZipCompressionMethod::BZIP2
|
||||
) ?
|
||||
self::VERSION_AE2 :
|
||||
self::VERSION_AE1;
|
||||
$entry->getUncompressedSize() < 20
|
||||
|| $entry->getCompressionMethod() === ZipCompressionMethod::BZIP2
|
||||
)
|
||||
? self::VERSION_AE2
|
||||
: self::VERSION_AE1;
|
||||
|
||||
$field = new self($vendorVersion, $keyStrength, $entry->getCompressionMethod());
|
||||
|
||||
@ -370,18 +384,4 @@ class WinZipAesExtraField implements ZipExtraField
|
||||
{
|
||||
return (int) ($this->getEncryptionStrength() / 8 / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf(
|
||||
'0x%04x WINZIP AES: VendorVersion=%d KeyStrength=0x%02x CompressionMethod=%s',
|
||||
__CLASS__,
|
||||
$this->vendorVersion,
|
||||
$this->keyStrength,
|
||||
$this->compressionMethod
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,39 @@ class Zip64ExtraField implements ZipExtraField
|
||||
$this->diskStart = $diskStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [self::HEADER_ID];
|
||||
$format = '0x%04x ZIP64: ';
|
||||
$formats = [];
|
||||
|
||||
if ($this->uncompressedSize !== null) {
|
||||
$formats[] = 'SIZE=%d';
|
||||
$args[] = $this->uncompressedSize;
|
||||
}
|
||||
|
||||
if ($this->compressedSize !== null) {
|
||||
$formats[] = 'COMP_SIZE=%d';
|
||||
$args[] = $this->compressedSize;
|
||||
}
|
||||
|
||||
if ($this->localHeaderOffset !== null) {
|
||||
$formats[] = 'OFFSET=%d';
|
||||
$args[] = $this->localHeaderOffset;
|
||||
}
|
||||
|
||||
if ($this->diskStart !== null) {
|
||||
$formats[] = 'DISK_START=%d';
|
||||
$args[] = $this->diskStart;
|
||||
}
|
||||
$format .= implode(' ', $formats);
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
@ -275,37 +308,4 @@ class Zip64ExtraField implements ZipExtraField
|
||||
{
|
||||
$this->diskStart = $diskStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$args = [self::HEADER_ID];
|
||||
$format = '0x%04x ZIP64: ';
|
||||
$formats = [];
|
||||
|
||||
if ($this->uncompressedSize !== null) {
|
||||
$formats[] = 'SIZE=%d';
|
||||
$args[] = $this->uncompressedSize;
|
||||
}
|
||||
|
||||
if ($this->compressedSize !== null) {
|
||||
$formats[] = 'COMP_SIZE=%d';
|
||||
$args[] = $this->compressedSize;
|
||||
}
|
||||
|
||||
if ($this->localHeaderOffset !== null) {
|
||||
$formats[] = 'OFFSET=%d';
|
||||
$args[] = $this->localHeaderOffset;
|
||||
}
|
||||
|
||||
if ($this->diskStart !== null) {
|
||||
$formats[] = 'DISK_START=%d';
|
||||
$args[] = $this->diskStart;
|
||||
}
|
||||
$format .= implode(' ', $formats);
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,5 @@ final class ZipExtraDriver
|
||||
if (isset(self::$implementations[$headerId])) {
|
||||
return self::$implementations[$headerId];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,11 @@ use PhpZip\Model\ZipEntry;
|
||||
*/
|
||||
interface ZipExtraField
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
|
||||
/**
|
||||
* Returns the Header ID (type) of this Extra Field.
|
||||
* The Header ID is an unsigned short integer (two bytes)
|
||||
@ -55,9 +60,4 @@ interface ZipExtraField
|
||||
* @return string the data
|
||||
*/
|
||||
public function packCentralDirData();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
}
|
||||
|
@ -25,6 +25,22 @@ class ImmutableZipContainer implements \Countable
|
||||
$this->archiveComment = $archiveComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties.
|
||||
* Any properties that are references to other variables, will remain references.
|
||||
* Once the cloning is complete, if a __clone() method is defined,
|
||||
* then the newly created object's __clone() method will be called, to allow any necessary properties that need to
|
||||
* be changed. NOT CALLABLE DIRECTLY.
|
||||
*
|
||||
* @see https://php.net/manual/en/language.oop5.cloning.php
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this->entries as $key => $value) {
|
||||
$this->entries[$key] = clone $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ZipEntry[]
|
||||
*/
|
||||
@ -53,20 +69,4 @@ class ImmutableZipContainer implements \Countable
|
||||
{
|
||||
return \count($this->entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties.
|
||||
* Any properties that are references to other variables, will remain references.
|
||||
* Once the cloning is complete, if a __clone() method is defined,
|
||||
* then the newly created object's __clone() method will be called, to allow any necessary properties that need to
|
||||
* be changed. NOT CALLABLE DIRECTLY.
|
||||
*
|
||||
* @see https://php.net/manual/en/language.oop5.cloning.php
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this->entries as $key => $value) {
|
||||
$this->entries[$key] = clone $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ class ZipContainer extends ImmutableZipContainer
|
||||
{
|
||||
$entryName = $entryName instanceof ZipEntry ? $entryName->getName() : (string) $entryName;
|
||||
|
||||
return isset($this->entries[$entryName]) ? $this->entries[$entryName] : null;
|
||||
return $this->entries[$entryName] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -225,8 +225,8 @@ class ZipContainer extends ImmutableZipContainer
|
||||
$entry = $entry instanceof ZipEntry ? $entry->getName() : (string) $entry;
|
||||
|
||||
if (
|
||||
$this->sourceContainer !== null &&
|
||||
isset($this->entries[$entry], $this->sourceContainer->entries[$entry])
|
||||
$this->sourceContainer !== null
|
||||
&& isset($this->entries[$entry], $this->sourceContainer->entries[$entry])
|
||||
) {
|
||||
$this->entries[$entry] = clone $this->sourceContainer->entries[$entry];
|
||||
|
||||
|
@ -64,12 +64,28 @@ class ZipEntry
|
||||
|
||||
/**
|
||||
* Pseudo compression method for WinZip AES encrypted entries.
|
||||
* Require php extension openssl or mcrypt.
|
||||
* Require php extension openssl.
|
||||
*
|
||||
* @deprecated Use {@see ZipCompressionMethod::WINZIP_AES}
|
||||
*/
|
||||
const METHOD_WINZIP_AES = ZipCompressionMethod::WINZIP_AES;
|
||||
|
||||
/**
|
||||
* Collections of Extra Fields in Central Directory.
|
||||
* Keys from Header ID [int] and value Extra Field [ExtraField].
|
||||
*
|
||||
* @var ExtraFieldsCollection
|
||||
*/
|
||||
protected $cdExtraFields;
|
||||
|
||||
/**
|
||||
* Collections of Extra Fields int local header.
|
||||
* Keys from Header ID [int] and value Extra Field [ExtraField].
|
||||
*
|
||||
* @var ExtraFieldsCollection
|
||||
*/
|
||||
protected $localExtraFields;
|
||||
|
||||
/** @var string Entry name (filename in archive) */
|
||||
private $name;
|
||||
|
||||
@ -118,22 +134,6 @@ class ZipEntry
|
||||
/** @var int relative Offset Of Local File Header */
|
||||
private $localHeaderOffset = 0;
|
||||
|
||||
/**
|
||||
* Collections of Extra Fields in Central Directory.
|
||||
* Keys from Header ID [int] and value Extra Field [ExtraField].
|
||||
*
|
||||
* @var ExtraFieldsCollection
|
||||
*/
|
||||
protected $cdExtraFields;
|
||||
|
||||
/**
|
||||
* Collections of Extra Fields int local header.
|
||||
* Keys from Header ID [int] and value Extra Field [ExtraField].
|
||||
*
|
||||
* @var ExtraFieldsCollection
|
||||
*/
|
||||
protected $localExtraFields;
|
||||
|
||||
/** @var string|null comment field */
|
||||
private $comment;
|
||||
|
||||
@ -163,6 +163,16 @@ class ZipEntry
|
||||
$this->localExtraFields = new ExtraFieldsCollection();
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
$this->cdExtraFields = clone $this->cdExtraFields;
|
||||
$this->localExtraFields = clone $this->localExtraFields;
|
||||
|
||||
if ($this->data !== null) {
|
||||
$this->data = clone $this->data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method only internal use.
|
||||
*
|
||||
@ -267,9 +277,9 @@ class ZipEntry
|
||||
if ($this->extractVersion !== self::UNKNOWN) {
|
||||
$this->extractVersion = max(
|
||||
$this->extractVersion,
|
||||
$this->isDirectory ?
|
||||
ZipVersion::v20_DEFLATED_FOLDER_ZIPCRYPTO :
|
||||
ZipVersion::v10_DEFAULT_MIN
|
||||
$this->isDirectory
|
||||
? ZipVersion::v20_DEFLATED_FOLDER_ZIPCRYPTO
|
||||
: ZipVersion::v10_DEFAULT_MIN
|
||||
);
|
||||
}
|
||||
|
||||
@ -343,7 +353,7 @@ class ZipEntry
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function setData($data)
|
||||
public function setData(ZipData $data = null)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
@ -487,9 +497,9 @@ class ZipEntry
|
||||
}
|
||||
|
||||
if (
|
||||
$this->compressionMethod === ZipCompressionMethod::DEFLATED ||
|
||||
$this->isDirectory ||
|
||||
$this->encryptionMethod === ZipEncryptionMethod::PKWARE
|
||||
$this->compressionMethod === ZipCompressionMethod::DEFLATED
|
||||
|| $this->isDirectory
|
||||
|| $this->encryptionMethod === ZipEncryptionMethod::PKWARE
|
||||
) {
|
||||
return ZipVersion::v20_DEFLATED_FOLDER_ZIPCRYPTO;
|
||||
}
|
||||
@ -1151,8 +1161,8 @@ class ZipEntry
|
||||
$headerId = (int) $headerId;
|
||||
|
||||
return
|
||||
isset($this->localExtraFields[$headerId]) ||
|
||||
isset($this->cdExtraFields[$headerId]);
|
||||
isset($this->localExtraFields[$headerId])
|
||||
|| isset($this->cdExtraFields[$headerId]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1358,12 +1368,12 @@ class ZipEntry
|
||||
}
|
||||
|
||||
if (
|
||||
$compressionLevel < ZipCompressionLevel::LEVEL_MIN ||
|
||||
$compressionLevel > ZipCompressionLevel::LEVEL_MAX
|
||||
$compressionLevel < ZipCompressionLevel::LEVEL_MIN
|
||||
|| $compressionLevel > ZipCompressionLevel::LEVEL_MAX
|
||||
) {
|
||||
throw new InvalidArgumentException(
|
||||
'Invalid compression level. Minimum level ' .
|
||||
ZipCompressionLevel::LEVEL_MIN . '. Maximum level ' . ZipCompressionLevel::LEVEL_MAX
|
||||
'Invalid compression level. Minimum level '
|
||||
. ZipCompressionLevel::LEVEL_MIN . '. Maximum level ' . ZipCompressionLevel::LEVEL_MAX
|
||||
);
|
||||
}
|
||||
$this->compressionLevel = $compressionLevel;
|
||||
@ -1385,15 +1395,18 @@ class ZipEntry
|
||||
switch ($this->compressionLevel) {
|
||||
case ZipCompressionLevel::MAXIMUM:
|
||||
$bit1 = true;
|
||||
|
||||
break;
|
||||
|
||||
case ZipCompressionLevel::FAST:
|
||||
$bit2 = true;
|
||||
|
||||
break;
|
||||
|
||||
case ZipCompressionLevel::SUPER_FAST:
|
||||
$bit1 = true;
|
||||
$bit2 = true;
|
||||
|
||||
break;
|
||||
// default is ZipCompressionLevel::NORMAL
|
||||
}
|
||||
@ -1535,8 +1548,6 @@ class ZipEntry
|
||||
if ($oldUnixExtra !== null) {
|
||||
return $oldUnixExtra->getAccessDateTime();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1557,17 +1568,5 @@ class ZipEntry
|
||||
if ($extendedExtra !== null) {
|
||||
return $extendedExtra->getCreateDateTime();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
$this->cdExtraFields = clone $this->cdExtraFields;
|
||||
$this->localExtraFields = clone $this->localExtraFields;
|
||||
|
||||
if ($this->data !== null) {
|
||||
$this->data = clone $this->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,33 @@ class ZipInfo
|
||||
$this->entry = $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$ctime = $this->entry->getCTime();
|
||||
$atime = $this->entry->getATime();
|
||||
$comment = $this->getComment();
|
||||
|
||||
return __CLASS__ . ' {'
|
||||
. 'Name="' . $this->getName() . '", '
|
||||
. ($this->isFolder() ? 'Folder, ' : '')
|
||||
. 'Size="' . FilesUtil::humanSize($this->getSize()) . '"'
|
||||
. ', Compressed size="' . FilesUtil::humanSize($this->getCompressedSize()) . '"'
|
||||
. ', Modified time="' . $this->entry->getMTime()->format(\DATE_W3C) . '", '
|
||||
. ($ctime !== null ? 'Created time="' . $ctime->format(\DATE_W3C) . '", ' : '')
|
||||
. ($atime !== null ? 'Accessed time="' . $atime->format(\DATE_W3C) . '", ' : '')
|
||||
. ($this->isEncrypted() ? 'Encrypted, ' : '')
|
||||
. ($comment !== null ? 'Comment="' . $comment . '", ' : '')
|
||||
. (!empty($this->crc) ? 'Crc=0x' . dechex($this->crc) . ', ' : '')
|
||||
. 'Method name="' . $this->getMethodName() . '", '
|
||||
. 'Attributes="' . $this->getAttributes() . '", '
|
||||
. 'Platform="' . $this->getPlatform() . '", '
|
||||
. 'Version=' . $this->getVersion()
|
||||
. '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZipEntry $entry
|
||||
*
|
||||
@ -236,31 +263,4 @@ class ZipInfo
|
||||
'version' => $this->getVersion(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$ctime = $this->entry->getCTime();
|
||||
$atime = $this->entry->getATime();
|
||||
$comment = $this->getComment();
|
||||
|
||||
return __CLASS__ . ' {'
|
||||
. 'Name="' . $this->getName() . '", '
|
||||
. ($this->isFolder() ? 'Folder, ' : '')
|
||||
. 'Size="' . FilesUtil::humanSize($this->getSize()) . '"'
|
||||
. ', Compressed size="' . FilesUtil::humanSize($this->getCompressedSize()) . '"'
|
||||
. ', Modified time="' . $this->entry->getMTime()->format(\DATE_W3C) . '", '
|
||||
. ($ctime !== null ? 'Created time="' . $ctime->format(\DATE_W3C) . '", ' : '')
|
||||
. ($atime !== null ? 'Accessed time="' . $atime->format(\DATE_W3C) . '", ' : '')
|
||||
. ($this->isEncrypted() ? 'Encrypted, ' : '')
|
||||
. ($comment !== null ? 'Comment="' . $comment . '", ' : '')
|
||||
. (!empty($this->crc) ? 'Crc=0x' . dechex($this->crc) . ', ' : '')
|
||||
. 'Method name="' . $this->getMethodName() . '", '
|
||||
. 'Attributes="' . $this->getAttributes() . '", '
|
||||
. 'Platform="' . $this->getPlatform() . '", '
|
||||
. 'Version=' . $this->getVersion()
|
||||
. '}';
|
||||
}
|
||||
}
|
||||
|
@ -40,15 +40,11 @@ class CryptoUtil
|
||||
{
|
||||
if (\extension_loaded('openssl')) {
|
||||
$numBits = \strlen($key) * 8;
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
|
||||
return openssl_decrypt($data, 'AES-' . $numBits . '-CTR', $key, \OPENSSL_RAW_DATA, $iv);
|
||||
}
|
||||
|
||||
if (\extension_loaded('mcrypt')) {
|
||||
return mcrypt_decrypt(\MCRYPT_RIJNDAEL_128, $key, $data, 'ctr', $iv);
|
||||
}
|
||||
|
||||
throw new RuntimeException('Extension openssl or mcrypt not loaded');
|
||||
throw new RuntimeException('Openssl extension not loaded');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,14 +60,10 @@ class CryptoUtil
|
||||
{
|
||||
if (\extension_loaded('openssl')) {
|
||||
$numBits = \strlen($key) * 8;
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
|
||||
return openssl_encrypt($data, 'AES-' . $numBits . '-CTR', $key, \OPENSSL_RAW_DATA, $iv);
|
||||
}
|
||||
|
||||
if (\extension_loaded('mcrypt')) {
|
||||
return mcrypt_encrypt(\MCRYPT_RIJNDAEL_128, $key, $data, 'ctr', $iv);
|
||||
}
|
||||
|
||||
throw new RuntimeException('Extension openssl or mcrypt not loaded');
|
||||
throw new RuntimeException('Openssl extension not loaded');
|
||||
}
|
||||
}
|
||||
|
@ -82,12 +82,12 @@ class DateTimeConverter
|
||||
|
||||
$date = getdate($unixTimestamp);
|
||||
$dosTime = (
|
||||
(($date['year'] - 1980) << 25) |
|
||||
($date['mon'] << 21) |
|
||||
($date['mday'] << 16) |
|
||||
($date['hours'] << 11) |
|
||||
($date['minutes'] << 5) |
|
||||
($date['seconds'] >> 1)
|
||||
(($date['year'] - 1980) << 25)
|
||||
| ($date['mon'] << 21)
|
||||
| ($date['mday'] << 16)
|
||||
| ($date['hours'] << 11)
|
||||
| ($date['minutes'] << 5)
|
||||
| ($date['seconds'] >> 1)
|
||||
);
|
||||
|
||||
if ($dosTime <= self::MIN_DOS_TIME) {
|
||||
|
@ -45,34 +45,42 @@ class FileAttribUtil implements DosAttrs, UnixStat
|
||||
switch ($permission & self::UNX_IFMT) {
|
||||
case self::UNX_IFDIR:
|
||||
$mode .= 'd';
|
||||
|
||||
break;
|
||||
|
||||
case self::UNX_IFREG:
|
||||
$mode .= '-';
|
||||
|
||||
break;
|
||||
|
||||
case self::UNX_IFLNK:
|
||||
$mode .= 'l';
|
||||
|
||||
break;
|
||||
|
||||
case self::UNX_IFBLK:
|
||||
$mode .= 'b';
|
||||
|
||||
break;
|
||||
|
||||
case self::UNX_IFCHR:
|
||||
$mode .= 'c';
|
||||
|
||||
break;
|
||||
|
||||
case self::UNX_IFIFO:
|
||||
$mode .= 'p';
|
||||
|
||||
break;
|
||||
|
||||
case self::UNX_IFSOCK:
|
||||
$mode .= 's';
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$mode .= '?';
|
||||
|
||||
break;
|
||||
}
|
||||
$mode .= ($permission & self::UNX_IRUSR) ? 'r' : '-';
|
||||
|
@ -72,11 +72,13 @@ final class FilesUtil
|
||||
case '*':
|
||||
$regexPattern .= ($escaping ? '\\*' : '.*');
|
||||
$escaping = false;
|
||||
|
||||
break;
|
||||
|
||||
case '?':
|
||||
$regexPattern .= ($escaping ? '\\?' : '.');
|
||||
$escaping = false;
|
||||
|
||||
break;
|
||||
|
||||
case '.':
|
||||
@ -90,6 +92,7 @@ final class FilesUtil
|
||||
case '%':
|
||||
$regexPattern .= '\\' . $currentChar;
|
||||
$escaping = false;
|
||||
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
@ -99,6 +102,7 @@ final class FilesUtil
|
||||
} else {
|
||||
$escaping = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '{':
|
||||
@ -109,6 +113,7 @@ final class FilesUtil
|
||||
$inCurrent++;
|
||||
}
|
||||
$escaping = false;
|
||||
|
||||
break;
|
||||
|
||||
case '}':
|
||||
@ -121,6 +126,7 @@ final class FilesUtil
|
||||
$regexPattern = '}';
|
||||
}
|
||||
$escaping = false;
|
||||
|
||||
break;
|
||||
|
||||
case ',':
|
||||
@ -131,6 +137,7 @@ final class FilesUtil
|
||||
} else {
|
||||
$regexPattern = ',';
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
$escaping = false;
|
||||
@ -406,11 +413,9 @@ final class FilesUtil
|
||||
'x-epoc/x-sisx-app',
|
||||
];
|
||||
|
||||
if (\in_array($mimeType, $badDeflateCompMimeTypes, true)) {
|
||||
return true;
|
||||
}
|
||||
return (bool) (\in_array($mimeType, $badDeflateCompMimeTypes, true))
|
||||
|
||||
return false;
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,6 +42,9 @@ use Symfony\Component\Finder\SplFileInfo as SymfonySplFileInfo;
|
||||
*/
|
||||
class ZipFile implements ZipFileInterface
|
||||
{
|
||||
/** @var ZipContainer */
|
||||
protected $zipContainer;
|
||||
|
||||
/** @var array default mime types */
|
||||
private static $defaultMimeTypes = [
|
||||
'zip' => 'application/zip',
|
||||
@ -55,9 +58,6 @@ class ZipFile implements ZipFileInterface
|
||||
'xpi' => 'application/x-xpinstall',
|
||||
];
|
||||
|
||||
/** @var ZipContainer */
|
||||
protected $zipContainer;
|
||||
|
||||
/** @var ZipReader|null */
|
||||
private $reader;
|
||||
|
||||
@ -69,6 +69,14 @@ class ZipFile implements ZipFileInterface
|
||||
$this->zipContainer = $this->createZipContainer(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all resources.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $inputStream
|
||||
* @param array $options
|
||||
@ -376,7 +384,7 @@ class ZipFile implements ZipFileInterface
|
||||
* @param string $destDir location where to extract the files
|
||||
* @param array|string|null $entries entries to extract
|
||||
* @param array $options extract options
|
||||
* @param array $extractedEntries if the extractedEntries argument
|
||||
* @param array|null $extractedEntries if the extractedEntries argument
|
||||
* is present, then the specified
|
||||
* array will be filled with
|
||||
* information about the
|
||||
@ -576,9 +584,9 @@ class ZipFile implements ZipFileInterface
|
||||
$compressionMethod = ZipCompressionMethod::STORED;
|
||||
} else {
|
||||
$mimeType = FilesUtil::getMimeTypeFromString($contents);
|
||||
$compressionMethod = FilesUtil::isBadCompressionMimeType($mimeType) ?
|
||||
ZipCompressionMethod::STORED :
|
||||
ZipCompressionMethod::DEFLATED;
|
||||
$compressionMethod = FilesUtil::isBadCompressionMimeType($mimeType)
|
||||
? ZipCompressionMethod::STORED
|
||||
: ZipCompressionMethod::DEFLATED;
|
||||
}
|
||||
}
|
||||
|
||||
@ -714,9 +722,9 @@ class ZipFile implements ZipFileInterface
|
||||
} elseif ($file->getSize() < 512) {
|
||||
$compressionMethod = ZipCompressionMethod::STORED;
|
||||
} else {
|
||||
$compressionMethod = FilesUtil::isBadCompressionFile($file->getPathname()) ?
|
||||
ZipCompressionMethod::STORED :
|
||||
ZipCompressionMethod::DEFLATED;
|
||||
$compressionMethod = FilesUtil::isBadCompressionFile($file->getPathname())
|
||||
? ZipCompressionMethod::STORED
|
||||
: ZipCompressionMethod::DEFLATED;
|
||||
}
|
||||
|
||||
$zipEntry->setCompressionMethod($compressionMethod);
|
||||
@ -838,9 +846,9 @@ class ZipFile implements ZipFileInterface
|
||||
$bufferContents = stream_get_contents($stream, min(1024, $length));
|
||||
rewind($stream);
|
||||
$mimeType = FilesUtil::getMimeTypeFromString($bufferContents);
|
||||
$compressionMethod = FilesUtil::isBadCompressionMimeType($mimeType) ?
|
||||
ZipCompressionMethod::STORED :
|
||||
ZipCompressionMethod::DEFLATED;
|
||||
$compressionMethod = FilesUtil::isBadCompressionMimeType($mimeType)
|
||||
? ZipCompressionMethod::STORED
|
||||
: ZipCompressionMethod::DEFLATED;
|
||||
}
|
||||
$zipEntry->setUncompressedSize($length);
|
||||
}
|
||||
@ -999,9 +1007,9 @@ class ZipFile implements ZipFileInterface
|
||||
$localPath = '';
|
||||
}
|
||||
|
||||
$iterator = $iterator instanceof \RecursiveIterator ?
|
||||
new \RecursiveIteratorIterator($iterator) :
|
||||
new \IteratorIterator($iterator);
|
||||
$iterator = $iterator instanceof \RecursiveIterator
|
||||
? new \RecursiveIteratorIterator($iterator)
|
||||
: new \IteratorIterator($iterator);
|
||||
/**
|
||||
* @var string[] $files
|
||||
* @var string $path
|
||||
@ -1843,14 +1851,6 @@ class ZipFile implements ZipFileInterface
|
||||
return $this->saveAsFile($meta['uri']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all resources.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to set.
|
||||
*
|
||||
|
@ -295,7 +295,7 @@ interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
|
||||
* @param string $destDir location where to extract the files
|
||||
* @param array|string|null $entries entries to extract
|
||||
* @param array $options extract options
|
||||
* @param array $extractedEntries if the extractedEntries argument
|
||||
* @param array|null $extractedEntries if the extractedEntries argument
|
||||
* is present, then the specified
|
||||
* array will be filled with
|
||||
* information about the
|
||||
|
@ -76,8 +76,10 @@ abstract class AbstractUnicodeExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testUnicodeErrorParse()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipException::class,
|
||||
$this->expectException(
|
||||
ZipException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Unicode path extra data must have at least 5 bytes.'
|
||||
);
|
||||
|
||||
@ -90,8 +92,10 @@ abstract class AbstractUnicodeExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testUnknownVersionParse()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipException::class,
|
||||
$this->expectException(
|
||||
ZipException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Unsupported version [2] for Unicode path extra data.'
|
||||
);
|
||||
|
||||
|
@ -96,8 +96,10 @@ final class ApkAlignmentExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testInvalidParse()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipException::class,
|
||||
$this->expectException(
|
||||
ZipException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Minimum 6 bytes of the extensible data block/field used for alignment of uncompressed entries.'
|
||||
);
|
||||
|
||||
|
@ -91,8 +91,10 @@ final class AsiExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testInvalidParse()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
Crc32Exception::class,
|
||||
$this->expectException(
|
||||
Crc32Exception::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Asi Unix Extra Filed Data (expected CRC32 value'
|
||||
);
|
||||
|
||||
|
@ -66,9 +66,9 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
||||
{
|
||||
return [
|
||||
[
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT |
|
||||
ExtendedTimestampExtraField::CREATE_TIME_BIT,
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||
| ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||
| ExtendedTimestampExtraField::CREATE_TIME_BIT,
|
||||
911512006,
|
||||
911430000,
|
||||
893709400,
|
||||
@ -76,8 +76,8 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
||||
"\x07\xC6\x91T6",
|
||||
],
|
||||
[
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT,
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||
| ExtendedTimestampExtraField::ACCESS_TIME_BIT,
|
||||
1492955702,
|
||||
1492955638,
|
||||
null,
|
||||
@ -115,8 +115,8 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
||||
$field->setAccessTime($atime);
|
||||
self::assertSame(
|
||||
$field->getFlags(),
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||
| ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||
);
|
||||
self::assertSame($field->getModifyTime(), $mtime);
|
||||
self::assertSame($field->getAccessTime(), $atime);
|
||||
@ -127,9 +127,9 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
||||
$field->setCreateTime($ctime);
|
||||
self::assertSame(
|
||||
$field->getFlags(),
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT |
|
||||
ExtendedTimestampExtraField::CREATE_TIME_BIT
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||
| ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||
| ExtendedTimestampExtraField::CREATE_TIME_BIT
|
||||
);
|
||||
self::assertSame($field->getModifyTime(), $mtime);
|
||||
self::assertSame($field->getAccessTime(), $atime);
|
||||
@ -141,8 +141,8 @@ final class ExtendedTimestampExtraFieldTest extends TestCase
|
||||
self::assertNull($field->getCreateDateTime());
|
||||
self::assertSame(
|
||||
$field->getFlags(),
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT |
|
||||
ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||
ExtendedTimestampExtraField::MODIFY_TIME_BIT
|
||||
| ExtendedTimestampExtraField::ACCESS_TIME_BIT
|
||||
);
|
||||
|
||||
$field->setAccessTime(null);
|
||||
|
@ -32,8 +32,10 @@ final class JarMarkerExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testInvalidUnpackLocalData()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipException::class,
|
||||
$this->expectException(
|
||||
ZipException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
"JarMarker doesn't expect any data"
|
||||
);
|
||||
|
||||
@ -45,8 +47,10 @@ final class JarMarkerExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testInvalidUnpackCdData()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipException::class,
|
||||
$this->expectException(
|
||||
ZipException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
"JarMarker doesn't expect any data"
|
||||
);
|
||||
|
||||
|
@ -14,8 +14,10 @@ use PhpZip\Model\Extra\Fields\NtfsExtraField;
|
||||
*/
|
||||
final class NtfsExtraFieldTest extends TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (\PHP_INT_SIZE === 4) {
|
||||
self::markTestSkipped('only 64 bit test');
|
||||
}
|
||||
@ -156,9 +158,9 @@ final class NtfsExtraFieldTest extends TestCase
|
||||
$atimeTimestamp,
|
||||
$ctimeTimestamp
|
||||
) {
|
||||
self::assertEquals(NtfsExtraField::ntfsTimeToTimestamp($mtimeNtfs), $mtimeTimestamp, '', 0.00001);
|
||||
self::assertEquals(NtfsExtraField::ntfsTimeToTimestamp($atimeNtfs), $atimeTimestamp, '', 0.00001);
|
||||
self::assertEquals(NtfsExtraField::ntfsTimeToTimestamp($ctimeNtfs), $ctimeTimestamp, '', 0.00001);
|
||||
self::assertEqualsWithDelta(NtfsExtraField::ntfsTimeToTimestamp($mtimeNtfs), $mtimeTimestamp, 0.00001);
|
||||
self::assertEqualsWithDelta(NtfsExtraField::ntfsTimeToTimestamp($atimeNtfs), $atimeTimestamp, 0.00001);
|
||||
self::assertEqualsWithDelta(NtfsExtraField::ntfsTimeToTimestamp($ctimeNtfs), $ctimeTimestamp, 0.00001);
|
||||
|
||||
self::assertEqualsIntegerWithDelta(NtfsExtraField::timestampToNtfsTime($mtimeTimestamp), $mtimeNtfs, 10);
|
||||
self::assertEqualsIntegerWithDelta(NtfsExtraField::timestampToNtfsTime($atimeTimestamp), $atimeNtfs, 10);
|
||||
|
@ -12,7 +12,7 @@ use PhpZip\Model\Extra\Fields\UnicodeCommentExtraField;
|
||||
final class UnicodeCommentExtraFieldTest extends AbstractUnicodeExtraFieldTest
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getUnicodeExtraFieldClassName()
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ use PhpZip\Model\Extra\Fields\UnicodePathExtraField;
|
||||
final class UnicodePathExtraFieldTest extends AbstractUnicodeExtraFieldTest
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getUnicodeExtraFieldClassName()
|
||||
{
|
||||
|
@ -37,8 +37,10 @@ final class UnrecognizedExtraFieldTest extends TestCase
|
||||
|
||||
public function testUnpackLocalData()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
RuntimeException::class,
|
||||
$this->expectException(
|
||||
RuntimeException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Unsupport parse'
|
||||
);
|
||||
|
||||
@ -47,8 +49,10 @@ final class UnrecognizedExtraFieldTest extends TestCase
|
||||
|
||||
public function testUnpackCentralDirData()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
RuntimeException::class,
|
||||
$this->expectException(
|
||||
RuntimeException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Unsupport parse'
|
||||
);
|
||||
|
||||
|
@ -157,7 +157,8 @@ final class WinZipAesExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testConstructUnsupportVendorVersion()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Unsupport WinZip AES vendor version: 3');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Unsupport WinZip AES vendor version: 3');
|
||||
|
||||
new WinZipAesExtraField(
|
||||
3,
|
||||
@ -171,7 +172,8 @@ final class WinZipAesExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testSetterUnsupportVendorVersion()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Unsupport WinZip AES vendor version: 3');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Unsupport WinZip AES vendor version: 3');
|
||||
|
||||
$extraField = new WinZipAesExtraField(
|
||||
WinZipAesExtraField::VERSION_AE1,
|
||||
@ -186,7 +188,8 @@ final class WinZipAesExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testConstructUnsupportCompressionMethod()
|
||||
{
|
||||
$this->setExpectedException(ZipUnsupportMethodException::class, 'Compression method 3 (Reduced compression factor 2) is not supported.');
|
||||
$this->expectException(ZipUnsupportMethodException::class);
|
||||
$this->expectExceptionMessage('Compression method 3 (Reduced compression factor 2) is not supported.');
|
||||
|
||||
new WinZipAesExtraField(
|
||||
WinZipAesExtraField::VERSION_AE1,
|
||||
@ -200,7 +203,8 @@ final class WinZipAesExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testSetterUnsupportCompressionMethod()
|
||||
{
|
||||
$this->setExpectedException(ZipUnsupportMethodException::class, 'Compression method 3 (Reduced compression factor 2) is not supported.');
|
||||
$this->expectException(ZipUnsupportMethodException::class);
|
||||
$this->expectExceptionMessage('Compression method 3 (Reduced compression factor 2) is not supported.');
|
||||
|
||||
$extraField = new WinZipAesExtraField(
|
||||
WinZipAesExtraField::VERSION_AE1,
|
||||
@ -215,7 +219,8 @@ final class WinZipAesExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testConstructUnsupportKeyStrength()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Key strength 16 not support value. Allow values: 1, 2, 3');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Key strength 16 not support value. Allow values: 1, 2, 3');
|
||||
|
||||
new WinZipAesExtraField(
|
||||
WinZipAesExtraField::VERSION_AE1,
|
||||
@ -229,7 +234,8 @@ final class WinZipAesExtraFieldTest extends TestCase
|
||||
*/
|
||||
public function testSetterUnsupportKeyStrength()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Key strength 16 not support value. Allow values: 1, 2, 3');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Key strength 16 not support value. Allow values: 1, 2, 3');
|
||||
|
||||
new WinZipAesExtraField(
|
||||
WinZipAesExtraField::VERSION_AE1,
|
||||
|
@ -15,8 +15,10 @@ use PhpZip\Model\ZipEntry;
|
||||
*/
|
||||
final class Zip64ExtraFieldTest extends TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (\PHP_INT_SIZE === 4) {
|
||||
self::markTestSkipped('only 64 bit test');
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class Issue24Test extends ZipTestCase
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public static function setUpBeforeClass()
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
stream_wrapper_register(self::PROTO_DUMMYFS, DummyFileSystemStream::class);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ class PhpZipExtResourceTest extends ZipTestCase
|
||||
$zipFile->extractTo($this->outputDirname);
|
||||
$zipFile->close();
|
||||
|
||||
static::assertTrue(is_dir($this->outputDirname . '/test/empty'));
|
||||
static::assertDirectoryExists($this->outputDirname . '/test/empty');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,7 +109,8 @@ class PhpZipExtResourceTest extends ZipTestCase
|
||||
*/
|
||||
public function testBug49072()
|
||||
{
|
||||
$this->setExpectedException(Crc32Exception::class, 'file1');
|
||||
$this->expectException(Crc32Exception::class);
|
||||
$this->expectExceptionMessage('file1');
|
||||
|
||||
$filename = __DIR__ . '/resources/pecl/bug49072.zip';
|
||||
|
||||
@ -128,13 +129,17 @@ class PhpZipExtResourceTest extends ZipTestCase
|
||||
public function testBug70752()
|
||||
{
|
||||
if (\PHP_INT_SIZE === 4) { // php 32 bit
|
||||
$this->setExpectedException(
|
||||
RuntimeException::class,
|
||||
$this->expectException(
|
||||
RuntimeException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
|
||||
);
|
||||
} else { // php 64 bit
|
||||
$this->setExpectedException(
|
||||
ZipAuthenticationException::class,
|
||||
$this->expectException(
|
||||
ZipAuthenticationException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Invalid password'
|
||||
);
|
||||
}
|
||||
@ -151,7 +156,7 @@ class PhpZipExtResourceTest extends ZipTestCase
|
||||
$zipFile->extractTo($this->outputDirname);
|
||||
static::markTestIncomplete('failed test');
|
||||
} catch (ZipException $exception) {
|
||||
static::assertFileNotExists($this->outputDirname . '/bug70752.txt');
|
||||
static::assertFileDoesNotExist($this->outputDirname . '/bug70752.txt');
|
||||
|
||||
throw $exception;
|
||||
} finally {
|
||||
@ -168,7 +173,8 @@ class PhpZipExtResourceTest extends ZipTestCase
|
||||
*/
|
||||
public function testPecl12414()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'Corrupt zip file. Cannot read zip entry.');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('Corrupt zip file. Cannot read zip entry.');
|
||||
|
||||
$filename = __DIR__ . '/resources/pecl/pecl12414.zip';
|
||||
|
||||
|
18
tests/Polyfill/LegacyTestCase.php
Normal file
18
tests/Polyfill/LegacyTestCase.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpZip\Tests\Polyfill;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @small
|
||||
*/
|
||||
class LegacyTestCase extends TestCase
|
||||
{
|
||||
use PhpUnit8CompatTrait;
|
||||
use PhpUnit9CompatTrait;
|
||||
}
|
22
tests/Polyfill/PhpUnit8CompatTrait.php
Normal file
22
tests/Polyfill/PhpUnit8CompatTrait.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace PhpZip\Tests\Polyfill;
|
||||
|
||||
use PHPUnit\Runner\Version;
|
||||
|
||||
trait PhpUnit8CompatTrait
|
||||
{
|
||||
/**
|
||||
* @param string $regularExpression
|
||||
*/
|
||||
public function expectExceptionMessageMatches(string $regularExpression): void
|
||||
{
|
||||
if (version_compare(Version::id(), '8.0.0', '<')) {
|
||||
$this->expectExceptionMessageRegExp($regularExpression);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent::expectExceptionMessageMatches($regularExpression);
|
||||
}
|
||||
}
|
53
tests/Polyfill/PhpUnit9CompatTrait.php
Normal file
53
tests/Polyfill/PhpUnit9CompatTrait.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpZip\Tests\Polyfill;
|
||||
|
||||
use PHPUnit\Framework\ExpectationFailedException;
|
||||
use PHPUnit\Runner\Version;
|
||||
use SebastianBergmann\RecursionContext\InvalidArgumentException;
|
||||
|
||||
trait PhpUnit9CompatTrait
|
||||
{
|
||||
/**
|
||||
* Asserts that a file does not exist.
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $message
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ExpectationFailedException
|
||||
*
|
||||
* @noinspection PhpDeprecationInspection
|
||||
*/
|
||||
public static function assertFileDoesNotExist(string $filename, string $message = ''): void
|
||||
{
|
||||
if (version_compare(Version::id(), '9.1.0', '<')) {
|
||||
static::assertFileNotExists($filename, $message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent::assertFileDoesNotExist($filename, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a directory does not exist.
|
||||
*
|
||||
* @throws ExpectationFailedException
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @noinspection PhpDeprecationInspection
|
||||
*/
|
||||
public static function assertDirectoryDoesNotExist(string $directory, string $message = ''): void
|
||||
{
|
||||
if (version_compare(Version::id(), '9.1.0', '<')) {
|
||||
static::assertDirectoryNotExists($directory, $message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent::assertDirectoryDoesNotExist($directory, $message);
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ final class SymlinkTest extends ZipTestCase
|
||||
self::assertCorrectZipArchive($this->outputFilename);
|
||||
|
||||
FilesUtil::removeDir($this->outputDirname);
|
||||
self::assertFalse(is_dir($this->outputDirname));
|
||||
self::assertDirectoryDoesNotExist($this->outputDirname);
|
||||
self::assertTrue(mkdir($this->outputDirname, 0755, true));
|
||||
|
||||
$zipFile->openFile($this->outputFilename);
|
||||
|
@ -55,7 +55,7 @@ class ZipAlignTest extends ZipTestCase
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$zipFile->addFromString(
|
||||
'entry' . $i . '.txt',
|
||||
random_bytes(mt_rand(100, 4096)),
|
||||
random_bytes(random_int(100, 4096)),
|
||||
ZipCompressionMethod::STORED
|
||||
);
|
||||
}
|
||||
@ -97,7 +97,7 @@ class ZipAlignTest extends ZipTestCase
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$zipFile->addFromString(
|
||||
'entry' . $i . '.txt',
|
||||
random_bytes(mt_rand(100, 4096)),
|
||||
random_bytes(random_int(100, 4096)),
|
||||
ZipCompressionMethod::STORED
|
||||
);
|
||||
}
|
||||
@ -126,7 +126,7 @@ class ZipAlignTest extends ZipTestCase
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$zipFile->addFromString(
|
||||
'entry' . $i . '.txt',
|
||||
random_bytes(mt_rand(100, 4096)),
|
||||
random_bytes(random_int(100, 4096)),
|
||||
ZipCompressionMethod::STORED
|
||||
);
|
||||
}
|
||||
@ -147,14 +147,14 @@ class ZipAlignTest extends ZipTestCase
|
||||
$zipFile->openFile($this->outputFilename);
|
||||
$zipFile->deleteFromRegex('~entry2[\\d]+\\.txt$~s');
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$isStored = (bool) mt_rand(0, 1);
|
||||
$isStored = (bool) random_int(0, 1);
|
||||
|
||||
$zipFile->addFromString(
|
||||
'entry_new_' . ($isStored ? 'stored' : 'deflated') . '_' . $i . '.txt',
|
||||
random_bytes(mt_rand(100, 4096)),
|
||||
$isStored ?
|
||||
ZipCompressionMethod::STORED :
|
||||
ZipCompressionMethod::DEFLATED
|
||||
random_bytes(random_int(100, 4096)),
|
||||
$isStored
|
||||
? ZipCompressionMethod::STORED
|
||||
: ZipCompressionMethod::DEFLATED
|
||||
);
|
||||
}
|
||||
$zipFile->setZipAlign(4);
|
||||
|
@ -89,7 +89,8 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testEmptyName($entryName, $exceptionMessage)
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, $exceptionMessage);
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage($exceptionMessage);
|
||||
|
||||
new ZipEntry($entryName);
|
||||
}
|
||||
@ -174,7 +175,8 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testOutOfRangeCompressionMethod($compressionMethod)
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'method out of range: ' . $compressionMethod);
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('method out of range: ' . $compressionMethod);
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setCompressionMethod($compressionMethod);
|
||||
@ -201,7 +203,8 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testUnsupportCompressionMethod($compressionMethod, $exceptionMessage)
|
||||
{
|
||||
$this->setExpectedException(ZipUnsupportMethodException::class, $exceptionMessage);
|
||||
$this->expectException(ZipUnsupportMethodException::class);
|
||||
$this->expectExceptionMessage($exceptionMessage);
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setCompressionMethod($compressionMethod);
|
||||
@ -253,7 +256,8 @@ class ZipEntryTest extends TestCase
|
||||
|
||||
public function testEmptyCharset()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Empty charset');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Empty charset');
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setCharset('');
|
||||
@ -398,7 +402,8 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testInvalidCreatedOs($zipOS)
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Platform out of range');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Platform out of range');
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setCreatedOS($zipOS);
|
||||
@ -422,7 +427,8 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testInvalidExtractedOs($zipOS)
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Platform out of range');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Platform out of range');
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setExtractedOS($zipOS);
|
||||
@ -545,7 +551,8 @@ class ZipEntryTest extends TestCase
|
||||
|
||||
public function testInvalidCompressedSize()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Compressed size < -1');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Compressed size < -1');
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setCompressedSize(-2);
|
||||
@ -553,7 +560,8 @@ class ZipEntryTest extends TestCase
|
||||
|
||||
public function testInvalidUncompressedSize()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Uncompressed size < -1');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Uncompressed size < -1');
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setUncompressedSize(-2);
|
||||
@ -568,7 +576,8 @@ class ZipEntryTest extends TestCase
|
||||
$zipEntry->setLocalHeaderOffset($localHeaderOffset);
|
||||
static::assertSame($zipEntry->getLocalHeaderOffset(), $localHeaderOffset);
|
||||
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Negative $localHeaderOffset');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Negative $localHeaderOffset');
|
||||
$zipEntry->setLocalHeaderOffset(-1);
|
||||
}
|
||||
|
||||
@ -652,7 +661,8 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testInvalidGPBF($gpbf)
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'general purpose bit flags out of range');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('general purpose bit flags out of range');
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setGeneralPurposeBitFlags($gpbf);
|
||||
@ -683,8 +693,8 @@ class ZipEntryTest extends TestCase
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setCompressionMethod(ZipCompressionMethod::DEFLATED);
|
||||
|
||||
$gpbf = ($bit1 ? GeneralPurposeBitFlag::COMPRESSION_FLAG1 : 0) |
|
||||
($bit2 ? GeneralPurposeBitFlag::COMPRESSION_FLAG2 : 0);
|
||||
$gpbf = ($bit1 ? GeneralPurposeBitFlag::COMPRESSION_FLAG1 : 0)
|
||||
| ($bit2 ? GeneralPurposeBitFlag::COMPRESSION_FLAG2 : 0);
|
||||
$zipEntry->setGeneralPurposeBitFlags($gpbf);
|
||||
static::assertSame($zipEntry->getCompressionLevel(), $compressionLevel);
|
||||
|
||||
@ -791,10 +801,12 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testInvalidCompressionLevel($compressionLevel)
|
||||
{
|
||||
$this->setExpectedException(
|
||||
InvalidArgumentException::class,
|
||||
'Invalid compression level. Minimum level ' . ZipCompressionLevel::LEVEL_MIN .
|
||||
'. Maximum level ' . ZipCompressionLevel::LEVEL_MAX
|
||||
$this->expectException(
|
||||
InvalidArgumentException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Invalid compression level. Minimum level ' . ZipCompressionLevel::LEVEL_MIN
|
||||
. '. Maximum level ' . ZipCompressionLevel::LEVEL_MAX
|
||||
);
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
@ -855,7 +867,8 @@ class ZipEntryTest extends TestCase
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'DosTime out of range');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('DosTime out of range');
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setDosTime($dosTime);
|
||||
@ -1012,7 +1025,8 @@ class ZipEntryTest extends TestCase
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'external attributes out of range');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('external attributes out of range');
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setExternalAttributes($externalAttributes);
|
||||
@ -1045,7 +1059,8 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testInvalidInternalAttributes($internalAttributes)
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'internal attributes out of range');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('internal attributes out of range');
|
||||
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
$zipEntry->setInternalAttributes($internalAttributes);
|
||||
@ -1140,7 +1155,8 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testLongComment()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Comment too long');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Comment too long');
|
||||
|
||||
$longComment = random_bytes(0xffff + 1);
|
||||
$zipEntry = new ZipEntry('entry');
|
||||
@ -1305,8 +1321,10 @@ class ZipEntryTest extends TestCase
|
||||
*/
|
||||
public function testInvalidEncryptionMethod($encryptionMethod)
|
||||
{
|
||||
$this->setExpectedException(
|
||||
InvalidArgumentException::class,
|
||||
$this->expectException(
|
||||
InvalidArgumentException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Encryption method ' . $encryptionMethod . ' is not supported.'
|
||||
);
|
||||
|
||||
@ -1456,7 +1474,7 @@ class ZipEntryTest extends TestCase
|
||||
* @param \DateTimeInterface|null $atime
|
||||
* @param \DateTimeInterface|null $ctime
|
||||
*/
|
||||
public function testMTimeATimeCTime(ExtraFieldsCollection $extraFieldsCollection, $mtime, $atime, $ctime)
|
||||
public function testMTimeATimeCTime(ExtraFieldsCollection $extraFieldsCollection, \DateTimeInterface $mtime, \DateTimeInterface $atime = null, \DateTimeInterface $ctime = null)
|
||||
{
|
||||
$unixTimestamp = time();
|
||||
|
||||
|
@ -30,7 +30,7 @@ abstract class ZipFileSetTestCase extends ZipTestCase
|
||||
/**
|
||||
* Before test.
|
||||
*/
|
||||
protected function setUp()
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->fillDirectory();
|
||||
|
@ -31,7 +31,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFileCantExists()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'does not exist');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('does not exist');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->openFile(uniqid('', false));
|
||||
@ -50,7 +51,8 @@ class ZipFileTest extends ZipTestCase
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setExpectedException(ZipException::class, 'can\'t open');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('can\'t open');
|
||||
|
||||
static::assertNotFalse(file_put_contents($this->outputFilename, 'content'));
|
||||
static::assertTrue(chmod($this->outputFilename, 0222));
|
||||
@ -64,7 +66,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFileEmptyFile()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'Corrupt zip file');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('Corrupt zip file');
|
||||
|
||||
static::assertNotFalse(touch($this->outputFilename));
|
||||
$zipFile = new ZipFile();
|
||||
@ -77,8 +80,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFileInvalidZip()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipException::class,
|
||||
$this->expectException(
|
||||
ZipException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Invalid zip file. The end of the central directory could not be found.'
|
||||
);
|
||||
|
||||
@ -92,7 +97,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFromStringNullString()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Empty string passed');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Empty string passed');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->openFromString(null);
|
||||
@ -103,7 +109,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFromStringEmptyString()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Empty string passed');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Empty string passed');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->openFromString('');
|
||||
@ -115,8 +122,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFromStringInvalidZip()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipException::class,
|
||||
$this->expectException(
|
||||
ZipException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Invalid zip file. The end of the central directory could not be found.'
|
||||
);
|
||||
|
||||
@ -149,7 +158,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFromStreamNullStream()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Stream must be a resource');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Stream must be a resource');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->openFromStream(null);
|
||||
@ -160,7 +170,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFromStreamInvalidResourceType()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Stream must be a resource');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Stream must be a resource');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
/** @noinspection PhpParamsInspection */
|
||||
@ -169,19 +180,22 @@ class ZipFileTest extends ZipTestCase
|
||||
|
||||
/**
|
||||
* @throws ZipException
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
public function testOpenFromStreamInvalidResourceType2()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Invalid resource type');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$exceptionMessage = PHP_VERSION_ID < 80000 ?
|
||||
'Invalid resource type' :
|
||||
'Stream must be a resource';
|
||||
$this->expectExceptionMessage($exceptionMessage);
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
|
||||
if (!\extension_loaded('gd')) {
|
||||
static::markTestSkipped('not extension gd');
|
||||
|
||||
return;
|
||||
}
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
$zipFile->openFromStream(imagecreate(1, 1));
|
||||
}
|
||||
|
||||
@ -190,7 +204,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFromStreamInvalidResourceType3()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Directory stream not supported');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Directory stream not supported');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->openFromStream(opendir(__DIR__));
|
||||
@ -203,7 +218,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFromStreamNoSeekable()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The stream wrapper type "http" is not supported');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The stream wrapper type "http" is not supported');
|
||||
|
||||
if (!$fp = @fopen('http://localhost', 'rb')) {
|
||||
if (!$fp = @fopen('http://example.org', 'rb')) {
|
||||
@ -222,7 +238,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFromStreamEmptyContents()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'Corrupt zip file');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('Corrupt zip file');
|
||||
|
||||
$fp = fopen($this->outputFilename, 'w+b');
|
||||
$zipFile = new ZipFile();
|
||||
@ -235,8 +252,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testOpenFromStreamInvalidZip()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipException::class,
|
||||
$this->expectException(
|
||||
ZipException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Invalid zip file. The end of the central directory could not be found.'
|
||||
);
|
||||
|
||||
@ -508,7 +527,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testRenameEntryNull()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'name is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('name is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->rename(null, 'new-file');
|
||||
@ -519,7 +539,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testRenameEntryNull2()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'name is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('name is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->rename('old-file', null);
|
||||
@ -530,7 +551,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testRenameEntryToExistsNewEntry()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'is exists');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('is exists');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile['file'] = 'content';
|
||||
@ -548,7 +570,7 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testRenameEntryNotFound()
|
||||
{
|
||||
$this->setExpectedException(ZipEntryNotFoundException::class);
|
||||
$this->expectException(ZipEntryNotFoundException::class);
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile['file'] = 'content';
|
||||
@ -615,7 +637,7 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testDeleteFromNameNotFoundEntry()
|
||||
{
|
||||
$this->setExpectedException(ZipEntryNotFoundException::class);
|
||||
$this->expectException(ZipEntryNotFoundException::class);
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->deleteFromName('entry');
|
||||
@ -674,7 +696,8 @@ class ZipFileTest extends ZipTestCase
|
||||
|
||||
public function testDeleteFromGlobFailNull()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The glob pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The glob pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->deleteFromGlob(null);
|
||||
@ -682,7 +705,8 @@ class ZipFileTest extends ZipTestCase
|
||||
|
||||
public function testDeleteFromGlobFailEmpty()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The glob pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The glob pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->deleteFromGlob('');
|
||||
@ -722,7 +746,8 @@ class ZipFileTest extends ZipTestCase
|
||||
|
||||
public function testDeleteFromRegexFailNull()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The regex pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The regex pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->deleteFromRegex(null);
|
||||
@ -730,7 +755,8 @@ class ZipFileTest extends ZipTestCase
|
||||
|
||||
public function testDeleteFromRegexFailEmpty()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The regex pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The regex pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->deleteFromRegex('');
|
||||
@ -806,10 +832,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testVeryLongArchiveComment()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class);
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
$comment = 'Very long comment' . \PHP_EOL .
|
||||
'Очень длинный комментарий' . \PHP_EOL;
|
||||
$comment = 'Very long comment' . \PHP_EOL
|
||||
. 'Очень длинный комментарий' . \PHP_EOL;
|
||||
$comment = str_repeat($comment, ceil(0xffff / \strlen($comment)) + \strlen($comment) + 1);
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
@ -873,7 +899,7 @@ class ZipFileTest extends ZipTestCase
|
||||
static::assertSame($zipFile->getEntryComment($entryName), (string) $entriesItem['comment']);
|
||||
}
|
||||
// modify comment
|
||||
$entries['file5.txt']['comment'] = mt_rand(1, 100000000);
|
||||
$entries['file5.txt']['comment'] = random_int(1, 100000000);
|
||||
$zipFile->setEntryComment('file5.txt', $entries['file5.txt']['comment']);
|
||||
$zipFile->saveAsFile($this->outputFilename);
|
||||
$zipFile->close();
|
||||
@ -898,10 +924,11 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testVeryLongEntryComment()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Comment too long');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Comment too long');
|
||||
|
||||
$comment = 'Very long comment' . \PHP_EOL .
|
||||
'Очень длинный комментарий' . \PHP_EOL;
|
||||
$comment = 'Very long comment' . \PHP_EOL
|
||||
. 'Очень длинный комментарий' . \PHP_EOL;
|
||||
$comment = str_repeat($comment, ceil(0xffff / \strlen($comment)) + \strlen($comment) + 1);
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
@ -914,7 +941,7 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testSetEntryCommentNotFoundEntry()
|
||||
{
|
||||
$this->setExpectedException(ZipEntryNotFoundException::class);
|
||||
$this->expectException(ZipEntryNotFoundException::class);
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->setEntryComment('test', 'comment');
|
||||
@ -979,8 +1006,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testSetInvalidCompressionLevel($compressionLevel)
|
||||
{
|
||||
$this->setExpectedException(
|
||||
InvalidArgumentException::class,
|
||||
$this->expectException(
|
||||
InvalidArgumentException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Invalid compression level. Minimum level 1. Maximum level 9'
|
||||
);
|
||||
|
||||
@ -1048,7 +1077,7 @@ class ZipFileTest extends ZipTestCase
|
||||
);
|
||||
|
||||
if ($contents === null) {
|
||||
static::assertTrue(is_dir($fullExtractedFilename));
|
||||
static::assertDirectoryExists($fullExtractedFilename);
|
||||
static::assertTrue(FilesUtil::isEmptyDir($fullExtractedFilename));
|
||||
} else {
|
||||
static::assertTrue(is_file($fullExtractedFilename));
|
||||
@ -1106,7 +1135,7 @@ class ZipFileTest extends ZipTestCase
|
||||
|
||||
if (\in_array($entryName, $extractEntries, true)) {
|
||||
if ($value === null) {
|
||||
static::assertTrue(is_dir($fullExtractFilename));
|
||||
static::assertDirectoryExists($fullExtractFilename);
|
||||
static::assertTrue(FilesUtil::isEmptyDir($fullExtractFilename));
|
||||
} else {
|
||||
static::assertTrue(is_file($fullExtractFilename));
|
||||
@ -1114,7 +1143,7 @@ class ZipFileTest extends ZipTestCase
|
||||
static::assertEquals($contents, $value);
|
||||
}
|
||||
} elseif ($value === null) {
|
||||
static::assertFalse(is_dir($fullExtractFilename));
|
||||
static::assertDirectoryDoesNotExist($fullExtractFilename);
|
||||
} else {
|
||||
static::assertFalse(is_file($fullExtractFilename));
|
||||
}
|
||||
@ -1131,7 +1160,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testExtractFail()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'not found');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('not found');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile['file'] = 'content';
|
||||
@ -1147,7 +1177,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testExtractFail2()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'Destination is not directory');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('Destination is not directory');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile['file'] = 'content';
|
||||
@ -1163,7 +1194,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testExtractFail3()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'Destination is not writable directory');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('Destination is not writable directory');
|
||||
|
||||
if (static::skipTestForRootUser()) {
|
||||
return;
|
||||
@ -1186,8 +1218,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFromArrayAccessNullName()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
InvalidArgumentException::class,
|
||||
$this->expectException(
|
||||
InvalidArgumentException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Key must not be null, but must contain the name of the zip entry.'
|
||||
);
|
||||
|
||||
@ -1200,8 +1234,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFromArrayAccessEmptyName()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
InvalidArgumentException::class,
|
||||
$this->expectException(
|
||||
InvalidArgumentException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Key is empty, but must contain the name of the zip entry.'
|
||||
);
|
||||
|
||||
@ -1214,7 +1250,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFromStringNullContents()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Contents is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Contents is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFromString('file', null);
|
||||
@ -1225,7 +1262,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFromStringNullEntryName()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Entry name is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Entry name is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFromString(null, 'contents');
|
||||
@ -1236,8 +1274,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFromStringUnsupportedMethod()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipUnsupportMethodException::class,
|
||||
$this->expectException(
|
||||
ZipUnsupportMethodException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Compression method 99 (AES Encryption) is not supported.'
|
||||
);
|
||||
|
||||
@ -1251,7 +1291,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFromStringEmptyEntryName()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Empty entry name');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Empty entry name');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFromString('', 'contents');
|
||||
@ -1292,7 +1333,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFromStreamInvalidResource()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Stream is not resource');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Stream is not resource');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
/** @noinspection PhpParamsInspection */
|
||||
@ -1304,7 +1346,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFromStreamEmptyEntryName()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Empty entry name');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Empty entry name');
|
||||
|
||||
$handle = fopen(__FILE__, 'rb');
|
||||
|
||||
@ -1317,8 +1360,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFromStreamUnsupportedMethod()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipUnsupportMethodException::class,
|
||||
$this->expectException(
|
||||
ZipUnsupportMethodException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Compression method 99 (AES Encryption) is not supported.'
|
||||
);
|
||||
|
||||
@ -1367,7 +1412,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFileNullFileName()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Filename is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Filename is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFile(null);
|
||||
@ -1378,7 +1424,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFileCantExists()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'File path/to/file is not readable');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('File path/to/file is not readable');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFile('path/to/file');
|
||||
@ -1389,8 +1436,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFileUnsupportedMethod()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipUnsupportMethodException::class,
|
||||
$this->expectException(
|
||||
ZipUnsupportMethodException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Compression method 99 (AES Encryption) is not supported.'
|
||||
);
|
||||
|
||||
@ -1412,7 +1461,8 @@ class ZipFileTest extends ZipTestCase
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'is not readable');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('is not readable');
|
||||
|
||||
static::assertNotFalse(file_put_contents($this->outputFilename, ''));
|
||||
static::assertTrue(chmod($this->outputFilename, 0244));
|
||||
@ -1426,7 +1476,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddDirNullDirname()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Input dir is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Input dir is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addDir(null);
|
||||
@ -1437,7 +1488,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddDirEmptyDirname()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The input directory is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The input directory is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addDir('');
|
||||
@ -1448,7 +1500,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddDirCantExists()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'does not exist');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('does not exist');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addDir(uniqid('', false));
|
||||
@ -1459,7 +1512,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddDirRecursiveNullDirname()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Input dir is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Input dir is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addDirRecursive(null);
|
||||
@ -1470,7 +1524,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddDirRecursiveEmptyDirname()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The input directory is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The input directory is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addDirRecursive('');
|
||||
@ -1481,7 +1536,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddDirRecursiveCantExists()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'does not exist');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('does not exist');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addDirRecursive(uniqid('', false));
|
||||
@ -1492,7 +1548,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobNull()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Input dir is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Input dir is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlob(null, '*.png');
|
||||
@ -1503,7 +1560,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobEmpty()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The input directory is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The input directory is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlob('', '*.png');
|
||||
@ -1514,7 +1572,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobCantExists()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'does not exist');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('does not exist');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlob('path/to/path', '*.png');
|
||||
@ -1525,7 +1584,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobNullPattern()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The glob pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The glob pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlob(__DIR__, null);
|
||||
@ -1536,7 +1596,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobEmptyPattern()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The glob pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The glob pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlob(__DIR__, '');
|
||||
@ -1547,7 +1608,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobRecursiveNull()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Input dir is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Input dir is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlobRecursive(null, '*.png');
|
||||
@ -1558,7 +1620,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobRecursiveEmpty()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The input directory is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The input directory is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlobRecursive('', '*.png');
|
||||
@ -1569,7 +1632,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobRecursiveCantExists()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'does not exist');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('does not exist');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlobRecursive('path/to/path', '*.png');
|
||||
@ -1580,7 +1644,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobRecursiveNullPattern()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The glob pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The glob pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlobRecursive(__DIR__, null);
|
||||
@ -1591,7 +1656,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromGlobRecursiveEmptyPattern()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The glob pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The glob pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlobRecursive(__DIR__, '');
|
||||
@ -1602,7 +1668,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexDirectoryNull()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The input directory is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The input directory is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromRegex(null, '~\.png$~i');
|
||||
@ -1613,7 +1680,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexDirectoryEmpty()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The input directory is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The input directory is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromRegex('', '~\.png$~i');
|
||||
@ -1624,7 +1692,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexCantExists()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'does not exist');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('does not exist');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromRegex('path/to/path', '~\.png$~i');
|
||||
@ -1635,7 +1704,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexNullPattern()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The regex pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The regex pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromRegex(__DIR__, null);
|
||||
@ -1646,7 +1716,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexEmptyPattern()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The regex pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The regex pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromRegex(__DIR__, '');
|
||||
@ -1657,7 +1728,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexRecursiveDirectoryNull()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The input directory is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The input directory is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromRegexRecursive(null, '~\.png$~i');
|
||||
@ -1668,7 +1740,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexRecursiveEmpty()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The input directory is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The input directory is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromRegexRecursive('', '~\.png$~i');
|
||||
@ -1679,7 +1752,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexRecursiveCantExists()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'does not exist');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('does not exist');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromGlobRecursive('path/to/path', '~\.png$~i');
|
||||
@ -1690,7 +1764,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexRecursiveNullPattern()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The regex pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The regex pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromRegexRecursive(__DIR__, null);
|
||||
@ -1701,7 +1776,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddFilesFromRegexRecursiveEmptyPattern()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'The regex pattern is not specified');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('The regex pattern is not specified');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFilesFromRegexRecursive(__DIR__, '');
|
||||
@ -1712,7 +1788,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testSaveAsStreamBadStream()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'handle is not resource');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('handle is not resource');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
/** @noinspection PhpParamsInspection */
|
||||
@ -1737,7 +1814,8 @@ class ZipFileTest extends ZipTestCase
|
||||
|
||||
$this->outputFilename = $this->outputDirname . \DIRECTORY_SEPARATOR . basename($this->outputFilename);
|
||||
|
||||
$this->setExpectedExceptionRegExp(InvalidArgumentException::class, '~Cannot open ".*?" for writing.~');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessageMatches('~Cannot open ".*?" for writing.~');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->saveAsFile($this->outputFilename);
|
||||
@ -1752,7 +1830,7 @@ class ZipFileTest extends ZipTestCase
|
||||
public function testZipFileArrayAccessAndCountableAndIterator()
|
||||
{
|
||||
$files = [];
|
||||
$numFiles = mt_rand(20, 100);
|
||||
$numFiles = random_int(20, 100);
|
||||
for ($i = 0; $i < $numFiles; $i++) {
|
||||
$files['file' . $i . '.txt'] = random_bytes(255);
|
||||
}
|
||||
@ -1894,7 +1972,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddEmptyDirNullName()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Entry name is null');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Entry name is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addEmptyDir(null);
|
||||
@ -1905,7 +1984,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testAddEmptyDirEmptyName()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Empty entry name');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Empty entry name');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addEmptyDir('');
|
||||
@ -1913,7 +1993,8 @@ class ZipFileTest extends ZipTestCase
|
||||
|
||||
public function testNotFoundEntry()
|
||||
{
|
||||
$this->setExpectedException(ZipEntryNotFoundException::class, '"bad entry name"');
|
||||
$this->expectException(ZipEntryNotFoundException::class);
|
||||
$this->expectExceptionMessage('"bad entry name"');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile['bad entry name'];
|
||||
@ -1960,7 +2041,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testRewriteString()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'Overwrite is only supported for open local files');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('Overwrite is only supported for open local files');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile['file'] = 'content';
|
||||
@ -1986,7 +2068,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testRewriteNullStream()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'input stream is null');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('input stream is null');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->rewrite();
|
||||
@ -2177,7 +2260,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testInvalidCompressionLevel()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Invalid compression level');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Invalid compression level');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFromString('file', 'content');
|
||||
@ -2189,7 +2273,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testInvalidCompressionLevelEntry()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Invalid compression level');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Invalid compression level');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFromString('file', 'content');
|
||||
@ -2249,8 +2334,10 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testInvalidCompressionMethodEntry()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipUnsupportMethodException::class,
|
||||
$this->expectException(
|
||||
ZipUnsupportMethodException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Compression method 99 (AES Encryption) is not supported.'
|
||||
);
|
||||
|
||||
@ -2428,7 +2515,7 @@ class ZipFileTest extends ZipTestCase
|
||||
{
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$fp = $zipFile->getEntryStream($entryName);
|
||||
static::assertInternalType('resource', $fp);
|
||||
static::assertIsResource($fp);
|
||||
static::assertSame(stream_get_contents($fp), $contents);
|
||||
fclose($fp);
|
||||
}
|
||||
@ -2566,7 +2653,8 @@ class ZipFileTest extends ZipTestCase
|
||||
*/
|
||||
public function testNoData()
|
||||
{
|
||||
$this->setExpectedException(ZipException::class, 'No data for zip entry file');
|
||||
$this->expectException(ZipException::class);
|
||||
$this->expectExceptionMessage('No data for zip entry file');
|
||||
|
||||
$entryName = 'file';
|
||||
|
||||
|
@ -54,8 +54,10 @@ final class ZipInfoTest extends ZipTestCase
|
||||
*/
|
||||
public function testZipInfoEntryNotFound()
|
||||
{
|
||||
$this->setExpectedException(
|
||||
ZipEntryNotFoundException::class,
|
||||
$this->expectException(
|
||||
ZipEntryNotFoundException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Zip Entry "unknown.name" was not found in the archive.'
|
||||
);
|
||||
|
||||
|
@ -24,7 +24,7 @@ class ZipMatcherTest extends TestCase
|
||||
$matcher = $zipFile->matcher();
|
||||
static::assertInstanceOf(ZipEntryMatcher::class, $matcher);
|
||||
|
||||
static::assertInternalType('array', $matcher->getMatches());
|
||||
static::assertIsArray($matcher->getMatches());
|
||||
static::assertCount(0, $matcher);
|
||||
|
||||
$matcher->add(1)->add(10)->add(20);
|
||||
|
@ -31,10 +31,8 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
public function testSetPassword()
|
||||
{
|
||||
if (\PHP_INT_SIZE === 4) { // php 32 bit
|
||||
$this->setExpectedException(
|
||||
RuntimeException::class,
|
||||
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
|
||||
);
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('Traditional PKWARE Encryption is not supported in 32-bit PHP.');
|
||||
}
|
||||
|
||||
$password = base64_encode(random_bytes(100));
|
||||
@ -66,10 +64,10 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
|
||||
foreach ($zipFile->getAllInfo() as $info) {
|
||||
static::assertTrue($info->isEncrypted());
|
||||
static::assertContains('Traditional PKWARE encryption', $info->getEncryptionMethodName());
|
||||
static::assertStringContainsString('Traditional PKWARE encryption', $info->getEncryptionMethodName());
|
||||
$decryptContent = $zipFile[$info->getName()];
|
||||
static::assertNotEmpty($decryptContent);
|
||||
static::assertContains('<?php', $decryptContent);
|
||||
static::assertStringContainsString('<?php', $decryptContent);
|
||||
}
|
||||
|
||||
// change encryption method to WinZip Aes and update file
|
||||
@ -100,11 +98,11 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
|
||||
foreach ($zipFile->getAllInfo() as $info) {
|
||||
static::assertTrue($info->isEncrypted());
|
||||
static::assertContains('Deflated', $info->getMethodName());
|
||||
static::assertContains('WinZip AES-256', $info->getEncryptionMethodName());
|
||||
static::assertStringContainsString('Deflated', $info->getMethodName());
|
||||
static::assertStringContainsString('WinZip AES-256', $info->getEncryptionMethodName());
|
||||
$decryptContent = $zipFile[$info->getName()];
|
||||
static::assertNotEmpty($decryptContent);
|
||||
static::assertContains('<?php', $decryptContent);
|
||||
static::assertStringContainsString('<?php', $decryptContent);
|
||||
}
|
||||
|
||||
// clear password
|
||||
@ -132,8 +130,10 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
public function testTraditionalEncryption()
|
||||
{
|
||||
if (\PHP_INT_SIZE === 4) { // php 32 bit
|
||||
$this->setExpectedException(
|
||||
RuntimeException::class,
|
||||
$this->expectException(
|
||||
RuntimeException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
|
||||
);
|
||||
}
|
||||
@ -155,7 +155,7 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
foreach ($zip->getAllInfo() as $info) {
|
||||
if (!$info->isFolder()) {
|
||||
static::assertTrue($info->isEncrypted());
|
||||
static::assertContains('Traditional PKWARE encryption', $info->getEncryptionMethodName());
|
||||
static::assertStringContainsString('Traditional PKWARE encryption', $info->getEncryptionMethodName());
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
@ -190,7 +190,7 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
if (!$info->isFolder()) {
|
||||
static::assertTrue($info->isEncrypted());
|
||||
static::assertSame($info->getEncryptionMethod(), $encryptionMethod);
|
||||
static::assertContains('WinZip AES-' . $bitSize, $info->getEncryptionMethodName());
|
||||
static::assertStringContainsString('WinZip AES-' . $bitSize, $info->getEncryptionMethodName());
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
@ -215,8 +215,10 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
public function testEncryptionEntries()
|
||||
{
|
||||
if (\PHP_INT_SIZE === 4) { // php 32 bit
|
||||
$this->setExpectedException(
|
||||
RuntimeException::class,
|
||||
$this->expectException(
|
||||
RuntimeException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
|
||||
);
|
||||
}
|
||||
@ -247,11 +249,11 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
|
||||
$info = $zip->getEntryInfo('.hidden');
|
||||
static::assertTrue($info->isEncrypted());
|
||||
static::assertContains('Traditional PKWARE encryption', $info->getEncryptionMethodName());
|
||||
static::assertStringContainsString('Traditional PKWARE encryption', $info->getEncryptionMethodName());
|
||||
|
||||
$info = $zip->getEntryInfo('text file.txt');
|
||||
static::assertTrue($info->isEncrypted());
|
||||
static::assertContains('WinZip AES', $info->getEncryptionMethodName());
|
||||
static::assertStringContainsString('WinZip AES', $info->getEncryptionMethodName());
|
||||
|
||||
static::assertFalse($zip->getEntryInfo('Текстовый документ.txt')->isEncrypted());
|
||||
static::assertFalse($zip->getEntryInfo('empty dir/')->isEncrypted());
|
||||
@ -266,8 +268,10 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
public function testEncryptionEntriesWithDefaultPassword()
|
||||
{
|
||||
if (\PHP_INT_SIZE === 4) { // php 32 bit
|
||||
$this->setExpectedException(
|
||||
RuntimeException::class,
|
||||
$this->expectException(
|
||||
RuntimeException::class
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
'Traditional PKWARE Encryption is not supported in 32-bit PHP.'
|
||||
);
|
||||
}
|
||||
@ -301,15 +305,15 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
|
||||
$info = $zip->getEntryInfo('.hidden');
|
||||
static::assertTrue($info->isEncrypted());
|
||||
static::assertContains('Traditional PKWARE encryption', $info->getEncryptionMethodName());
|
||||
static::assertStringContainsString('Traditional PKWARE encryption', $info->getEncryptionMethodName());
|
||||
|
||||
$info = $zip->getEntryInfo('text file.txt');
|
||||
static::assertTrue($info->isEncrypted());
|
||||
static::assertContains('WinZip AES', $info->getEncryptionMethodName());
|
||||
static::assertStringContainsString('WinZip AES', $info->getEncryptionMethodName());
|
||||
|
||||
$info = $zip->getEntryInfo('Текстовый документ.txt');
|
||||
static::assertTrue($info->isEncrypted());
|
||||
static::assertContains('WinZip AES', $info->getEncryptionMethodName());
|
||||
static::assertStringContainsString('WinZip AES', $info->getEncryptionMethodName());
|
||||
|
||||
static::assertFalse($zip->getEntryInfo('empty dir/')->isEncrypted());
|
||||
|
||||
@ -321,7 +325,8 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
*/
|
||||
public function testSetEncryptionMethodInvalid()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Encryption method 9999 is not supported.');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Encryption method 9999 is not supported.');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$encryptionMethod = 9999;
|
||||
@ -369,7 +374,8 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
*/
|
||||
public function testInvalidEncryptionMethodEntry()
|
||||
{
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'Encryption method 99 is not supported.');
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Encryption method 99 is not supported.');
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->addFromString('file', 'content', ZipCompressionMethod::STORED);
|
||||
@ -471,7 +477,7 @@ class ZipPasswordTest extends ZipFileSetTestCase
|
||||
foreach ($zipFile as $name => $contents) {
|
||||
static::assertNotEmpty($name);
|
||||
static::assertNotEmpty($contents);
|
||||
static::assertContains('test contents', $contents);
|
||||
static::assertStringContainsString('test contents', $contents);
|
||||
static::assertSame($zipFile2[$name], $contents);
|
||||
}
|
||||
$zipFile2->close();
|
||||
|
@ -31,18 +31,18 @@ class ZipStreamOpenTest extends TestCase
|
||||
{
|
||||
if ($resource === null || $resource === false) {
|
||||
static::markTestSkipped('skip resource');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($exceptionClass !== null) {
|
||||
$this->setExpectedException(
|
||||
$exceptionClass,
|
||||
$this->expectException(
|
||||
$exceptionClass
|
||||
);
|
||||
$this->expectExceptionMessage(
|
||||
$exceptionMessage
|
||||
);
|
||||
}
|
||||
|
||||
static::assertInternalType('resource', $resource);
|
||||
static::assertIsResource($resource);
|
||||
|
||||
$zipFile = new ZipFile();
|
||||
$zipFile->openFromStream($resource);
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
namespace PhpZip\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PhpZip\Constants\ZipConstants;
|
||||
use PhpZip\Tests\Polyfill\LegacyTestCase;
|
||||
use PhpZip\Util\FilesUtil;
|
||||
|
||||
/**
|
||||
* PHPUnit test case and helper methods.
|
||||
*/
|
||||
abstract class ZipTestCase extends TestCase
|
||||
abstract class ZipTestCase extends LegacyTestCase
|
||||
{
|
||||
/** @var string */
|
||||
protected $outputFilename;
|
||||
@ -22,7 +22,7 @@ abstract class ZipTestCase extends TestCase
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
protected function setUp()
|
||||
protected function setUp(): void
|
||||
{
|
||||
$id = uniqid('phpzip', false);
|
||||
$tempDir = sys_get_temp_dir() . \DIRECTORY_SEPARATOR . 'phpunit-phpzip';
|
||||
@ -37,10 +37,8 @@ abstract class ZipTestCase extends TestCase
|
||||
/**
|
||||
* After test.
|
||||
*/
|
||||
protected function tearDown()
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
if ($this->outputFilename !== null && file_exists($this->outputFilename)) {
|
||||
unlink($this->outputFilename);
|
||||
}
|
||||
@ -92,8 +90,8 @@ abstract class ZipTestCase extends TestCase
|
||||
$output = implode(\PHP_EOL, $output);
|
||||
|
||||
static::assertSame($returnCode, 0);
|
||||
static::assertNotContains(' Errors', $output);
|
||||
static::assertContains(' Ok', $output);
|
||||
static::assertStringNotContainsString(' Errors', $output);
|
||||
static::assertStringContainsString(' Ok', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,8 +121,8 @@ abstract class ZipTestCase extends TestCase
|
||||
|
||||
static::assertSame($returnCode, 0, $output);
|
||||
static::assertNotContains('incorrect password', $output);
|
||||
static::assertContains(' OK', $output);
|
||||
static::assertContains('No errors', $output);
|
||||
static::assertStringContainsString(' OK', $output);
|
||||
static::assertStringContainsString('No errors', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,9 +133,9 @@ abstract class ZipTestCase extends TestCase
|
||||
*/
|
||||
protected static function existsProgram($program, array $successCodes = [0])
|
||||
{
|
||||
$command = \DIRECTORY_SEPARATOR === '\\' ?
|
||||
escapeshellarg($program) :
|
||||
'which ' . escapeshellarg($program);
|
||||
$command = \DIRECTORY_SEPARATOR === '\\'
|
||||
? escapeshellarg($program)
|
||||
: 'which ' . escapeshellarg($program);
|
||||
$command .= ' 2>&1';
|
||||
|
||||
exec($command, $output, $returnCode);
|
||||
@ -157,7 +155,7 @@ abstract class ZipTestCase extends TestCase
|
||||
|
||||
$output = implode(\PHP_EOL, $output);
|
||||
|
||||
static::assertContains('Empty zipfile', $output);
|
||||
static::assertStringContainsString('Empty zipfile', $output);
|
||||
}
|
||||
$actualEmptyZipData = pack('VVVVVv', ZipConstants::END_CD, 0, 0, 0, 0, 0);
|
||||
static::assertStringEqualsFile($filename, $actualEmptyZipData);
|
||||
@ -189,7 +187,7 @@ abstract class ZipTestCase extends TestCase
|
||||
fwrite(\STDERR, 'Install on Windows:' . \PHP_EOL);
|
||||
fwrite(\STDERR, ' 1. Install Android Studio' . \PHP_EOL);
|
||||
fwrite(\STDERR, ' 2. Install Android Sdk' . \PHP_EOL);
|
||||
fwrite(\STDERR, ' 3. Add zipalign path to \$Path' . \PHP_EOL);
|
||||
fwrite(\STDERR, ' 3. Add zipalign path to $Path' . \PHP_EOL);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user