From 260d607868d5ab1f6cefb42c1bd3369eab48a740 Mon Sep 17 00:00:00 2001 From: nilsteampassnet Date: Sat, 23 Nov 2024 11:18:48 +0100 Subject: [PATCH] * Composer update * Fix library name typo in composer.json --- composer.json | 9 +- composer.lock | 96 ++++++---- includes/config/include.php | 2 +- .../zxcvbn-php/.github/workflows/ci.yml | 41 ----- vendor/bjeavons/zxcvbn-php/composer.json | 3 +- vendor/bjeavons/zxcvbn-php/phpstan.neon | 5 + .../zxcvbn-php/src/Matchers/BaseMatch.php | 5 +- .../zxcvbn-php/src/Matchers/Bruteforce.php | 13 +- .../zxcvbn-php/src/Matchers/DateMatch.php | 6 +- .../src/Matchers/DictionaryMatch.php | 6 +- .../zxcvbn-php/src/Matchers/L33tMatch.php | 5 +- .../zxcvbn-php/src/Matchers/RepeatMatch.php | 6 +- .../src/Matchers/ReverseDictionaryMatch.php | 7 +- .../zxcvbn-php/src/Matchers/SequenceMatch.php | 7 +- .../zxcvbn-php/src/Matchers/SpatialMatch.php | 8 +- .../zxcvbn-php/src/Matchers/YearMatch.php | 10 +- .../bjeavons/zxcvbn-php/src/Math/Binomial.php | 2 +- .../zxcvbn-php/src/Math/BinomialProvider.php | 2 +- .../Math/Impl/AbstractBinomialProvider.php | 2 +- .../AbstractBinomialProviderWithFallback.php | 2 +- .../src/Math/Impl/BinomialProviderFloat64.php | 2 +- .../src/Math/Impl/BinomialProviderInt64.php | 2 +- .../Math/Impl/BinomialProviderPhp73Gmp.php | 2 +- vendor/composer/autoload_classmap.php | 4 + vendor/composer/autoload_psr4.php | 3 +- vendor/composer/autoload_real.php | 2 +- vendor/composer/autoload_static.php | 13 +- vendor/composer/composer/composer.json | 2 +- vendor/composer/composer/composer.lock | 102 +++++------ .../Composer/Autoload/AutoloadGenerator.php | 4 +- .../Command/BaseDependencyCommand.php | 12 +- .../src/Composer/Command/BumpCommand.php | 2 +- .../src/Composer/Command/DiagnoseCommand.php | 2 +- .../src/Composer/Command/HomeCommand.php | 12 +- .../src/Composer/Command/InitCommand.php | 11 +- .../src/Composer/Command/RequireCommand.php | 2 +- .../composer/src/Composer/Compiler.php | 22 ++- .../composer/src/Composer/Composer.php | 4 +- .../Composer/DependencyResolver/Problem.php | 2 +- .../Composer/Downloader/FossilDownloader.php | 48 +++-- .../src/Composer/Downloader/GitDownloader.php | 140 ++++++++------- .../Composer/Downloader/GzipDownloader.php | 4 +- .../src/Composer/Downloader/HgDownloader.php | 23 +-- .../src/Composer/Downloader/RarDownloader.php | 4 +- .../src/Composer/Downloader/SvnDownloader.php | 24 +-- .../src/Composer/Downloader/XzDownloader.php | 4 +- .../src/Composer/Downloader/ZipDownloader.php | 34 ++-- .../composer/src/Composer/Package/Locker.php | 5 +- .../Package/Version/VersionGuesser.php | 12 +- .../src/Composer/Platform/HhvmDetector.php | 6 +- .../Repository/InstalledRepository.php | 9 +- .../Composer/Repository/PathRepository.php | 6 +- .../Composer/Repository/Vcs/FossilDriver.php | 25 +-- .../src/Composer/Repository/Vcs/GitDriver.php | 20 +-- .../src/Composer/Repository/Vcs/HgDriver.php | 27 ++- .../src/Composer/Repository/Vcs/SvnDriver.php | 19 +- .../composer/src/Composer/Util/Bitbucket.php | 2 +- .../composer/src/Composer/Util/Filesystem.php | 20 +-- .../composer/src/Composer/Util/Git.php | 161 ++++++++++++----- .../composer/src/Composer/Util/GitHub.php | 4 +- .../composer/src/Composer/Util/GitLab.php | 4 +- .../composer/src/Composer/Util/Hg.php | 2 +- .../composer/src/Composer/Util/Perforce.php | 22 ++- .../composer/src/Composer/Util/Platform.php | 15 +- .../src/Composer/Util/ProcessExecutor.php | 52 +++++- .../composer/src/Composer/Util/Svn.php | 54 +++--- vendor/composer/installed.json | 120 ++++++++----- vendor/composer/installed.php | 63 ++++--- vendor/voku/portable-ascii/.deepsource.toml | 4 + vendor/voku/portable-ascii/CHANGELOG.md | 8 + vendor/voku/portable-ascii/composer.json | 2 +- .../portable-ascii/src/voku/helper/ASCII.php | 165 +++++------------- 72 files changed, 847 insertions(+), 703 deletions(-) delete mode 100644 vendor/bjeavons/zxcvbn-php/.github/workflows/ci.yml create mode 100644 vendor/bjeavons/zxcvbn-php/phpstan.neon create mode 100644 vendor/voku/portable-ascii/.deepsource.toml diff --git a/composer.json b/composer.json index bbf58ee4f..06a33909a 100755 --- a/composer.json +++ b/composer.json @@ -126,6 +126,13 @@ "options": { "symlink": false } + }, + { + "type": "path", + "url": "includes/libraries/teampassclasses/folderservices", + "options": { + "symlink": false + } } ], "require": { @@ -149,7 +156,7 @@ "teampassclasses/oauth2controller": "dev-master", "teampassclasses/configmanager": "dev-master", "teampassclasses/emailservice": "dev-master", - "teampassclasses/FolderServices": "dev-master", + "teampassclasses/folderservices": "dev-master", "illuminate/contracts": "^10.32", "illuminate/collections": "^10.48", "nesbot/carbon": "^2.71", diff --git a/composer.lock b/composer.lock index 25b4f30d5..373210563 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "64ee2e1d0026c68c1f41f48c7dcec2ad", + "content-hash": "d1155633d409330b1905ac8b6fb21840", "packages": [ { "name": "bjeavons/zxcvbn-php", - "version": "1.3.1", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/bjeavons/zxcvbn-php.git", - "reference": "994928ae5b17ecff8baa2406832d37bdf01116c0" + "reference": "603e015f2c81118a8f42930140311d125eba6f8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bjeavons/zxcvbn-php/zipball/994928ae5b17ecff8baa2406832d37bdf01116c0", - "reference": "994928ae5b17ecff8baa2406832d37bdf01116c0", + "url": "https://api.github.com/repos/bjeavons/zxcvbn-php/zipball/603e015f2c81118a8f42930140311d125eba6f8a", + "reference": "603e015f2c81118a8f42930140311d125eba6f8a", "shasum": "" }, "require": { @@ -27,6 +27,7 @@ }, "require-dev": { "php-coveralls/php-coveralls": "*", + "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^8.5", "squizlabs/php_codesniffer": "3.*" }, @@ -57,9 +58,9 @@ ], "support": { "issues": "https://github.com/bjeavons/zxcvbn-php/issues", - "source": "https://github.com/bjeavons/zxcvbn-php/tree/1.3.1" + "source": "https://github.com/bjeavons/zxcvbn-php/tree/1.4.1" }, - "time": "2021-12-21T18:37:02+00:00" + "time": "2024-11-21T22:10:41+00:00" }, { "name": "brick/math", @@ -341,16 +342,16 @@ }, { "name": "composer/composer", - "version": "2.8.2", + "version": "2.8.3", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "6e543d03187c882ea1c6ba43add2467754427803" + "reference": "2a7c71266b2545a3bed9f4860734081963f6e688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/6e543d03187c882ea1c6ba43add2467754427803", - "reference": "6e543d03187c882ea1c6ba43add2467754427803", + "url": "https://api.github.com/repos/composer/composer/zipball/2a7c71266b2545a3bed9f4860734081963f6e688", + "reference": "2a7c71266b2545a3bed9f4860734081963f6e688", "shasum": "" }, "require": { @@ -364,7 +365,7 @@ "justinrainbow/json-schema": "^5.3", "php": "^7.2.5 || ^8.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "react/promise": "^3.2", + "react/promise": "^2.11 || ^3.2", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", "seld/signal-handler": "^2.0", @@ -435,7 +436,7 @@ "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", "security": "https://github.com/composer/composer/security/policy", - "source": "https://github.com/composer/composer/tree/2.8.2" + "source": "https://github.com/composer/composer/tree/2.8.3" }, "funding": [ { @@ -451,7 +452,7 @@ "type": "tidelift" } ], - "time": "2024-10-29T15:12:11+00:00" + "time": "2024-11-17T12:13:04+00:00" }, { "name": "composer/metadata-minifier", @@ -1961,7 +1962,7 @@ }, { "name": "illuminate/collections", - "version": "v10.48.23", + "version": "v10.48.24", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", @@ -2016,7 +2017,7 @@ }, { "name": "illuminate/conditionable", - "version": "v10.48.23", + "version": "v10.48.24", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -2062,7 +2063,7 @@ }, { "name": "illuminate/container", - "version": "v10.48.23", + "version": "v10.48.24", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", @@ -2113,7 +2114,7 @@ }, { "name": "illuminate/contracts", - "version": "v10.48.23", + "version": "v10.48.24", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -2161,7 +2162,7 @@ }, { "name": "illuminate/filesystem", - "version": "v10.48.23", + "version": "v10.48.24", "source": { "type": "git", "url": "https://github.com/illuminate/filesystem.git", @@ -2228,7 +2229,7 @@ }, { "name": "illuminate/macroable", - "version": "v10.48.23", + "version": "v10.48.24", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -2274,7 +2275,7 @@ }, { "name": "illuminate/support", - "version": "v10.48.23", + "version": "v10.48.24", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", @@ -2345,7 +2346,7 @@ }, { "name": "illuminate/translation", - "version": "v10.48.23", + "version": "v10.48.24", "source": { "type": "git", "url": "https://github.com/illuminate/translation.git", @@ -2396,7 +2397,7 @@ }, { "name": "illuminate/validation", - "version": "v10.48.23", + "version": "v10.48.24", "source": { "type": "git", "url": "https://github.com/illuminate/validation.git", @@ -5954,6 +5955,40 @@ "relative": true } }, + { + "name": "teampassclasses/folderservices", + "version": "dev-master", + "dist": { + "type": "path", + "url": "includes/libraries/teampassclasses/folderservices", + "reference": "737c43b0e11b6d6f15ae63fda23d87548cc87fc9" + }, + "require": { + "php": "^8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "TeampassClasses\\FolderServices\\": "src/" + } + }, + "license": [ + "GPL-3.0-only" + ], + "authors": [ + { + "name": "Nils Laumaillé" + } + ], + "description": "Handle the folder management.", + "keywords": [ + "folder" + ], + "transport-options": { + "symlink": false, + "relative": true + } + }, { "name": "teampassclasses/language", "version": "dev-master", @@ -6495,16 +6530,16 @@ }, { "name": "voku/portable-ascii", - "version": "2.0.1", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "b56450eed252f6801410d810c8e1727224ae0743" + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", - "reference": "b56450eed252f6801410d810c8e1727224ae0743", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", "shasum": "" }, "require": { @@ -6529,7 +6564,7 @@ "authors": [ { "name": "Lars Moelleken", - "homepage": "http://www.moelleken.org/" + "homepage": "https://www.moelleken.org/" } ], "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", @@ -6541,7 +6576,7 @@ ], "support": { "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/2.0.1" + "source": "https://github.com/voku/portable-ascii/tree/2.0.3" }, "funding": [ { @@ -6565,7 +6600,7 @@ "type": "tidelift" } ], - "time": "2022-03-08T17:03:00+00:00" + "time": "2024-11-21T01:49:47+00:00" }, { "name": "voku/portable-utf8", @@ -7183,6 +7218,7 @@ "teampassclasses/oauth2controller": 20, "teampassclasses/configmanager": 20, "teampassclasses/emailservice": 20, + "teampassclasses/folderservices": 20, "passwordlib/passwordlib": 15 }, "prefer-stable": true, diff --git a/includes/config/include.php b/includes/config/include.php index f39cce4af..7bb2d84a7 100755 --- a/includes/config/include.php +++ b/includes/config/include.php @@ -28,7 +28,7 @@ define('TP_VERSION', '3.1.2'); define("UPGRADE_MIN_DATE", "1732264740"); -define('TP_VERSION_MINOR', '166'); +define('TP_VERSION_MINOR', '167'); define('TP_TOOL_NAME', 'Teampass'); define('TP_ONE_DAY_SECONDS', 86400); define('TP_ONE_WEEK_SECONDS', 604800); diff --git a/vendor/bjeavons/zxcvbn-php/.github/workflows/ci.yml b/vendor/bjeavons/zxcvbn-php/.github/workflows/ci.yml deleted file mode 100644 index ce6f607e9..000000000 --- a/vendor/bjeavons/zxcvbn-php/.github/workflows/ci.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: CI - -on: push - -jobs: - all: - runs-on: ${{ matrix.operating-system }} - strategy: - matrix: - operating-system: - - ubuntu-latest - # - windows-latest # Disabled - apparently checkouts have \r\n which breaks phpcs - - macos-latest - php-versions: - - '7.2' - - '7.3' - - '7.4' - - '8.0' - - '8.1' - name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, intl - ini-values: post_max_size=256M, short_open_tag=On - coverage: xdebug - tools: php-cs-fixer, phpunit:7 - - - name: Composer Install - run: composer install --no-progress - - - name: Code style checks - run: ./vendor/bin/phpcs . - - - name: Unit tests - run: ./vendor/bin/phpunit diff --git a/vendor/bjeavons/zxcvbn-php/composer.json b/vendor/bjeavons/zxcvbn-php/composer.json index 2c40aaaa9..ae9c8a912 100644 --- a/vendor/bjeavons/zxcvbn-php/composer.json +++ b/vendor/bjeavons/zxcvbn-php/composer.json @@ -19,7 +19,8 @@ "require-dev": { "phpunit/phpunit": "^8.5", "php-coveralls/php-coveralls": "*", - "squizlabs/php_codesniffer": "3.*" + "squizlabs/php_codesniffer": "3.*", + "phpstan/phpstan": "^2.0" }, "suggest": { "ext-gmp": "Required for optimized binomial calculations (also requires PHP >= 7.3)" diff --git a/vendor/bjeavons/zxcvbn-php/phpstan.neon b/vendor/bjeavons/zxcvbn-php/phpstan.neon new file mode 100644 index 000000000..ac417193a --- /dev/null +++ b/vendor/bjeavons/zxcvbn-php/phpstan.neon @@ -0,0 +1,5 @@ +parameters: + level: 0 + paths: + - src + - test diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/BaseMatch.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/BaseMatch.php index 527dbc595..97f77d3c4 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/BaseMatch.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/BaseMatch.php @@ -4,7 +4,6 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Math\Binomial; use ZxcvbnPhp\Scorer; @@ -48,10 +47,8 @@ public function __construct(string $password, int $begin, int $end, string $toke * * @param bool $isSoleMatch * Whether this is the only match in the password - * @return array - * Associative array with warning (string) and suggestions (array of strings) + * @return array{'warning': string, "suggestions": string[]} */ - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] abstract public function getFeedback(bool $isSoleMatch): array; /** diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/Bruteforce.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/Bruteforce.php index cba7bcc24..3e082235a 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/Bruteforce.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/Bruteforce.php @@ -4,16 +4,9 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Scorer; -/** - * Class Bruteforce - * @package ZxcvbnPhp\Matchers - * - * Intentionally not named with Match suffix to prevent autoloading from Matcher. - */ -class Bruteforce extends BaseMatch +final class Bruteforce extends BaseMatch { public const BRUTEFORCE_CARDINALITY = 10; @@ -32,7 +25,9 @@ public static function match(string $password, array $userInputs = []): array } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { return [ diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/DateMatch.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/DateMatch.php index f3fdcd914..6db9cf9c6 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/DateMatch.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/DateMatch.php @@ -4,9 +4,9 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; +/** @phpstan-consistent-constructor */ class DateMatch extends BaseMatch { public const NUM_YEARS = 119; // Years match against 1900 - 2019 @@ -108,7 +108,9 @@ public static function match(string $password, array $userInputs = []): array return $matches; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { return [ diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/DictionaryMatch.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/DictionaryMatch.php index b936681bf..7be2340b8 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/DictionaryMatch.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/DictionaryMatch.php @@ -4,10 +4,10 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; use ZxcvbnPhp\Math\Binomial; +/** @phpstan-consistent-constructor */ class DictionaryMatch extends BaseMatch { public $pattern = 'dictionary'; @@ -88,10 +88,8 @@ public function __construct(string $password, int $begin, int $end, string $toke } /** - * @param bool $isSoleMatch - * @return array + * @return array{'warning': string, "suggestions": string[]} */ - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] public function getFeedback(bool $isSoleMatch): array { $startUpper = '/^[A-Z][^A-Z]+$/u'; diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/L33tMatch.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/L33tMatch.php index 6b6288bdf..9163706d7 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/L33tMatch.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/L33tMatch.php @@ -4,7 +4,6 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; use ZxcvbnPhp\Math\Binomial; @@ -98,7 +97,9 @@ public function __construct(string $password, int $begin, int $end, string $toke } } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { $feedback = parent::getFeedback($isSoleMatch); diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/RepeatMatch.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/RepeatMatch.php index 3f38da275..1b23074ef 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/RepeatMatch.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/RepeatMatch.php @@ -4,10 +4,10 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; use ZxcvbnPhp\Scorer; +/** @phpstan-consistent-constructor */ class RepeatMatch extends BaseMatch { public const GREEDY_MATCH = '/(.+)\1+/u'; @@ -85,7 +85,9 @@ public static function match(string $password, array $userInputs = []): array return $matches; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { $warning = mb_strlen($this->repeatedChar) == 1 diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/ReverseDictionaryMatch.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/ReverseDictionaryMatch.php index c7b86b683..a935bff7c 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/ReverseDictionaryMatch.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/ReverseDictionaryMatch.php @@ -4,7 +4,6 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; class ReverseDictionaryMatch extends DictionaryMatch @@ -42,7 +41,9 @@ protected function getRawGuesses(): float return parent::getRawGuesses() * 2; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { $feedback = parent::getFeedback($isSoleMatch); @@ -54,7 +55,7 @@ public function getFeedback(bool $isSoleMatch): array return $feedback; } - public static function mbStrRev(string $string, string $encoding = null): string + public static function mbStrRev(string $string, ?string $encoding = null): string { if ($encoding === null) { $encoding = mb_detect_encoding($string) ?: 'UTF-8'; diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/SequenceMatch.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/SequenceMatch.php index 1350f2af8..17a8ea868 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/SequenceMatch.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/SequenceMatch.php @@ -4,8 +4,7 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; - +/** @phpstan-consistent-constructor */ class SequenceMatch extends BaseMatch { public const MAX_DELTA = 5; @@ -87,7 +86,9 @@ public static function findSequenceMatch(string $password, int $begin, int $end, } } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { return [ diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/SpatialMatch.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/SpatialMatch.php index 6de328bbe..1a9460353 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/SpatialMatch.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/SpatialMatch.php @@ -4,10 +4,10 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; use ZxcvbnPhp\Math\Binomial; +/** @phpstan-consistent-constructor */ class SpatialMatch extends BaseMatch { public const SHIFTED_CHARACTERS = '~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?'; @@ -58,7 +58,9 @@ public static function match(string $password, array $userInputs = [], array $gr return $matches; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { $warning = $this->turns == 1 @@ -93,7 +95,7 @@ public function __construct(string $password, int $begin, int $end, string $toke /** * Match spatial patterns in a adjacency graph. * @param string $password - * @param array $graph + * @param array $graph * @param string $graphName * @return array */ diff --git a/vendor/bjeavons/zxcvbn-php/src/Matchers/YearMatch.php b/vendor/bjeavons/zxcvbn-php/src/Matchers/YearMatch.php index 9deeea622..84f711c30 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Matchers/YearMatch.php +++ b/vendor/bjeavons/zxcvbn-php/src/Matchers/YearMatch.php @@ -4,10 +4,9 @@ namespace ZxcvbnPhp\Matchers; -use JetBrains\PhpStorm\ArrayShape; use ZxcvbnPhp\Matcher; -class YearMatch extends BaseMatch +final class YearMatch extends BaseMatch { public const NUM_YEARS = 119; @@ -24,7 +23,7 @@ class YearMatch extends BaseMatch public static function match(string $password, array $userInputs = []): array { $matches = []; - $groups = static::findAll($password, "/(19\d\d|200\d|201\d)/u"); + $groups = static::findAll($password, "/(19\d\d|20\d\d)/u"); foreach ($groups as $captures) { $matches[] = new static($password, $captures[1]['begin'], $captures[1]['end'], $captures[1]['token']); } @@ -32,7 +31,10 @@ public static function match(string $password, array $userInputs = []): array return $matches; } - #[ArrayShape(['warning' => 'string', 'suggestions' => 'string[]'])] + + /** + * @return array{'warning': string, "suggestions": string[]} + */ public function getFeedback(bool $isSoleMatch): array { return [ diff --git a/vendor/bjeavons/zxcvbn-php/src/Math/Binomial.php b/vendor/bjeavons/zxcvbn-php/src/Math/Binomial.php index f3c7e368a..94e882fc6 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Math/Binomial.php +++ b/vendor/bjeavons/zxcvbn-php/src/Math/Binomial.php @@ -67,4 +67,4 @@ private static function initProvider(): BinomialProvider return new $bestProviderClass(); } -} \ No newline at end of file +} diff --git a/vendor/bjeavons/zxcvbn-php/src/Math/BinomialProvider.php b/vendor/bjeavons/zxcvbn-php/src/Math/BinomialProvider.php index 05a4cdc90..fbec1568f 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Math/BinomialProvider.php +++ b/vendor/bjeavons/zxcvbn-php/src/Math/BinomialProvider.php @@ -14,4 +14,4 @@ interface BinomialProvider * @return float */ public function binom(int $n, int $k): float; -} \ No newline at end of file +} diff --git a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/AbstractBinomialProvider.php b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/AbstractBinomialProvider.php index f5d9ae120..fe2a043c1 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/AbstractBinomialProvider.php +++ b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/AbstractBinomialProvider.php @@ -25,4 +25,4 @@ public function binom(int $n, int $k): float } abstract protected function calculate(int $n, int $k): float; -} \ No newline at end of file +} diff --git a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/AbstractBinomialProviderWithFallback.php b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/AbstractBinomialProviderWithFallback.php index 37389270e..1487723c2 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/AbstractBinomialProviderWithFallback.php +++ b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/AbstractBinomialProviderWithFallback.php @@ -28,4 +28,4 @@ protected function getFallbackProvider(): AbstractBinomialProvider return $this->fallback; } -} \ No newline at end of file +} diff --git a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderFloat64.php b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderFloat64.php index e8aeffe12..e68a02c32 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderFloat64.php +++ b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderFloat64.php @@ -20,4 +20,4 @@ protected function calculate(int $n, int $k): float return $c; } -} \ No newline at end of file +} diff --git a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderInt64.php b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderInt64.php index 2f12ddcaf..601617239 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderInt64.php +++ b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderInt64.php @@ -30,4 +30,4 @@ protected function tryCalculate(int $n, int $k): ?float return null; } } -} \ No newline at end of file +} diff --git a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderPhp73Gmp.php b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderPhp73Gmp.php index fdbdefc1c..2d5fa3daf 100644 --- a/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderPhp73Gmp.php +++ b/vendor/bjeavons/zxcvbn-php/src/Math/Impl/BinomialProviderPhp73Gmp.php @@ -14,4 +14,4 @@ protected function calculate(int $n, int $k): float { return (float)gmp_strval(gmp_binomial($n, $k)); } -} \ No newline at end of file +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 3fdc2edbe..ade7c8251 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -2231,6 +2231,10 @@ 'TeampassClasses\\EmailService\\EmailService' => $vendorDir . '/teampassclasses/emailservice/src/EmailService.php', 'TeampassClasses\\EmailService\\EmailSettings' => $vendorDir . '/teampassclasses/emailservice/src/EmailSettings.php', 'TeampassClasses\\Encryption\\Encryption' => $vendorDir . '/teampassclasses/encryption/src/Encryption.php', + 'TeampassClasses\\FolderServices\\FolderCacheUpdater' => $vendorDir . '/teampassclasses/folderservices/src/FolderCacheUpdater.php', + 'TeampassClasses\\FolderServices\\FolderComplexityService' => $vendorDir . '/teampassclasses/folderservices/src/FolderComplexityService.php', + 'TeampassClasses\\FolderServices\\FolderCreationService' => $vendorDir . '/teampassclasses/folderservices/src/FolderCreationService.php', + 'TeampassClasses\\FolderServices\\FolderPermissionChecker' => $vendorDir . '/teampassclasses/folderservices/src/FolderPermissionChecker.php', 'TeampassClasses\\Language\\Language' => $vendorDir . '/teampassclasses/language/src/Language.php', 'TeampassClasses\\LdapExtra\\ActiveDirectoryExtra' => $vendorDir . '/teampassclasses/ldapextra/src/ActiveDirectoryExtra.php', 'TeampassClasses\\LdapExtra\\LdapExtra' => $vendorDir . '/teampassclasses/ldapextra/src/LdapExtra.php', diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 5d51d3e6c..36e1733b8 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -7,7 +7,7 @@ return array( 'voku\\helper\\' => array($vendorDir . '/voku/anti-xss/src/voku/helper'), - 'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku', $vendorDir . '/voku/portable-utf8/src/voku'), + 'voku\\' => array($vendorDir . '/voku/portable-utf8/src/voku', $vendorDir . '/voku/portable-ascii/src/voku'), 'ZxcvbnPhp\\' => array($vendorDir . '/bjeavons/zxcvbn-php/src'), 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), 'TiBeN\\' => array($vendorDir . '/tiben/crontab-manager/src'), @@ -20,6 +20,7 @@ 'TeampassClasses\\NestedTree\\' => array($vendorDir . '/teampassclasses/nestedtree/src'), 'TeampassClasses\\LdapExtra\\' => array($vendorDir . '/teampassclasses/ldapextra/src'), 'TeampassClasses\\Language\\' => array($vendorDir . '/teampassclasses/language/src'), + 'TeampassClasses\\FolderServices\\' => array($vendorDir . '/teampassclasses/folderservices/src'), 'TeampassClasses\\Encryption\\' => array($vendorDir . '/teampassclasses/encryption/src'), 'TeampassClasses\\EmailService\\' => array($vendorDir . '/teampassclasses/emailservice/src'), 'TeampassClasses\\ConfigManager\\' => array($vendorDir . '/teampassclasses/configmanager/src'), diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 55500a304..4ceffb704 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -35,7 +35,7 @@ public static function getLoader() require __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInite3f3ee27f81ca21f7bd7499d7b935c11::getInitializer($loader)); - $loader->setApcuPrefix('fd0d2973befe4918015b'); + $loader->setApcuPrefix('320c3616d334d4073af5'); $loader->register(true); $filesToLoad = \Composer\Autoload\ComposerStaticInite3f3ee27f81ca21f7bd7499d7b935c11::$files; diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index dbfe97231..86a2c0b5c 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -58,6 +58,7 @@ class ComposerStaticInite3f3ee27f81ca21f7bd7499d7b935c11 'TeampassClasses\\NestedTree\\' => 27, 'TeampassClasses\\LdapExtra\\' => 26, 'TeampassClasses\\Language\\' => 25, + 'TeampassClasses\\FolderServices\\' => 31, 'TeampassClasses\\Encryption\\' => 27, 'TeampassClasses\\EmailService\\' => 29, 'TeampassClasses\\ConfigManager\\' => 30, @@ -192,8 +193,8 @@ class ComposerStaticInite3f3ee27f81ca21f7bd7499d7b935c11 ), 'voku\\' => array ( - 0 => __DIR__ . '/..' . '/voku/portable-ascii/src/voku', - 1 => __DIR__ . '/..' . '/voku/portable-utf8/src/voku', + 0 => __DIR__ . '/..' . '/voku/portable-utf8/src/voku', + 1 => __DIR__ . '/..' . '/voku/portable-ascii/src/voku', ), 'ZxcvbnPhp\\' => array ( @@ -243,6 +244,10 @@ class ComposerStaticInite3f3ee27f81ca21f7bd7499d7b935c11 array ( 0 => __DIR__ . '/..' . '/teampassclasses/language/src', ), + 'TeampassClasses\\FolderServices\\' => + array ( + 0 => __DIR__ . '/..' . '/teampassclasses/folderservices/src', + ), 'TeampassClasses\\Encryption\\' => array ( 0 => __DIR__ . '/..' . '/teampassclasses/encryption/src', @@ -2851,6 +2856,10 @@ class ComposerStaticInite3f3ee27f81ca21f7bd7499d7b935c11 'TeampassClasses\\EmailService\\EmailService' => __DIR__ . '/..' . '/teampassclasses/emailservice/src/EmailService.php', 'TeampassClasses\\EmailService\\EmailSettings' => __DIR__ . '/..' . '/teampassclasses/emailservice/src/EmailSettings.php', 'TeampassClasses\\Encryption\\Encryption' => __DIR__ . '/..' . '/teampassclasses/encryption/src/Encryption.php', + 'TeampassClasses\\FolderServices\\FolderCacheUpdater' => __DIR__ . '/..' . '/teampassclasses/folderservices/src/FolderCacheUpdater.php', + 'TeampassClasses\\FolderServices\\FolderComplexityService' => __DIR__ . '/..' . '/teampassclasses/folderservices/src/FolderComplexityService.php', + 'TeampassClasses\\FolderServices\\FolderCreationService' => __DIR__ . '/..' . '/teampassclasses/folderservices/src/FolderCreationService.php', + 'TeampassClasses\\FolderServices\\FolderPermissionChecker' => __DIR__ . '/..' . '/teampassclasses/folderservices/src/FolderPermissionChecker.php', 'TeampassClasses\\Language\\Language' => __DIR__ . '/..' . '/teampassclasses/language/src/Language.php', 'TeampassClasses\\LdapExtra\\ActiveDirectoryExtra' => __DIR__ . '/..' . '/teampassclasses/ldapextra/src/ActiveDirectoryExtra.php', 'TeampassClasses\\LdapExtra\\LdapExtra' => __DIR__ . '/..' . '/teampassclasses/ldapextra/src/LdapExtra.php', diff --git a/vendor/composer/composer/composer.json b/vendor/composer/composer/composer.json index a943cd7f9..743ca0bba 100644 --- a/vendor/composer/composer/composer.json +++ b/vendor/composer/composer/composer.json @@ -37,7 +37,7 @@ "symfony/filesystem": "^5.4.35 || ^6.3.12 || ^7.0.3", "symfony/finder": "^5.4.35 || ^6.3.12 || ^7.0.3", "symfony/process": "^5.4.35 || ^6.3.12 || ^7.0.3", - "react/promise": "^3.2", + "react/promise": "^2.11 || ^3.2", "composer/pcre": "^2.2 || ^3.2", "symfony/polyfill-php73": "^1.24", "symfony/polyfill-php80": "^1.24", diff --git a/vendor/composer/composer/composer.lock b/vendor/composer/composer/composer.lock index b07c8411a..b49b1e1c2 100644 --- a/vendor/composer/composer/composer.lock +++ b/vendor/composer/composer/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7c2f8d4d04b8146b2fcd203cb81fa8d5", + "content-hash": "d6c1c91b79d7140594e249343184ce6f", "packages": [ { "name": "composer/ca-bundle", - "version": "1.5.2", + "version": "1.5.3", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "48a792895a2b7a6ee65dd5442c299d7b835b6137" + "reference": "3b1fc3f0be055baa7c6258b1467849c3e8204eb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/48a792895a2b7a6ee65dd5442c299d7b835b6137", - "reference": "48a792895a2b7a6ee65dd5442c299d7b835b6137", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/3b1fc3f0be055baa7c6258b1467849c3e8204eb2", + "reference": "3b1fc3f0be055baa7c6258b1467849c3e8204eb2", "shasum": "" }, "require": { @@ -64,7 +64,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.5.2" + "source": "https://github.com/composer/ca-bundle/tree/1.5.3" }, "funding": [ { @@ -80,7 +80,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T07:49:53+00:00" + "time": "2024-11-04T10:15:26+00:00" }, { "name": "composer/class-map-generator", @@ -226,16 +226,16 @@ }, { "name": "composer/pcre", - "version": "2.3.1", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "26859a860a7f140fc08422c3cc14ad9c2a287d79" + "reference": "ebb81df8f52b40172d14062ae96a06939d80a069" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/26859a860a7f140fc08422c3cc14ad9c2a287d79", - "reference": "26859a860a7f140fc08422c3cc14ad9c2a287d79", + "url": "https://api.github.com/repos/composer/pcre/zipball/ebb81df8f52b40172d14062ae96a06939d80a069", + "reference": "ebb81df8f52b40172d14062ae96a06939d80a069", "shasum": "" }, "require": { @@ -245,8 +245,8 @@ "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "phpstan/phpstan": "^1.11.10", - "phpstan/phpstan-strict-rules": "^1.1", + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", "phpunit/phpunit": "^8 || ^9" }, "type": "library", @@ -285,7 +285,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/2.3.1" + "source": "https://github.com/composer/pcre/tree/2.3.2" }, "funding": [ { @@ -301,7 +301,7 @@ "type": "tidelift" } ], - "time": "2024-08-27T12:02:26+00:00" + "time": "2024-11-12T16:24:47+00:00" }, { "name": "composer/semver", @@ -941,16 +941,16 @@ }, { "name": "symfony/console", - "version": "v5.4.45", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "108d436c2af470858bdaba3257baab3a74172017" + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/108d436c2af470858bdaba3257baab3a74172017", - "reference": "108d436c2af470858bdaba3257baab3a74172017", + "url": "https://api.github.com/repos/symfony/console/zipball/c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", "shasum": "" }, "require": { @@ -1020,7 +1020,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.45" + "source": "https://github.com/symfony/console/tree/v5.4.47" }, "funding": [ { @@ -1036,7 +1036,7 @@ "type": "tidelift" } ], - "time": "2024-10-08T07:27:17+00:00" + "time": "2024-11-06T11:30:55+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1787,16 +1787,16 @@ }, { "name": "symfony/process", - "version": "v5.4.45", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "95f3f19d0f8f06e4253c66a0828ddb69f8b8ede4" + "reference": "5d1662fb32ebc94f17ddb8d635454a776066733d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/95f3f19d0f8f06e4253c66a0828ddb69f8b8ede4", - "reference": "95f3f19d0f8f06e4253c66a0828ddb69f8b8ede4", + "url": "https://api.github.com/repos/symfony/process/zipball/5d1662fb32ebc94f17ddb8d635454a776066733d", + "reference": "5d1662fb32ebc94f17ddb8d635454a776066733d", "shasum": "" }, "require": { @@ -1829,7 +1829,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.45" + "source": "https://github.com/symfony/process/tree/v5.4.47" }, "funding": [ { @@ -1845,7 +1845,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:11:13+00:00" + "time": "2024-11-06T11:36:42+00:00" }, { "name": "symfony/service-contracts", @@ -1932,16 +1932,16 @@ }, { "name": "symfony/string", - "version": "v5.4.45", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "7f6807add88b1e2635f3c6de5e1ace631ed7cad2" + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/7f6807add88b1e2635f3c6de5e1ace631ed7cad2", - "reference": "7f6807add88b1e2635f3c6de5e1ace631ed7cad2", + "url": "https://api.github.com/repos/symfony/string/zipball/136ca7d72f72b599f2631aca474a4f8e26719799", + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799", "shasum": "" }, "require": { @@ -1998,7 +1998,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.45" + "source": "https://github.com/symfony/string/tree/v5.4.47" }, "funding": [ { @@ -2014,22 +2014,22 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:11:13+00:00" + "time": "2024-11-10T20:33:58+00:00" } ], "packages-dev": [ { "name": "phpstan/phpstan", - "version": "1.12.7", + "version": "1.12.10", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0" + "reference": "fc463b5d0fe906dcf19689be692c65c50406a071" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", - "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/fc463b5d0fe906dcf19689be692c65c50406a071", + "reference": "fc463b5d0fe906dcf19689be692c65c50406a071", "shasum": "" }, "require": { @@ -2074,7 +2074,7 @@ "type": "github" } ], - "time": "2024-10-18T11:12:07+00:00" + "time": "2024-11-11T15:37:09+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -2125,21 +2125,21 @@ }, { "name": "phpstan/phpstan-phpunit", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "f3ea021866f4263f07ca3636bf22c64be9610c11" + "reference": "11d4235fbc6313ecbf93708606edfd3222e44949" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/f3ea021866f4263f07ca3636bf22c64be9610c11", - "reference": "f3ea021866f4263f07ca3636bf22c64be9610c11", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/11d4235fbc6313ecbf93708606edfd3222e44949", + "reference": "11d4235fbc6313ecbf93708606edfd3222e44949", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.11" + "phpstan/phpstan": "^1.12" }, "conflict": { "phpunit/phpunit": "<7.0" @@ -2171,9 +2171,9 @@ "description": "PHPUnit extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.4.0" + "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.4.1" }, - "time": "2024-04-20T06:39:00+00:00" + "time": "2024-11-12T12:43:59+00:00" }, { "name": "phpstan/phpstan-strict-rules", @@ -2226,16 +2226,16 @@ }, { "name": "phpstan/phpstan-symfony", - "version": "1.4.10", + "version": "1.4.12", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "f7d5782044bedf93aeb3f38e09c91148ee90e5a1" + "reference": "c7b7e7f520893621558bfbfdb2694d4364565c1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/f7d5782044bedf93aeb3f38e09c91148ee90e5a1", - "reference": "f7d5782044bedf93aeb3f38e09c91148ee90e5a1", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/c7b7e7f520893621558bfbfdb2694d4364565c1d", + "reference": "c7b7e7f520893621558bfbfdb2694d4364565c1d", "shasum": "" }, "require": { @@ -2292,9 +2292,9 @@ "description": "Symfony Framework extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-symfony/issues", - "source": "https://github.com/phpstan/phpstan-symfony/tree/1.4.10" + "source": "https://github.com/phpstan/phpstan-symfony/tree/1.4.12" }, - "time": "2024-09-26T18:14:50+00:00" + "time": "2024-11-06T10:13:18+00:00" }, { "name": "symfony/phpunit-bridge", diff --git a/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php b/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php index 44431128f..6db30b8fd 100644 --- a/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php +++ b/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php @@ -665,11 +665,11 @@ protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem foreach ($package->getIncludePaths() as $includePath) { $includePath = trim($includePath, '/'); - $includePaths[] = empty($installPath) ? $includePath : $installPath.'/'.$includePath; + $includePaths[] = $installPath === '' ? $includePath : $installPath.'/'.$includePath; } } - if (!$includePaths) { + if (\count($includePaths) === 0) { return null; } diff --git a/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php b/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php index bb2a64233..55b502e03 100644 --- a/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php +++ b/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php @@ -197,9 +197,9 @@ protected function doExecute(InputInterface $input, OutputInterface $output, boo /** * Assembles and prints a bottom-up table of the dependencies. * - * @param array{PackageInterface, Link, mixed}[] $results + * @param array{PackageInterface, Link, array|false}[] $results */ - protected function printTable(OutputInterface $output, $results): void + protected function printTable(OutputInterface $output, array $results): void { $table = []; $doubles = []; @@ -221,13 +221,13 @@ protected function printTable(OutputInterface $output, $results): void $packageUrl = PackageInfo::getViewSourceOrHomepageUrl($package); $nameWithLink = $packageUrl !== null ? '' . $package->getPrettyName() . '' : $package->getPrettyName(); $rows[] = [$nameWithLink, $version, $link->getDescription(), sprintf('%s (%s)', $link->getTarget(), $link->getPrettyConstraint())]; - if ($children) { + if (is_array($children)) { $queue = array_merge($queue, $children); } } $results = $queue; $table = array_merge($rows, $table); - } while (!empty($results)); + } while (\count($results) > 0); $this->renderTable($table, $output); } @@ -254,7 +254,7 @@ protected function initStyles(OutputInterface $output): void /** * Recursively prints a tree of the selected results. * - * @param array{PackageInterface, Link, mixed[]|bool}[] $results Results to be printed at this level. + * @param array{PackageInterface, Link, array|false}[] $results Results to be printed at this level. * @param string $prefix Prefix of the current tree level. * @param int $level Current level of recursion. */ @@ -275,7 +275,7 @@ protected function printTree(array $results, string $prefix = '', int $level = 1 $linkText = sprintf('%s <%s>%s %s', $link->getDescription(), $prevColor, $link->getTarget(), $link->getPrettyConstraint()); $circularWarn = $children === false ? '(circular dependency aborted here)' : ''; $this->writeTreeLine(rtrim(sprintf("%s%s%s (%s) %s", $prefix, $isLast ? '└──' : '├──', $packageText, $linkText, $circularWarn))); - if ($children) { + if (is_array($children)) { $this->printTree($children, $prefix . ($isLast ? ' ' : '│ '), $level + 1); } } diff --git a/vendor/composer/composer/src/Composer/Command/BumpCommand.php b/vendor/composer/composer/src/Composer/Command/BumpCommand.php index dc3df1e12..a87a65e1c 100644 --- a/vendor/composer/composer/src/Composer/Command/BumpCommand.php +++ b/vendor/composer/composer/src/Composer/Command/BumpCommand.php @@ -216,7 +216,7 @@ public function doBump( $io->write('No requirements to update in '.$composerJsonPath.'.'); } - if (!$dryRun && $composer->getLocker()->isLocked() && $changeCount > 0) { + if (!$dryRun && $composer->getLocker()->isLocked() && $composer->getConfig()->get('lock') && $changeCount > 0) { $composer->getLocker()->updateHash($composerJson); } diff --git a/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php b/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php index 263ee0644..7dade55ef 100644 --- a/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php +++ b/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php @@ -302,7 +302,7 @@ private function checkGit(): string return 'proc_open is not available, git cannot be used'; } - $this->process->execute('git config color.ui', $output); + $this->process->execute(['git', 'config', 'color.ui'], $output); if (strtolower(trim($output)) === 'always') { return 'Your git color.ui setting is set to always, this is known to create issues. Use "git config --global color.ui true" to set it correctly.'; } diff --git a/vendor/composer/composer/src/Composer/Command/HomeCommand.php b/vendor/composer/composer/src/Composer/Command/HomeCommand.php index 5aec6f4c1..3547faec7 100644 --- a/vendor/composer/composer/src/Composer/Command/HomeCommand.php +++ b/vendor/composer/composer/src/Composer/Command/HomeCommand.php @@ -122,22 +122,20 @@ private function handlePackage(CompletePackageInterface $package, bool $showHome */ private function openBrowser(string $url): void { - $url = ProcessExecutor::escape($url); - $process = new ProcessExecutor($this->getIO()); if (Platform::isWindows()) { - $process->execute('start "web" explorer ' . $url, $output); + $process->execute(['start', '"web"', 'explorer', $url], $output); return; } - $linux = $process->execute('which xdg-open', $output); - $osx = $process->execute('which open', $output); + $linux = $process->execute(['which', 'xdg-open'], $output); + $osx = $process->execute(['which', 'open'], $output); if (0 === $linux) { - $process->execute('xdg-open ' . $url, $output); + $process->execute(['xdg-open', $url], $output); } elseif (0 === $osx) { - $process->execute('open ' . $url, $output); + $process->execute(['open', $url], $output); } else { $this->getIO()->writeError('No suitable browser opening command found, open yourself: ' . $url); } diff --git a/vendor/composer/composer/src/Composer/Command/InitCommand.php b/vendor/composer/composer/src/Composer/Command/InitCommand.php index 6d7311dd4..8b01dda6f 100644 --- a/vendor/composer/composer/src/Composer/Command/InitCommand.php +++ b/vendor/composer/composer/src/Composer/Command/InitCommand.php @@ -27,6 +27,7 @@ use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; use Composer\Console\Input\InputOption; +use Composer\Util\ProcessExecutor; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\ExecutableFinder; use Symfony\Component\Process\Process; @@ -535,15 +536,11 @@ protected function getGitConfig(): array return $this->gitConfig; } - $finder = new ExecutableFinder(); - $gitBin = $finder->find('git'); + $process = new ProcessExecutor($this->getIO()); - $cmd = new Process([$gitBin, 'config', '-l']); - $cmd->run(); - - if ($cmd->isSuccessful()) { + if (0 === $process->execute(['git', 'config', '-l'], $output)) { $this->gitConfig = []; - Preg::matchAllStrictGroups('{^([^=]+)=(.*)$}m', $cmd->getOutput(), $matches); + Preg::matchAllStrictGroups('{^([^=]+)=(.*)$}m', $output, $matches); foreach ($matches[1] as $key => $match) { $this->gitConfig[$match] = $matches[2][$key]; } diff --git a/vendor/composer/composer/src/Composer/Command/RequireCommand.php b/vendor/composer/composer/src/Composer/Command/RequireCommand.php index 92d0a77b5..59d1e0585 100644 --- a/vendor/composer/composer/src/Composer/Command/RequireCommand.php +++ b/vendor/composer/composer/src/Composer/Command/RequireCommand.php @@ -554,7 +554,7 @@ private function updateRequirementsAfterResolution(array $requirementsToUpdate, if (!$dryRun) { $this->updateFile($this->json, $requirements, $requireKey, $removeKey, $sortPackages); - if ($locker->isLocked()) { + if ($locker->isLocked() && $composer->getConfig()->get('lock')) { $stabilityFlags = RootPackageLoader::extractStabilityFlags($requirements, $composer->getPackage()->getMinimumStability(), []); $locker->updateHash($this->json, function (array $lockData) use ($stabilityFlags) { foreach ($stabilityFlags as $packageName => $flag) { diff --git a/vendor/composer/composer/src/Composer/Compiler.php b/vendor/composer/composer/src/Composer/Compiler.php index def3ff8c4..591132c7f 100644 --- a/vendor/composer/composer/src/Composer/Compiler.php +++ b/vendor/composer/composer/src/Composer/Compiler.php @@ -15,6 +15,7 @@ use Composer\Json\JsonFile; use Composer\CaBundle\CaBundle; use Composer\Pcre\Preg; +use Composer\Util\ProcessExecutor; use Symfony\Component\Finder\Finder; use Symfony\Component\Process\Process; use Seld\PharUtils\Timestamps; @@ -48,23 +49,22 @@ public function compile(string $pharFile = 'composer.phar'): void unlink($pharFile); } - $process = new Process(['git', 'log', '--pretty=%H', '-n1', 'HEAD'], __DIR__); - if ($process->run() !== 0) { + $process = new ProcessExecutor(); + + if (0 !== $process->execute(['git', 'log', '--pretty=%H', '-n1', 'HEAD'], $output, dirname(dirname(__DIR__)))) { throw new \RuntimeException('Can\'t run git log. You must ensure to run compile from composer git repository clone and that git binary is available.'); } - $this->version = trim($process->getOutput()); + $this->version = trim($output); - $process = new Process(['git', 'log', '-n1', '--pretty=%ci', 'HEAD'], __DIR__); - if ($process->run() !== 0) { + if (0 !== $process->execute(['git', 'log', '-n1', '--pretty=%ci', 'HEAD'], $output, dirname(dirname(__DIR__)))) { throw new \RuntimeException('Can\'t run git log. You must ensure to run compile from composer git repository clone and that git binary is available.'); } - $this->versionDate = new \DateTime(trim($process->getOutput())); + $this->versionDate = new \DateTime(trim($output)); $this->versionDate->setTimezone(new \DateTimeZone('UTC')); - $process = new Process(['git', 'describe', '--tags', '--exact-match', 'HEAD'], __DIR__); - if ($process->run() === 0) { - $this->version = trim($process->getOutput()); + if (0 === $process->execute(['git', 'describe', '--tags', '--exact-match', 'HEAD'], $output, dirname(dirname(__DIR__)))) { + $this->version = trim($output); } else { // get branch-alias defined in composer.json for dev-main (if any) $localConfig = __DIR__.'/../../composer.json'; @@ -75,6 +75,10 @@ public function compile(string $pharFile = 'composer.phar'): void } } + if ('' === $this->version) { + throw new \UnexpectedValueException('Version detection failed'); + } + $phar = new \Phar($pharFile, 0, 'composer.phar'); $phar->setSignatureAlgorithm(\Phar::SHA512); diff --git a/vendor/composer/composer/src/Composer/Composer.php b/vendor/composer/composer/src/Composer/Composer.php index abb571359..234174462 100644 --- a/vendor/composer/composer/src/Composer/Composer.php +++ b/vendor/composer/composer/src/Composer/Composer.php @@ -51,9 +51,9 @@ class Composer extends PartialComposer * * @see getVersion() */ - public const VERSION = '2.8.2'; + public const VERSION = '2.8.3'; public const BRANCH_ALIAS_VERSION = ''; - public const RELEASE_DATE = '2024-10-29 16:12:11'; + public const RELEASE_DATE = '2024-11-17 13:13:04'; public const SOURCE_VERSION = ''; /** diff --git a/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php b/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php index c58d8601b..fa84ae0c0 100644 --- a/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php +++ b/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php @@ -598,7 +598,7 @@ private static function computeCheckForLowerPrioRepo(Pool $pool, bool $isVerbose if ($topPackage instanceof RootPackageInterface) { return [ "- Root composer.json requires $packageName".self::constraintToText($constraint).', it is ', - 'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' from '.$nextRepo->getRepoName().' but '.$topPackage->getPrettyName().' is the root package and cannot be modified. See https://getcomposer.org/dep-on-root for details and assistance.', + 'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' from '.$nextRepo->getRepoName().' but '.$topPackage->getPrettyName().' '.$topPackage->getPrettyVersion().' is the root package and cannot be modified. See https://getcomposer.org/dep-on-root for details and assistance.', ]; } } diff --git a/vendor/composer/composer/src/Composer/Downloader/FossilDownloader.php b/vendor/composer/composer/src/Composer/Downloader/FossilDownloader.php index 6634771dc..60c6ed49d 100644 --- a/vendor/composer/composer/src/Composer/Downloader/FossilDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/FossilDownloader.php @@ -12,10 +12,12 @@ namespace Composer\Downloader; +use Composer\Util\Platform; use React\Promise\PromiseInterface; use Composer\Package\PackageInterface; use Composer\Pcre\Preg; use Composer\Util\ProcessExecutor; +use RuntimeException; /** * @author BohwaZ @@ -38,22 +40,13 @@ protected function doInstall(PackageInterface $package, string $path, string $ur // Ensure we are allowed to use this URL by config $this->config->prohibitUrlByConfig($url, $this->io); - $url = ProcessExecutor::escape($url); - $ref = ProcessExecutor::escape($package->getSourceReference()); $repoFile = $path . '.fossil'; + $realPath = Platform::realpath($path); + $this->io->writeError("Cloning ".$package->getSourceReference()); - $command = sprintf('fossil clone -- %s %s', $url, ProcessExecutor::escape($repoFile)); - if (0 !== $this->process->execute($command, $ignoredOutput)) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); - } - $command = sprintf('fossil open --nested -- %s', ProcessExecutor::escape($repoFile)); - if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); - } - $command = sprintf('fossil update -- %s', $ref); - if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); - } + $this->execute(['fossil', 'clone', '--', $url, $repoFile]); + $this->execute(['fossil', 'open', '--nested', '--', $repoFile], $realPath); + $this->execute(['fossil', 'update', '--', (string) $package->getSourceReference()], $realPath); return \React\Promise\resolve(null); } @@ -66,17 +59,15 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, // Ensure we are allowed to use this URL by config $this->config->prohibitUrlByConfig($url, $this->io); - $ref = ProcessExecutor::escape($target->getSourceReference()); $this->io->writeError(" Updating to ".$target->getSourceReference()); if (!$this->hasMetadataRepository($path)) { throw new \RuntimeException('The .fslckout file is missing from '.$path.', see https://getcomposer.org/commit-deps for more information'); } - $command = sprintf('fossil pull && fossil up %s', $ref); - if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); - } + $realPath = Platform::realpath($path); + $this->execute(['fossil', 'pull'], $realPath); + $this->execute(['fossil', 'up', (string) $target->getSourceReference()], $realPath); return \React\Promise\resolve(null); } @@ -90,7 +81,7 @@ public function getLocalChanges(PackageInterface $package, string $path): ?strin return null; } - $this->process->execute('fossil changes', $output, realpath($path)); + $this->process->execute(['fossil', 'changes'], $output, Platform::realpath($path)); $output = trim($output); @@ -102,11 +93,7 @@ public function getLocalChanges(PackageInterface $package, string $path): ?strin */ protected function getCommitLogs(string $fromReference, string $toReference, string $path): string { - $command = sprintf('fossil timeline -t ci -W 0 -n 0 before %s', ProcessExecutor::escape($toReference)); - - if (0 !== $this->process->execute($command, $output, realpath($path))) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); - } + $this->execute(['fossil', 'timeline', '-t', 'ci', '-W', '0', '-n', '0', 'before', $toReference], Platform::realpath($path), $output); $log = ''; $match = '/\d\d:\d\d:\d\d\s+\[' . $toReference . '\]/'; @@ -121,6 +108,17 @@ protected function getCommitLogs(string $fromReference, string $toReference, str return $log; } + /** + * @param non-empty-list $command + * @throws \RuntimeException + */ + private function execute(array $command, ?string $cwd = null, ?string &$output = null): void + { + if (0 !== $this->process->execute($command, $output, $cwd)) { + throw new \RuntimeException('Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput()); + } + } + /** * @inheritDoc */ diff --git a/vendor/composer/composer/src/Composer/Downloader/GitDownloader.php b/vendor/composer/composer/src/Composer/Downloader/GitDownloader.php index f29d74522..e54d95473 100644 --- a/vendor/composer/composer/src/Composer/Downloader/GitDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/GitDownloader.php @@ -73,7 +73,7 @@ protected function doDownload(PackageInterface $package, string $path, string $u // --dissociate option is only available since git 2.3.0-rc0 if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=') && Cache::isUsable($cachePath)) { $this->io->writeError(" - Syncing " . $package->getName() . " (" . $package->getFullPrettyVersion() . ") into cache"); - $this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG); + $this->io->writeError(sprintf(' Cloning to cache at %s', $cachePath), true, IOInterface::DEBUG); $ref = $package->getSourceReference(); if ($this->gitUtil->fetchRefOrSyncMirror($url, $cachePath, $ref, $package->getPrettyVersion()) && is_dir($cachePath)) { $this->cachedPackages[$package->getId()][$ref] = true; @@ -94,24 +94,30 @@ protected function doInstall(PackageInterface $package, string $path, string $ur $path = $this->normalizePath($path); $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($url)).'/'; $ref = $package->getSourceReference(); - $flag = Platform::isWindows() ? '/D ' : ''; if (!empty($this->cachedPackages[$package->getId()][$ref])) { $msg = "Cloning ".$this->getShortHash($ref).' from cache'; - $cloneFlags = '--dissociate --reference %cachePath% '; + $cloneFlags = ['--dissociate', '--reference', $cachePath]; $transportOptions = $package->getTransportOptions(); if (isset($transportOptions['git']['single_use_clone']) && $transportOptions['git']['single_use_clone']) { - $cloneFlags = ''; + $cloneFlags = []; } - $command = - 'git clone --no-checkout %cachePath% %path% ' . $cloneFlags - . '&& cd '.$flag.'%path% ' - . '&& git remote set-url origin -- %sanitizedUrl% && git remote add composer -- %sanitizedUrl%'; + $commands = [ + array_merge(['git', 'clone', '--no-checkout', $cachePath, $path], $cloneFlags), + ['git', 'remote', 'set-url', 'origin', '--', '%sanitizedUrl%'], + ['git', 'remote', 'add', 'composer', '--', '%sanitizedUrl%'], + ]; } else { $msg = "Cloning ".$this->getShortHash($ref); - $command = 'git clone --no-checkout -- %url% %path% && cd '.$flag.'%path% && git remote add composer -- %url% && git fetch composer && git remote set-url origin -- %sanitizedUrl% && git remote set-url composer -- %sanitizedUrl%'; + $commands = [ + array_merge(['git', 'clone', '--no-checkout', '--', '%url%', $path]), + ['git', 'remote', 'add', 'composer', '--', '%url%'], + ['git', 'fetch', 'composer'], + ['git', 'remote', 'set-url', 'origin', '--', '%sanitizedUrl%'], + ['git', 'remote', 'set-url', 'composer', '--', '%sanitizedUrl%'], + ]; if (Platform::getEnv('COMPOSER_DISABLE_NETWORK')) { throw new \RuntimeException('The required git reference for '.$package->getName().' is not in cache and network is disabled, aborting'); } @@ -119,20 +125,8 @@ protected function doInstall(PackageInterface $package, string $path, string $ur $this->io->writeError($msg); - $commandCallable = static function (string $url) use ($path, $command, $cachePath): string { - return str_replace( - ['%url%', '%path%', '%cachePath%', '%sanitizedUrl%'], - [ - ProcessExecutor::escape($url), - ProcessExecutor::escape($path), - ProcessExecutor::escape($cachePath), - ProcessExecutor::escape(Preg::replace('{://([^@]+?):(.+?)@}', '://', $url)), - ], - $command - ); - }; + $this->gitUtil->runCommands($commands, $url, $path, true); - $this->gitUtil->runCommand($commandCallable, $url, $path, true); $sourceUrl = $package->getSourceUrl(); if ($url !== $sourceUrl && $sourceUrl !== null) { $this->updateOriginUrl($path, $sourceUrl); @@ -166,10 +160,10 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, if (!empty($this->cachedPackages[$target->getId()][$ref])) { $msg = "Checking out ".$this->getShortHash($ref).' from cache'; - $command = '(git rev-parse --quiet --verify %ref% || (git remote set-url composer -- %cachePath% && git fetch composer && git fetch --tags composer)) && git remote set-url composer -- %sanitizedUrl%'; + $remoteUrl = $cachePath; } else { $msg = "Checking out ".$this->getShortHash($ref); - $command = '(git remote set-url composer -- %url% && git rev-parse --quiet --verify %ref% || (git fetch composer && git fetch --tags composer)) && git remote set-url composer -- %sanitizedUrl%'; + $remoteUrl = '%url%'; if (Platform::getEnv('COMPOSER_DISABLE_NETWORK')) { throw new \RuntimeException('The required git reference for '.$target->getName().' is not in cache and network is disabled, aborting'); } @@ -177,20 +171,19 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, $this->io->writeError($msg); - $commandCallable = static function ($url) use ($ref, $command, $cachePath): string { - return str_replace( - ['%url%', '%ref%', '%cachePath%', '%sanitizedUrl%'], - [ - ProcessExecutor::escape($url), - ProcessExecutor::escape($ref.'^{commit}'), - ProcessExecutor::escape($cachePath), - ProcessExecutor::escape(Preg::replace('{://([^@]+?):(.+?)@}', '://', $url)), - ], - $command - ); - }; + if (0 !== $this->process->execute(['git', 'rev-parse', '--quiet', '--verify', $ref.'^{commit}'], $output, $path)) { + $commands = [ + ['git', 'remote', 'set-url', 'composer', '--', $remoteUrl], + ['git', 'fetch', 'composer'], + ['git', 'fetch', '--tags', 'composer'], + ]; + + $this->gitUtil->runCommands($commands, $url, $path); + } + + $command = ['git', 'remote', 'set-url', 'composer', '--', '%sanitizedUrl%']; + $this->gitUtil->runCommands([$command], $url, $path); - $this->gitUtil->runCommand($commandCallable, $url, $path); if ($newRef = $this->updateToCommit($target, $path, (string) $ref, $target->getPrettyVersion())) { if ($target->getDistReference() === $target->getSourceReference()) { $target->setDistReference($newRef); @@ -200,7 +193,7 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, $updateOriginUrl = false; if ( - 0 === $this->process->execute('git remote -v', $output, $path) + 0 === $this->process->execute(['git', 'remote', '-v'], $output, $path) && Preg::isMatch('{^origin\s+(?P\S+)}m', $output, $originMatch) && Preg::isMatch('{^composer\s+(?P\S+)}m', $output, $composerMatch) ) { @@ -225,9 +218,9 @@ public function getLocalChanges(PackageInterface $package, string $path): ?strin return null; } - $command = 'git status --porcelain --untracked-files=no'; + $command = ['git', 'status', '--porcelain', '--untracked-files=no']; if (0 !== $this->process->execute($command, $output, $path)) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); + throw new \RuntimeException('Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput()); } $output = trim($output); @@ -243,9 +236,9 @@ public function getUnpushedChanges(PackageInterface $package, string $path): ?st return null; } - $command = 'git show-ref --head -d'; + $command = ['git', 'show-ref', '--head', '-d']; if (0 !== $this->process->execute($command, $output, $path)) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); + throw new \RuntimeException('Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput()); } $refs = trim($output); @@ -310,12 +303,12 @@ public function getUnpushedChanges(PackageInterface $package, string $path): ?st // first pass and we found unpushed changes, fetch from all remotes to make sure we have up to date // remotes and then try again as outdated remotes can sometimes cause false-positives if ($unpushedChanges && $i === 0) { - $this->process->execute('git fetch --all', $output, $path); + $this->process->execute(['git', 'fetch', '--all'], $output, $path); // update list of refs after fetching - $command = 'git show-ref --head -d'; + $command = ['git', 'show-ref', '--head', '-d']; if (0 !== $this->process->execute($command, $output, $path)) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); + throw new \RuntimeException('Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput()); } $refs = trim($output); } @@ -425,7 +418,7 @@ protected function reapplyChanges(string $path): void if (!empty($this->hasStashedChanges[$path])) { unset($this->hasStashedChanges[$path]); $this->io->writeError(' Re-applying stashed changes'); - if (0 !== $this->process->execute('git stash pop', $output, $path)) { + if (0 !== $this->process->execute(['git', 'stash', 'pop'], $output, $path)) { throw new \RuntimeException("Failed to apply stashed changes:\n\n".$this->process->getErrorOutput()); } } @@ -441,18 +434,29 @@ protected function reapplyChanges(string $path): void */ protected function updateToCommit(PackageInterface $package, string $path, string $reference, string $prettyVersion): ?string { - $force = !empty($this->hasDiscardedChanges[$path]) || !empty($this->hasStashedChanges[$path]) ? '-f ' : ''; + $force = !empty($this->hasDiscardedChanges[$path]) || !empty($this->hasStashedChanges[$path]) ? ['-f'] : []; // This uses the "--" sequence to separate branch from file parameters. // // Otherwise git tries the branch name as well as file name. // If the non-existent branch is actually the name of a file, the file // is checked out. - $template = 'git checkout '.$force.'%s -- && git reset --hard %1$s --'; + $branch = Preg::replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $prettyVersion); + /** + * @var \Closure(non-empty-list): bool $execute + * @phpstan-ignore varTag.nativeType + */ + $execute = function (array $command) use (&$output, $path) { + /** @var non-empty-list $command */ + $output = ''; + + return 0 === $this->process->execute($command, $output, $path); + }; + $branches = null; - if (0 === $this->process->execute('git branch -r', $output, $path)) { + if ($execute(['git', 'branch', '-r'])) { $branches = $output; } @@ -462,8 +466,10 @@ protected function updateToCommit(PackageInterface $package, string $path, strin && null !== $branches && Preg::isMatch('{^\s+composer/'.preg_quote($reference).'$}m', $branches) ) { - $command = sprintf('git checkout '.$force.'-B %s %s -- && git reset --hard %2$s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$reference)); - if (0 === $this->process->execute($command, $output, $path)) { + $command1 = array_merge(['git', 'checkout'], $force, ['-B', $branch, 'composer/'.$reference, '--']); + $command2 = ['git', 'reset', '--hard', 'composer/'.$reference, '--']; + + if ($execute($command1) && $execute($command2)) { return null; } } @@ -475,17 +481,18 @@ protected function updateToCommit(PackageInterface $package, string $path, strin $branch = 'v' . $branch; } - $command = sprintf('git checkout %s --', ProcessExecutor::escape($branch)); - $fallbackCommand = sprintf('git checkout '.$force.'-B %s %s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$branch)); - $resetCommand = sprintf('git reset --hard %s --', ProcessExecutor::escape($reference)); + $command = ['git', 'checkout', $branch, '--']; + $fallbackCommand = array_merge(['git', 'checkout'], $force, ['-B', $branch, 'composer/'.$branch, '--']); + $resetCommand = ['git', 'reset', '--hard', $reference, '--']; - if (0 === $this->process->execute("($command || $fallbackCommand) && $resetCommand", $output, $path)) { + if (($execute($command) || $execute($fallbackCommand)) && $execute($resetCommand)) { return null; } } - $command = sprintf($template, ProcessExecutor::escape($gitRef)); - if (0 === $this->process->execute($command, $output, $path)) { + $command1 = array_merge(['git', 'checkout'], $force, [$gitRef, '--']); + $command2 = ['git', 'reset', '--hard', $gitRef, '--']; + if ($execute($command1) && $execute($command2)) { return null; } @@ -497,12 +504,14 @@ protected function updateToCommit(PackageInterface $package, string $path, strin $exceptionExtra = "\nIt looks like the commit hash is not available in the repository, maybe ".($package->isDev() ? 'the commit was removed from the branch' : 'the tag was recreated').'? Run "composer update '.$package->getPrettyName().'" to resolve this.'; } + $command = implode(' ', $command1). ' && '.implode(' ', $command2); + throw new \RuntimeException(Url::sanitize('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput() . $exceptionExtra)); } protected function updateOriginUrl(string $path, string $url): void { - $this->process->execute(sprintf('git remote set-url origin -- %s', ProcessExecutor::escape($url)), $output, $path); + $this->process->execute(['git', 'remote', 'set-url', 'origin', '--', $url], $output, $path); $this->setPushUrl($path, $url); } @@ -515,7 +524,7 @@ protected function setPushUrl(string $path, string $url): void if (!in_array('ssh', $protocols, true)) { $pushUrl = 'https://' . $match[1] . '/'.$match[2].'/'.$match[3].'.git'; } - $cmd = sprintf('git remote set-url --push origin -- %s', ProcessExecutor::escape($pushUrl)); + $cmd = ['git', 'remote', 'set-url', '--push', 'origin', '--', $pushUrl]; $this->process->execute($cmd, $ignoredOutput, $path); } } @@ -526,10 +535,10 @@ protected function setPushUrl(string $path, string $url): void protected function getCommitLogs(string $fromReference, string $toReference, string $path): string { $path = $this->normalizePath($path); - $command = sprintf('git log %s..%s --pretty=format:"%%h - %%an: %%s"'.GitUtil::getNoShowSignatureFlag($this->process), ProcessExecutor::escape($fromReference), ProcessExecutor::escape($toReference)); + $command = array_merge(['git', 'log', $fromReference.'..'.$toReference, '--pretty=format:%h - %an: %s'], GitUtil::getNoShowSignatureFlags($this->process)); if (0 !== $this->process->execute($command, $output, $path)) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); + throw new \RuntimeException('Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput()); } return $output; @@ -542,7 +551,10 @@ protected function getCommitLogs(string $fromReference, string $toReference, str protected function discardChanges(string $path): PromiseInterface { $path = $this->normalizePath($path); - if (0 !== $this->process->execute('git clean -df && git reset --hard', $output, $path)) { + if (0 !== $this->process->execute(['git', 'clean', '-df'], $output, $path)) { + throw new \RuntimeException("Could not reset changes\n\n:".$output); + } + if (0 !== $this->process->execute(['git', 'reset', '--hard'], $output, $path)) { throw new \RuntimeException("Could not reset changes\n\n:".$output); } @@ -558,7 +570,7 @@ protected function discardChanges(string $path): PromiseInterface protected function stashChanges(string $path): PromiseInterface { $path = $this->normalizePath($path); - if (0 !== $this->process->execute('git stash --include-untracked', $output, $path)) { + if (0 !== $this->process->execute(['git', 'stash', '--include-untracked'], $output, $path)) { throw new \RuntimeException("Could not stash changes\n\n:".$output); } @@ -573,7 +585,7 @@ protected function stashChanges(string $path): PromiseInterface protected function viewDiff(string $path): void { $path = $this->normalizePath($path); - if (0 !== $this->process->execute('git diff HEAD', $output, $path)) { + if (0 !== $this->process->execute(['git', 'diff', 'HEAD'], $output, $path)) { throw new \RuntimeException("Could not view diff\n\n:".$output); } diff --git a/vendor/composer/composer/src/Composer/Downloader/GzipDownloader.php b/vendor/composer/composer/src/Composer/Downloader/GzipDownloader.php index 9037f5226..010219822 100644 --- a/vendor/composer/composer/src/Composer/Downloader/GzipDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/GzipDownloader.php @@ -31,7 +31,7 @@ protected function extract(PackageInterface $package, string $file, string $path // Try to use gunzip on *nix if (!Platform::isWindows()) { - $command = 'gzip -cd -- ' . ProcessExecutor::escape($file) . ' > ' . ProcessExecutor::escape($targetFilepath); + $command = ['sh', '-c', 'gzip -cd -- "$0" > "$1"', $file, $targetFilepath]; if (0 === $this->process->execute($command, $ignoredOutput)) { return \React\Promise\resolve(null); @@ -44,7 +44,7 @@ protected function extract(PackageInterface $package, string $file, string $path return \React\Promise\resolve(null); } - $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(); + $processError = 'Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput(); throw new \RuntimeException($processError); } diff --git a/vendor/composer/composer/src/Composer/Downloader/HgDownloader.php b/vendor/composer/composer/src/Composer/Downloader/HgDownloader.php index b0cc9cd7d..4709ae35e 100644 --- a/vendor/composer/composer/src/Composer/Downloader/HgDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/HgDownloader.php @@ -41,16 +41,15 @@ protected function doInstall(PackageInterface $package, string $path, string $ur { $hgUtils = new HgUtils($this->io, $this->config, $this->process); - $cloneCommand = static function (string $url) use ($path): string { - return sprintf('hg clone -- %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($path)); + $cloneCommand = static function (string $url) use ($path): array { + return ['hg', 'clone', '--', $url, $path]; }; $hgUtils->runCommand($cloneCommand, $url, $path); - $ref = ProcessExecutor::escape($package->getSourceReference()); - $command = sprintf('hg up -- %s', $ref); + $command = ['hg', 'up', '--', (string) $package->getSourceReference()]; if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); + throw new \RuntimeException('Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput()); } return \React\Promise\resolve(null); @@ -70,10 +69,14 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, throw new \RuntimeException('The .hg directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information'); } - $command = static function ($url) use ($ref): string { - return sprintf('hg pull -- %s && hg up -- %s', ProcessExecutor::escape($url), ProcessExecutor::escape($ref)); + $command = static function ($url): array { + return ['hg', 'pull', '--', $url]; }; + $hgUtils->runCommand($command, $url, $path); + $command = static function () use ($ref): array { + return ['hg', 'up', '--', $ref]; + }; $hgUtils->runCommand($command, $url, $path); return \React\Promise\resolve(null); @@ -88,7 +91,7 @@ public function getLocalChanges(PackageInterface $package, string $path): ?strin return null; } - $this->process->execute('hg st', $output, realpath($path)); + $this->process->execute(['hg', 'st'], $output, realpath($path)); $output = trim($output); @@ -100,10 +103,10 @@ public function getLocalChanges(PackageInterface $package, string $path): ?strin */ protected function getCommitLogs(string $fromReference, string $toReference, string $path): string { - $command = sprintf('hg log -r %s:%s --style compact', ProcessExecutor::escape($fromReference), ProcessExecutor::escape($toReference)); + $command = ['hg', 'log', '-r', $fromReference.':'.$toReference, '--style', 'compact']; if (0 !== $this->process->execute($command, $output, realpath($path))) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); + throw new \RuntimeException('Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput()); } return $output; diff --git a/vendor/composer/composer/src/Composer/Downloader/RarDownloader.php b/vendor/composer/composer/src/Composer/Downloader/RarDownloader.php index a4142c655..04e16eaff 100644 --- a/vendor/composer/composer/src/Composer/Downloader/RarDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/RarDownloader.php @@ -34,13 +34,13 @@ protected function extract(PackageInterface $package, string $file, string $path // Try to use unrar on *nix if (!Platform::isWindows()) { - $command = 'unrar x -- ' . ProcessExecutor::escape($file) . ' ' . ProcessExecutor::escape($path) . ' >/dev/null && chmod -R u+w ' . ProcessExecutor::escape($path); + $command = ['sh', '-c', 'unrar x -- "$0" "$1" >/dev/null && chmod -R u+w "$1"', $file, $path]; if (0 === $this->process->execute($command, $ignoredOutput)) { return \React\Promise\resolve(null); } - $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(); + $processError = 'Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput(); } if (!class_exists('RarArchive')) { diff --git a/vendor/composer/composer/src/Composer/Downloader/SvnDownloader.php b/vendor/composer/composer/src/Composer/Downloader/SvnDownloader.php index be180d63d..ca88ea839 100644 --- a/vendor/composer/composer/src/Composer/Downloader/SvnDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/SvnDownloader.php @@ -59,7 +59,7 @@ protected function doInstall(PackageInterface $package, string $path, string $ur } $this->io->writeError(" Checking out ".$package->getSourceReference()); - $this->execute($package, $url, "svn co", sprintf("%s/%s", $url, $ref), null, $path); + $this->execute($package, $url, ['svn', 'co'], sprintf("%s/%s", $url, $ref), null, $path); return \React\Promise\resolve(null); } @@ -77,13 +77,13 @@ protected function doUpdate(PackageInterface $initial, PackageInterface $target, } $util = new SvnUtil($url, $this->io, $this->config, $this->process); - $flags = ""; + $flags = []; if (version_compare($util->binaryVersion(), '1.7.0', '>=')) { - $flags .= ' --ignore-ancestry'; + $flags[] = '--ignore-ancestry'; } $this->io->writeError(" Checking out " . $ref); - $this->execute($target, $url, "svn switch" . $flags, sprintf("%s/%s", $url, $ref), $path); + $this->execute($target, $url, array_merge(['svn', 'switch'], $flags), sprintf("%s/%s", $url, $ref), $path); return \React\Promise\resolve(null); } @@ -97,7 +97,7 @@ public function getLocalChanges(PackageInterface $package, string $path): ?strin return null; } - $this->process->execute('svn status --ignore-externals', $output, $path); + $this->process->execute(['svn', 'status', '--ignore-externals'], $output, $path); return Preg::isMatch('{^ *[^X ] +}m', $output) ? $output : null; } @@ -107,13 +107,13 @@ public function getLocalChanges(PackageInterface $package, string $path): ?strin * if necessary. * * @param string $baseUrl Base URL of the repository - * @param string $command SVN command to run + * @param non-empty-list $command SVN command to run * @param string $url SVN url * @param string $cwd Working directory * @param string $path Target for a checkout * @throws \RuntimeException */ - protected function execute(PackageInterface $package, string $baseUrl, string $command, string $url, ?string $cwd = null, ?string $path = null): string + protected function execute(PackageInterface $package, string $baseUrl, array $command, string $url, ?string $cwd = null, ?string $path = null): string { $util = new SvnUtil($baseUrl, $this->io, $this->config, $this->process); $util->setCacheCredentials($this->cacheCredentials); @@ -194,10 +194,10 @@ protected function getCommitLogs(string $fromReference, string $toReference, str { if (Preg::isMatch('{@(\d+)$}', $fromReference) && Preg::isMatch('{@(\d+)$}', $toReference)) { // retrieve the svn base url from the checkout folder - $command = sprintf('svn info --non-interactive --xml -- %s', ProcessExecutor::escape($path)); + $command = ['svn', 'info', '--non-interactive', '--xml', '--', $path]; if (0 !== $this->process->execute($command, $output, $path)) { throw new \RuntimeException( - 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput() + 'Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput() ); } @@ -214,7 +214,7 @@ protected function getCommitLogs(string $fromReference, string $toReference, str $fromRevision = Preg::replace('{.*@(\d+)$}', '$1', $fromReference); $toRevision = Preg::replace('{.*@(\d+)$}', '$1', $toReference); - $command = sprintf('svn log -r%s:%s --incremental', ProcessExecutor::escape($fromRevision), ProcessExecutor::escape($toRevision)); + $command = ['svn', 'log', '-r', $fromRevision.':'.$toRevision, '--incremental']; $util = new SvnUtil($baseUrl, $this->io, $this->config, $this->process); $util->setCacheCredentials($this->cacheCredentials); @@ -222,7 +222,7 @@ protected function getCommitLogs(string $fromReference, string $toReference, str return $util->executeLocal($command, $path, null, $this->io->isVerbose()); } catch (\RuntimeException $e) { throw new \RuntimeException( - 'Failed to execute ' . $command . "\n\n".$e->getMessage() + 'Failed to execute ' . implode(' ', $command) . "\n\n".$e->getMessage() ); } } @@ -235,7 +235,7 @@ protected function getCommitLogs(string $fromReference, string $toReference, str */ protected function discardChanges(string $path): PromiseInterface { - if (0 !== $this->process->execute('svn revert -R .', $output, $path)) { + if (0 !== $this->process->execute(['svn', 'revert', '-R', '.'], $output, $path)) { throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput()); } diff --git a/vendor/composer/composer/src/Composer/Downloader/XzDownloader.php b/vendor/composer/composer/src/Composer/Downloader/XzDownloader.php index 8c44cd199..286d32cff 100644 --- a/vendor/composer/composer/src/Composer/Downloader/XzDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/XzDownloader.php @@ -26,13 +26,13 @@ class XzDownloader extends ArchiveDownloader { protected function extract(PackageInterface $package, string $file, string $path): PromiseInterface { - $command = 'tar -xJf ' . ProcessExecutor::escape($file) . ' -C ' . ProcessExecutor::escape($path); + $command = ['tar', '-xJf', $file, '-C', $path]; if (0 === $this->process->execute($command, $ignoredOutput)) { return \React\Promise\resolve(null); } - $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(); + $processError = 'Failed to execute ' . implode(' ', $command) . "\n\n" . $this->process->getErrorOutput(); throw new \RuntimeException($processError); } diff --git a/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php b/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php index 1904668be..54d23a5c6 100644 --- a/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php +++ b/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php @@ -27,7 +27,7 @@ */ class ZipDownloader extends ArchiveDownloader { - /** @var array */ + /** @var array> */ private static $unzipCommands; /** @var bool */ private static $hasZipArchive; @@ -46,16 +46,16 @@ public function download(PackageInterface $package, string $path, ?PackageInterf self::$unzipCommands = []; $finder = new ExecutableFinder; if (Platform::isWindows() && ($cmd = $finder->find('7z', null, ['C:\Program Files\7-Zip']))) { - self::$unzipCommands[] = ['7z', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s']; + self::$unzipCommands[] = ['7z', $cmd, 'x', '-bb0', '-y', '%file%', '-o%path%']; } if ($cmd = $finder->find('unzip')) { - self::$unzipCommands[] = ['unzip', ProcessExecutor::escape($cmd).' -qq %s -d %s']; + self::$unzipCommands[] = ['unzip', $cmd, '-qq', '%file%', '-d', '%path%']; } if (!Platform::isWindows() && ($cmd = $finder->find('7z'))) { // 7z linux/macOS support is only used if unzip is not present - self::$unzipCommands[] = ['7z', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s']; + self::$unzipCommands[] = ['7z', $cmd, 'x', '-bb0', '-y', '%file%', '-o%path%']; } if (!Platform::isWindows() && ($cmd = $finder->find('7zz'))) { // 7zz linux/macOS support is only used if unzip is not present - self::$unzipCommands[] = ['7zz', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s']; + self::$unzipCommands[] = ['7zz', $cmd, 'x', '-bb0', '-y', '%file%', '-o%path%']; } } @@ -114,24 +114,28 @@ private function extractWithSystemUnzip(PackageInterface $package, string $file, // Force Exception throwing if the other alternative extraction method is not available $isLastChance = !self::$hasZipArchive; - if (!self::$unzipCommands) { + if (0 === \count(self::$unzipCommands)) { // This was call as the favorite extract way, but is not available // We switch to the alternative return $this->extractWithZipArchive($package, $file, $path); } $commandSpec = reset(self::$unzipCommands); - $command = sprintf($commandSpec[1], ProcessExecutor::escape($file), ProcessExecutor::escape($path)); - // normalize separators to backslashes to avoid problems with 7-zip on windows - // see https://github.com/composer/composer/issues/10058 - if (Platform::isWindows()) { - $command = sprintf($commandSpec[1], ProcessExecutor::escape(strtr($file, '/', '\\')), ProcessExecutor::escape(strtr($path, '/', '\\'))); - } - $executable = $commandSpec[0]; + $command = array_slice($commandSpec, 1); + $map = [ + // normalize separators to backslashes to avoid problems with 7-zip on windows + // see https://github.com/composer/composer/issues/10058 + '%file%' => strtr($file, '/', DIRECTORY_SEPARATOR), + '%path%' => strtr($path, '/', DIRECTORY_SEPARATOR), + ]; + $command = array_map(static function ($value) use ($map) { + return strtr($value, $map); + }, $command); + if (!$warned7ZipLinux && !Platform::isWindows() && in_array($executable, ['7z', '7zz'], true)) { $warned7ZipLinux = true; - if (0 === $this->process->execute($executable, $output)) { + if (0 === $this->process->execute([$commandSpec[1]], $output)) { if (Preg::isMatchStrictGroups('{^\s*7-Zip(?: \[64\])? ([0-9.]+)}', $output, $match) && version_compare($match[1], '21.01', '<')) { $this->io->writeError(' Unzipping using '.$executable.' '.$match[1].' may result in incorrect file permissions. Install '.$executable.' 21.01+ or unzip to ensure you get correct permissions.'); } @@ -186,7 +190,7 @@ private function extractWithSystemUnzip(PackageInterface $package, string $file, $output = $process->getErrorOutput(); $output = str_replace(', '.$file.'.zip or '.$file.'.ZIP', '', $output); - return $tryFallback(new \RuntimeException('Failed to extract '.$package->getName().': ('.$process->getExitCode().') '.$command."\n\n".$output)); + return $tryFallback(new \RuntimeException('Failed to extract '.$package->getName().': ('.$process->getExitCode().') '.implode(' ', $command)."\n\n".$output)); } }); } catch (\Throwable $e) { diff --git a/vendor/composer/composer/src/Composer/Package/Locker.php b/vendor/composer/composer/src/Composer/Package/Locker.php index 160031a30..38cd8ef3a 100644 --- a/vendor/composer/composer/src/Composer/Package/Locker.php +++ b/vendor/composer/composer/src/Composer/Package/Locker.php @@ -554,13 +554,14 @@ private function getPackageTime(PackageInterface $package): ?string case 'git': GitUtil::cleanEnv(); - if (0 === $this->process->execute('git log -n1 --pretty=%ct '.ProcessExecutor::escape($sourceRef).GitUtil::getNoShowSignatureFlag($this->process), $output, $path) && Preg::isMatch('{^\s*\d+\s*$}', $output)) { + $command = array_merge(['git', 'log', '-n1', '--pretty=%ct', (string) $sourceRef], GitUtil::getNoShowSignatureFlags($this->process)); + if (0 === $this->process->execute($command, $output, $path) && Preg::isMatch('{^\s*\d+\s*$}', $output)) { $datetime = new \DateTime('@'.trim($output), new \DateTimeZone('UTC')); } break; case 'hg': - if (0 === $this->process->execute('hg log --template "{date|hgdate}" -r '.ProcessExecutor::escape($sourceRef), $output, $path) && Preg::isMatch('{^\s*(\d+)\s*}', $output, $match)) { + if (0 === $this->process->execute(['hg', 'log', '--template', '{date|hgdate}', '-r', (string) $sourceRef], $output, $path) && Preg::isMatch('{^\s*(\d+)\s*}', $output, $match)) { $datetime = new \DateTime('@'.$match[1], new \DateTimeZone('UTC')); } break; diff --git a/vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php b/vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php index 8a0fe9c14..7e0f8278e 100644 --- a/vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php +++ b/vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php @@ -198,7 +198,7 @@ private function guessGitVersion(array $packageConfig, string $path): array } if (null === $commit) { - $command = 'git log --pretty="%H" -n1 HEAD'.GitUtil::getNoShowSignatureFlag($this->process); + $command = array_merge(['git', 'log', '--pretty=%H', '-n1', 'HEAD'], GitUtil::getNoShowSignatureFlags($this->process)); if (0 === $this->process->execute($command, $output, $path)) { $commit = trim($output) ?: null; } @@ -217,7 +217,7 @@ private function guessGitVersion(array $packageConfig, string $path): array private function versionFromGitTags(string $path): ?array { // try to fetch current version from git tags - if (0 === $this->process->execute('git describe --exact-match --tags', $output, $path)) { + if (0 === $this->process->execute(['git', 'describe', '--exact-match', '--tags'], $output, $path)) { try { $version = $this->versionParser->normalize(trim($output)); @@ -237,7 +237,7 @@ private function versionFromGitTags(string $path): ?array private function guessHgVersion(array $packageConfig, string $path): ?array { // try to fetch current version from hg branch - if (0 === $this->process->execute('hg branch', $output, $path)) { + if (0 === $this->process->execute(['hg', 'branch'], $output, $path)) { $branch = trim($output); $version = $this->versionParser->normalizeBranch($branch); $isFeatureBranch = 0 === strpos($version, 'dev-'); @@ -375,14 +375,14 @@ private function guessFossilVersion(string $path): array $prettyVersion = null; // try to fetch current version from fossil - if (0 === $this->process->execute('fossil branch list', $output, $path)) { + if (0 === $this->process->execute(['fossil', 'branch', 'list'], $output, $path)) { $branch = trim($output); $version = $this->versionParser->normalizeBranch($branch); $prettyVersion = 'dev-' . $branch; } // try to fetch current version from fossil tags - if (0 === $this->process->execute('fossil tag list', $output, $path)) { + if (0 === $this->process->execute(['fossil', 'tag', 'list'], $output, $path)) { try { $version = $this->versionParser->normalize(trim($output)); $prettyVersion = trim($output); @@ -403,7 +403,7 @@ private function guessSvnVersion(array $packageConfig, string $path): ?array SvnUtil::cleanEnv(); // try to fetch current version from svn - if (0 === $this->process->execute('svn info --xml', $output, $path)) { + if (0 === $this->process->execute(['svn', 'info', '--xml'], $output, $path)) { $trunkPath = isset($packageConfig['trunk-path']) ? preg_quote($packageConfig['trunk-path'], '#') : 'trunk'; $branchesPath = isset($packageConfig['branches-path']) ? preg_quote($packageConfig['branches-path'], '#') : 'branches'; $tagsPath = isset($packageConfig['tags-path']) ? preg_quote($packageConfig['tags-path'], '#') : 'tags'; diff --git a/vendor/composer/composer/src/Composer/Platform/HhvmDetector.php b/vendor/composer/composer/src/Composer/Platform/HhvmDetector.php index 46886c353..284b0ba8a 100644 --- a/vendor/composer/composer/src/Composer/Platform/HhvmDetector.php +++ b/vendor/composer/composer/src/Composer/Platform/HhvmDetector.php @@ -49,11 +49,7 @@ public function getVersion(): ?string $hhvmPath = $this->executableFinder->find('hhvm'); if ($hhvmPath !== null) { $this->processExecutor = $this->processExecutor ?? new ProcessExecutor(); - $exitCode = $this->processExecutor->execute( - ProcessExecutor::escape($hhvmPath). - ' --php -d hhvm.jit=0 -r "echo HHVM_VERSION;" 2>/dev/null', - self::$hhvmVersion - ); + $exitCode = $this->processExecutor->execute([$hhvmPath, '--php', '-d', 'hhvm.jit=0', '-r', 'echo HHVM_VERSION;'], self::$hhvmVersion); if ($exitCode !== 0) { self::$hhvmVersion = false; } diff --git a/vendor/composer/composer/src/Composer/Repository/InstalledRepository.php b/vendor/composer/composer/src/Composer/Repository/InstalledRepository.php index e3b52079e..3520fdec6 100644 --- a/vendor/composer/composer/src/Composer/Repository/InstalledRepository.php +++ b/vendor/composer/composer/src/Composer/Repository/InstalledRepository.php @@ -84,7 +84,7 @@ public function findPackagesWithReplacersAndProviders(string $name, $constraint * @param string[] $packagesFound Used internally when recurring * * @return array[] An associative array of arrays as described above. - * @phpstan-return array + * @phpstan-return array|false}> */ public function getDependents($needle, ?ConstraintInterface $constraint = null, bool $invert = false, bool $recurse = true, ?array $packagesFound = null): array { @@ -137,6 +137,7 @@ public function getDependents($needle, ?ConstraintInterface $constraint = null, } } } + unset($needle); } // Require-dev is only relevant for the root package @@ -163,7 +164,7 @@ public function getDependents($needle, ?ConstraintInterface $constraint = null, } // When inverting, we need to check for conflicts of the needles against installed packages - if ($invert && in_array($package->getName(), $needles)) { + if ($invert && in_array($package->getName(), $needles, true)) { foreach ($package->getConflicts() as $link) { foreach ($this->findPackages($link->getTarget()) as $pkg) { $version = new Constraint('=', $pkg->getVersion()); @@ -176,7 +177,7 @@ public function getDependents($needle, ?ConstraintInterface $constraint = null, // List conflicts against X as they may explain why the current version was selected, or explain why it is rejected if the conflict matched when inverting foreach ($package->getConflicts() as $link) { - if (in_array($link->getTarget(), $needles)) { + if (in_array($link->getTarget(), $needles, true)) { foreach ($this->findPackages($link->getTarget()) as $pkg) { $version = new Constraint('=', $pkg->getVersion()); if ($link->getConstraint()->matches($version) === $invert) { @@ -187,7 +188,7 @@ public function getDependents($needle, ?ConstraintInterface $constraint = null, } // When inverting, we need to check for conflicts of the needles' requirements against installed packages - if ($invert && $constraint && in_array($package->getName(), $needles) && $constraint->matches(new Constraint('=', $package->getVersion()))) { + if ($invert && $constraint && in_array($package->getName(), $needles, true) && $constraint->matches(new Constraint('=', $package->getVersion()))) { foreach ($package->getRequires() as $link) { if (PlatformRepository::isPlatformPackage($link->getTarget())) { if ($this->findPackage($link->getTarget(), $link->getConstraint())) { diff --git a/vendor/composer/composer/src/Composer/Repository/PathRepository.php b/vendor/composer/composer/src/Composer/Repository/PathRepository.php index 4e99bd415..0b8d99236 100644 --- a/vendor/composer/composer/src/Composer/Repository/PathRepository.php +++ b/vendor/composer/composer/src/Composer/Repository/PathRepository.php @@ -194,8 +194,8 @@ protected function initialize(): void // carry over the root package version if this path repo is in the same git repository as root package if (!isset($package['version']) && ($rootVersion = Platform::getEnv('COMPOSER_ROOT_VERSION'))) { if ( - 0 === $this->process->execute('git rev-parse HEAD', $ref1, $path) - && 0 === $this->process->execute('git rev-parse HEAD', $ref2) + 0 === $this->process->execute(['git', 'rev-parse', 'HEAD'], $ref1, $path) + && 0 === $this->process->execute(['git', 'rev-parse', 'HEAD'], $ref2) && $ref1 === $ref2 ) { $package['version'] = $this->versionGuesser->getRootVersionFromEnv(); @@ -203,7 +203,7 @@ protected function initialize(): void } $output = ''; - if ('auto' === $reference && is_dir($path . DIRECTORY_SEPARATOR . '.git') && 0 === $this->process->execute('git log -n1 --pretty=%H'.GitUtil::getNoShowSignatureFlag($this->process), $output, $path)) { + if ('auto' === $reference && is_dir($path . DIRECTORY_SEPARATOR . '.git') && 0 === $this->process->execute(array_merge(['git', 'log', '-n1', '--pretty=%H'], GitUtil::getNoShowSignatureFlags($this->process)), $output, $path)) { $package['dist']['reference'] = trim($output); } diff --git a/vendor/composer/composer/src/Composer/Repository/Vcs/FossilDriver.php b/vendor/composer/composer/src/Composer/Repository/Vcs/FossilDriver.php index e55b0d3ac..8a305216c 100644 --- a/vendor/composer/composer/src/Composer/Repository/Vcs/FossilDriver.php +++ b/vendor/composer/composer/src/Composer/Repository/Vcs/FossilDriver.php @@ -71,7 +71,7 @@ public function initialize(): void */ protected function checkFossil(): void { - if (0 !== $this->process->execute('fossil version', $ignoredOutput)) { + if (0 !== $this->process->execute(['fossil', 'version'], $ignoredOutput)) { throw new \RuntimeException("fossil was not found, check that it is installed and in your PATH env.\n\n" . $this->process->getErrorOutput()); } } @@ -81,6 +81,8 @@ protected function checkFossil(): void */ protected function updateLocalRepo(): void { + assert($this->repoFile !== null); + $fs = new Filesystem(); $fs->ensureDirectoryExists($this->checkoutDir); @@ -89,8 +91,8 @@ protected function updateLocalRepo(): void } // update the repo if it is a valid fossil repository - if (is_file($this->repoFile) && is_dir($this->checkoutDir) && 0 === $this->process->execute('fossil info', $output, $this->checkoutDir)) { - if (0 !== $this->process->execute('fossil pull', $output, $this->checkoutDir)) { + if (is_file($this->repoFile) && is_dir($this->checkoutDir) && 0 === $this->process->execute(['fossil', 'info'], $output, $this->checkoutDir)) { + if (0 !== $this->process->execute(['fossil', 'pull'], $output, $this->checkoutDir)) { $this->io->writeError('Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')'); } } else { @@ -100,13 +102,13 @@ protected function updateLocalRepo(): void $fs->ensureDirectoryExists($this->checkoutDir); - if (0 !== $this->process->execute(sprintf('fossil clone -- %s %s', ProcessExecutor::escape($this->url), ProcessExecutor::escape($this->repoFile)), $output)) { + if (0 !== $this->process->execute(['fossil', 'clone', '--', $this->url, $this->repoFile], $output)) { $output = $this->process->getErrorOutput(); throw new \RuntimeException('Failed to clone '.$this->url.' to repository ' . $this->repoFile . "\n\n" .$output); } - if (0 !== $this->process->execute(sprintf('fossil open --nested -- %s', ProcessExecutor::escape($this->repoFile)), $output, $this->checkoutDir)) { + if (0 !== $this->process->execute(['fossil', 'open', '--nested', '--', $this->repoFile], $output, $this->checkoutDir)) { $output = $this->process->getErrorOutput(); throw new \RuntimeException('Failed to open repository '.$this->repoFile.' in ' . $this->checkoutDir . "\n\n" .$output); @@ -155,10 +157,9 @@ public function getDist(string $identifier): ?array */ public function getFileContent(string $file, string $identifier): ?string { - $command = sprintf('fossil cat -r %s -- %s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file)); - $this->process->execute($command, $content, $this->checkoutDir); + $this->process->execute(['fossil', 'cat', '-r', $identifier, '--', $file], $content, $this->checkoutDir); - if (!trim($content)) { + if ('' === trim($content)) { return null; } @@ -170,7 +171,7 @@ public function getFileContent(string $file, string $identifier): ?string */ public function getChangeDate(string $identifier): ?\DateTimeImmutable { - $this->process->execute('fossil finfo -b -n 1 composer.json', $output, $this->checkoutDir); + $this->process->execute(['fossil', 'finfo', '-b', '-n', '1', 'composer.json'], $output, $this->checkoutDir); [, $date] = explode(' ', trim($output), 3); return new \DateTimeImmutable($date, new \DateTimeZone('UTC')); @@ -184,7 +185,7 @@ public function getTags(): array if (null === $this->tags) { $tags = []; - $this->process->execute('fossil tag list', $output, $this->checkoutDir); + $this->process->execute(['fossil', 'tag', 'list'], $output, $this->checkoutDir); foreach ($this->process->splitLines($output) as $tag) { $tags[$tag] = $tag; } @@ -203,7 +204,7 @@ public function getBranches(): array if (null === $this->branches) { $branches = []; - $this->process->execute('fossil branch list', $output, $this->checkoutDir); + $this->process->execute(['fossil', 'branch', 'list'], $output, $this->checkoutDir); foreach ($this->process->splitLines($output) as $branch) { $branch = trim(Preg::replace('/^\*/', '', trim($branch))); $branches[$branch] = $branch; @@ -237,7 +238,7 @@ public static function supports(IOInterface $io, Config $config, string $url, bo $process = new ProcessExecutor($io); // check whether there is a fossil repo in that path - if ($process->execute('fossil info', $output, $url) === 0) { + if ($process->execute(['fossil', 'info'], $output, $url) === 0) { return true; } } diff --git a/vendor/composer/composer/src/Composer/Repository/Vcs/GitDriver.php b/vendor/composer/composer/src/Composer/Repository/Vcs/GitDriver.php index 57bc9b2ef..7be1faba0 100644 --- a/vendor/composer/composer/src/Composer/Repository/Vcs/GitDriver.php +++ b/vendor/composer/composer/src/Composer/Repository/Vcs/GitDriver.php @@ -102,7 +102,7 @@ public function getRootIdentifier(): string } // select currently checked out branch as default branch - $this->process->execute('git branch --no-color', $output, $this->repoDir); + $this->process->execute(['git', 'branch', '--no-color'], $output, $this->repoDir); $branches = $this->process->splitLines($output); if (!in_array('* master', $branches)) { foreach ($branches as $branch) { @@ -150,8 +150,7 @@ public function getFileContent(string $file, string $identifier): ?string throw new \RuntimeException('Invalid git identifier detected. Identifier must not start with a -, given: ' . $identifier); } - $resource = sprintf('%s:%s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file)); - $this->process->execute(sprintf('git show %s', $resource), $content, $this->repoDir); + $this->process->execute(['git', 'show', $identifier.':'.$file], $content, $this->repoDir); if (trim($content) === '') { return null; @@ -165,10 +164,7 @@ public function getFileContent(string $file, string $identifier): ?string */ public function getChangeDate(string $identifier): ?\DateTimeImmutable { - $this->process->execute(sprintf( - 'git -c log.showSignature=false log -1 --format=%%at %s', - ProcessExecutor::escape($identifier) - ), $output, $this->repoDir); + $this->process->execute(['git', '-c', 'log.showSignature=false', 'log', '-1', '--format=%at', $identifier], $output, $this->repoDir); return new \DateTimeImmutable('@'.trim($output), new \DateTimeZone('UTC')); } @@ -181,7 +177,7 @@ public function getTags(): array if (null === $this->tags) { $this->tags = []; - $this->process->execute('git show-ref --tags --dereference', $output, $this->repoDir); + $this->process->execute(['git', 'show-ref', '--tags', '--dereference'], $output, $this->repoDir); foreach ($this->process->splitLines($output) as $tag) { if ($tag !== '' && Preg::isMatch('{^([a-f0-9]{40}) refs/tags/(\S+?)(\^\{\})?$}', $tag, $match)) { $this->tags[$match[2]] = $match[1]; @@ -200,7 +196,7 @@ public function getBranches(): array if (null === $this->branches) { $branches = []; - $this->process->execute('git branch --no-color --no-abbrev -v', $output, $this->repoDir); + $this->process->execute(['git', 'branch', '--no-color', '--no-abbrev', '-v'], $output, $this->repoDir); foreach ($this->process->splitLines($output) as $branch) { if ($branch !== '' && !Preg::isMatch('{^ *[^/]+/HEAD }', $branch)) { if (Preg::isMatchStrictGroups('{^(?:\* )? *(\S+) *([a-f0-9]+)(?: .*)?$}', $branch, $match) && $match[1][0] !== '-') { @@ -233,7 +229,7 @@ public static function supports(IOInterface $io, Config $config, string $url, bo $process = new ProcessExecutor($io); // check whether there is a git repo in that path - if ($process->execute('git tag', $output, $url) === 0) { + if ($process->execute(['git', 'tag'], $output, $url) === 0) { return true; } GitUtil::checkForRepoOwnershipError($process->getErrorOutput(), $url); @@ -247,9 +243,7 @@ public static function supports(IOInterface $io, Config $config, string $url, bo GitUtil::cleanEnv(); try { - $gitUtil->runCommand(static function ($url): string { - return 'git ls-remote --heads -- ' . ProcessExecutor::escape($url); - }, $url, sys_get_temp_dir()); + $gitUtil->runCommands([['git', 'ls-remote', '--heads', '--', '%url%']], $url, sys_get_temp_dir()); } catch (\RuntimeException $e) { return false; } diff --git a/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php b/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php index e468ca746..625a2a1eb 100644 --- a/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php +++ b/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php @@ -63,8 +63,8 @@ public function initialize(): void $hgUtils = new HgUtils($this->io, $this->config, $this->process); // update the repo if it is a valid hg repository - if (is_dir($this->repoDir) && 0 === $this->process->execute('hg summary', $output, $this->repoDir)) { - if (0 !== $this->process->execute('hg pull', $output, $this->repoDir)) { + if (is_dir($this->repoDir) && 0 === $this->process->execute(['hg', 'summary'], $output, $this->repoDir)) { + if (0 !== $this->process->execute(['hg', 'pull'], $output, $this->repoDir)) { $this->io->writeError('Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')'); } } else { @@ -72,8 +72,8 @@ public function initialize(): void $fs->removeDirectory($this->repoDir); $repoDir = $this->repoDir; - $command = static function ($url) use ($repoDir): string { - return sprintf('hg clone --noupdate -- %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($repoDir)); + $command = static function ($url) use ($repoDir): array { + return ['hg', 'clone', '--noupdate', '--', $url, $repoDir]; }; $hgUtils->runCommand($command, $this->url, null); @@ -90,7 +90,7 @@ public function initialize(): void public function getRootIdentifier(): string { if (null === $this->rootIdentifier) { - $this->process->execute('hg tip --template "{node}"', $output, $this->repoDir); + $this->process->execute(['hg', 'tip', '--template', '{node}'], $output, $this->repoDir); $output = $this->process->splitLines($output); $this->rootIdentifier = $output[0]; } @@ -131,7 +131,7 @@ public function getFileContent(string $file, string $identifier): ?string throw new \RuntimeException('Invalid hg identifier detected. Identifier must not start with a -, given: ' . $identifier); } - $resource = sprintf('hg cat -r %s -- %s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file)); + $resource = ['hg', 'cat', '-r', $identifier, '--', $file]; $this->process->execute($resource, $content, $this->repoDir); if (!trim($content)) { @@ -147,10 +147,7 @@ public function getFileContent(string $file, string $identifier): ?string public function getChangeDate(string $identifier): ?\DateTimeImmutable { $this->process->execute( - sprintf( - 'hg log --template "{date|rfc3339date}" -r %s', - ProcessExecutor::escape($identifier) - ), + ['hg', 'log', '--template', '{date|rfc3339date}', '-r', $identifier], $output, $this->repoDir ); @@ -166,7 +163,7 @@ public function getTags(): array if (null === $this->tags) { $tags = []; - $this->process->execute('hg tags', $output, $this->repoDir); + $this->process->execute(['hg', 'tags'], $output, $this->repoDir); foreach ($this->process->splitLines($output) as $tag) { if ($tag && Preg::isMatchStrictGroups('(^([^\s]+)\s+\d+:(.*)$)', $tag, $match)) { $tags[$match[1]] = $match[2]; @@ -189,14 +186,14 @@ public function getBranches(): array $branches = []; $bookmarks = []; - $this->process->execute('hg branches', $output, $this->repoDir); + $this->process->execute(['hg', 'branches'], $output, $this->repoDir); foreach ($this->process->splitLines($output) as $branch) { if ($branch && Preg::isMatchStrictGroups('(^([^\s]+)\s+\d+:([a-f0-9]+))', $branch, $match) && $match[1][0] !== '-') { $branches[$match[1]] = $match[2]; } } - $this->process->execute('hg bookmarks', $output, $this->repoDir); + $this->process->execute(['hg', 'bookmarks'], $output, $this->repoDir); foreach ($this->process->splitLines($output) as $branch) { if ($branch && Preg::isMatchStrictGroups('(^(?:[\s*]*)([^\s]+)\s+\d+:(.*)$)', $branch, $match) && $match[1][0] !== '-') { $bookmarks[$match[1]] = $match[2]; @@ -228,7 +225,7 @@ public static function supports(IOInterface $io, Config $config, string $url, bo $process = new ProcessExecutor($io); // check whether there is a hg repo in that path - if ($process->execute('hg summary', $output, $url) === 0) { + if ($process->execute(['hg', 'summary'], $output, $url) === 0) { return true; } } @@ -238,7 +235,7 @@ public static function supports(IOInterface $io, Config $config, string $url, bo } $process = new ProcessExecutor($io); - $exit = $process->execute(sprintf('hg identify -- %s', ProcessExecutor::escape($url)), $ignored); + $exit = $process->execute(['hg', 'identify', '--', $url], $ignored); return $exit === 0; } diff --git a/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php b/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php index d4f318079..9a303ee14 100644 --- a/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php +++ b/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php @@ -187,7 +187,7 @@ public function getFileContent(string $file, string $identifier): ?string try { $resource = $path.$file; - $output = $this->execute('svn cat', $this->baseUrl . $resource . $rev); + $output = $this->execute(['svn', 'cat'], $this->baseUrl . $resource . $rev); if ('' === trim($output)) { return null; } @@ -213,7 +213,7 @@ public function getChangeDate(string $identifier): ?\DateTimeImmutable $rev = ''; } - $output = $this->execute('svn info', $this->baseUrl . $path . $rev); + $output = $this->execute(['svn', 'info'], $this->baseUrl . $path . $rev); foreach ($this->process->splitLines($output) as $line) { if ($line !== '' && Preg::isMatchStrictGroups('{^Last Changed Date: ([^(]+)}', $line, $match)) { return new \DateTimeImmutable($match[1], new \DateTimeZone('UTC')); @@ -232,7 +232,7 @@ public function getTags(): array $tags = []; if ($this->tagsPath !== false) { - $output = $this->execute('svn ls --verbose', $this->baseUrl . '/' . $this->tagsPath); + $output = $this->execute(['svn', 'ls', '--verbose'], $this->baseUrl . '/' . $this->tagsPath); if ($output !== '') { $lastRev = 0; foreach ($this->process->splitLines($output) as $line) { @@ -271,7 +271,7 @@ public function getBranches(): array $trunkParent = $this->baseUrl . '/' . $this->trunkPath; } - $output = $this->execute('svn ls --verbose', $trunkParent); + $output = $this->execute(['svn', 'ls', '--verbose'], $trunkParent); if ($output !== '') { foreach ($this->process->splitLines($output) as $line) { $line = trim($line); @@ -290,7 +290,7 @@ public function getBranches(): array unset($output); if ($this->branchesPath !== false) { - $output = $this->execute('svn ls --verbose', $this->baseUrl . '/' . $this->branchesPath); + $output = $this->execute(['svn', 'ls', '--verbose'], $this->baseUrl . '/' . $this->branchesPath); if ($output !== '') { $lastRev = 0; foreach ($this->process->splitLines(trim($output)) as $line) { @@ -331,10 +331,7 @@ public static function supports(IOInterface $io, Config $config, string $url, bo } $process = new ProcessExecutor($io); - $exit = $process->execute( - "svn info --non-interactive -- ".ProcessExecutor::escape($url), - $ignoredOutput - ); + $exit = $process->execute(['svn', 'info', '--non-interactive', '--', $url], $ignoredOutput); if ($exit === 0) { // This is definitely a Subversion repository. @@ -375,11 +372,11 @@ protected static function normalizeUrl(string $url): string * Execute an SVN command and try to fix up the process with credentials * if necessary. * - * @param string $command The svn command to run. + * @param non-empty-list $command The svn command to run. * @param string $url The SVN URL. * @throws \RuntimeException */ - protected function execute(string $command, string $url): string + protected function execute(array $command, string $url): string { if (null === $this->util) { $this->util = new SvnUtil($this->baseUrl, $this->io, $this->config, $this->process); diff --git a/vendor/composer/composer/src/Composer/Util/Bitbucket.php b/vendor/composer/composer/src/Composer/Util/Bitbucket.php index 2be4a815c..15743a7e3 100644 --- a/vendor/composer/composer/src/Composer/Util/Bitbucket.php +++ b/vendor/composer/composer/src/Composer/Util/Bitbucket.php @@ -77,7 +77,7 @@ public function authorizeOAuth(string $originUrl): bool } // if available use token from git config - if (0 === $this->process->execute('git config bitbucket.accesstoken', $output)) { + if (0 === $this->process->execute(['git', 'config', 'bitbucket.accesstoken'], $output)) { $this->io->setAuthentication($originUrl, 'x-token-auth', trim($output)); return true; diff --git a/vendor/composer/composer/src/Composer/Util/Filesystem.php b/vendor/composer/composer/src/Composer/Util/Filesystem.php index 099747add..57e4fd6f3 100644 --- a/vendor/composer/composer/src/Composer/Util/Filesystem.php +++ b/vendor/composer/composer/src/Composer/Util/Filesystem.php @@ -109,9 +109,9 @@ public function removeDirectory(string $directory) } if (Platform::isWindows()) { - $cmd = sprintf('rmdir /S /Q %s', ProcessExecutor::escape(realpath($directory))); + $cmd = ['rmdir', '/S', '/Q', Platform::realpath($directory)]; } else { - $cmd = sprintf('rm -rf %s', ProcessExecutor::escape($directory)); + $cmd = ['rm', '-rf', $directory]; } $result = $this->getProcess()->execute($cmd, $output) === 0; @@ -144,9 +144,9 @@ public function removeDirectoryAsync(string $directory) } if (Platform::isWindows()) { - $cmd = sprintf('rmdir /S /Q %s', ProcessExecutor::escape(realpath($directory))); + $cmd = ['rmdir', '/S', '/Q', Platform::realpath($directory)]; } else { - $cmd = sprintf('rm -rf %s', ProcessExecutor::escape($directory)); + $cmd = ['rm', '-rf', $directory]; } $promise = $this->getProcess()->executeAsync($cmd); @@ -427,8 +427,7 @@ public function rename(string $source, string $target) if (Platform::isWindows()) { // Try to copy & delete - this is a workaround for random "Access denied" errors. - $command = sprintf('xcopy %s %s /E /I /Q /Y', ProcessExecutor::escape($source), ProcessExecutor::escape($target)); - $result = $this->getProcess()->execute($command, $output); + $result = $this->getProcess()->execute(['xcopy', $source, $target, '/E', '/I', '/Q', '/Y'], $output); // clear stat cache because external processes aren't tracked by the php stat cache clearstatcache(); @@ -441,8 +440,7 @@ public function rename(string $source, string $target) } else { // We do not use PHP's "rename" function here since it does not support // the case where $source, and $target are located on different partitions. - $command = sprintf('mv %s %s', ProcessExecutor::escape($source), ProcessExecutor::escape($target)); - $result = $this->getProcess()->execute($command, $output); + $result = $this->getProcess()->execute(['mv', $source, $target], $output); // clear stat cache because external processes aren't tracked by the php stat cache clearstatcache(); @@ -841,11 +839,7 @@ public function junction(string $target, string $junction) @rmdir($junction); } - $cmd = sprintf( - 'mklink /J %s %s', - ProcessExecutor::escape(str_replace('/', DIRECTORY_SEPARATOR, $junction)), - ProcessExecutor::escape(realpath($target)) - ); + $cmd = ['mklink', '/J', str_replace('/', DIRECTORY_SEPARATOR, $junction), Platform::realpath($target)]; if ($this->getProcess()->execute($cmd, $output) !== 0) { throw new IOException(sprintf('Failed to create junction to "%s" at "%s".', $target, $junction), 0, null, $target); } diff --git a/vendor/composer/composer/src/Composer/Util/Git.php b/vendor/composer/composer/src/Composer/Util/Git.php index f3369c8aa..e340c1b46 100644 --- a/vendor/composer/composer/src/Composer/Util/Git.php +++ b/vendor/composer/composer/src/Composer/Util/Git.php @@ -63,26 +63,90 @@ public function setHttpDownloader(HttpDownloader $httpDownloader): void } /** + * Runs a set of commands using the $url or a variation of it (with auth, ssh, ..) + * + * Commands should use %url% placeholders for the URL instead of inlining it to allow this function to do its job + * %sanitizedUrl% is also automatically replaced by the url without user/pass + * + * As soon as a single command fails it will halt, so assume the commands are run as && in bash + * + * @param non-empty-array> $commands + * @param mixed $commandOutput the output will be written into this var if passed by ref + * if a callable is passed it will be used as output handler + */ + public function runCommands(array $commands, string $url, ?string $cwd, bool $initialClone = false, &$commandOutput = null): void + { + $callables = []; + foreach ($commands as $cmd) { + $callables[] = static function (string $url) use ($cmd): array { + $map = [ + '%url%' => $url, + '%sanitizedUrl%' => Preg::replace('{://([^@]+?):(.+?)@}', '://', $url), + ]; + + return array_map(static function ($value) use ($map): string { + return $map[$value] ?? $value; + }, $cmd); + }; + } + + // @phpstan-ignore method.deprecated + $this->runCommand($callables, $url, $cwd, $initialClone, $commandOutput); + } + + /** + * @param callable|array $commandCallable * @param mixed $commandOutput the output will be written into this var if passed by ref * if a callable is passed it will be used as output handler + * @deprecated Use runCommands with placeholders instead of callbacks for simplicity */ - public function runCommand(callable $commandCallable, string $url, ?string $cwd, bool $initialClone = false, &$commandOutput = null): void + public function runCommand($commandCallable, string $url, ?string $cwd, bool $initialClone = false, &$commandOutput = null): void { + $commandCallables = is_callable($commandCallable) ? [$commandCallable] : $commandCallable; + $lastCommand = ''; + // Ensure we are allowed to use this URL by config $this->config->prohibitUrlByConfig($url, $this->io); if ($initialClone) { $origCwd = $cwd; - $cwd = null; } + $runCommands = function ($url) use ($commandCallables, $cwd, &$commandOutput, &$lastCommand, $initialClone) { + $collectOutputs = !is_callable($commandOutput); + $outputs = []; + + $status = 0; + $counter = 0; + foreach ($commandCallables as $callable) { + $lastCommand = $callable($url); + if ($collectOutputs) { + $outputs[] = ''; + $output = &$outputs[count($outputs) - 1]; + } else { + $output = &$commandOutput; + } + $status = $this->process->execute($lastCommand, $output, $initialClone && $counter === 0 ? null : $cwd); + if ($status !== 0) { + break; + } + $counter++; + } + + if ($collectOutputs) { + $commandOutput = implode('', $outputs); + } + + return $status; + }; + if (Preg::isMatch('{^ssh://[^@]+@[^:]+:[^0-9]+}', $url)) { throw new \InvalidArgumentException('The source URL ' . $url . ' is invalid, ssh URLs should have a port number after ":".' . "\n" . 'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.'); } if (!$initialClone) { // capture username/password from URL if there is one and we have no auth configured yet - $this->process->execute('git remote -v', $output, $cwd); + $this->process->execute(['git', 'remote', '-v'], $output, $cwd); if (Preg::isMatchStrictGroups('{^(?:composer|origin)\s+https?://(.+):(.+)@([^/]+)}im', $output, $match) && !$this->io->hasAuthentication($match[3])) { $this->io->setAuthentication($match[3], rawurldecode($match[1]), rawurldecode($match[2])); } @@ -100,7 +164,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, $protoUrl = $protocol . "://" . $match[1] . "/" . $match[2]; } - if (0 === $this->process->execute($commandCallable($protoUrl), $commandOutput, $cwd)) { + if (0 === $runCommands($protoUrl)) { return; } $messages[] = '- ' . $protoUrl . "\n" . Preg::replace('#^#m', ' ', $this->process->getErrorOutput()); @@ -119,11 +183,9 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, // if we have a private github url and the ssh protocol is disabled then we skip it and directly fallback to https $bypassSshForGitHub = Preg::isMatch('{^git@' . self::getGitHubDomainsRegex($this->config) . ':(.+?)\.git$}i', $url) && !in_array('ssh', $protocols, true); - $command = $commandCallable($url); - $auth = null; $credentials = []; - if ($bypassSshForGitHub || 0 !== $this->process->execute($command, $commandOutput, $cwd)) { + if ($bypassSshForGitHub || 0 !== $runCommands($url)) { $errorMsg = $this->process->getErrorOutput(); // private github repository without ssh key access, try https with auth // @phpstan-ignore composerPcre.maybeUnsafeStrictGroups @@ -143,8 +205,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, if ($this->io->hasAuthentication($match[1])) { $auth = $this->io->getAuthentication($match[1]); $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[1] . '/' . $match[2] . '.git'; - $command = $commandCallable($authUrl); - if (0 === $this->process->execute($command, $commandOutput, $cwd)) { + if (0 === $runCommands($authUrl)) { return; } @@ -180,8 +241,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, $auth = $this->io->getAuthentication($domain); $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $domain . '/' . $repo_with_git_part; - $command = $commandCallable($authUrl); - if (0 === $this->process->execute($command, $commandOutput, $cwd)) { + if (0 === $runCommands($authUrl)) { // Well if that succeeded on our first try, let's just // take the win. return; @@ -199,8 +259,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, if ($this->io->hasAuthentication($domain)) { $auth = $this->io->getAuthentication($domain); $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $domain . '/' . $repo_with_git_part; - $command = $commandCallable($authUrl); - if (0 === $this->process->execute($command, $commandOutput, $cwd)) { + if (0 === $runCommands($authUrl)) { return; } @@ -209,8 +268,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, //Falling back to ssh $sshUrl = 'git@bitbucket.org:' . $repo_with_git_part; $this->io->writeError(' No bitbucket authentication configured. Falling back to ssh.'); - $command = $commandCallable($sshUrl); - if (0 === $this->process->execute($command, $commandOutput, $cwd)) { + if (0 === $runCommands($sshUrl)) { return; } @@ -242,8 +300,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, $authUrl = $match[1] . '://' . rawurlencode((string) $auth['username']) . ':' . rawurlencode((string) $auth['password']) . '@' . $match[2] . '/' . $match[3]; } - $command = $commandCallable($authUrl); - if (0 === $this->process->execute($command, $commandOutput, $cwd)) { + if (0 === $runCommands($authUrl)) { return; } @@ -280,8 +337,7 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, if (null !== $auth) { $authUrl = $match[1] . rawurlencode((string) $auth['username']) . ':' . rawurlencode((string) $auth['password']) . '@' . $match[2] . $match[3]; - $command = $commandCallable($authUrl); - if (0 === $this->process->execute($command, $commandOutput, $cwd)) { + if (0 === $runCommands($authUrl)) { $this->io->setAuthentication($match[2], $auth['username'], $auth['password']); $authHelper = new AuthHelper($this->io, $this->config); $authHelper->storeAuth($match[2], $storeAuth); @@ -298,11 +354,12 @@ public function runCommand(callable $commandCallable, string $url, ?string $cwd, $this->filesystem->removeDirectory($origCwd); } + $lastCommand = implode(' ', $lastCommand); if (count($credentials) > 0) { - $command = $this->maskCredentials($command, $credentials); + $lastCommand = $this->maskCredentials($lastCommand, $credentials); $errorMsg = $this->maskCredentials($errorMsg, $credentials); } - $this->throwException('Failed to execute ' . $command . "\n\n" . $errorMsg, $url); + $this->throwException('Failed to execute ' . $lastCommand . "\n\n" . $errorMsg, $url); } } @@ -315,14 +372,16 @@ public function syncMirror(string $url, string $dir): bool } // update the repo if it is a valid git repository - if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') { + if (is_dir($dir) && 0 === $this->process->execute(['git', 'rev-parse', '--git-dir'], $output, $dir) && trim($output) === '.') { try { - $commandCallable = static function ($url): string { - $sanitizedUrl = Preg::replace('{://([^@]+?):(.+?)@}', '://', $url); - - return sprintf('git remote set-url origin -- %s && git remote update --prune origin && git remote set-url origin -- %s && git gc --auto', ProcessExecutor::escape($url), ProcessExecutor::escape($sanitizedUrl)); - }; - $this->runCommand($commandCallable, $url, $dir); + $commands = [ + ['git', 'remote', 'set-url', 'origin', '--', '%url%'], + ['git', 'remote', 'update', '--prune', 'origin'], + ['git', 'remote', 'set-url', 'origin', '--', '%sanitizedUrl%'], + ['git', 'gc', '--auto'], + ]; + + $this->runCommands($commands, $url, $dir); } catch (\Exception $e) { $this->io->writeError('Sync mirror failed: ' . $e->getMessage() . '', true, IOInterface::DEBUG); @@ -336,11 +395,7 @@ public function syncMirror(string $url, string $dir): bool // clean up directory and do a fresh clone into it $this->filesystem->removeDirectory($dir); - $commandCallable = static function ($url) use ($dir): string { - return sprintf('git clone --mirror -- %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($dir)); - }; - - $this->runCommand($commandCallable, $url, $dir, true); + $this->runCommands([['git', 'clone', '--mirror', '--', '%url%', $dir]], $url, $dir, true); return true; } @@ -352,10 +407,10 @@ public function fetchRefOrSyncMirror(string $url, string $dir, string $ref, ?str $branch = Preg::replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $prettyVersion); $branches = null; $tags = null; - if (0 === $this->process->execute('git branch', $output, $dir)) { + if (0 === $this->process->execute(['git', 'branch'], $output, $dir)) { $branches = $output; } - if (0 === $this->process->execute('git tag', $output, $dir)) { + if (0 === $this->process->execute(['git', 'tag'], $output, $dir)) { $tags = $output; } @@ -390,11 +445,23 @@ public static function getNoShowSignatureFlag(ProcessExecutor $process): string return ''; } + /** + * @return list + */ + public static function getNoShowSignatureFlags(ProcessExecutor $process): array + { + $flags = static::getNoShowSignatureFlag($process); + if ('' === $flags) { + return []; + } + + return explode(' ', substr($flags, 1)); + } + private function checkRefIsInMirror(string $dir, string $ref): bool { - if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') { - $escapedRef = ProcessExecutor::escape($ref.'^{commit}'); - $exitCode = $this->process->execute(sprintf('git rev-parse --quiet --verify %s', $escapedRef), $ignoredOutput, $dir); + if (is_dir($dir) && 0 === $this->process->execute(['git', 'rev-parse', '--git-dir'], $output, $dir) && trim($output) === '.') { + $exitCode = $this->process->execute(['git', 'rev-parse', '--quiet', '--verify', $ref.'^{commit}'], $ignoredOutput, $dir); if ($exitCode === 0) { return true; } @@ -439,15 +506,15 @@ public function getMirrorDefaultBranch(string $url, string $dir, bool $isLocalPa try { if ($isLocalPathRepository) { - $this->process->execute('git remote show origin', $output, $dir); + $this->process->execute(['git', 'remote', 'show', 'origin'], $output, $dir); } else { - $commandCallable = static function ($url): string { - $sanitizedUrl = Preg::replace('{://([^@]+?):(.+?)@}', '://', $url); - - return sprintf('git remote set-url origin -- %s && git remote show origin && git remote set-url origin -- %s', ProcessExecutor::escape($url), ProcessExecutor::escape($sanitizedUrl)); - }; + $commands = [ + ['git', 'remote', 'set-url', 'origin', '--', '%url%'], + ['git', 'remote', 'show', 'origin'], + ['git', 'remote', 'set-url', 'origin', '--', '%sanitizedUrl%'], + ]; - $this->runCommand($commandCallable, $url, $dir, false, $output); + $this->runCommands($commands, $url, $dir, false, $output); } $lines = $this->process->splitLines($output); @@ -513,7 +580,7 @@ private function throwException($message, string $url): void // git might delete a directory when it fails and php will not know clearstatcache(); - if (0 !== $this->process->execute('git --version', $ignoredOutput)) { + if (0 !== $this->process->execute(['git', '--version'], $ignoredOutput)) { throw new \RuntimeException(Url::sanitize('Failed to clone ' . $url . ', git was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput())); } @@ -529,7 +596,7 @@ public static function getVersion(ProcessExecutor $process): ?string { if (false === self::$version) { self::$version = null; - if (0 === $process->execute('git --version', $output) && Preg::isMatch('/^git version (\d+(?:\.\d+)+)/m', $output, $matches)) { + if (0 === $process->execute(['git', '--version'], $output) && Preg::isMatch('/^git version (\d+(?:\.\d+)+)/m', $output, $matches)) { self::$version = $matches[1]; } } diff --git a/vendor/composer/composer/src/Composer/Util/GitHub.php b/vendor/composer/composer/src/Composer/Util/GitHub.php index 3574e5183..64ee4f559 100644 --- a/vendor/composer/composer/src/Composer/Util/GitHub.php +++ b/vendor/composer/composer/src/Composer/Util/GitHub.php @@ -61,7 +61,7 @@ public function authorizeOAuth(string $originUrl): bool } // if available use token from git config - if (0 === $this->process->execute('git config github.accesstoken', $output)) { + if (0 === $this->process->execute(['git', 'config', 'github.accesstoken'], $output)) { $this->io->setAuthentication($originUrl, trim($output), 'x-oauth-basic'); return true; @@ -86,7 +86,7 @@ public function authorizeOAuthInteractively(string $originUrl, ?string $message } $note = 'Composer'; - if ($this->config->get('github-expose-hostname') === true && 0 === $this->process->execute('hostname', $output)) { + if ($this->config->get('github-expose-hostname') === true && 0 === $this->process->execute(['hostname'], $output)) { $note .= ' on ' . trim($output); } $note .= ' ' . date('Y-m-d Hi'); diff --git a/vendor/composer/composer/src/Composer/Util/GitLab.php b/vendor/composer/composer/src/Composer/Util/GitLab.php index e5985c2db..35d8e0ded 100644 --- a/vendor/composer/composer/src/Composer/Util/GitLab.php +++ b/vendor/composer/composer/src/Composer/Util/GitLab.php @@ -65,14 +65,14 @@ public function authorizeOAuth(string $originUrl): bool } // if available use token from git config - if (0 === $this->process->execute('git config gitlab.accesstoken', $output)) { + if (0 === $this->process->execute(['git', 'config', 'gitlab.accesstoken'], $output)) { $this->io->setAuthentication($originUrl, trim($output), 'oauth2'); return true; } // if available use deploy token from git config - if (0 === $this->process->execute('git config gitlab.deploytoken.user', $tokenUser) && 0 === $this->process->execute('git config gitlab.deploytoken.token', $tokenPassword)) { + if (0 === $this->process->execute(['git', 'config', 'gitlab.deploytoken.user'], $tokenUser) && 0 === $this->process->execute(['git', 'config', 'gitlab.deploytoken.token'], $tokenPassword)) { $this->io->setAuthentication($originUrl, trim($tokenUser), trim($tokenPassword)); return true; diff --git a/vendor/composer/composer/src/Composer/Util/Hg.php b/vendor/composer/composer/src/Composer/Util/Hg.php index 28107584b..34b4796fa 100644 --- a/vendor/composer/composer/src/Composer/Util/Hg.php +++ b/vendor/composer/composer/src/Composer/Util/Hg.php @@ -111,7 +111,7 @@ public static function getVersion(ProcessExecutor $process): ?string { if (false === self::$version) { self::$version = null; - if (0 === $process->execute('hg --version', $output) && Preg::isMatch('/^.+? (\d+(?:\.\d+)+)(?:\+.*?)?\)?\r?\n/', $output, $matches)) { + if (0 === $process->execute(['hg', '--version'], $output) && Preg::isMatch('/^.+? (\d+(?:\.\d+)+)(?:\+.*?)?\)?\r?\n/', $output, $matches)) { self::$version = $matches[1]; } } diff --git a/vendor/composer/composer/src/Composer/Util/Perforce.php b/vendor/composer/composer/src/Composer/Util/Perforce.php index ff931158c..bfed834b1 100644 --- a/vendor/composer/composer/src/Composer/Util/Perforce.php +++ b/vendor/composer/composer/src/Composer/Util/Perforce.php @@ -14,6 +14,7 @@ use Composer\IO\IOInterface; use Composer\Pcre\Preg; +use Symfony\Component\Process\ExecutableFinder; use Symfony\Component\Process\Process; /** @@ -81,7 +82,7 @@ public static function create($repoConfig, string $port, string $path, ProcessEx public static function checkServerExists(string $url, ProcessExecutor $processExecutor): bool { - return 0 === $processExecutor->execute('p4 -p ' . ProcessExecutor::escape($url) . ' info -s', $ignoredOutput); + return 0 === $processExecutor->execute(['p4', '-p', $url, 'info', '-s'], $ignoredOutput); } /** @@ -248,7 +249,7 @@ public function queryP4User(): void } $this->p4User = $this->io->ask('Enter P4 User:'); if ($this->windowsFlag) { - $command = 'p4 set P4USER=' . $this->p4User; + $command = $this->getP4Executable().' set P4USER=' . $this->p4User; } else { $command = 'export P4USER=' . $this->p4User; } @@ -261,7 +262,7 @@ public function queryP4User(): void protected function getP4variable(string $name): ?string { if ($this->windowsFlag) { - $command = 'p4 set'; + $command = $this->getP4Executable().' set'; $this->executeCommand($command); $result = trim($this->commandResult); $resArray = explode(PHP_EOL, $result); @@ -309,7 +310,7 @@ public function queryP4Password(): ?string */ public function generateP4Command(string $command, bool $useClient = true): string { - $p4Command = 'p4 '; + $p4Command = $this->getP4Executable().' '; $p4Command .= '-u ' . $this->getUser() . ' '; if ($useClient) { $p4Command .= '-c ' . $this->getClient() . ' '; @@ -620,4 +621,17 @@ public function setFilesystem(Filesystem $fs): void { $this->filesystem = $fs; } + + private function getP4Executable(): string + { + static $p4Executable; + + if ($p4Executable) { + return $p4Executable; + } + + $finder = new ExecutableFinder(); + + return $p4Executable = $finder->find('p4') ?? 'p4'; + } } diff --git a/vendor/composer/composer/src/Composer/Util/Platform.php b/vendor/composer/composer/src/Composer/Util/Platform.php index b13fe5bb8..dcbfaa1c5 100644 --- a/vendor/composer/composer/src/Composer/Util/Platform.php +++ b/vendor/composer/composer/src/Composer/Util/Platform.php @@ -54,6 +54,19 @@ public static function getCwd(bool $allowEmpty = false): string return $cwd; } + /** + * Infallible realpath version that falls back on the given $path if realpath is not working + */ + public static function realpath(string $path): string + { + $realPath = realpath($path); + if ($realPath === false) { + return $path; + } + + return $realPath; + } + /** * getenv() equivalent but reads from the runtime global variables first * @@ -308,7 +321,7 @@ private static function isVirtualBoxGuest(): bool if (defined('PHP_OS_FAMILY') && PHP_OS_FAMILY === 'Linux') { $process = new ProcessExecutor(); try { - if (0 === $process->execute('lsmod | grep vboxguest', $ignoredOutput)) { + if (0 === $process->execute(['lsmod'], $output) && str_contains($output, 'vboxguest')) { return self::$isVirtualBoxGuest = true; } } catch (\Exception $e) { diff --git a/vendor/composer/composer/src/Composer/Util/ProcessExecutor.php b/vendor/composer/composer/src/Composer/Util/ProcessExecutor.php index bf4b49846..dc773beb9 100644 --- a/vendor/composer/composer/src/Composer/Util/ProcessExecutor.php +++ b/vendor/composer/composer/src/Composer/Util/ProcessExecutor.php @@ -20,6 +20,7 @@ use Symfony\Component\Process\Exception\RuntimeException; use React\Promise\Promise; use React\Promise\PromiseInterface; +use Symfony\Component\Process\ExecutableFinder; /** * @author Robert Schönthal @@ -33,6 +34,14 @@ class ProcessExecutor private const STATUS_FAILED = 4; private const STATUS_ABORTED = 5; + private const BUILTIN_CMD_COMMANDS = [ + 'assoc', 'break', 'call', 'cd', 'chdir', 'cls', 'color', 'copy', 'date', + 'del', 'dir', 'echo', 'endlocal', 'erase', 'exit', 'for', 'ftype', 'goto', + 'help', 'if', 'label', 'md', 'mkdir', 'mklink', 'move', 'path', 'pause', + 'popd', 'prompt', 'pushd', 'rd', 'rem', 'ren', 'rename', 'rmdir', 'set', + 'setlocal', 'shift', 'start', 'time', 'title', 'type', 'ver', 'vol', + ]; + private const GIT_CMDS_NEED_GIT_DIR = [ ['show'], ['log'], @@ -63,6 +72,9 @@ class ProcessExecutor /** @var bool */ private $allowAsync = false; + /** @var array */ + private static $executables = []; + public function __construct(?IOInterface $io = null) { $this->io = $io; @@ -71,7 +83,7 @@ public function __construct(?IOInterface $io = null) /** * runs a process on the commandline * - * @param string|list $command the command to execute + * @param string|non-empty-list $command the command to execute * @param mixed $output the output will be written into this var if passed by ref * if a callable is passed it will be used as output handler * @param null|string $cwd the working directory @@ -89,7 +101,7 @@ public function execute($command, &$output = null, ?string $cwd = null): int /** * runs a process on the commandline in TTY mode * - * @param string|list $command the command to execute + * @param string|non-empty-list $command the command to execute * @param null|string $cwd the working directory * @return int statuscode */ @@ -103,15 +115,26 @@ public function executeTty($command, ?string $cwd = null): int } /** - * @param string|list $command + * @param string|non-empty-list $command * @param array|null $env * @param mixed $output */ private function runProcess($command, ?string $cwd, ?array $env, bool $tty, &$output = null): ?int { + // On Windows, we don't rely on the OS to find the executable if possible to avoid lookups + // in the current directory which could be untrusted. Instead we use the ExecutableFinder. + if (is_string($command)) { + if (Platform::isWindows() && Preg::isMatch('{^([^:/\\\\]++) }', $command, $match)) { + $command = substr_replace($command, self::escape(self::getExecutable($match[1])), 0, strlen($match[1])); + } + $process = Process::fromShellCommandline($command, $cwd, $env, null, static::getTimeout()); } else { + if (Platform::isWindows() && \strlen($command[0]) === strcspn($command[0], ':/\\')) { + $command[0] = self::getExecutable($command[0]); + } + $process = new Process($command, $cwd, $env, null, static::getTimeout()); } @@ -161,7 +184,7 @@ function (string $signal) { } /** - * @param string|list $command + * @param string|non-empty-list $command * @param mixed $output */ private function doExecute($command, ?string $cwd, bool $tty, &$output = null): int @@ -178,7 +201,7 @@ private function doExecute($command, ?string $cwd, bool $tty, &$output = null): $isBareRepository = !is_dir(sprintf('%s/.git', rtrim($cwd, '/'))); if ($isBareRepository) { $configValue = ''; - $this->runProcess('git config safe.bareRepository', $cwd, ['GIT_DIR' => $cwd], $tty, $configValue); + $this->runProcess(['git', 'config', 'safe.bareRepository'], $cwd, ['GIT_DIR' => $cwd], $tty, $configValue); $configValue = trim($configValue); if ($configValue === 'explicit') { $env = ['GIT_DIR' => $cwd]; @@ -550,4 +573,23 @@ public function requiresGitDirEnv($command): bool return false; } + + /** + * Resolves executable paths on Windows + */ + private static function getExecutable(string $name): string + { + if (\in_array(strtolower($name), self::BUILTIN_CMD_COMMANDS, true)) { + return $name; + } + + if (!isset(self::$executables[$name])) { + $path = (new ExecutableFinder())->find($name, $name); + if ($path !== null) { + self::$executables[$name] = $path; + } + } + + return self::$executables[$name] ?? $name; + } } diff --git a/vendor/composer/composer/src/Composer/Util/Svn.php b/vendor/composer/composer/src/Composer/Util/Svn.php index ea7d5dbeb..506a14ec7 100644 --- a/vendor/composer/composer/src/Composer/Util/Svn.php +++ b/vendor/composer/composer/src/Composer/Util/Svn.php @@ -90,7 +90,7 @@ public static function cleanEnv(): void * Execute an SVN remote command and try to fix up the process with credentials * if necessary. * - * @param string $command SVN command to run + * @param non-empty-list $command SVN command to run * @param string $url SVN url * @param ?string $cwd Working directory * @param ?string $path Target for a checkout @@ -98,7 +98,7 @@ public static function cleanEnv(): void * * @throws \RuntimeException */ - public function execute(string $command, string $url, ?string $cwd = null, ?string $path = null, bool $verbose = false): string + public function execute(array $command, string $url, ?string $cwd = null, ?string $path = null, bool $verbose = false): string { // Ensure we are allowed to use this URL by config $this->config->prohibitUrlByConfig($url, $this->io); @@ -110,20 +110,23 @@ public function execute(string $command, string $url, ?string $cwd = null, ?stri * Execute an SVN local command and try to fix up the process with credentials * if necessary. * - * @param string $command SVN command to run + * @param non-empty-list $command SVN command to run * @param string $path Path argument passed thru to the command * @param string $cwd Working directory * @param bool $verbose Output all output to the user * * @throws \RuntimeException */ - public function executeLocal(string $command, string $path, ?string $cwd = null, bool $verbose = false): string + public function executeLocal(array $command, string $path, ?string $cwd = null, bool $verbose = false): string { // A local command has no remote url return $this->executeWithAuthRetry($command, $cwd, '', $path, $verbose); } - private function executeWithAuthRetry(string $svnCommand, ?string $cwd, string $url, ?string $path, bool $verbose): ?string + /** + * @param non-empty-list $svnCommand + */ + private function executeWithAuthRetry(array $svnCommand, ?string $cwd, string $url, ?string $path, bool $verbose): ?string { // Regenerate the command at each try, to use the newly user-provided credentials $command = $this->getCommand($svnCommand, $url, $path); @@ -209,22 +212,23 @@ protected function doAuthDance(): Svn /** * A method to create the svn commands run. * - * @param string $cmd Usually 'svn ls' or something like that. + * @param non-empty-list $cmd Usually 'svn ls' or something like that. * @param string $url Repo URL. * @param string $path Target for a checkout + * + * @return non-empty-list */ - protected function getCommand(string $cmd, string $url, ?string $path = null): string + protected function getCommand(array $cmd, string $url, ?string $path = null): array { - $cmd = sprintf( - '%s %s%s -- %s', + $cmd = array_merge( $cmd, - '--non-interactive ', - $this->getCredentialString(), - ProcessExecutor::escape($url) + ['--non-interactive'], + $this->getCredentialArgs(), + ['--', $url] ); - if ($path) { - $cmd .= ' ' . ProcessExecutor::escape($path); + if ($path !== null) { + $cmd[] = $path; } return $cmd; @@ -234,18 +238,18 @@ protected function getCommand(string $cmd, string $url, ?string $path = null): s * Return the credential string for the svn command. * * Adds --no-auth-cache when credentials are present. + * + * @return list */ - protected function getCredentialString(): string + protected function getCredentialArgs(): array { if (!$this->hasAuth()) { - return ''; + return []; } - return sprintf( - ' %s--username %s --password %s ', - $this->getAuthCache(), - ProcessExecutor::escape($this->getUsername()), - ProcessExecutor::escape($this->getPassword()) + return array_merge( + $this->getAuthCacheArgs(), + ['--username', $this->getUsername(), '--password', $this->getPassword()] ); } @@ -295,10 +299,12 @@ protected function hasAuth(): bool /** * Return the no-auth-cache switch. + * + * @return list */ - protected function getAuthCache(): string + protected function getAuthCacheArgs(): array { - return $this->cacheCredentials ? '' : '--no-auth-cache '; + return $this->cacheCredentials ? [] : ['--no-auth-cache']; } /** @@ -349,7 +355,7 @@ private function createAuthFromUrl(): bool public function binaryVersion(): ?string { if (!self::$version) { - if (0 === $this->process->execute('svn --version', $output)) { + if (0 === $this->process->execute(['svn', '--version'], $output)) { if (Preg::isMatch('{(\d+(?:\.\d+)+)}', $output, $match)) { self::$version = $match[1]; } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 4fc25c2ed..ca7e0920c 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,17 +2,17 @@ "packages": [ { "name": "bjeavons/zxcvbn-php", - "version": "1.3.1", - "version_normalized": "1.3.1.0", + "version": "1.4.1", + "version_normalized": "1.4.1.0", "source": { "type": "git", "url": "https://github.com/bjeavons/zxcvbn-php.git", - "reference": "994928ae5b17ecff8baa2406832d37bdf01116c0" + "reference": "603e015f2c81118a8f42930140311d125eba6f8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bjeavons/zxcvbn-php/zipball/994928ae5b17ecff8baa2406832d37bdf01116c0", - "reference": "994928ae5b17ecff8baa2406832d37bdf01116c0", + "url": "https://api.github.com/repos/bjeavons/zxcvbn-php/zipball/603e015f2c81118a8f42930140311d125eba6f8a", + "reference": "603e015f2c81118a8f42930140311d125eba6f8a", "shasum": "" }, "require": { @@ -22,13 +22,14 @@ }, "require-dev": { "php-coveralls/php-coveralls": "*", + "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^8.5", "squizlabs/php_codesniffer": "3.*" }, "suggest": { "ext-gmp": "Required for optimized binomial calculations (also requires PHP >= 7.3)" }, - "time": "2021-12-21T18:37:02+00:00", + "time": "2024-11-21T22:10:41+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -54,7 +55,7 @@ ], "support": { "issues": "https://github.com/bjeavons/zxcvbn-php/issues", - "source": "https://github.com/bjeavons/zxcvbn-php/tree/1.3.1" + "source": "https://github.com/bjeavons/zxcvbn-php/tree/1.4.1" }, "install-path": "../bjeavons/zxcvbn-php" }, @@ -350,17 +351,17 @@ }, { "name": "composer/composer", - "version": "2.8.2", - "version_normalized": "2.8.2.0", + "version": "2.8.3", + "version_normalized": "2.8.3.0", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "6e543d03187c882ea1c6ba43add2467754427803" + "reference": "2a7c71266b2545a3bed9f4860734081963f6e688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/6e543d03187c882ea1c6ba43add2467754427803", - "reference": "6e543d03187c882ea1c6ba43add2467754427803", + "url": "https://api.github.com/repos/composer/composer/zipball/2a7c71266b2545a3bed9f4860734081963f6e688", + "reference": "2a7c71266b2545a3bed9f4860734081963f6e688", "shasum": "" }, "require": { @@ -374,7 +375,7 @@ "justinrainbow/json-schema": "^5.3", "php": "^7.2.5 || ^8.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "react/promise": "^3.2", + "react/promise": "^2.11 || ^3.2", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", "seld/signal-handler": "^2.0", @@ -399,7 +400,7 @@ "ext-zip": "Enabling the zip extension allows you to unzip archives", "ext-zlib": "Allow gzip compression of HTTP requests" }, - "time": "2024-10-29T15:12:11+00:00", + "time": "2024-11-17T12:13:04+00:00", "bin": [ "bin/composer" ], @@ -447,7 +448,7 @@ "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", "security": "https://github.com/composer/composer/security/policy", - "source": "https://github.com/composer/composer/tree/2.8.2" + "source": "https://github.com/composer/composer/tree/2.8.3" }, "funding": [ { @@ -2104,8 +2105,8 @@ }, { "name": "illuminate/collections", - "version": "v10.48.23", - "version_normalized": "10.48.23.0", + "version": "v10.48.24", + "version_normalized": "10.48.24.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", @@ -2162,8 +2163,8 @@ }, { "name": "illuminate/conditionable", - "version": "v10.48.23", - "version_normalized": "10.48.23.0", + "version": "v10.48.24", + "version_normalized": "10.48.24.0", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -2211,8 +2212,8 @@ }, { "name": "illuminate/container", - "version": "v10.48.23", - "version_normalized": "10.48.23.0", + "version": "v10.48.24", + "version_normalized": "10.48.24.0", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", @@ -2265,8 +2266,8 @@ }, { "name": "illuminate/contracts", - "version": "v10.48.23", - "version_normalized": "10.48.23.0", + "version": "v10.48.24", + "version_normalized": "10.48.24.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -2316,8 +2317,8 @@ }, { "name": "illuminate/filesystem", - "version": "v10.48.23", - "version_normalized": "10.48.23.0", + "version": "v10.48.24", + "version_normalized": "10.48.24.0", "source": { "type": "git", "url": "https://github.com/illuminate/filesystem.git", @@ -2386,8 +2387,8 @@ }, { "name": "illuminate/macroable", - "version": "v10.48.23", - "version_normalized": "10.48.23.0", + "version": "v10.48.24", + "version_normalized": "10.48.24.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -2435,8 +2436,8 @@ }, { "name": "illuminate/support", - "version": "v10.48.23", - "version_normalized": "10.48.23.0", + "version": "v10.48.24", + "version_normalized": "10.48.24.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", @@ -2509,8 +2510,8 @@ }, { "name": "illuminate/translation", - "version": "v10.48.23", - "version_normalized": "10.48.23.0", + "version": "v10.48.24", + "version_normalized": "10.48.24.0", "source": { "type": "git", "url": "https://github.com/illuminate/translation.git", @@ -2563,8 +2564,8 @@ }, { "name": "illuminate/validation", - "version": "v10.48.23", - "version_normalized": "10.48.23.0", + "version": "v10.48.24", + "version_normalized": "10.48.24.0", "source": { "type": "git", "url": "https://github.com/illuminate/validation.git", @@ -6669,6 +6670,43 @@ }, "install-path": "../teampassclasses/encryption" }, + { + "name": "teampassclasses/folderservices", + "version": "dev-master", + "version_normalized": "dev-master", + "dist": { + "type": "path", + "url": "includes/libraries/teampassclasses/folderservices", + "reference": "737c43b0e11b6d6f15ae63fda23d87548cc87fc9" + }, + "require": { + "php": "^8.1" + }, + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "TeampassClasses\\FolderServices\\": "src/" + } + }, + "license": [ + "GPL-3.0-only" + ], + "authors": [ + { + "name": "Nils Laumaillé" + } + ], + "description": "Handle the folder management.", + "keywords": [ + "folder" + ], + "transport-options": { + "symlink": false, + "relative": true + }, + "install-path": "../teampassclasses/folderservices" + }, { "name": "teampassclasses/language", "version": "dev-master", @@ -7246,17 +7284,17 @@ }, { "name": "voku/portable-ascii", - "version": "2.0.1", - "version_normalized": "2.0.1.0", + "version": "2.0.3", + "version_normalized": "2.0.3.0", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "b56450eed252f6801410d810c8e1727224ae0743" + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", - "reference": "b56450eed252f6801410d810c8e1727224ae0743", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", "shasum": "" }, "require": { @@ -7268,7 +7306,7 @@ "suggest": { "ext-intl": "Use Intl for transliterator_transliterate() support" }, - "time": "2022-03-08T17:03:00+00:00", + "time": "2024-11-21T01:49:47+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -7283,7 +7321,7 @@ "authors": [ { "name": "Lars Moelleken", - "homepage": "http://www.moelleken.org/" + "homepage": "https://www.moelleken.org/" } ], "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", @@ -7295,7 +7333,7 @@ ], "support": { "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/2.0.1" + "source": "https://github.com/voku/portable-ascii/tree/2.0.3" }, "funding": [ { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 808fc12b5..036588ced 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -11,9 +11,9 @@ ), 'versions' => array( 'bjeavons/zxcvbn-php' => array( - 'pretty_version' => '1.3.1', - 'version' => '1.3.1.0', - 'reference' => '994928ae5b17ecff8baa2406832d37bdf01116c0', + 'pretty_version' => '1.4.1', + 'version' => '1.4.1.0', + 'reference' => '603e015f2c81118a8f42930140311d125eba6f8a', 'type' => 'library', 'install_path' => __DIR__ . '/../bjeavons/zxcvbn-php', 'aliases' => array(), @@ -56,9 +56,9 @@ 'dev_requirement' => false, ), 'composer/composer' => array( - 'pretty_version' => '2.8.2', - 'version' => '2.8.2.0', - 'reference' => '6e543d03187c882ea1c6ba43add2467754427803', + 'pretty_version' => '2.8.3', + 'version' => '2.8.3.0', + 'reference' => '2a7c71266b2545a3bed9f4860734081963f6e688', 'type' => 'library', 'install_path' => __DIR__ . '/./composer', 'aliases' => array(), @@ -263,8 +263,8 @@ 'dev_requirement' => false, ), 'illuminate/collections' => array( - 'pretty_version' => 'v10.48.23', - 'version' => '10.48.23.0', + 'pretty_version' => 'v10.48.24', + 'version' => '10.48.24.0', 'reference' => '37c863cffb345869dd134eff8e646bc82a19cc96', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/collections', @@ -272,8 +272,8 @@ 'dev_requirement' => false, ), 'illuminate/conditionable' => array( - 'pretty_version' => 'v10.48.23', - 'version' => '10.48.23.0', + 'pretty_version' => 'v10.48.24', + 'version' => '10.48.24.0', 'reference' => 'd0958e4741fc9d6f516a552060fd1b829a85e009', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/conditionable', @@ -281,8 +281,8 @@ 'dev_requirement' => false, ), 'illuminate/container' => array( - 'pretty_version' => 'v10.48.23', - 'version' => '10.48.23.0', + 'pretty_version' => 'v10.48.24', + 'version' => '10.48.24.0', 'reference' => 'ddc26273085fad3c471b2602ad820e0097ff7939', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/container', @@ -290,8 +290,8 @@ 'dev_requirement' => false, ), 'illuminate/contracts' => array( - 'pretty_version' => 'v10.48.23', - 'version' => '10.48.23.0', + 'pretty_version' => 'v10.48.24', + 'version' => '10.48.24.0', 'reference' => '8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/contracts', @@ -299,8 +299,8 @@ 'dev_requirement' => false, ), 'illuminate/filesystem' => array( - 'pretty_version' => 'v10.48.23', - 'version' => '10.48.23.0', + 'pretty_version' => 'v10.48.24', + 'version' => '10.48.24.0', 'reference' => '592fb581a52fba43bf78c2e4b22db540c9f9f149', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/filesystem', @@ -308,8 +308,8 @@ 'dev_requirement' => false, ), 'illuminate/macroable' => array( - 'pretty_version' => 'v10.48.23', - 'version' => '10.48.23.0', + 'pretty_version' => 'v10.48.24', + 'version' => '10.48.24.0', 'reference' => 'dff667a46ac37b634dcf68909d9d41e94dc97c27', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/macroable', @@ -317,8 +317,8 @@ 'dev_requirement' => false, ), 'illuminate/support' => array( - 'pretty_version' => 'v10.48.23', - 'version' => '10.48.23.0', + 'pretty_version' => 'v10.48.24', + 'version' => '10.48.24.0', 'reference' => '56c6d9895605b019e3debb9440454596ef99312a', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/support', @@ -326,8 +326,8 @@ 'dev_requirement' => false, ), 'illuminate/translation' => array( - 'pretty_version' => 'v10.48.23', - 'version' => '10.48.23.0', + 'pretty_version' => 'v10.48.24', + 'version' => '10.48.24.0', 'reference' => '4da8ed16d6ea6008acf43c7375a9b2073fb10e0b', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/translation', @@ -335,8 +335,8 @@ 'dev_requirement' => false, ), 'illuminate/validation' => array( - 'pretty_version' => 'v10.48.23', - 'version' => '10.48.23.0', + 'pretty_version' => 'v10.48.24', + 'version' => '10.48.24.0', 'reference' => 'c9be8b183279f0175233e0758285a297431045ac', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/validation', @@ -976,6 +976,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'teampassclasses/folderservices' => array( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '737c43b0e11b6d6f15ae63fda23d87548cc87fc9', + 'type' => 'library', + 'install_path' => __DIR__ . '/../teampassclasses/folderservices', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'teampassclasses/language' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', @@ -1085,9 +1094,9 @@ 'dev_requirement' => false, ), 'voku/portable-ascii' => array( - 'pretty_version' => '2.0.1', - 'version' => '2.0.1.0', - 'reference' => 'b56450eed252f6801410d810c8e1727224ae0743', + 'pretty_version' => '2.0.3', + 'version' => '2.0.3.0', + 'reference' => 'b1d923f88091c6bf09699efcd7c8a1b1bfd7351d', 'type' => 'library', 'install_path' => __DIR__ . '/../voku/portable-ascii', 'aliases' => array(), diff --git a/vendor/voku/portable-ascii/.deepsource.toml b/vendor/voku/portable-ascii/.deepsource.toml new file mode 100644 index 000000000..3f8f43cef --- /dev/null +++ b/vendor/voku/portable-ascii/.deepsource.toml @@ -0,0 +1,4 @@ +version = 1 + +[[analyzers]] +name = "php" \ No newline at end of file diff --git a/vendor/voku/portable-ascii/CHANGELOG.md b/vendor/voku/portable-ascii/CHANGELOG.md index 12fc393a7..52f4912e7 100644 --- a/vendor/voku/portable-ascii/CHANGELOG.md +++ b/vendor/voku/portable-ascii/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +### 2.0.3 (2024-11-21) + +- use modern phpdocs e.g. list or conditional-return annotations + +### 2.0.2 (2024-11-21) + +- small fix for PHP 8.4 (thanks to @gilbertoalbino) + ### 2.0.1 (2022-03-08) - "To people of Russia": There is a war in Ukraine right now. The forces of the Russian Federation are attacking civilians. diff --git a/vendor/voku/portable-ascii/composer.json b/vendor/voku/portable-ascii/composer.json index 99dee4f80..b3a22fa8c 100644 --- a/vendor/voku/portable-ascii/composer.json +++ b/vendor/voku/portable-ascii/composer.json @@ -12,7 +12,7 @@ "authors": [ { "name": "Lars Moelleken", - "homepage": "http://www.moelleken.org/" + "homepage": "https://www.moelleken.org/" } ], "require": { diff --git a/vendor/voku/portable-ascii/src/voku/helper/ASCII.php b/vendor/voku/portable-ascii/src/voku/helper/ASCII.php index 7d8b66de7..406407e19 100644 --- a/vendor/voku/portable-ascii/src/voku/helper/ASCII.php +++ b/vendor/voku/portable-ascii/src/voku/helper/ASCII.php @@ -214,9 +214,9 @@ final class ASCII /** * Get all languages from the constants "ASCII::.*LANGUAGE_CODE". * - * @return string[] - * - * @phpstan-return array + * @return array + *

An associative array where the key is the language code in lowercase + * and the value is the corresponding language string.

*/ public static function getAllLanguages(): array { @@ -246,15 +246,13 @@ public static function getAllLanguages(): array * var_dump($array['ru']['б']); // 'b' * * - * @psalm-suppress InvalidNullableReturnType - we use the prepare* methods here, so we don't get NULL here - * * @param bool $replace_extra_symbols [optional]

Add some more replacements e.g. "£" with " pound ".

* * @psalm-pure * - * @return array - * - * @phpstan-return array> + * @return array> + *

An array where the key is the language code, and the value is + * an associative array mapping original characters to their replacements.

*/ public static function charsArray(bool $replace_extra_symbols = false): array { @@ -281,14 +279,11 @@ public static function charsArray(bool $replace_extra_symbols = false): array * * @psalm-pure * - * @return array - *

An array of replacements.

- * - * @phpstan-return array> + * @return array> + *

An array of replacements.

*/ public static function charsArrayWithMultiLanguageValues(bool $replace_extra_symbols = false): array { - /** @var array>> */ static $CHARS_ARRAY = []; $cacheKey = '' . $replace_extra_symbols; @@ -303,18 +298,13 @@ public static function charsArrayWithMultiLanguageValues(bool $replace_extra_sym false ); - /** @noinspection PhpSillyAssignmentInspection - hack for phpstan */ - /** @var array $language_all_chars */ - $language_all_chars = $language_all_chars; - - /** @noinspection AlterInForeachInspection */ + /* @noinspection AlterInForeachInspection | ok here */ foreach ($language_all_chars as $key => &$value) { $return[$value][] = $key; } $CHARS_ARRAY[$cacheKey] = $return; - /** @var array> $return - hack for phpstan */ return $return; } @@ -330,21 +320,17 @@ public static function charsArrayWithMultiLanguageValues(bool $replace_extra_sym * echo $array['orig'][$tmpKey]; // 'ё' * * - * @psalm-suppress InvalidNullableReturnType - we use the prepare* methods here, so we don't get NULL here - * * @param string $language [optional]

Language of the source string e.g.: en, de_at, or de-ch. * (default is 'en') | ASCII::*_LANGUAGE_CODE

* @param bool $replace_extra_symbols [optional]

Add some more replacements e.g. "£" with " pound ".

- * @param bool $asOrigReplaceArray [optional]

TRUE === return {orig: string[], replace: string[]} + * @param bool $asOrigReplaceArray [optional]

TRUE === return {orig: list, replace: list} * array

* * @psalm-pure * - * @return array - *

An array of replacements.

+ * @return ($asOrigReplaceArray is true ? array{orig: list, replace: list} : array) * * @phpstan-param ASCII::*_LANGUAGE_CODE $language - * @phpstan-return array{orig: string[], replace: string[]}|array */ public static function charsArrayWithOneLanguage( string $language = self::ENGLISH_LANGUAGE_CODE, @@ -354,7 +340,6 @@ public static function charsArrayWithOneLanguage( $language = self::get_language($language); // init - /** @var array|array{orig: string[], replace: string[]}>> */ static $CHARS_ARRAY = []; $cacheKey = '' . $replace_extra_symbols . '-' . $asOrigReplaceArray; @@ -366,7 +351,6 @@ public static function charsArrayWithOneLanguage( if ($replace_extra_symbols) { self::prepareAsciiAndExtrasMaps(); - /** @noinspection DuplicatedCode */ if (isset(self::$ASCII_MAPS_AND_EXTRAS[$language])) { $tmpArray = self::$ASCII_MAPS_AND_EXTRAS[$language]; @@ -379,7 +363,6 @@ public static function charsArrayWithOneLanguage( $CHARS_ARRAY[$cacheKey][$language] = $tmpArray; } } else { - /** @noinspection NestedPositiveIfStatementsInspection */ if ($asOrigReplaceArray) { $CHARS_ARRAY[$cacheKey][$language] = [ 'orig' => [], @@ -392,7 +375,6 @@ public static function charsArrayWithOneLanguage( } else { self::prepareAsciiMaps(); - /** @noinspection DuplicatedCode */ if (isset(self::$ASCII_MAPS[$language])) { $tmpArray = self::$ASCII_MAPS[$language]; @@ -405,7 +387,6 @@ public static function charsArrayWithOneLanguage( $CHARS_ARRAY[$cacheKey][$language] = $tmpArray; } } else { - /** @noinspection NestedPositiveIfStatementsInspection */ if ($asOrigReplaceArray) { $CHARS_ARRAY[$cacheKey][$language] = [ 'orig' => [], @@ -430,22 +411,18 @@ public static function charsArrayWithOneLanguage( * * * @param bool $replace_extra_symbols [optional]

Add some more replacements e.g. "£" with " pound ".

- * @param bool $asOrigReplaceArray [optional]

TRUE === return {orig: string[], replace: string[]} + * @param bool $asOrigReplaceArray [optional]

TRUE === return {orig: list, replace: list} * array

* * @psalm-pure * - * @return array - *

An array of replacements.

- * - * @phpstan-return array{orig: string[], replace: string[]}|array + * @return ($asOrigReplaceArray is true ? array{orig: list, replace: list} : array) */ public static function charsArrayWithSingleLanguageValues( bool $replace_extra_symbols = false, bool $asOrigReplaceArray = true ): array { // init - /** @var array|array{orig: string[], replace: string[]}> */ static $CHARS_ARRAY = []; $cacheKey = '' . $replace_extra_symbols . '-' . $asOrigReplaceArray; @@ -456,22 +433,19 @@ public static function charsArrayWithSingleLanguageValues( if ($replace_extra_symbols) { self::prepareAsciiAndExtrasMaps(); - /** @noinspection AlterInForeachInspection */ - /** @psalm-suppress PossiblyNullIterator - we use the prepare* methods here, so we don't get NULL here */ + /* @noinspection AlterInForeachInspection | ok here */ foreach (self::$ASCII_MAPS_AND_EXTRAS ?? [] as &$map) { $CHARS_ARRAY[$cacheKey][] = $map; } } else { self::prepareAsciiMaps(); - /** @noinspection AlterInForeachInspection */ - /** @psalm-suppress PossiblyNullIterator - we use the prepare* methods here, so we don't get NULL here */ + /* @noinspection AlterInForeachInspection | ok here */ foreach (self::$ASCII_MAPS ?? [] as &$map) { $CHARS_ARRAY[$cacheKey][] = $map; } } - /** @phpstan-ignore-next-line - ... error? */ $CHARS_ARRAY[$cacheKey] = \array_merge([], ...$CHARS_ARRAY[$cacheKey]); if ($asOrigReplaceArray) { @@ -590,13 +564,11 @@ public static function normalize_msword(string $str): string return ''; } - /** @var array{orig: string[], replace: string[]} */ static $MSWORD_CACHE = ['orig' => [], 'replace' => []]; if (empty($MSWORD_CACHE['orig'])) { self::prepareAsciiMaps(); - /** @var array */ $map = self::$ASCII_MAPS[self::EXTRA_MSWORD_CHARS_LANGUAGE_CODE] ?? []; $MSWORD_CACHE = [ @@ -636,7 +608,6 @@ public static function normalize_whitespace( return ''; } - /** @var array> */ static $WHITESPACE_CACHE = []; $cacheKey = (int) $keepNonBreakingSpace; @@ -673,7 +644,6 @@ public static function normalize_whitespace( } if (!$keepBidiUnicodeControls) { - /** @var array|null */ static $BIDI_UNICODE_CONTROLS_CACHE = null; if ($BIDI_UNICODE_CONTROLS_CACHE === null) { @@ -689,7 +659,7 @@ public static function normalize_whitespace( /** * Remove invisible characters from a string. * - * e.g.: This prevents sandwiching null characters between ascii characters, like Java\0script. + * This prevents malicious code injection through null bytes or other control characters. * * copy&past from https://github.com/bcit-ci/CodeIgniter/blob/develop/system/core/Common.php * @@ -735,21 +705,16 @@ public static function remove_invisible_characters( } /** - * WARNING: This method will return broken characters and is only for special cases. + * WARNING: This method will return broken characters and is only for special cases. * - * Convert two UTF-8 encoded string to a single-byte strings suitable for + * Convert two UTF-8 encoded strings to a single-byte strings suitable for * functions that need the same string length after the conversion. * * The function simply uses (and updates) a tailored dynamic encoding * (in/out map parameter) where non-ascii characters are remapped to * the range [128-255] in order of appearance. * - * @param string $str1 - * @param string $str2 - * - * @return string[] - * - * @phpstan-return array{0: string, 1: string} + * @return array{0: string, 1: string} */ public static function to_ascii_remap(string $str1, string $str2): array { @@ -775,14 +740,14 @@ public static function to_ascii_remap(string $str1, string $str2): array * @param string $str

The input string.

* @param string $language [optional]

Language of the source string. * (default is 'en') | ASCII::*_LANGUAGE_CODE

- * @param bool $remove_unsupported_chars [optional]

Whether or not to remove the + * @param bool $remove_unsupported_chars [optional]

Whether to remove the * unsupported characters.

* @param bool $replace_extra_symbols [optional]

Add some more replacements e.g. "£" with " pound * ".

* @param bool $use_transliterate [optional]

Use ASCII::to_transliterate() for unknown chars.

- * @param bool|null $replace_single_chars_only [optional]

Single char replacement is better for the - * performance, but some languages need to replace more then one char - * at the same time. | NULL === auto-setting, depended on the + * @param bool $replace_single_chars_only [optional]

Single char replacement is better for the + * performance, but some languages need to replace more than one char + * at the same time. If FALSE === auto-setting, depended on the * language

* * @psalm-pure @@ -798,18 +763,17 @@ public static function to_ascii( bool $remove_unsupported_chars = true, bool $replace_extra_symbols = false, bool $use_transliterate = false, - bool $replace_single_chars_only = null + bool $replace_single_chars_only = false ): string { if ($str === '') { return ''; } - /** @phpstan-var ASCII::*_LANGUAGE_CODE - hack for phpstan */ + /** @phpstan-var ASCII::*_LANGUAGE_CODE $language - hack for phpstan */ $language = self::get_language($language); static $EXTRA_SYMBOLS_CACHE = null; - /** @var array> */ static $REPLACE_HELPER_CACHE = []; $cacheKey = $language . '-' . $replace_extra_symbols; @@ -977,7 +941,6 @@ public static function to_ascii( } } - /** @psalm-suppress PossiblyNullOperand - we use the prepare* methods here, so we don't get NULL here */ if (!isset(self::$ASCII_MAPS[$language])) { $use_transliterate = true; } @@ -1001,10 +964,10 @@ public static function to_ascii( * ASCII::to_filename('שדגשדג.png', true)); // 'shdgshdg.png' * * - * @param string $str + * @param string $str

The string input.

* @param bool $use_transliterate

ASCII::to_transliterate() is used by default - unsafe characters are * simply replaced with hyphen otherwise.

- * @param string $fallback_char + * @param string $fallback_char

The fallback character. - "-" is the default

* * @psalm-pure * @@ -1040,27 +1003,27 @@ public static function to_filename( } /** - * Converts the string into an URL slug. This includes replacing non-ASCII - * characters with their closest ASCII equivalents, removing remaining - * non-ASCII and non-alphanumeric characters, and replacing whitespace with - * $separator. The separator defaults to a single dash, and the string - * is also converted to lowercase. The language of the source string can - * also be supplied for language-specific transliteration. - * - * @param string $str + * Converts a string into a URL-friendly slug. + * + * - This includes replacing non-ASCII characters with their closest ASCII equivalents, removing remaining + * non-ASCII and non-alphanumeric characters, and replacing whitespace with $separator. + * - The separator defaults to a single dash, and the string is also converted to lowercase. + * - The language of the source string can also be supplied for language-specific transliteration. + * + * @param string $str

The string input.

* @param string $separator [optional]

The string used to replace whitespace.

* @param string $language [optional]

Language of the source string. * (default is 'en') | ASCII::*_LANGUAGE_CODE

* @param array $replacements [optional]

A map of replaceable strings.

- * @param bool $replace_extra_symbols [optional]

Add some more replacements e.g. "£" with " + * @param bool $replace_extra_symbols [optional]

Add some more replacements e.g. "£" with " * pound ".

* @param bool $use_str_to_lower [optional]

Use "string to lower" for the input.

- * @param bool $use_transliterate [optional]

Use ASCII::to_transliterate() for unknown + * @param bool $use_transliterate [optional]

Use ASCII::to_transliterate() for unknown * chars.

* @psalm-pure * * @return string - *

A string that has been converted to an URL slug.

+ *

The URL-friendly slug.

* * @phpstan-param ASCII::*_LANGUAGE_CODE $language */ @@ -1135,21 +1098,16 @@ public static function to_slugify( * * @return string *

A String that contains only ASCII characters.

- * - * @noinspection ParameterDefaultValueIsNotNullInspection */ public static function to_transliterate( string $str, $unknown = '?', bool $strict = false ): string { - /** @var array|null */ static $UTF8_TO_TRANSLIT = null; - /** null|\Transliterator */ static $TRANSLITERATOR = null; - /** @var bool|null */ static $SUPPORT_INTL = null; if ($str === '') { @@ -1168,7 +1126,7 @@ public static function to_transliterate( $str = self::clean($str); - // check again, if we only have ASCII, now ... + // check again if we only have ASCII, now ... if ( $str_tmp !== $str && @@ -1184,7 +1142,6 @@ public static function to_transliterate( ) { if (!isset($TRANSLITERATOR)) { // INFO: see "*-Latin" rules via "transliterator_list_ids()" - /** @var \Transliterator */ $TRANSLITERATOR = \transliterator_create('NFKC; [:Nonspacing Mark:] Remove; NFKC; Any-Latin; Latin-ASCII;'); } @@ -1192,8 +1149,7 @@ public static function to_transliterate( $str_tmp = \transliterator_transliterate($TRANSLITERATOR, $str); if ($str_tmp !== false) { - - // check again, if we only have ASCII, now ... + // check again if we only have ASCII, now ... if ( $str_tmp !== $str && @@ -1285,7 +1241,6 @@ public static function to_transliterate( $new_char = $ord & 255; if (isset($UTF8_TO_TRANSLIT[$bank][$new_char])) { - // keep for debugging /* echo "file: " . sprintf('x%02x', $bank) . "\n"; @@ -1299,8 +1254,7 @@ public static function to_transliterate( $new_char = $UTF8_TO_TRANSLIT[$bank][$new_char]; - /** @noinspection MissingOrEmptyGroupStatementInspection */ - /** @noinspection PhpStatementHasEmptyBodyInspection */ + /* @noinspection PhpStatementHasEmptyBodyInspection */ if ($unknown === null && $new_char === '') { // nothing } elseif ( @@ -1313,7 +1267,6 @@ public static function to_transliterate( $c = $new_char; } } else { - // keep for debugging missing chars /* echo "file: " . sprintf('x%02x', $bank) . "\n"; @@ -1352,7 +1305,7 @@ public static function to_transliterate( * @param array $map

Internal-Map of code points to ASCII characters.

* * @return string - *

Mapped borken string.

+ *

Mapped broken string.

* * @phpstan-param array $map */ @@ -1385,12 +1338,6 @@ private static function to_ascii_remap_intern(string $str, array &$map): string * DE_DE -> de * de-de -> de * - * @noinspection ReturnTypeCanBeDeclaredInspection - * - * @param string $language - * - * @psalm-pure - * * @return string */ private static function get_language(string $language) @@ -1417,39 +1364,22 @@ private static function get_language(string $language) /** * Get data from "/data/*.php". * - * @noinspection ReturnTypeCanBeDeclaredInspection - * - * @param string $file - * - * @psalm-pure - * - * @return array + * @return array */ private static function getData(string $file) { - /** @noinspection PhpIncludeInspection */ - /** @noinspection UsingInclusionReturnValueInspection */ - /** @psalm-suppress UnresolvableInclude */ return include __DIR__ . '/data/' . $file . '.php'; } /** * Get data from "/data/*.php". * - * @param string $file - * - * @psalm-pure - * - * @return array + * @return array */ private static function getDataIfExists(string $file): array { $file = __DIR__ . '/data/' . $file . '.php'; - /** @psalm-suppress ImpureFunctionCall */ if (\is_file($file)) { - /** @noinspection PhpIncludeInspection */ - /** @noinspection UsingInclusionReturnValueInspection */ - /** @psalm-suppress UnresolvableInclude */ return include $file; } @@ -1457,8 +1387,6 @@ private static function getDataIfExists(string $file): array } /** - * @psalm-pure - * * @return void */ private static function prepareAsciiAndExtrasMaps() @@ -1467,7 +1395,6 @@ private static function prepareAsciiAndExtrasMaps() self::prepareAsciiMaps(); self::prepareAsciiExtras(); - /** @psalm-suppress PossiblyNullArgument - we use the prepare* methods here, so we don't get NULL here */ self::$ASCII_MAPS_AND_EXTRAS = \array_merge_recursive( self::$ASCII_MAPS ?? [], self::$ASCII_EXTRAS ?? [] @@ -1476,8 +1403,6 @@ private static function prepareAsciiAndExtrasMaps() } /** - * @psalm-pure - * * @return void */ private static function prepareAsciiMaps() @@ -1488,8 +1413,6 @@ private static function prepareAsciiMaps() } /** - * @psalm-pure - * * @return void */ private static function prepareAsciiExtras()