From d7ad1d603f9c7814d701611c9b1669a2468e2b02 Mon Sep 17 00:00:00 2001 From: Sascha Greuel Date: Tue, 10 Oct 2023 16:47:17 +0200 Subject: [PATCH] Implemented DSN Connection Strings Support This PR introduces support for DSN connection strings to simplify the configuration process. Users can now use a single string to determine the type of connection (`Network` or `Pipe`) and its details. This PR resolves #28, closes #25, resolves #26, closes #27, closes #31 1. Added a static `createFromDSN` method to the `ClamAV` abstract class. This method parses the provided DSN string and returns an appropriate instance (`Network` or `Pipe`). 2. Updated the `ClamAVTest` unit test to cover the new DSN creation functionality. 3. Updated composer dependencies 4. Applied smaller code, and documentation optimizations 5. Improved code coverage 6. Updated README Users can now initialize a connection using a DSN string: ```php $clam = ClamAV::createFromDSN('tcp://localhost:3310'); $version = $clam->version(); ``` This approach provides a more flexible and user-friendly way to set up a connection. The existing unit tests have been updated accordingly. --- .php-cs-fixer.dist.php | 122 +++++++ .travis.yml | 3 +- README.md | 7 +- composer.json | 2 +- composer.lock | 621 +++++++++++++++--------------------- docker-compose.yml | 1 - phpunit.xml | 34 +- src/ClamAV/ClamAV.php | 50 +-- src/ClamAV/Network.php | 18 +- src/ClamAV/Pipe.php | 12 +- tests/ClamAV/ClamAVTest.php | 126 +++++++- 11 files changed, 553 insertions(+), 443 deletions(-) create mode 100644 .php-cs-fixer.dist.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..1dca607 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,122 @@ +exclude('*/vendor/*') + ->exclude('node_modules') + ->in(__DIR__) + ->notPath('lib/system/api'); + +return (new PhpCsFixer\Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@PSR1' => true, + '@PSR2' => true, + '@PSR12' => true, + '@PER' => true, + + 'array_push' => true, + 'backtick_to_shell_exec' => true, + 'no_alias_language_construct_call' => true, + 'no_mixed_echo_print' => true, + 'pow_to_exponentiation' => true, + 'random_api_migration' => true, + + 'array_syntax' => ['syntax' => 'short'], + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_whitespace_before_comma_in_array' => true, + 'normalize_index_brace' => true, + 'whitespace_after_comma_in_array' => true, + + 'non_printable_character' => ['use_escape_sequences_in_strings' => true], + + 'magic_constant_casing' => true, + 'magic_method_casing' => true, + 'native_function_casing' => true, + 'native_function_type_declaration_casing' => true, + + 'cast_spaces' => ['space' => 'none'], + 'no_unset_cast' => true, + + 'class_attributes_separation' => true, + 'no_null_property_initialization' => true, + 'self_accessor' => true, + 'single_class_element_per_statement' => true, + + 'no_empty_comment' => true, + 'single_line_comment_style' => ['comment_types' => ['hash']], + + 'native_constant_invocation' => ['strict' => false], + + 'no_alternative_syntax' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_unneeded_control_parentheses' => ['statements' => ['break', 'clone', 'continue', 'echo_print', 'return', 'switch_case', 'yield', 'yield_from']], + 'no_unneeded_curly_braces' => ['namespaces' => true], + 'switch_continue_to_break' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + + 'function_typehint_space' => true, + 'lambda_not_used_import' => true, + 'native_function_invocation' => ['include' => ['@internal']], + 'no_unreachable_default_argument_value' => true, + 'nullable_type_declaration_for_default_null_value' => true, + 'static_lambda' => true, + + 'fully_qualified_strict_types' => true, + 'no_unused_imports' => true, + + 'dir_constant' => true, + 'explicit_indirect_variable' => true, + 'function_to_constant' => true, + 'is_null' => true, + 'no_unset_on_property' => true, + + 'list_syntax' => ['syntax' => 'short'], + + 'clean_namespace' => true, + 'no_leading_namespace_whitespace' => true, + + 'no_homoglyph_names' => true, + + 'binary_operator_spaces' => true, + 'concat_space' => ['spacing' => 'one'], + 'increment_style' => ['style' => 'post'], + 'logical_operators' => true, + 'object_operator_without_whitespace' => true, + 'operator_linebreak' => true, + 'standardize_increment' => true, + 'standardize_not_equals' => true, + 'ternary_to_elvis_operator' => true, + 'ternary_to_null_coalescing' => true, + 'unary_operator_spaces' => true, + + 'no_useless_return' => true, + 'return_assignment' => true, + + 'multiline_whitespace_before_semicolons' => true, + 'no_empty_statement' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'space_after_semicolon' => ['remove_in_empty_for_expressions' => true], + + 'escape_implicit_backslashes' => true, + 'explicit_string_variable' => true, + 'heredoc_to_nowdoc' => true, + 'no_binary_string' => true, + 'simple_to_complex_string_variable' => true, + + 'array_indentation' => true, + 'blank_line_before_statement' => ['statements' => ['return', 'exit']], + 'method_chaining_indentation' => true, + 'no_extra_blank_lines' => ['tokens' => ['case', 'continue', 'curly_brace_block', 'default', 'extra', 'parenthesis_brace_block', 'square_brace_block', 'switch', 'throw', 'use']], + 'no_spaces_around_offset' => true, + + // SoftCreatR style + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => true, + 'import_functions' => false, + ], + 'ordered_imports' => [ + 'imports_order' => ['class', 'function', 'const'], + ], + ]) + ->setFinder($finder); diff --git a/.travis.yml b/.travis.yml index c0496fc..a26d638 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,8 @@ -dist: focal +dist: jammy language: php php: -- 8.0 - 8.1 notifications: diff --git a/README.md b/README.md index fa3dc3e..a2fa417 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,15 @@ Install using composer: composer require appwrite/php-clamav ``` +Example usage: ```php ping(); // Check ClamAV is up and running @@ -36,7 +37,7 @@ $clam->shutdown(); // Shutdown ClamAV ## System Requirements -This package requires PHP 7.1 or later. We recommend using the latest PHP version whenever possible. +This package requires PHP 8.1 or later. We recommend using the latest PHP version whenever possible. ## Find Us diff --git a/composer.json b/composer.json index 0ddc25a..6d69817 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ "ext-sockets": "*" }, "require-dev": { - "phpunit/phpunit": "^9" + "phpunit/phpunit": ">=9" }, "minimum-stability": "stable" } diff --git a/composer.lock b/composer.lock index 179ad12..68e69e2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,91 +4,21 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fa520ce5ec18c933888bcf33ec560427", + "content-hash": "2fd328c82d2edc1a0a21c232694dae18", "packages": [], "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -126,7 +56,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { @@ -134,20 +64,20 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "nikic/php-parser", - "version": "v4.15.1", + "version": "v4.17.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", "shasum": "" }, "require": { @@ -188,9 +118,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2023-08-13T19:53:39+00:00" }, { "name": "phar-io/manifest", @@ -305,44 +235,44 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.17", + "version": "10.1.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + "reference": "355324ca4980b8916c18b9db29f3ef484078f26e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/355324ca4980b8916c18b9db29f3ef484078f26e", + "reference": "355324ca4980b8916c18b9db29f3ef484078f26e", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", + "nikic/php-parser": "^4.15", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", "theseer/tokenizer": "^1.2.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.1" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "10.1-dev" } }, "autoload": { @@ -370,7 +300,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.7" }, "funding": [ { @@ -378,32 +309,32 @@ "type": "github" } ], - "time": "2022-08-30T12:24:04+00:00" + "time": "2023-10-04T15:34:17+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -430,7 +361,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" }, "funding": [ { @@ -438,28 +370,28 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2023-08-31T06:24:48+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-pcntl": "*" @@ -467,7 +399,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -493,7 +425,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" }, "funding": [ { @@ -501,32 +433,32 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2023-02-03T06:56:09+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -552,7 +484,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" }, "funding": [ { @@ -560,32 +493,32 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2023-08-31T14:07:24+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.3", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -611,7 +544,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" }, "funding": [ { @@ -619,24 +552,23 @@ "type": "github" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2023-02-03T06:57:52+00:00" }, { "name": "phpunit/phpunit", - "version": "9.5.25", + "version": "10.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d" + "reference": "62bd7af13d282deeb95650077d28ba3600ca321c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", - "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/62bd7af13d282deeb95650077d28ba3600ca321c", + "reference": "62bd7af13d282deeb95650077d28ba3600ca321c", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -646,27 +578,26 @@ "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.13", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.5", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.2", - "sebastian/version": "^3.0.2" + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.5", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.1", + "sebastian/global-state": "^6.0.1", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -674,7 +605,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-main": "10.4-dev" } }, "autoload": { @@ -705,7 +636,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.25" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.4.1" }, "funding": [ { @@ -721,32 +653,32 @@ "type": "tidelift" } ], - "time": "2022-09-25T03:44:45+00:00" + "time": "2023-10-08T05:01:11+00:00" }, { "name": "sebastian/cli-parser", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -769,7 +701,7 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" }, "funding": [ { @@ -777,32 +709,32 @@ "type": "github" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2023-02-03T06:58:15+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -825,7 +757,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" }, "funding": [ { @@ -833,32 +765,32 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2023-02-03T06:58:43+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -880,7 +812,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" }, "funding": [ { @@ -888,34 +820,36 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2023-02-03T06:59:15+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -954,7 +888,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" }, "funding": [ { @@ -962,33 +897,33 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2023-08-14T13:18:12+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957", + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" + "nikic/php-parser": "^4.10", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.1-dev" } }, "autoload": { @@ -1011,7 +946,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.1.0" }, "funding": [ { @@ -1019,33 +955,33 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-09-28T11:50:59+00:00" }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3", + "phpunit/phpunit": "^10.0", "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1077,7 +1013,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" }, "funding": [ { @@ -1085,27 +1022,27 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2023-05-01T07:48:21+00:00" }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-posix": "*" @@ -1113,7 +1050,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1132,7 +1069,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -1140,7 +1077,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" }, "funding": [ { @@ -1148,34 +1086,34 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-04-11T05:39:26+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.5", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1217,7 +1155,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1" }, "funding": [ { @@ -1225,38 +1164,35 @@ "type": "github" } ], - "time": "2022-09-14T06:03:37+00:00" + "time": "2023-09-24T13:22:09+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.5", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1281,7 +1217,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" }, "funding": [ { @@ -1289,33 +1226,33 @@ "type": "github" } ], - "time": "2022-02-14T08:28:10+00:00" + "time": "2023-07-19T07:19:23+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" + "nikic/php-parser": "^4.10", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -1338,7 +1275,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1" }, "funding": [ { @@ -1346,34 +1284,34 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-08-31T09:25:50+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1395,7 +1333,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" }, "funding": [ { @@ -1403,32 +1341,32 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2023-02-03T07:08:32+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1450,7 +1388,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" }, "funding": [ { @@ -1458,32 +1396,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2023-02-03T07:06:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1510,65 +1448,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" }, "funding": [ { @@ -1576,32 +1459,32 @@ "type": "github" } ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2023-02-03T07:05:40+00:00" }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1624,7 +1507,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { @@ -1632,29 +1515,29 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { "name": "sebastian/version", - "version": "3.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1677,7 +1560,7 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { @@ -1685,7 +1568,7 @@ "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { "name": "theseer/tokenizer", diff --git a/docker-compose.yml b/docker-compose.yml index 24a3b5b..1519395 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ ---- version: '3.7' services: diff --git a/phpunit.xml b/phpunit.xml index 3d8f92b..955055e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,13 +1,23 @@ - - - - - ./src/ - - - - - ./tests/ - - + + + + + tests + + + + + + src + + diff --git a/src/ClamAV/ClamAV.php b/src/ClamAV/ClamAV.php index 83630ac..d23dd00 100644 --- a/src/ClamAV/ClamAV.php +++ b/src/ClamAV/ClamAV.php @@ -11,6 +11,9 @@ namespace Appwrite\ClamAV; +use InvalidArgumentException; +use Socket; + abstract class ClamAV { /** @@ -19,15 +22,30 @@ abstract class ClamAV public const CLAMAV_MAX = 20000; /** - * @return resource + * Create a new connection based on the DSN string. + */ + public static function createFromDSN(string $dsn): Pipe|Network + { + if (\str_starts_with($dsn, 'unix://')) { + return new Pipe(\substr($dsn, 7)); + } + + if (\str_starts_with($dsn, 'tcp://')) { + [$host, $port] = \explode(':', \substr($dsn, 6)); + + return new Network($host, (int)$port); + } + + throw new InvalidArgumentException("Unsupported scheme in DSN"); + } + + /** + * Returns a remote socket. */ - abstract protected function getSocket(); + abstract protected function getSocket(): Socket; /** * Send a given command to ClamAV. - * - * @param string $command - * @return string|null */ private function sendCommand(string $command): ?string { @@ -44,8 +62,6 @@ private function sendCommand(string $command): ?string /** * Check if ClamAV is up and responsive. - * - * @return bool */ public function ping(): bool { @@ -56,8 +72,6 @@ public function ping(): bool /** * Check ClamAV Version. - * - * @return string */ public function version(): string { @@ -66,8 +80,6 @@ public function version(): string /** * Reload ClamAV virus databases. - * - * @return string|null */ public function reload(): ?string { @@ -76,8 +88,6 @@ public function reload(): ?string /** * Shutdown ClamAV and preform a clean exit. - * - * @return string|null */ public function shutdown(): ?string { @@ -89,9 +99,6 @@ public function shutdown(): ?string * enabled (if not disabled in clamd.conf). A full path is required. * * Returns whether the given file/directory is clean (true), or not (false). - * - * @param string $file - * @return bool */ public function fileScanInStream(string $file): bool { @@ -105,6 +112,11 @@ public function fileScanInStream(string $file): bool while (!\feof($handle)) { $data = \fread($handle, $chunkSize); + + if ($data === "") { + continue; + } + $packet = \pack(\sprintf("Na%d", $chunkSize), $chunkSize, $data); \socket_send($socket, $packet, $chunkSize + 4, 0); } @@ -124,9 +136,6 @@ public function fileScanInStream(string $file): bool * enabled (if not disabled in clamd.conf). A full path is required. * * Returns whether the given file/directory is clean (true), or not (false). - * - * @param string $file - * @return bool */ public function fileScan(string $file): bool { @@ -141,9 +150,6 @@ public function fileScan(string $file): bool /** * Scan file or directory (recursively) with archive support * enabled, and don't stop the scanning when a virus is found. - * - * @param string $file - * @return array */ public function continueScan(string $file): array { diff --git a/src/ClamAV/Network.php b/src/ClamAV/Network.php index 268546d..6040c24 100644 --- a/src/ClamAV/Network.php +++ b/src/ClamAV/Network.php @@ -13,6 +13,7 @@ use RuntimeException; use Socket; + use const AF_INET; use const SOCK_STREAM; @@ -21,30 +22,21 @@ class Network extends ClamAV /** * @var string */ - private const CLAMAV_HOST = '127.0.0.1'; + public const CLAMAV_HOST = '127.0.0.1'; /** * @var int */ - private const CLAMAV_PORT = 3310; + public const CLAMAV_PORT = 3310; - /** - * @var string - */ private string $host; - /** - * @var int - */ private int $port; /** * Network constructor * * You need to pass the host address and the port the server. - * - * @param string $host - * @param int $port */ public function __construct(string $host = self::CLAMAV_HOST, int $port = self::CLAMAV_PORT) { @@ -53,9 +45,7 @@ public function __construct(string $host = self::CLAMAV_HOST, int $port = self:: } /** - * Returns a remote socket. - * - * @return Socket + * @inheritDoc */ protected function getSocket(): Socket { diff --git a/src/ClamAV/Pipe.php b/src/ClamAV/Pipe.php index 2507d67..c517333 100644 --- a/src/ClamAV/Pipe.php +++ b/src/ClamAV/Pipe.php @@ -12,6 +12,7 @@ namespace Appwrite\ClamAV; use Socket; + use const AF_UNIX; use const SOCK_STREAM; @@ -20,11 +21,8 @@ class Pipe extends ClamAV /** * @var string */ - private const CLAMAV_HOST = '/run/clamav/clamd.sock'; + public const CLAMAV_SOCK = '/run/clamav/clamd.sock'; - /** - * @var string - */ private string $pip; /** @@ -32,18 +30,14 @@ class Pipe extends ClamAV * * This class can be used to connect to local socket. * You need to pass the path to the socket pipe. - * - * @param string $pip */ - public function __construct(string $pip = self::CLAMAV_HOST) + public function __construct(string $pip = self::CLAMAV_SOCK) { $this->pip = $pip; } /** * Returns a local socket. - * - * @return Socket */ protected function getSocket(): Socket { diff --git a/tests/ClamAV/ClamAVTest.php b/tests/ClamAV/ClamAVTest.php index 3f68ce8..4e0bcf5 100644 --- a/tests/ClamAV/ClamAVTest.php +++ b/tests/ClamAV/ClamAVTest.php @@ -11,26 +11,26 @@ namespace Appwrite\ClamAV\Tests; +use Appwrite\ClamAV\ClamAV; use Appwrite\ClamAV\Network; use Appwrite\ClamAV\Pipe; +use InvalidArgumentException; use PHPUnit\Framework\TestCase; +use ReflectionClass; +use ReflectionException; +use RuntimeException; +use Socket; class ClamAVTest extends TestCase { - /** - * @var Network|null - */ protected ?Network $network; - /** - * @var Pipe|null - */ protected ?Pipe $pipe; protected function setUp(): void { - $this->network = new Network('localhost', 3310); - $this->pipe = new Pipe(); + $this->network = ClamAV::createFromDSN('tcp://127.0.0.1:3310'); + $this->pipe = ClamAV::createFromDSN('unix:///var/run/clamav/clamd.ctl'); } protected function tearDown(): void @@ -39,23 +39,129 @@ protected function tearDown(): void $this->pipe = null; } + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + * + * @throws ReflectionException + */ + public function testGetSocket(): void + { + $pipe = new Pipe(); + + $reflection = new ReflectionClass($pipe); + $method = $reflection->getMethod('getSocket'); + $method->setAccessible(true); + + self::assertInstanceOf(Socket::class, $method->invoke($pipe)); + } + + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + * + * @throws ReflectionException + */ + public function testGetSocketThrowsException(): void + { + // Provide an invalid path to cause socket creation to fail + $network = new Network('1.2.3.4', 1234); + + $reflection = new ReflectionClass($network); + $method = $reflection->getMethod('getSocket'); + $method->setAccessible(true); + + $this->expectException(RuntimeException::class); + + $method->invoke($network); + } + + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + */ public function testVersion(): void { self::assertStringStartsWith('ClamAV ', $this->network->version()); } + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + */ public function testPing(): void { - self::assertTrue($this->network->ping()); + self::assertIsBool($this->network->ping()); } + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + */ + public function testFileScan(): void + { + self::assertIsBool($this->network->fileScan(__FILE__)); + } + + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + */ + public function testContinueScan(): void + { + $results = $this->network->continueScan(__FILE__); + + self::assertIsArray($results); + self::assertNotEmpty($results[0]['file']); + self::assertNotEmpty($results[0]['stats']); + } + + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + */ public function testFileScanInStream(): void { - self::assertTrue($this->network->fileScanInStream(__FILE__)); + self::assertIsBool($this->network->fileScanInStream(__FILE__)); } + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + */ public function testReload(): void { self::assertStringStartsWith('RELOADING', $this->network->reload()); } + + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + */ + public function testDSNCreation(): void + { + self::assertInstanceOf(Network::class, ClamAV::createFromDSN('tcp://localhost:3310')); + self::assertInstanceOf(Pipe::class, ClamAV::createFromDSN('unix:///var/run/clamav/clamd.ctl')); + } + + /** + * @covers \Appwrite\ClamAV\ClamAV + * @covers \Appwrite\ClamAV\Network + * @covers \Appwrite\ClamAV\Pipe + */ + public function testDSNCreationWithInvalidDSN(): void + { + $this->expectException(InvalidArgumentException::class); + + ClamAV::createFromDSN('foo://bar'); + } }