diff options
| author | Mario Vavti <mario@mariovavti.com> | 2025-11-07 20:55:45 +0100 |
|---|---|---|
| committer | Mario Vavti <mario@mariovavti.com> | 2025-11-07 20:55:45 +0100 |
| commit | 6c74672d40a639c5a88b02c48c5222ad7d0edf12 (patch) | |
| tree | 9daf0ef27ddf0565ac43d69e7c14c965f26d274a /vendor | |
| parent | 6320506c2738258c0bab9a6778342fbdc958b022 (diff) | |
| download | volse-hubzilla-6c74672d40a639c5a88b02c48c5222ad7d0edf12.tar.gz volse-hubzilla-6c74672d40a639c5a88b02c48c5222ad7d0edf12.tar.bz2 volse-hubzilla-6c74672d40a639c5a88b02c48c5222ad7d0edf12.zip | |
bump composer PHP version to 8.2 and update libs
Diffstat (limited to 'vendor')
30 files changed, 694 insertions, 481 deletions
diff --git a/vendor/brick/math/CHANGELOG.md b/vendor/brick/math/CHANGELOG.md index a07ba88a7..377cdae22 100644 --- a/vendor/brick/math/CHANGELOG.md +++ b/vendor/brick/math/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to this project will be documented in this file. +## [0.14.0](https://github.com/brick/math/releases/tag/0.14.0) - 2025-08-29 + +✨ **New features** + +- New methods: `BigInteger::clamp()` and `BigDecimal::clamp()` (#96 by @JesterIruka) + +✨ **Improvements** + +- All pure methods in `BigNumber` classes are now marked as `@pure` for better static analysis + +💥 **Breaking changes** + +- Minimum PHP version is now 8.2 +- `BigNumber` classes are now `readonly` +- `BigNumber` is now marked as sealed: it must not be extended outside of this package +- Exception classes are now `final` + ## [0.13.1](https://github.com/brick/math/releases/tag/0.13.1) - 2025-03-29 ✨ **Improvements** diff --git a/vendor/brick/math/composer.json b/vendor/brick/math/composer.json index f400aa447..ad1dfe07a 100644 --- a/vendor/brick/math/composer.json +++ b/vendor/brick/math/composer.json @@ -19,12 +19,12 @@ ], "license": "MIT", "require": { - "php": "^8.1" + "php": "^8.2" }, "require-dev": { - "phpunit/phpunit": "^10.1", + "phpunit/phpunit": "^11.5", "php-coveralls/php-coveralls": "^2.2", - "vimeo/psalm": "6.8.8" + "phpstan/phpstan": "2.1.22" }, "autoload": { "psr-4": { diff --git a/vendor/brick/math/phpstan.neon b/vendor/brick/math/phpstan.neon new file mode 100644 index 000000000..216ba1e8d --- /dev/null +++ b/vendor/brick/math/phpstan.neon @@ -0,0 +1,14 @@ +parameters: + level: 10 + checkUninitializedProperties: true + paths: + - src + ignoreErrors: + - '~Impure call to function array_shift\(\) in pure method~' + - '~Possibly impure call to function assert\(\) in pure method~' + - '~Possibly impure call to function hex2bin\(\) in pure method~' + - '~Possibly impure call to function preg_match\(\) in pure method~' + - '~Impure static variable in pure method Brick\\Math\\Big(Integer|Decimal|Rational)::(zero|one|ten)\(\)~' + - + message: '~Parameter #\d \$\S+ of function bc\S+ expects numeric-string, string given~' + path: src/Internal/Calculator/BcMathCalculator.php diff --git a/vendor/brick/math/psalm-baseline.xml b/vendor/brick/math/psalm-baseline.xml deleted file mode 100644 index 112adf451..000000000 --- a/vendor/brick/math/psalm-baseline.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<files psalm-version="6.8.8@1361cd33008feb3ae2b4a93f1860e14e538ec8c2"> - <file src="src/BigInteger.php"> - <FalsableReturnStatement> - <code><![CDATA[\hex2bin($hex)]]></code> - </FalsableReturnStatement> - <InvalidFalsableReturnType> - <code><![CDATA[string]]></code> - </InvalidFalsableReturnType> - </file> - <file src="src/Exception/DivisionByZeroException.php"> - <ClassMustBeFinal> - <code><![CDATA[DivisionByZeroException]]></code> - </ClassMustBeFinal> - </file> - <file src="src/Exception/IntegerOverflowException.php"> - <ClassMustBeFinal> - <code><![CDATA[IntegerOverflowException]]></code> - </ClassMustBeFinal> - </file> - <file src="src/Exception/NegativeNumberException.php"> - <ClassMustBeFinal> - <code><![CDATA[NegativeNumberException]]></code> - </ClassMustBeFinal> - </file> - <file src="src/Exception/NumberFormatException.php"> - <ClassMustBeFinal> - <code><![CDATA[NumberFormatException]]></code> - </ClassMustBeFinal> - </file> - <file src="src/Exception/RoundingNecessaryException.php"> - <ClassMustBeFinal> - <code><![CDATA[RoundingNecessaryException]]></code> - </ClassMustBeFinal> - </file> - <file src="src/Internal/Calculator/BcMathCalculator.php"> - <ClassMustBeFinal> - <code><![CDATA[BcMathCalculator]]></code> - </ClassMustBeFinal> - </file> - <file src="src/Internal/Calculator/GmpCalculator.php"> - <ClassMustBeFinal> - <code><![CDATA[GmpCalculator]]></code> - </ClassMustBeFinal> - </file> - <file src="src/Internal/Calculator/NativeCalculator.php"> - <ClassMustBeFinal> - <code><![CDATA[NativeCalculator]]></code> - </ClassMustBeFinal> - <InvalidOperand> - <code><![CDATA[$a * $b]]></code> - <code><![CDATA[$a * 1]]></code> - <code><![CDATA[$a + $b]]></code> - <code><![CDATA[$b * 1]]></code> - <code><![CDATA[$b * 1]]></code> - <code><![CDATA[$blockA * $blockB + $carry]]></code> - <code><![CDATA[$blockA + $blockB]]></code> - <code><![CDATA[$blockA + $blockB + $carry]]></code> - <code><![CDATA[$blockA - $blockB]]></code> - <code><![CDATA[$blockA - $blockB - $carry]]></code> - <code><![CDATA[$carry]]></code> - <code><![CDATA[$mul % $complement]]></code> - <code><![CDATA[$mul - $value]]></code> - <code><![CDATA[$nb - 1]]></code> - <code><![CDATA[$sum += $complement]]></code> - <code><![CDATA[($mul - $value) / $complement]]></code> - <code><![CDATA[($nb - 1) * 10]]></code> - </InvalidOperand> - </file> -</files> diff --git a/vendor/brick/math/src/BigDecimal.php b/vendor/brick/math/src/BigDecimal.php index 0932fd642..1a540c7d6 100644 --- a/vendor/brick/math/src/BigDecimal.php +++ b/vendor/brick/math/src/BigDecimal.php @@ -8,14 +8,13 @@ use Brick\Math\Exception\DivisionByZeroException; use Brick\Math\Exception\MathException; use Brick\Math\Exception\NegativeNumberException; use Brick\Math\Internal\Calculator; +use Brick\Math\Internal\CalculatorRegistry; use Override; /** * Immutable, arbitrary-precision signed decimal numbers. - * - * @psalm-immutable */ -final class BigDecimal extends BigNumber +final readonly class BigDecimal extends BigNumber { /** * The unscaled value of this decimal number. @@ -24,20 +23,22 @@ final class BigDecimal extends BigNumber * No leading zero must be present. * No leading minus sign must be present if the value is 0. */ - private readonly string $value; + private string $value; /** * The scale (number of digits after the decimal point) of this decimal number. * * This must be zero or more. */ - private readonly int $scale; + private int $scale; /** * Protected constructor. Use a factory method to obtain an instance. * * @param string $value The unscaled value, validated. * @param int $scale The scale, validated. + * + * @pure */ protected function __construct(string $value, int $scale = 0) { @@ -45,9 +46,6 @@ final class BigDecimal extends BigNumber $this->scale = $scale; } - /** - * @psalm-pure - */ #[Override] protected static function from(BigNumber $number): static { @@ -63,7 +61,7 @@ final class BigDecimal extends BigNumber * @param int $scale The scale of the number. If negative, the scale will be set to zero * and the unscaled value will be adjusted accordingly. * - * @psalm-pure + * @pure */ public static function ofUnscaledValue(BigNumber|int|float|string $value, int $scale = 0) : BigDecimal { @@ -82,14 +80,11 @@ final class BigDecimal extends BigNumber /** * Returns a BigDecimal representing zero, with a scale of zero. * - * @psalm-pure + * @pure */ public static function zero() : BigDecimal { - /** - * @psalm-suppress ImpureStaticVariable - * @var BigDecimal|null $zero - */ + /** @var BigDecimal|null $zero */ static $zero; if ($zero === null) { @@ -102,14 +97,11 @@ final class BigDecimal extends BigNumber /** * Returns a BigDecimal representing one, with a scale of zero. * - * @psalm-pure + * @pure */ public static function one() : BigDecimal { - /** - * @psalm-suppress ImpureStaticVariable - * @var BigDecimal|null $one - */ + /** @var BigDecimal|null $one */ static $one; if ($one === null) { @@ -122,14 +114,11 @@ final class BigDecimal extends BigNumber /** * Returns a BigDecimal representing ten, with a scale of zero. * - * @psalm-pure + * @pure */ public static function ten() : BigDecimal { - /** - * @psalm-suppress ImpureStaticVariable - * @var BigDecimal|null $ten - */ + /** @var BigDecimal|null $ten */ static $ten; if ($ten === null) { @@ -147,6 +136,8 @@ final class BigDecimal extends BigNumber * @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigDecimal. * * @throws MathException If the number is not valid, or is not convertible to a BigDecimal. + * + * @pure */ public function plus(BigNumber|int|float|string $that) : BigDecimal { @@ -162,7 +153,7 @@ final class BigDecimal extends BigNumber [$a, $b] = $this->scaleValues($this, $that); - $value = Calculator::get()->add($a, $b); + $value = CalculatorRegistry::get()->add($a, $b); $scale = $this->scale > $that->scale ? $this->scale : $that->scale; return new BigDecimal($value, $scale); @@ -176,6 +167,8 @@ final class BigDecimal extends BigNumber * @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigDecimal. * * @throws MathException If the number is not valid, or is not convertible to a BigDecimal. + * + * @pure */ public function minus(BigNumber|int|float|string $that) : BigDecimal { @@ -187,7 +180,7 @@ final class BigDecimal extends BigNumber [$a, $b] = $this->scaleValues($this, $that); - $value = Calculator::get()->sub($a, $b); + $value = CalculatorRegistry::get()->sub($a, $b); $scale = $this->scale > $that->scale ? $this->scale : $that->scale; return new BigDecimal($value, $scale); @@ -201,6 +194,8 @@ final class BigDecimal extends BigNumber * @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigDecimal. * * @throws MathException If the multiplier is not a valid number, or is not convertible to a BigDecimal. + * + * @pure */ public function multipliedBy(BigNumber|int|float|string $that) : BigDecimal { @@ -214,7 +209,7 @@ final class BigDecimal extends BigNumber return $that; } - $value = Calculator::get()->mul($this->value, $that->value); + $value = CalculatorRegistry::get()->mul($this->value, $that->value); $scale = $this->scale + $that->scale; return new BigDecimal($value, $scale); @@ -229,6 +224,8 @@ final class BigDecimal extends BigNumber * * @throws \InvalidArgumentException If the scale or rounding mode is invalid. * @throws MathException If the number is invalid, is zero, or rounding was necessary. + * + * @pure */ public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { @@ -251,7 +248,7 @@ final class BigDecimal extends BigNumber $p = $this->valueWithMinScale($that->scale + $scale); $q = $that->valueWithMinScale($this->scale - $scale); - $result = Calculator::get()->divRound($p, $q, $roundingMode); + $result = CalculatorRegistry::get()->divRound($p, $q, $roundingMode); return new BigDecimal($result, $scale); } @@ -265,6 +262,8 @@ final class BigDecimal extends BigNumber * * @throws MathException If the divisor is not a valid number, is not convertible to a BigDecimal, is zero, * or the result yields an infinite number of digits. + * + * @pure */ public function exactlyDividedBy(BigNumber|int|float|string $that) : BigDecimal { @@ -279,7 +278,7 @@ final class BigDecimal extends BigNumber $d = \rtrim($b, '0'); $scale = \strlen($b) - \strlen($d); - $calculator = Calculator::get(); + $calculator = CalculatorRegistry::get(); foreach ([5, 2] as $prime) { for (;;) { @@ -298,11 +297,35 @@ final class BigDecimal extends BigNumber } /** + * Limits (clamps) this number between the given minimum and maximum values. + * + * If the number is lower than $min, returns a copy of $min. + * If the number is greater than $max, returns a copy of $max. + * Otherwise, returns this number unchanged. + * + * @param BigNumber|int|float|string $min The minimum. Must be convertible to a BigDecimal. + * @param BigNumber|int|float|string $max The maximum. Must be convertible to a BigDecimal. + * + * @throws MathException If min/max are not convertible to a BigDecimal. + */ + public function clamp(BigNumber|int|float|string $min, BigNumber|int|float|string $max) : BigDecimal + { + if ($this->isLessThan($min)) { + return BigDecimal::of($min); + } elseif ($this->isGreaterThan($max)) { + return BigDecimal::of($max); + } + return $this; + } + + /** * Returns this number exponentiated to the given value. * * The result has a scale of `$this->scale * $exponent`. * * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. + * + * @pure */ public function power(int $exponent) : BigDecimal { @@ -322,7 +345,7 @@ final class BigDecimal extends BigNumber )); } - return new BigDecimal(Calculator::get()->pow($this->value, $exponent), $this->scale * $exponent); + return new BigDecimal(CalculatorRegistry::get()->pow($this->value, $exponent), $this->scale * $exponent); } /** @@ -333,6 +356,8 @@ final class BigDecimal extends BigNumber * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * * @throws MathException If the divisor is not a valid decimal number, or is zero. + * + * @pure */ public function quotient(BigNumber|int|float|string $that) : BigDecimal { @@ -345,7 +370,7 @@ final class BigDecimal extends BigNumber $p = $this->valueWithMinScale($that->scale); $q = $that->valueWithMinScale($this->scale); - $quotient = Calculator::get()->divQ($p, $q); + $quotient = CalculatorRegistry::get()->divQ($p, $q); return new BigDecimal($quotient, 0); } @@ -358,6 +383,8 @@ final class BigDecimal extends BigNumber * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * * @throws MathException If the divisor is not a valid decimal number, or is zero. + * + * @pure */ public function remainder(BigNumber|int|float|string $that) : BigDecimal { @@ -370,7 +397,7 @@ final class BigDecimal extends BigNumber $p = $this->valueWithMinScale($that->scale); $q = $that->valueWithMinScale($this->scale); - $remainder = Calculator::get()->divR($p, $q); + $remainder = CalculatorRegistry::get()->divR($p, $q); $scale = $this->scale > $that->scale ? $this->scale : $that->scale; @@ -384,11 +411,11 @@ final class BigDecimal extends BigNumber * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * - * @return BigDecimal[] An array containing the quotient and the remainder. - * - * @psalm-return array{BigDecimal, BigDecimal} + * @return array{BigDecimal, BigDecimal} An array containing the quotient and the remainder. * * @throws MathException If the divisor is not a valid decimal number, or is zero. + * + * @pure */ public function quotientAndRemainder(BigNumber|int|float|string $that) : array { @@ -401,7 +428,7 @@ final class BigDecimal extends BigNumber $p = $this->valueWithMinScale($that->scale); $q = $that->valueWithMinScale($this->scale); - [$quotient, $remainder] = Calculator::get()->divQR($p, $q); + [$quotient, $remainder] = CalculatorRegistry::get()->divQR($p, $q); $scale = $this->scale > $that->scale ? $this->scale : $that->scale; @@ -416,6 +443,8 @@ final class BigDecimal extends BigNumber * * @throws \InvalidArgumentException If the scale is negative. * @throws NegativeNumberException If this number is negative. + * + * @pure */ public function sqrt(int $scale) : BigDecimal { @@ -447,13 +476,15 @@ final class BigDecimal extends BigNumber $value = \substr($value, 0, $addDigits); } - $value = Calculator::get()->sqrt($value); + $value = CalculatorRegistry::get()->sqrt($value); return new BigDecimal($value, $scale); } /** * Returns a copy of this BigDecimal with the decimal point moved $n places to the left. + * + * @pure */ public function withPointMovedLeft(int $n) : BigDecimal { @@ -470,6 +501,8 @@ final class BigDecimal extends BigNumber /** * Returns a copy of this BigDecimal with the decimal point moved $n places to the right. + * + * @pure */ public function withPointMovedRight(int $n) : BigDecimal { @@ -496,6 +529,8 @@ final class BigDecimal extends BigNumber /** * Returns a copy of this BigDecimal with any trailing zeros removed from the fractional part. + * + * @pure */ public function stripTrailingZeros() : BigDecimal { @@ -527,6 +562,8 @@ final class BigDecimal extends BigNumber /** * Returns the absolute value of this number. + * + * @pure */ public function abs() : BigDecimal { @@ -535,10 +572,12 @@ final class BigDecimal extends BigNumber /** * Returns the negated value of this number. + * + * @pure */ public function negated() : BigDecimal { - return new BigDecimal(Calculator::get()->neg($this->value), $this->scale); + return new BigDecimal(CalculatorRegistry::get()->neg($this->value), $this->scale); } #[Override] @@ -553,7 +592,7 @@ final class BigDecimal extends BigNumber if ($that instanceof BigDecimal) { [$a, $b] = $this->scaleValues($this, $that); - return Calculator::get()->cmp($a, $b); + return CalculatorRegistry::get()->cmp($a, $b); } return - $that->compareTo($this); @@ -565,11 +604,17 @@ final class BigDecimal extends BigNumber return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1); } + /** + * @pure + */ public function getUnscaledValue() : BigInteger { return self::newBigInteger($this->value); } + /** + * @pure + */ public function getScale() : int { return $this->scale; @@ -588,6 +633,8 @@ final class BigDecimal extends BigNumber * 123.456 => 6 * 0.00123 => 3 * 0.0012300 => 5 + * + * @pure */ public function getPrecision(): int { @@ -606,6 +653,8 @@ final class BigDecimal extends BigNumber * Returns a string representing the integral part of this decimal number. * * Example: `-123.456` => `-123`. + * + * @pure */ public function getIntegralPart() : string { @@ -624,6 +673,8 @@ final class BigDecimal extends BigNumber * If the scale is zero, an empty string is returned. * * Examples: `-123.456` => '456', `123` => ''. + * + * @pure */ public function getFractionalPart() : string { @@ -638,6 +689,8 @@ final class BigDecimal extends BigNumber /** * Returns whether this decimal number has a non-zero fractional part. + * + * @pure */ public function hasNonZeroFractionalPart() : bool { @@ -702,7 +755,7 @@ final class BigDecimal extends BigNumber $value = $this->getUnscaledValueWithLeadingZeros(); - /** @var numeric-string */ + /** @phpstan-ignore return.type */ return \substr($value, 0, -$this->scale) . '.' . \substr($value, -$this->scale); } @@ -722,7 +775,6 @@ final class BigDecimal extends BigNumber * This method is only here to allow unserializing the object and cannot be accessed directly. * * @internal - * @psalm-suppress RedundantPropertyInitializationCheck * * @param array{value: string, scale: int} $data * @@ -730,10 +782,12 @@ final class BigDecimal extends BigNumber */ public function __unserialize(array $data): void { + /** @phpstan-ignore isset.initializedProperty */ if (isset($this->value)) { throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); } + /** @phpstan-ignore deadCode.unreachable */ $this->value = $data['value']; $this->scale = $data['scale']; } @@ -742,6 +796,8 @@ final class BigDecimal extends BigNumber * Puts the internal values of the given decimal numbers on the same scale. * * @return array{string, string} The scaled integer values of $x and $y. + * + * @pure */ private function scaleValues(BigDecimal $x, BigDecimal $y) : array { @@ -757,6 +813,9 @@ final class BigDecimal extends BigNumber return [$a, $b]; } + /** + * @pure + */ private function valueWithMinScale(int $scale) : string { $value = $this->value; @@ -770,6 +829,8 @@ final class BigDecimal extends BigNumber /** * Adds leading zeros if necessary to the unscaled value to represent the full decimal number. + * + * @pure */ private function getUnscaledValueWithLeadingZeros() : string { diff --git a/vendor/brick/math/src/BigInteger.php b/vendor/brick/math/src/BigInteger.php index 6ede65e3a..48a7bb3cf 100644 --- a/vendor/brick/math/src/BigInteger.php +++ b/vendor/brick/math/src/BigInteger.php @@ -10,6 +10,7 @@ use Brick\Math\Exception\MathException; use Brick\Math\Exception\NegativeNumberException; use Brick\Math\Exception\NumberFormatException; use Brick\Math\Internal\Calculator; +use Brick\Math\Internal\CalculatorRegistry; use Override; /** @@ -17,10 +18,8 @@ use Override; * * All methods accepting a number as a parameter accept either a BigInteger instance, * an integer, or a string representing an arbitrary size integer. - * - * @psalm-immutable */ -final class BigInteger extends BigNumber +final readonly class BigInteger extends BigNumber { /** * The value, as a string of digits with optional leading minus sign. @@ -28,21 +27,20 @@ final class BigInteger extends BigNumber * No leading zeros must be present. * No leading minus sign must be present if the number is zero. */ - private readonly string $value; + private string $value; /** * Protected constructor. Use a factory method to obtain an instance. * * @param string $value A string of digits, with optional leading minus sign. + * + * @pure */ protected function __construct(string $value) { $this->value = $value; } - /** - * @psalm-pure - */ #[Override] protected static function from(BigNumber $number): static { @@ -66,7 +64,7 @@ final class BigInteger extends BigNumber * @throws NumberFormatException If the number is empty, or contains invalid chars for the given base. * @throws \InvalidArgumentException If the base is out of range. * - * @psalm-pure + * @pure */ public static function fromBase(string $number, int $base) : BigInteger { @@ -115,7 +113,7 @@ final class BigInteger extends BigNumber return new BigInteger($sign . $number); } - $result = Calculator::get()->fromBase($number, $base); + $result = CalculatorRegistry::get()->fromBase($number, $base); return new BigInteger($sign . $result); } @@ -131,7 +129,7 @@ final class BigInteger extends BigNumber * @throws NumberFormatException If the given number is empty or contains invalid chars for the given alphabet. * @throws \InvalidArgumentException If the alphabet does not contain at least 2 chars. * - * @psalm-pure + * @pure */ public static function fromArbitraryBase(string $number, string $alphabet) : BigInteger { @@ -151,7 +149,7 @@ final class BigInteger extends BigNumber throw NumberFormatException::charNotInAlphabet($matches[0]); } - $number = Calculator::get()->fromArbitraryBase($number, $alphabet, $base); + $number = CalculatorRegistry::get()->fromArbitraryBase($number, $alphabet, $base); return new BigInteger($number); } @@ -172,6 +170,8 @@ final class BigInteger extends BigNumber * sign bit. * * @throws NumberFormatException If the string is empty. + * + * @pure */ public static function fromBytes(string $value, bool $signed = true) : BigInteger { @@ -203,12 +203,10 @@ final class BigInteger extends BigNumber * * Using the default random bytes generator, this method is suitable for cryptographic use. * - * @psalm-param (callable(int): string)|null $randomBytesGenerator - * - * @param int $numBits The number of bits. - * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, and returns a - * string of random bytes of the given length. Defaults to the - * `random_bytes()` function. + * @param int $numBits The number of bits. + * @param (callable(int): string)|null $randomBytesGenerator A function that accepts a number of bytes, and returns + * a string of random bytes of the given length. Defaults + * to the `random_bytes()` function. * * @throws \InvalidArgumentException If $numBits is negative. */ @@ -243,13 +241,11 @@ final class BigInteger extends BigNumber * * Using the default random bytes generator, this method is suitable for cryptographic use. * - * @psalm-param (callable(int): string)|null $randomBytesGenerator - * - * @param BigNumber|int|float|string $min The lower bound. Must be convertible to a BigInteger. - * @param BigNumber|int|float|string $max The upper bound. Must be convertible to a BigInteger. - * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, - * and returns a string of random bytes of the given length. - * Defaults to the `random_bytes()` function. + * @param BigNumber|int|float|string $min The lower bound. Must be convertible to a BigInteger. + * @param BigNumber|int|float|string $max The upper bound. Must be convertible to a BigInteger. + * @param (callable(int): string)|null $randomBytesGenerator A function that accepts a number of bytes, and returns + * a string of random bytes of the given length. Defaults + * to the `random_bytes()` function. * * @throws MathException If one of the parameters cannot be converted to a BigInteger, * or `$min` is greater than `$max`. @@ -284,14 +280,11 @@ final class BigInteger extends BigNumber /** * Returns a BigInteger representing zero. * - * @psalm-pure + * @pure */ public static function zero() : BigInteger { - /** - * @psalm-suppress ImpureStaticVariable - * @var BigInteger|null $zero - */ + /** @var BigInteger|null $zero */ static $zero; if ($zero === null) { @@ -304,14 +297,11 @@ final class BigInteger extends BigNumber /** * Returns a BigInteger representing one. * - * @psalm-pure + * @pure */ public static function one() : BigInteger { - /** - * @psalm-suppress ImpureStaticVariable - * @var BigInteger|null $one - */ + /** @var BigInteger|null $one */ static $one; if ($one === null) { @@ -324,14 +314,11 @@ final class BigInteger extends BigNumber /** * Returns a BigInteger representing ten. * - * @psalm-pure + * @pure */ public static function ten() : BigInteger { - /** - * @psalm-suppress ImpureStaticVariable - * @var BigInteger|null $ten - */ + /** @var BigInteger|null $ten */ static $ten; if ($ten === null) { @@ -341,6 +328,9 @@ final class BigInteger extends BigNumber return $ten; } + /** + * @pure + */ public static function gcdMultiple(BigInteger $a, BigInteger ...$n): BigInteger { $result = $a; @@ -362,6 +352,8 @@ final class BigInteger extends BigNumber * @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigInteger. * * @throws MathException If the number is not valid, or is not convertible to a BigInteger. + * + * @pure */ public function plus(BigNumber|int|float|string $that) : BigInteger { @@ -375,7 +367,7 @@ final class BigInteger extends BigNumber return $that; } - $value = Calculator::get()->add($this->value, $that->value); + $value = CalculatorRegistry::get()->add($this->value, $that->value); return new BigInteger($value); } @@ -386,6 +378,8 @@ final class BigInteger extends BigNumber * @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigInteger. * * @throws MathException If the number is not valid, or is not convertible to a BigInteger. + * + * @pure */ public function minus(BigNumber|int|float|string $that) : BigInteger { @@ -395,7 +389,7 @@ final class BigInteger extends BigNumber return $this; } - $value = Calculator::get()->sub($this->value, $that->value); + $value = CalculatorRegistry::get()->sub($this->value, $that->value); return new BigInteger($value); } @@ -406,6 +400,8 @@ final class BigInteger extends BigNumber * @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigInteger. * * @throws MathException If the multiplier is not a valid number, or is not convertible to a BigInteger. + * + * @pure */ public function multipliedBy(BigNumber|int|float|string $that) : BigInteger { @@ -419,7 +415,7 @@ final class BigInteger extends BigNumber return $that; } - $value = Calculator::get()->mul($this->value, $that->value); + $value = CalculatorRegistry::get()->mul($this->value, $that->value); return new BigInteger($value); } @@ -432,6 +428,8 @@ final class BigInteger extends BigNumber * * @throws MathException If the divisor is not a valid number, is not convertible to a BigInteger, is zero, * or RoundingMode::UNNECESSARY is used and the remainder is not zero. + * + * @pure */ public function dividedBy(BigNumber|int|float|string $that, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigInteger { @@ -445,15 +443,40 @@ final class BigInteger extends BigNumber throw DivisionByZeroException::divisionByZero(); } - $result = Calculator::get()->divRound($this->value, $that->value, $roundingMode); + $result = CalculatorRegistry::get()->divRound($this->value, $that->value, $roundingMode); return new BigInteger($result); } /** + * Limits (clamps) this number between the given minimum and maximum values. + * + * If the number is lower than $min, returns a copy of $min. + * If the number is greater than $max, returns a copy of $max. + * Otherwise, returns this number unchanged. + * + * @param BigNumber|int|float|string $min The minimum. Must be convertible to a BigInteger. + * @param BigNumber|int|float|string $max The maximum. Must be convertible to a BigInteger. + * + * @throws MathException If min/max are not convertible to a BigInteger. + */ + public function clamp(BigNumber|int|float|string $min, BigNumber|int|float|string $max) : BigInteger + { + if ($this->isLessThan($min)) { + return BigInteger::of($min); + } elseif ($this->isGreaterThan($max)) { + return BigInteger::of($max); + } + return $this; + } + + + /** * Returns this number exponentiated to the given value. * * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. + * + * @pure */ public function power(int $exponent) : BigInteger { @@ -473,7 +496,7 @@ final class BigInteger extends BigNumber )); } - return new BigInteger(Calculator::get()->pow($this->value, $exponent)); + return new BigInteger(CalculatorRegistry::get()->pow($this->value, $exponent)); } /** @@ -482,6 +505,8 @@ final class BigInteger extends BigNumber * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * * @throws DivisionByZeroException If the divisor is zero. + * + * @pure */ public function quotient(BigNumber|int|float|string $that) : BigInteger { @@ -495,7 +520,7 @@ final class BigInteger extends BigNumber throw DivisionByZeroException::divisionByZero(); } - $quotient = Calculator::get()->divQ($this->value, $that->value); + $quotient = CalculatorRegistry::get()->divQ($this->value, $that->value); return new BigInteger($quotient); } @@ -508,6 +533,8 @@ final class BigInteger extends BigNumber * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * * @throws DivisionByZeroException If the divisor is zero. + * + * @pure */ public function remainder(BigNumber|int|float|string $that) : BigInteger { @@ -521,7 +548,7 @@ final class BigInteger extends BigNumber throw DivisionByZeroException::divisionByZero(); } - $remainder = Calculator::get()->divR($this->value, $that->value); + $remainder = CalculatorRegistry::get()->divR($this->value, $that->value); return new BigInteger($remainder); } @@ -531,11 +558,11 @@ final class BigInteger extends BigNumber * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * - * @return BigInteger[] An array containing the quotient and the remainder. - * - * @psalm-return array{BigInteger, BigInteger} + * @return array{BigInteger, BigInteger} An array containing the quotient and the remainder. * * @throws DivisionByZeroException If the divisor is zero. + * + * @pure */ public function quotientAndRemainder(BigNumber|int|float|string $that) : array { @@ -545,7 +572,7 @@ final class BigInteger extends BigNumber throw DivisionByZeroException::divisionByZero(); } - [$quotient, $remainder] = Calculator::get()->divQR($this->value, $that->value); + [$quotient, $remainder] = CalculatorRegistry::get()->divQR($this->value, $that->value); return [ new BigInteger($quotient), @@ -564,6 +591,8 @@ final class BigInteger extends BigNumber * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * * @throws DivisionByZeroException If the divisor is zero. + * + * @pure */ public function mod(BigNumber|int|float|string $that) : BigInteger { @@ -573,7 +602,7 @@ final class BigInteger extends BigNumber throw DivisionByZeroException::modulusMustNotBeZero(); } - $value = Calculator::get()->mod($this->value, $that->value); + $value = CalculatorRegistry::get()->mod($this->value, $that->value); return new BigInteger($value); } @@ -585,6 +614,8 @@ final class BigInteger extends BigNumber * @throws NegativeNumberException If $m is negative. * @throws MathException If this BigInteger has no multiplicative inverse mod m (that is, this BigInteger * is not relatively prime to m). + * + * @pure */ public function modInverse(BigInteger $m) : BigInteger { @@ -600,7 +631,7 @@ final class BigInteger extends BigNumber return BigInteger::zero(); } - $value = Calculator::get()->modInverse($this->value, $m->value); + $value = CalculatorRegistry::get()->modInverse($this->value, $m->value); if ($value === null) { throw new MathException('Unable to compute the modInverse for the given modulus.'); @@ -619,6 +650,8 @@ final class BigInteger extends BigNumber * * @throws NegativeNumberException If any of the operands is negative. * @throws DivisionByZeroException If the modulus is zero. + * + * @pure */ public function modPow(BigNumber|int|float|string $exp, BigNumber|int|float|string $mod) : BigInteger { @@ -633,7 +666,7 @@ final class BigInteger extends BigNumber throw DivisionByZeroException::modulusMustNotBeZero(); } - $result = Calculator::get()->modPow($this->value, $exp->value, $mod->value); + $result = CalculatorRegistry::get()->modPow($this->value, $exp->value, $mod->value); return new BigInteger($result); } @@ -644,6 +677,8 @@ final class BigInteger extends BigNumber * The GCD is always positive, unless both operands are zero, in which case it is zero. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. + * + * @pure */ public function gcd(BigNumber|int|float|string $that) : BigInteger { @@ -657,7 +692,7 @@ final class BigInteger extends BigNumber return $that; } - $value = Calculator::get()->gcd($this->value, $that->value); + $value = CalculatorRegistry::get()->gcd($this->value, $that->value); return new BigInteger($value); } @@ -668,6 +703,8 @@ final class BigInteger extends BigNumber * The result is the largest x such that x² ≤ n. * * @throws NegativeNumberException If this number is negative. + * + * @pure */ public function sqrt() : BigInteger { @@ -675,13 +712,15 @@ final class BigInteger extends BigNumber throw new NegativeNumberException('Cannot calculate the square root of a negative number.'); } - $value = Calculator::get()->sqrt($this->value); + $value = CalculatorRegistry::get()->sqrt($this->value); return new BigInteger($value); } /** * Returns the absolute value of this number. + * + * @pure */ public function abs() : BigInteger { @@ -690,10 +729,12 @@ final class BigInteger extends BigNumber /** * Returns the inverse of this number. + * + * @pure */ public function negated() : BigInteger { - return new BigInteger(Calculator::get()->neg($this->value)); + return new BigInteger(CalculatorRegistry::get()->neg($this->value)); } /** @@ -702,12 +743,14 @@ final class BigInteger extends BigNumber * This method returns a negative BigInteger if and only if both operands are negative. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. + * + * @pure */ public function and(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); - return new BigInteger(Calculator::get()->and($this->value, $that->value)); + return new BigInteger(CalculatorRegistry::get()->and($this->value, $that->value)); } /** @@ -716,12 +759,14 @@ final class BigInteger extends BigNumber * This method returns a negative BigInteger if and only if either of the operands is negative. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. + * + * @pure */ public function or(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); - return new BigInteger(Calculator::get()->or($this->value, $that->value)); + return new BigInteger(CalculatorRegistry::get()->or($this->value, $that->value)); } /** @@ -730,16 +775,20 @@ final class BigInteger extends BigNumber * This method returns a negative BigInteger if and only if exactly one of the operands is negative. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. + * + * @pure */ public function xor(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); - return new BigInteger(Calculator::get()->xor($this->value, $that->value)); + return new BigInteger(CalculatorRegistry::get()->xor($this->value, $that->value)); } /** * Returns the bitwise-not of this BigInteger. + * + * @pure */ public function not() : BigInteger { @@ -748,6 +797,8 @@ final class BigInteger extends BigNumber /** * Returns the integer left shifted by a given number of bits. + * + * @pure */ public function shiftedLeft(int $distance) : BigInteger { @@ -764,6 +815,8 @@ final class BigInteger extends BigNumber /** * Returns the integer right shifted by a given number of bits. + * + * @pure */ public function shiftedRight(int $distance) : BigInteger { @@ -789,6 +842,8 @@ final class BigInteger extends BigNumber * * For positive BigIntegers, this is equivalent to the number of bits in the ordinary binary representation. * Computes (ceil(log2(this < 0 ? -this : this+1))). + * + * @pure */ public function getBitLength() : int { @@ -807,6 +862,8 @@ final class BigInteger extends BigNumber * Returns the index of the rightmost (lowest-order) one bit in this BigInteger. * * Returns -1 if this BigInteger contains no one bits. + * + * @pure */ public function getLowestSetBit() : int { @@ -826,6 +883,8 @@ final class BigInteger extends BigNumber /** * Returns whether this number is even. + * + * @pure */ public function isEven() : bool { @@ -834,6 +893,8 @@ final class BigInteger extends BigNumber /** * Returns whether this number is odd. + * + * @pure */ public function isOdd() : bool { @@ -848,6 +909,8 @@ final class BigInteger extends BigNumber * @param int $n The bit to test, 0-based. * * @throws \InvalidArgumentException If the bit to test is negative. + * + * @pure */ public function testBit(int $n) : bool { @@ -864,7 +927,7 @@ final class BigInteger extends BigNumber $that = BigNumber::of($that); if ($that instanceof BigInteger) { - return Calculator::get()->cmp($this->value, $that->value); + return CalculatorRegistry::get()->cmp($this->value, $that->value); } return - $that->compareTo($this); @@ -924,6 +987,8 @@ final class BigInteger extends BigNumber * The output will always be lowercase for bases greater than 10. * * @throws \InvalidArgumentException If the base is out of range. + * + * @pure */ public function toBase(int $base) : string { @@ -935,7 +1000,7 @@ final class BigInteger extends BigNumber throw new \InvalidArgumentException(\sprintf('Base %d is out of range [2, 36]', $base)); } - return Calculator::get()->toBase($this->value, $base); + return CalculatorRegistry::get()->toBase($this->value, $base); } /** @@ -948,6 +1013,8 @@ final class BigInteger extends BigNumber * * @throws NegativeNumberException If this number is negative. * @throws \InvalidArgumentException If the given alphabet does not contain at least 2 chars. + * + * @pure */ public function toArbitraryBase(string $alphabet) : string { @@ -961,7 +1028,7 @@ final class BigInteger extends BigNumber throw new NegativeNumberException(__FUNCTION__ . '() does not support negative numbers.'); } - return Calculator::get()->toArbitraryBase($this->value, $alphabet, $base); + return CalculatorRegistry::get()->toArbitraryBase($this->value, $alphabet, $base); } /** @@ -981,6 +1048,8 @@ final class BigInteger extends BigNumber * @param bool $signed Whether to output a signed number in two's-complement representation with a leading sign bit. * * @throws NegativeNumberException If $signed is false, and the number is negative. + * + * @pure */ public function toBytes(bool $signed = true) : string { @@ -1020,7 +1089,10 @@ final class BigInteger extends BigNumber } } - return \hex2bin($hex); + $result = \hex2bin($hex); + assert($result !== false); + + return $result; } /** @@ -1049,7 +1121,6 @@ final class BigInteger extends BigNumber * This method is only here to allow unserializing the object and cannot be accessed directly. * * @internal - * @psalm-suppress RedundantPropertyInitializationCheck * * @param array{value: string} $data * @@ -1057,10 +1128,12 @@ final class BigInteger extends BigNumber */ public function __unserialize(array $data): void { + /** @phpstan-ignore isset.initializedProperty */ if (isset($this->value)) { throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); } + /** @phpstan-ignore deadCode.unreachable */ $this->value = $data['value']; } } diff --git a/vendor/brick/math/src/BigNumber.php b/vendor/brick/math/src/BigNumber.php index 5dabd314b..2fbdf696e 100644 --- a/vendor/brick/math/src/BigNumber.php +++ b/vendor/brick/math/src/BigNumber.php @@ -11,11 +11,14 @@ use Brick\Math\Exception\RoundingNecessaryException; use Override; /** - * Common interface for arbitrary-precision rational numbers. + * Base class for arbitrary-precision numbers. * - * @psalm-immutable + * This class is sealed: it is part of the public API but should not be subclassed in userland. + * Protected methods may change in any version. + * + * @phpstan-sealed BigInteger|BigDecimal|BigRational */ -abstract class BigNumber implements \JsonSerializable +abstract readonly class BigNumber implements \JsonSerializable, \Stringable { /** * The regular expression used to parse integer or decimal numbers. @@ -43,7 +46,8 @@ abstract class BigNumber implements \JsonSerializable /** * Creates a BigNumber of the given value. * - * The concrete return type is dependent on the given value, with the following rules: + * When of() is called on BigNumber, the concrete return type is dependent on the given value, with the following + * rules: * * - BigNumber instances are returned as is * - integer numbers are returned as BigInteger @@ -52,18 +56,20 @@ abstract class BigNumber implements \JsonSerializable * - strings containing a `.` character or using an exponential notation are returned as BigDecimal * - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger * + * When of() is called on BigInteger, BigDecimal, or BigRational, the resulting number is converted to an instance + * of the subclass when possible; otherwise a RoundingNecessaryException exception is thrown. + * * @throws NumberFormatException If the format of the number is not valid. * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. * @throws RoundingNecessaryException If the value cannot be converted to an instance of the subclass without rounding. * - * @psalm-pure + * @pure */ final public static function of(BigNumber|int|float|string $value) : static { $value = self::_of($value); if (static::class === BigNumber::class) { - // https://github.com/vimeo/psalm/issues/10309 assert($value instanceof static); return $value; @@ -76,7 +82,7 @@ abstract class BigNumber implements \JsonSerializable * @throws NumberFormatException If the format of the number is not valid. * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. * - * @psalm-pure + * @pure */ private static function _of(BigNumber|int|float|string $value) : BigNumber { @@ -102,9 +108,6 @@ abstract class BigNumber implements \JsonSerializable $numerator = $matches['numerator']; $denominator = $matches['denominator']; - assert($numerator !== null); - assert($denominator !== null); - $numerator = self::cleanUp($sign, $numerator); $denominator = self::cleanUp(null, $denominator); @@ -138,7 +141,7 @@ abstract class BigNumber implements \JsonSerializable } if ($point !== null || $exponent !== null) { - $fractional = ($fractional ?? ''); + $fractional ??= ''; $exponent = ($exponent !== null) ? (int)$exponent : 0; if ($exponent === PHP_INT_MIN || $exponent === PHP_INT_MAX) { @@ -170,15 +173,15 @@ abstract class BigNumber implements \JsonSerializable * * @throws RoundingNecessaryException If the value cannot be converted. * - * @psalm-pure + * @pure */ abstract protected static function from(BigNumber $number): static; /** * Proxy method to access BigInteger's protected constructor from sibling classes. * + * @pure * @internal - * @psalm-pure */ final protected function newBigInteger(string $value) : BigInteger { @@ -188,8 +191,8 @@ abstract class BigNumber implements \JsonSerializable /** * Proxy method to access BigDecimal's protected constructor from sibling classes. * + * @pure * @internal - * @psalm-pure */ final protected function newBigDecimal(string $value, int $scale = 0) : BigDecimal { @@ -199,8 +202,8 @@ abstract class BigNumber implements \JsonSerializable /** * Proxy method to access BigRational's protected constructor from sibling classes. * + * @pure * @internal - * @psalm-pure */ final protected function newBigRational(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator) : BigRational { @@ -216,7 +219,7 @@ abstract class BigNumber implements \JsonSerializable * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * - * @psalm-pure + * @pure */ final public static function min(BigNumber|int|float|string ...$values) : static { @@ -246,7 +249,7 @@ abstract class BigNumber implements \JsonSerializable * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * - * @psalm-pure + * @pure */ final public static function max(BigNumber|int|float|string ...$values) : static { @@ -270,41 +273,43 @@ abstract class BigNumber implements \JsonSerializable /** * Returns the sum of the given values. * - * @param BigNumber|int|float|string ...$values The numbers to add. All the numbers need to be convertible - * to an instance of the class this method is called on. + * When called on BigNumber, sum() accepts any supported type and returns a result whose type is the widest among + * the given values (BigInteger < BigDecimal < BigRational). + * + * When called on BigInteger, BigDecimal, or BigRational, sum() requires that all values can be converted to that + * specific subclass, and returns a result of the same type. + * + * @param BigNumber|int|float|string ...$values The values to add. All values must be convertible to the class on + * which this method is called. * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * - * @psalm-pure + * @pure */ final public static function sum(BigNumber|int|float|string ...$values) : static { - /** @var static|null $sum */ - $sum = null; - - foreach ($values as $value) { - $value = static::of($value); + $first = array_shift($values); - $sum = $sum === null ? $value : self::add($sum, $value); + if ($first === null) { + throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.'); } - if ($sum === null) { - throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.'); + $sum = static::of($first); + + foreach ($values as $value) { + $sum = self::add($sum, static::of($value)); } + assert($sum instanceof static); + return $sum; } /** * Adds two BigNumber instances in the correct order to avoid a RoundingNecessaryException. * - * @todo This could be better resolved by creating an abstract protected method in BigNumber, and leaving to - * concrete classes the responsibility to perform the addition themselves or delegate it to the given number, - * depending on their ability to perform the operation. This will also require a version bump because we're - * potentially breaking custom BigNumber implementations (if any...) - * - * @psalm-pure + * @pure */ private static function add(BigNumber $a, BigNumber $b) : BigNumber { @@ -324,8 +329,6 @@ abstract class BigNumber implements \JsonSerializable return $b->plus($a); } - /** @var BigInteger $a */ - return $a->plus($b); } @@ -333,9 +336,9 @@ abstract class BigNumber implements \JsonSerializable * Removes optional leading zeros and applies sign. * * @param string|null $sign The sign, '+' or '-', optional. Null is allowed for convenience and treated as '+'. - * @param string $number The number, validated as a non-empty string of digits. + * @param string $number The number, validated as a string of digits. * - * @psalm-pure + * @pure */ private static function cleanUp(string|null $sign, string $number) : string { @@ -350,6 +353,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number is equal to the given one. + * + * @pure */ final public function isEqualTo(BigNumber|int|float|string $that) : bool { @@ -358,6 +363,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number is strictly lower than the given one. + * + * @pure */ final public function isLessThan(BigNumber|int|float|string $that) : bool { @@ -366,6 +373,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number is lower than or equal to the given one. + * + * @pure */ final public function isLessThanOrEqualTo(BigNumber|int|float|string $that) : bool { @@ -374,6 +383,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number is strictly greater than the given one. + * + * @pure */ final public function isGreaterThan(BigNumber|int|float|string $that) : bool { @@ -382,6 +393,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number is greater than or equal to the given one. + * + * @pure */ final public function isGreaterThanOrEqualTo(BigNumber|int|float|string $that) : bool { @@ -390,6 +403,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number equals zero. + * + * @pure */ final public function isZero() : bool { @@ -398,6 +413,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number is strictly negative. + * + * @pure */ final public function isNegative() : bool { @@ -406,6 +423,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number is negative or zero. + * + * @pure */ final public function isNegativeOrZero() : bool { @@ -414,6 +433,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number is strictly positive. + * + * @pure */ final public function isPositive() : bool { @@ -422,6 +443,8 @@ abstract class BigNumber implements \JsonSerializable /** * Checks if this number is positive or zero. + * + * @pure */ final public function isPositiveOrZero() : bool { @@ -431,20 +454,24 @@ abstract class BigNumber implements \JsonSerializable /** * Returns the sign of this number. * - * @psalm-return -1|0|1 + * Returns -1 if the number is negative, 0 if zero, 1 if positive. + * + * @return -1|0|1 * - * @return int -1 if the number is negative, 0 if zero, 1 if positive. + * @pure */ abstract public function getSign() : int; /** * Compares this number to the given one. * - * @psalm-return -1|0|1 + * Returns -1 if `$this` is lower than, 0 if equal to, 1 if greater than `$that`. * - * @return int -1 if `$this` is lower than, 0 if equal to, 1 if greater than `$that`. + * @return -1|0|1 * * @throws MathException If the number is not valid. + * + * @pure */ abstract public function compareTo(BigNumber|int|float|string $that) : int; @@ -452,6 +479,8 @@ abstract class BigNumber implements \JsonSerializable * Converts this number to a BigInteger. * * @throws RoundingNecessaryException If this number cannot be converted to a BigInteger without rounding. + * + * @pure */ abstract public function toBigInteger() : BigInteger; @@ -459,11 +488,15 @@ abstract class BigNumber implements \JsonSerializable * Converts this number to a BigDecimal. * * @throws RoundingNecessaryException If this number cannot be converted to a BigDecimal without rounding. + * + * @pure */ abstract public function toBigDecimal() : BigDecimal; /** * Converts this number to a BigRational. + * + * @pure */ abstract public function toBigRational() : BigRational; @@ -475,6 +508,8 @@ abstract class BigNumber implements \JsonSerializable * * @throws RoundingNecessaryException If this number cannot be converted to the given scale without rounding. * This only applies when RoundingMode::UNNECESSARY is used. + * + * @pure */ abstract public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal; @@ -485,6 +520,8 @@ abstract class BigNumber implements \JsonSerializable * Note that the acceptable range for an integer depends on the platform and differs for 32-bit and 64-bit. * * @throws MathException If this number cannot be exactly converted to a native integer. + * + * @pure */ abstract public function toInt() : int; @@ -496,6 +533,8 @@ abstract class BigNumber implements \JsonSerializable * * If the number is greater than the largest representable floating point number, positive infinity is returned. * If the number is less than the smallest representable floating point number, negative infinity is returned. + * + * @pure */ abstract public function toFloat() : float; @@ -504,6 +543,8 @@ abstract class BigNumber implements \JsonSerializable * * The output of this method can be parsed by the `of()` factory method; * this will yield an object equal to this one, without any information loss. + * + * @pure */ abstract public function __toString() : string; diff --git a/vendor/brick/math/src/BigRational.php b/vendor/brick/math/src/BigRational.php index fc36e5573..56045e537 100644 --- a/vendor/brick/math/src/BigRational.php +++ b/vendor/brick/math/src/BigRational.php @@ -14,20 +14,18 @@ use Override; * An arbitrarily large rational number. * * This class is immutable. - * - * @psalm-immutable */ -final class BigRational extends BigNumber +final readonly class BigRational extends BigNumber { /** * The numerator. */ - private readonly BigInteger $numerator; + private BigInteger $numerator; /** * The denominator. Always strictly positive. */ - private readonly BigInteger $denominator; + private BigInteger $denominator; /** * Protected constructor. Use a factory method to obtain an instance. @@ -37,6 +35,8 @@ final class BigRational extends BigNumber * @param bool $checkDenominator Whether to check the denominator for negative and zero. * * @throws DivisionByZeroException If the denominator is zero. + * + * @pure */ protected function __construct(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator) { @@ -55,9 +55,6 @@ final class BigRational extends BigNumber $this->denominator = $denominator; } - /** - * @psalm-pure - */ #[Override] protected static function from(BigNumber $number): static { @@ -77,7 +74,7 @@ final class BigRational extends BigNumber * @throws RoundingNecessaryException If an argument represents a non-integer number. * @throws DivisionByZeroException If the denominator is zero. * - * @psalm-pure + * @pure */ public static function nd( BigNumber|int|float|string $numerator, @@ -92,14 +89,11 @@ final class BigRational extends BigNumber /** * Returns a BigRational representing zero. * - * @psalm-pure + * @pure */ public static function zero() : BigRational { - /** - * @psalm-suppress ImpureStaticVariable - * @var BigRational|null $zero - */ + /** @var BigRational|null $zero */ static $zero; if ($zero === null) { @@ -112,14 +106,11 @@ final class BigRational extends BigNumber /** * Returns a BigRational representing one. * - * @psalm-pure + * @pure */ public static function one() : BigRational { - /** - * @psalm-suppress ImpureStaticVariable - * @var BigRational|null $one - */ + /** @var BigRational|null $one */ static $one; if ($one === null) { @@ -132,14 +123,11 @@ final class BigRational extends BigNumber /** * Returns a BigRational representing ten. * - * @psalm-pure + * @pure */ public static function ten() : BigRational { - /** - * @psalm-suppress ImpureStaticVariable - * @var BigRational|null $ten - */ + /** @var BigRational|null $ten */ static $ten; if ($ten === null) { @@ -149,11 +137,17 @@ final class BigRational extends BigNumber return $ten; } + /** + * @pure + */ public function getNumerator() : BigInteger { return $this->numerator; } + /** + * @pure + */ public function getDenominator() : BigInteger { return $this->denominator; @@ -161,6 +155,8 @@ final class BigRational extends BigNumber /** * Returns the quotient of the division of the numerator by the denominator. + * + * @pure */ public function quotient() : BigInteger { @@ -169,6 +165,8 @@ final class BigRational extends BigNumber /** * Returns the remainder of the division of the numerator by the denominator. + * + * @pure */ public function remainder() : BigInteger { @@ -178,9 +176,9 @@ final class BigRational extends BigNumber /** * Returns the quotient and remainder of the division of the numerator by the denominator. * - * @return BigInteger[] + * @return array{BigInteger, BigInteger} * - * @psalm-return array{BigInteger, BigInteger} + * @pure */ public function quotientAndRemainder() : array { @@ -193,6 +191,8 @@ final class BigRational extends BigNumber * @param BigNumber|int|float|string $that The number to add. * * @throws MathException If the number is not valid. + * + * @pure */ public function plus(BigNumber|int|float|string $that) : BigRational { @@ -211,6 +211,8 @@ final class BigRational extends BigNumber * @param BigNumber|int|float|string $that The number to subtract. * * @throws MathException If the number is not valid. + * + * @pure */ public function minus(BigNumber|int|float|string $that) : BigRational { @@ -229,6 +231,8 @@ final class BigRational extends BigNumber * @param BigNumber|int|float|string $that The multiplier. * * @throws MathException If the multiplier is not a valid number. + * + * @pure */ public function multipliedBy(BigNumber|int|float|string $that) : BigRational { @@ -246,6 +250,8 @@ final class BigRational extends BigNumber * @param BigNumber|int|float|string $that The divisor. * * @throws MathException If the divisor is not a valid number, or is zero. + * + * @pure */ public function dividedBy(BigNumber|int|float|string $that) : BigRational { @@ -261,6 +267,8 @@ final class BigRational extends BigNumber * Returns this number exponentiated to the given value. * * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. + * + * @pure */ public function power(int $exponent) : BigRational { @@ -287,6 +295,8 @@ final class BigRational extends BigNumber * The reciprocal has the numerator and denominator swapped. * * @throws DivisionByZeroException If the numerator is zero. + * + * @pure */ public function reciprocal() : BigRational { @@ -295,6 +305,8 @@ final class BigRational extends BigNumber /** * Returns the absolute value of this BigRational. + * + * @pure */ public function abs() : BigRational { @@ -303,6 +315,8 @@ final class BigRational extends BigNumber /** * Returns the negated value of this BigRational. + * + * @pure */ public function negated() : BigRational { @@ -311,6 +325,8 @@ final class BigRational extends BigNumber /** * Returns the simplified value of this BigRational. + * + * @pure */ public function simplified() : BigRational { @@ -406,7 +422,6 @@ final class BigRational extends BigNumber * This method is only here to allow unserializing the object and cannot be accessed directly. * * @internal - * @psalm-suppress RedundantPropertyInitializationCheck * * @param array{numerator: BigInteger, denominator: BigInteger} $data * @@ -414,10 +429,12 @@ final class BigRational extends BigNumber */ public function __unserialize(array $data): void { + /** @phpstan-ignore isset.initializedProperty */ if (isset($this->numerator)) { throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); } + /** @phpstan-ignore deadCode.unreachable */ $this->numerator = $data['numerator']; $this->denominator = $data['denominator']; } diff --git a/vendor/brick/math/src/Exception/DivisionByZeroException.php b/vendor/brick/math/src/Exception/DivisionByZeroException.php index ce7769ac2..2daaf5ed8 100644 --- a/vendor/brick/math/src/Exception/DivisionByZeroException.php +++ b/vendor/brick/math/src/Exception/DivisionByZeroException.php @@ -7,10 +7,10 @@ namespace Brick\Math\Exception; /** * Exception thrown when a division by zero occurs. */ -class DivisionByZeroException extends MathException +final class DivisionByZeroException extends MathException { /** - * @psalm-pure + * @pure */ public static function divisionByZero() : DivisionByZeroException { @@ -18,7 +18,7 @@ class DivisionByZeroException extends MathException } /** - * @psalm-pure + * @pure */ public static function modulusMustNotBeZero() : DivisionByZeroException { @@ -26,7 +26,7 @@ class DivisionByZeroException extends MathException } /** - * @psalm-pure + * @pure */ public static function denominatorMustNotBeZero() : DivisionByZeroException { diff --git a/vendor/brick/math/src/Exception/IntegerOverflowException.php b/vendor/brick/math/src/Exception/IntegerOverflowException.php index c73b49097..56f3cf84c 100644 --- a/vendor/brick/math/src/Exception/IntegerOverflowException.php +++ b/vendor/brick/math/src/Exception/IntegerOverflowException.php @@ -9,10 +9,10 @@ use Brick\Math\BigInteger; /** * Exception thrown when an integer overflow occurs. */ -class IntegerOverflowException extends MathException +final class IntegerOverflowException extends MathException { /** - * @psalm-pure + * @pure */ public static function toIntOverflow(BigInteger $value) : IntegerOverflowException { diff --git a/vendor/brick/math/src/Exception/NegativeNumberException.php b/vendor/brick/math/src/Exception/NegativeNumberException.php index 473911341..73ed3a494 100644 --- a/vendor/brick/math/src/Exception/NegativeNumberException.php +++ b/vendor/brick/math/src/Exception/NegativeNumberException.php @@ -7,6 +7,6 @@ namespace Brick\Math\Exception; /** * Exception thrown when attempting to perform an unsupported operation, such as a square root, on a negative number. */ -class NegativeNumberException extends MathException +final class NegativeNumberException extends MathException { } diff --git a/vendor/brick/math/src/Exception/NumberFormatException.php b/vendor/brick/math/src/Exception/NumberFormatException.php index 119cadbb4..0dcda3483 100644 --- a/vendor/brick/math/src/Exception/NumberFormatException.php +++ b/vendor/brick/math/src/Exception/NumberFormatException.php @@ -7,8 +7,11 @@ namespace Brick\Math\Exception; /** * Exception thrown when attempting to create a number from a string with an invalid format. */ -class NumberFormatException extends MathException +final class NumberFormatException extends MathException { + /** + * @pure + */ public static function invalidFormat(string $value) : self { return new self(\sprintf( @@ -20,7 +23,7 @@ class NumberFormatException extends MathException /** * @param string $char The failing character. * - * @psalm-pure + * @pure */ public static function charNotInAlphabet(string $char) : self { diff --git a/vendor/brick/math/src/Exception/RoundingNecessaryException.php b/vendor/brick/math/src/Exception/RoundingNecessaryException.php index 57bfcd844..034a04069 100644 --- a/vendor/brick/math/src/Exception/RoundingNecessaryException.php +++ b/vendor/brick/math/src/Exception/RoundingNecessaryException.php @@ -7,10 +7,10 @@ namespace Brick\Math\Exception; /** * Exception thrown when a number cannot be represented at the requested scale without rounding. */ -class RoundingNecessaryException extends MathException +final class RoundingNecessaryException extends MathException { /** - * @psalm-pure + * @pure */ public static function roundingNecessary() : RoundingNecessaryException { diff --git a/vendor/brick/math/src/Internal/Calculator.php b/vendor/brick/math/src/Internal/Calculator.php index 44dd66924..a5e000a42 100644 --- a/vendor/brick/math/src/Internal/Calculator.php +++ b/vendor/brick/math/src/Internal/Calculator.php @@ -17,10 +17,8 @@ use Brick\Math\RoundingMode; * All methods must return strings respecting this format, unless specified otherwise. * * @internal - * - * @psalm-immutable */ -abstract class Calculator +abstract readonly class Calculator { /** * The maximum exponent value allowed for the pow() method. @@ -33,62 +31,11 @@ abstract class Calculator public const ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz'; /** - * The Calculator instance in use. - */ - private static ?Calculator $instance = null; - - /** - * Sets the Calculator instance to use. - * - * An instance is typically set only in unit tests: the autodetect is usually the best option. - * - * @param Calculator|null $calculator The calculator instance, or NULL to revert to autodetect. - */ - final public static function set(?Calculator $calculator) : void - { - self::$instance = $calculator; - } - - /** - * Returns the Calculator instance to use. - * - * If none has been explicitly set, the fastest available implementation will be returned. - * - * @psalm-pure - * @psalm-suppress ImpureStaticProperty - */ - final public static function get() : Calculator - { - if (self::$instance === null) { - /** @psalm-suppress ImpureMethodCall */ - self::$instance = self::detect(); - } - - return self::$instance; - } - - /** - * Returns the fastest available Calculator implementation. - * - * @codeCoverageIgnore - */ - private static function detect() : Calculator - { - if (\extension_loaded('gmp')) { - return new Calculator\GmpCalculator(); - } - - if (\extension_loaded('bcmath')) { - return new Calculator\BcMathCalculator(); - } - - return new Calculator\NativeCalculator(); - } - - /** * Extracts the sign & digits of the operands. * * @return array{bool, bool, string, string} Whether $a and $b are negative, followed by their digits. + * + * @pure */ final protected function init(string $a, string $b) : array { @@ -103,6 +50,8 @@ abstract class Calculator /** * Returns the absolute value of a number. + * + * @pure */ final public function abs(string $n) : string { @@ -111,6 +60,8 @@ abstract class Calculator /** * Negates a number. + * + * @pure */ final public function neg(string $n) : string { @@ -128,9 +79,11 @@ abstract class Calculator /** * Compares two numbers. * - * @psalm-return -1|0|1 + * Returns -1 if the first number is less than, 0 if equal to, 1 if greater than the second number. + * + * @return -1|0|1 * - * @return int -1 if the first number is less than, 0 if equal to, 1 if greater than the second number. + * @pure */ final public function cmp(string $a, string $b) : int { @@ -160,16 +113,22 @@ abstract class Calculator /** * Adds two numbers. + * + * @pure */ abstract public function add(string $a, string $b) : string; /** * Subtracts two numbers. + * + * @pure */ abstract public function sub(string $a, string $b) : string; /** * Multiplies two numbers. + * + * @pure */ abstract public function mul(string $a, string $b) : string; @@ -180,6 +139,8 @@ abstract class Calculator * @param string $b The divisor, must not be zero. * * @return string The quotient. + * + * @pure */ abstract public function divQ(string $a, string $b) : string; @@ -190,6 +151,8 @@ abstract class Calculator * @param string $b The divisor, must not be zero. * * @return string The remainder. + * + * @pure */ abstract public function divR(string $a, string $b) : string; @@ -200,6 +163,8 @@ abstract class Calculator * @param string $b The divisor, must not be zero. * * @return array{string, string} An array containing the quotient and remainder. + * + * @pure */ abstract public function divQR(string $a, string $b) : array; @@ -210,11 +175,15 @@ abstract class Calculator * @param int $e The exponent, validated as an integer between 0 and MAX_POWER. * * @return string The power. + * + * @pure */ abstract public function pow(string $a, int $e) : string; /** * @param string $b The modulus; must not be zero. + * + * @pure */ public function mod(string $a, string $b) : string { @@ -229,6 +198,8 @@ abstract class Calculator * This method can be overridden by the concrete implementation if the underlying library has built-in support. * * @param string $m The modulus; must not be negative or zero. + * + * @pure */ public function modInverse(string $x, string $m) : ?string { @@ -257,6 +228,8 @@ abstract class Calculator * @param string $base The base number; must be positive or zero. * @param string $exp The exponent; must be positive or zero. * @param string $mod The modulus; must be strictly positive. + * + * @pure */ abstract public function modPow(string $base, string $exp, string $mod) : string; @@ -267,6 +240,8 @@ abstract class Calculator * has built-in support for GCD calculations. * * @return string The GCD, always positive, or zero if both arguments are zero. + * + * @pure */ public function gcd(string $a, string $b) : string { @@ -283,6 +258,8 @@ abstract class Calculator /** * @return array{string, string, string} GCD, X, Y + * + * @pure */ private function gcdExtended(string $a, string $b) : array { @@ -303,6 +280,8 @@ abstract class Calculator * * The result is the largest x such that x² ≤ n. * The input MUST NOT be negative. + * + * @pure */ abstract public function sqrt(string $n) : string; @@ -316,6 +295,8 @@ abstract class Calculator * @param int $base The base of the number, validated from 2 to 36. * * @return string The converted number, following the Calculator conventions. + * + * @pure */ public function fromBase(string $number, int $base) : string { @@ -332,6 +313,8 @@ abstract class Calculator * @param int $base The base to convert to, validated from 2 to 36. * * @return string The converted number, lowercase. + * + * @pure */ public function toBase(string $number, int $base) : string { @@ -359,6 +342,8 @@ abstract class Calculator * @param int $base The base of the number, validated from 2 to alphabet length. * * @return string The number in base 10, following the Calculator conventions. + * + * @pure */ final public function fromArbitraryBase(string $number, string $alphabet, int $base) : string { @@ -405,6 +390,8 @@ abstract class Calculator * @param int $base The base to convert to, validated from 2 to alphabet length. * * @return string The converted number in the given alphabet. + * + * @pure */ final public function toArbitraryBase(string $number, string $alphabet, int $base) : string { @@ -434,10 +421,9 @@ abstract class Calculator * @param string $b The divisor, must not be zero. * @param RoundingMode $roundingMode The rounding mode. * - * @throws \InvalidArgumentException If the rounding mode is invalid. * @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary. * - * @psalm-suppress ImpureFunctionCall + * @pure */ final public function divRound(string $a, string $b, RoundingMode $roundingMode) : string { @@ -498,9 +484,6 @@ abstract class Calculator $lastDigitIsEven = ($lastDigit % 2 === 0); $increment = $lastDigitIsEven ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0; break; - - default: - throw new \InvalidArgumentException('Invalid rounding mode.'); } if ($increment) { @@ -515,6 +498,8 @@ abstract class Calculator * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for bitwise operations. + * + * @pure */ public function and(string $a, string $b) : string { @@ -526,6 +511,8 @@ abstract class Calculator * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for bitwise operations. + * + * @pure */ public function or(string $a, string $b) : string { @@ -537,6 +524,8 @@ abstract class Calculator * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for bitwise operations. + * + * @pure */ public function xor(string $a, string $b) : string { @@ -549,6 +538,8 @@ abstract class Calculator * @param 'and'|'or'|'xor' $operator The operator to use. * @param string $a The left operand. * @param string $b The right operand. + * + * @pure */ private function bitwise(string $operator, string $a, string $b) : string { @@ -596,6 +587,8 @@ abstract class Calculator /** * @param string $number A positive, binary number. + * + * @pure */ private function twosComplement(string $number) : string { @@ -625,6 +618,8 @@ abstract class Calculator * Converts a decimal number to a binary string. * * @param string $number The number to convert, positive or zero, only digits. + * + * @pure */ private function toBinary(string $number) : string { @@ -642,6 +637,8 @@ abstract class Calculator * Returns the positive decimal representation of a binary number. * * @param string $bytes The bytes representing the number. + * + * @pure */ private function toDecimal(string $bytes) : string { diff --git a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php index 93a27ff81..5ba961ed3 100644 --- a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php @@ -11,10 +11,8 @@ use Override; * Calculator implementation built around the bcmath library. * * @internal - * - * @psalm-immutable */ -class BcMathCalculator extends Calculator +final readonly class BcMathCalculator extends Calculator { #[Override] public function add(string $a, string $b) : string diff --git a/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php b/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php index 0e44deeb3..c0f9bd585 100644 --- a/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php @@ -5,16 +5,15 @@ declare(strict_types=1); namespace Brick\Math\Internal\Calculator; use Brick\Math\Internal\Calculator; +use GMP; use Override; /** * Calculator implementation built around the GMP library. * * @internal - * - * @psalm-immutable */ -class GmpCalculator extends Calculator +final readonly class GmpCalculator extends Calculator { #[Override] public function add(string $a, string $b) : string @@ -51,6 +50,10 @@ class GmpCalculator extends Calculator { [$q, $r] = \gmp_div_qr($a, $b); + /** + * @var GMP $q + * @var GMP $r + */ return [ \gmp_strval($q), \gmp_strval($r) diff --git a/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php b/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php index f71c55bed..ee476c9f7 100644 --- a/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php @@ -11,10 +11,8 @@ use Override; * Calculator implementation using only native PHP code. * * @internal - * - * @psalm-immutable */ -class NativeCalculator extends Calculator +final readonly class NativeCalculator extends Calculator { /** * The max number of digits the platform can natively add, subtract, multiply or divide without overflow. @@ -24,9 +22,10 @@ class NativeCalculator extends Calculator * Example: 32-bit: max number 1,999,999,999 (9 digits + carry) * 64-bit: max number 1,999,999,999,999,999,999 (18 digits + carry) */ - private readonly int $maxDigits; + private int $maxDigits; /** + * @pure * @codeCoverageIgnore */ public function __construct() @@ -34,7 +33,6 @@ class NativeCalculator extends Calculator $this->maxDigits = match (PHP_INT_SIZE) { 4 => 9, 8 => 18, - default => throw new \RuntimeException('The platform is not 32-bit or 64-bit as expected.') }; } @@ -42,8 +40,8 @@ class NativeCalculator extends Calculator public function add(string $a, string $b) : string { /** - * @psalm-var numeric-string $a - * @psalm-var numeric-string $b + * @var numeric-string $a + * @var numeric-string $b */ $result = $a + $b; @@ -80,8 +78,8 @@ class NativeCalculator extends Calculator public function mul(string $a, string $b) : string { /** - * @psalm-var numeric-string $a - * @psalm-var numeric-string $b + * @var numeric-string $a + * @var numeric-string $b */ $result = $a * $b; @@ -151,11 +149,11 @@ class NativeCalculator extends Calculator return [$this->neg($a), '0']; } - /** @psalm-var numeric-string $a */ + /** @var numeric-string $a */ $na = $a * 1; // cast to number if (is_int($na)) { - /** @psalm-var numeric-string $b */ + /** @var numeric-string $b */ $nb = $b * 1; if (is_int($nb)) { @@ -202,7 +200,6 @@ class NativeCalculator extends Calculator $aa = $this->mul($a, $a); - /** @psalm-suppress PossiblyInvalidArgument We're sure that $e / 2 is an int now */ $result = $this->pow($aa, $e / 2); if ($odd === 1) { @@ -278,6 +275,8 @@ class NativeCalculator extends Calculator /** * Performs the addition of two non-signed large integers. + * + * @pure */ private function doAdd(string $a, string $b) : string { @@ -291,14 +290,13 @@ class NativeCalculator extends Calculator if ($i < 0) { $blockLength += $i; - /** @psalm-suppress LoopInvalidation */ $i = 0; } - /** @psalm-var numeric-string $blockA */ + /** @var numeric-string $blockA */ $blockA = \substr($a, $i, $blockLength); - /** @psalm-var numeric-string $blockB */ + /** @var numeric-string $blockB */ $blockB = \substr($b, $i, $blockLength); $sum = (string) ($blockA + $blockB + $carry); @@ -330,6 +328,8 @@ class NativeCalculator extends Calculator /** * Performs the subtraction of two non-signed large integers. + * + * @pure */ private function doSub(string $a, string $b) : string { @@ -360,14 +360,13 @@ class NativeCalculator extends Calculator if ($i < 0) { $blockLength += $i; - /** @psalm-suppress LoopInvalidation */ $i = 0; } - /** @psalm-var numeric-string $blockA */ + /** @var numeric-string $blockA */ $blockA = \substr($a, $i, $blockLength); - /** @psalm-var numeric-string $blockB */ + /** @var numeric-string $blockB */ $blockB = \substr($b, $i, $blockLength); $sum = $blockA - $blockB - $carry; @@ -407,6 +406,8 @@ class NativeCalculator extends Calculator /** * Performs the multiplication of two non-signed large integers. + * + * @pure */ private function doMul(string $a, string $b) : string { @@ -423,7 +424,6 @@ class NativeCalculator extends Calculator if ($i < 0) { $blockALength += $i; - /** @psalm-suppress LoopInvalidation */ $i = 0; } @@ -437,7 +437,6 @@ class NativeCalculator extends Calculator if ($j < 0) { $blockBLength += $j; - /** @psalm-suppress LoopInvalidation */ $j = 0; } @@ -480,6 +479,8 @@ class NativeCalculator extends Calculator * Performs the division of two non-signed large integers. * * @return string[] The quotient and remainder. + * + * @pure */ private function doDiv(string $a, string $b) : array { @@ -498,7 +499,7 @@ class NativeCalculator extends Calculator $r = $a; // remainder $z = $y; // focus length, always $y or $y+1 - /** @psalm-var numeric-string $b */ + /** @var numeric-string $b */ $nb = $b * 1; // cast to number // performance optimization in cases where the remainder will never cause int overflow if (is_int(($nb - 1) * 10 + 9)) { @@ -506,7 +507,7 @@ class NativeCalculator extends Calculator for ($i = $z - 1; $i < $x; $i++) { $n = $r * 10 + (int) $a[$i]; - /** @psalm-var int $nb */ + /** @var int $nb */ $q .= \intdiv($n, $nb); $r = $n % $nb; } @@ -553,7 +554,9 @@ class NativeCalculator extends Calculator /** * Compares two non-signed large numbers. * - * @psalm-return -1|0|1 + * @return -1|0|1 + * + * @pure */ private function doCmp(string $a, string $b) : int { @@ -575,6 +578,8 @@ class NativeCalculator extends Calculator * The numbers must only consist of digits, without leading minus sign. * * @return array{string, string, int} + * + * @pure */ private function pad(string $a, string $b) : array { diff --git a/vendor/brick/math/src/Internal/CalculatorRegistry.php b/vendor/brick/math/src/Internal/CalculatorRegistry.php new file mode 100644 index 000000000..394fae69a --- /dev/null +++ b/vendor/brick/math/src/Internal/CalculatorRegistry.php @@ -0,0 +1,73 @@ +<?php + +declare(strict_types=1); + +namespace Brick\Math\Internal; + +use function extension_loaded; + +/** + * Stores the current Calculator instance used by BigNumber classes. + * + * @internal + */ +final class CalculatorRegistry +{ + /** + * The Calculator instance in use. + */ + private static ?Calculator $instance = null; + + /** + * Sets the Calculator instance to use. + * + * An instance is typically set only in unit tests: autodetect is usually the best option. + * + * @param Calculator|null $calculator The calculator instance, or null to revert to autodetect. + */ + final public static function set(?Calculator $calculator) : void + { + self::$instance = $calculator; + } + + /** + * Returns the Calculator instance to use. + * + * If none has been explicitly set, the fastest available implementation will be returned. + * + * Note: even though this method is not technically pure, it is considered pure when used in a normal context, when + * only relying on autodetect. + * + * @pure + */ + final public static function get() : Calculator + { + /** @phpstan-ignore impure.staticPropertyAccess */ + if (self::$instance === null) { + /** @phpstan-ignore impure.propertyAssign */ + self::$instance = self::detect(); + } + + /** @phpstan-ignore impure.staticPropertyAccess */ + return self::$instance; + } + + /** + * Returns the fastest available Calculator implementation. + * + * @pure + * @codeCoverageIgnore + */ + private static function detect() : Calculator + { + if (extension_loaded('gmp')) { + return new Calculator\GmpCalculator(); + } + + if (extension_loaded('bcmath')) { + return new Calculator\BcMathCalculator(); + } + + return new Calculator\NativeCalculator(); + } +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 744bb05c9..f3ccb3931 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -47,6 +47,7 @@ return array( 'Brick\\Math\\Exception\\NumberFormatException' => $vendorDir . '/brick/math/src/Exception/NumberFormatException.php', 'Brick\\Math\\Exception\\RoundingNecessaryException' => $vendorDir . '/brick/math/src/Exception/RoundingNecessaryException.php', 'Brick\\Math\\Internal\\Calculator' => $vendorDir . '/brick/math/src/Internal/Calculator.php', + 'Brick\\Math\\Internal\\CalculatorRegistry' => $vendorDir . '/brick/math/src/Internal/CalculatorRegistry.php', 'Brick\\Math\\Internal\\Calculator\\BcMathCalculator' => $vendorDir . '/brick/math/src/Internal/Calculator/BcMathCalculator.php', 'Brick\\Math\\Internal\\Calculator\\GmpCalculator' => $vendorDir . '/brick/math/src/Internal/Calculator/GmpCalculator.php', 'Brick\\Math\\Internal\\Calculator\\NativeCalculator' => $vendorDir . '/brick/math/src/Internal/Calculator/NativeCalculator.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 2f1c48437..febd406a3 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -391,6 +391,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'Brick\\Math\\Exception\\NumberFormatException' => __DIR__ . '/..' . '/brick/math/src/Exception/NumberFormatException.php', 'Brick\\Math\\Exception\\RoundingNecessaryException' => __DIR__ . '/..' . '/brick/math/src/Exception/RoundingNecessaryException.php', 'Brick\\Math\\Internal\\Calculator' => __DIR__ . '/..' . '/brick/math/src/Internal/Calculator.php', + 'Brick\\Math\\Internal\\CalculatorRegistry' => __DIR__ . '/..' . '/brick/math/src/Internal/CalculatorRegistry.php', 'Brick\\Math\\Internal\\Calculator\\BcMathCalculator' => __DIR__ . '/..' . '/brick/math/src/Internal/Calculator/BcMathCalculator.php', 'Brick\\Math\\Internal\\Calculator\\GmpCalculator' => __DIR__ . '/..' . '/brick/math/src/Internal/Calculator/GmpCalculator.php', 'Brick\\Math\\Internal\\Calculator\\NativeCalculator' => __DIR__ . '/..' . '/brick/math/src/Internal/Calculator/NativeCalculator.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 4fce06fbd..6ee7d6beb 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -155,28 +155,28 @@ }, { "name": "brick/math", - "version": "0.13.1", - "version_normalized": "0.13.1.0", + "version": "0.14.0", + "version_normalized": "0.14.0.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04" + "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/fc7ed316430118cc7836bf45faff18d5dfc8de04", - "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04", + "url": "https://api.github.com/repos/brick/math/zipball/113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", + "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.2" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^10.1", - "vimeo/psalm": "6.8.8" + "phpstan/phpstan": "2.1.22", + "phpunit/phpunit": "^11.5" }, - "time": "2025-03-29T13:50:30+00:00", + "time": "2025-08-29T12:40:03+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -206,7 +206,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.13.1" + "source": "https://github.com/brick/math/tree/0.14.0" }, "funding": [ { @@ -1443,17 +1443,17 @@ }, { "name": "paragonie/easy-ecc", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", + "version": "v1.3.1", + "version_normalized": "1.3.1.0", "source": { "type": "git", "url": "https://github.com/paragonie/easy-ecc.git", - "reference": "1a72ed23a6598d482f2794c5ee6b2eb5abb364b2" + "reference": "ee588d73919f18ee27789ec1f0af2025fe74406a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/easy-ecc/zipball/1a72ed23a6598d482f2794c5ee6b2eb5abb364b2", - "reference": "1a72ed23a6598d482f2794c5ee6b2eb5abb364b2", + "url": "https://api.github.com/repos/paragonie/easy-ecc/zipball/ee588d73919f18ee27789ec1f0af2025fe74406a", + "reference": "ee588d73919f18ee27789ec1f0af2025fe74406a", "shasum": "" }, "require": { @@ -1468,7 +1468,7 @@ "phpunit/phpunit": "^7|^8|^9", "vimeo/psalm": "^1|^3|^4|^5|^6" }, - "time": "2025-07-19T03:27:16+00:00", + "time": "2025-10-22T18:38:57+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -3451,28 +3451,28 @@ }, { "name": "symfony/filesystem", - "version": "v6.4.24", - "version_normalized": "6.4.24.0", + "version": "v7.3.6", + "version_normalized": "7.3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "75ae2edb7cdcc0c53766c30b0a2512b8df574bd8" + "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/75ae2edb7cdcc0c53766c30b0a2512b8df574bd8", - "reference": "75ae2edb7cdcc0c53766c30b0a2512b8df574bd8", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e9bcfd7837928ab656276fe00464092cc9e1826a", + "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^5.4|^6.4|^7.0" + "symfony/process": "^6.4|^7.0" }, - "time": "2025-07-10T08:14:14+00:00", + "time": "2025-11-05T09:52:27+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -3500,7 +3500,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.24" + "source": "https://github.com/symfony/filesystem/tree/v7.3.6" }, "funding": [ { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 72a641687..9ee3bc95a 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'zotlabs/hubzilla', 'pretty_version' => 'dev-10.6RC', 'version' => 'dev-10.6RC', - 'reference' => 'd11b05de71d84416aa085abd8570c038b1dc618a', + 'reference' => '6320506c2738258c0bab9a6778342fbdc958b022', 'type' => 'application', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -29,9 +29,9 @@ 'dev_requirement' => false, ), 'brick/math' => array( - 'pretty_version' => '0.13.1', - 'version' => '0.13.1.0', - 'reference' => 'fc7ed316430118cc7836bf45faff18d5dfc8de04', + 'pretty_version' => '0.14.0', + 'version' => '0.14.0.0', + 'reference' => '113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2', 'type' => 'library', 'install_path' => __DIR__ . '/../brick/math', 'aliases' => array(), @@ -191,9 +191,9 @@ 'dev_requirement' => false, ), 'paragonie/easy-ecc' => array( - 'pretty_version' => 'v1.3.0', - 'version' => '1.3.0.0', - 'reference' => '1a72ed23a6598d482f2794c5ee6b2eb5abb364b2', + 'pretty_version' => 'v1.3.1', + 'version' => '1.3.1.0', + 'reference' => 'ee588d73919f18ee27789ec1f0af2025fe74406a', 'type' => 'library', 'install_path' => __DIR__ . '/../paragonie/easy-ecc', 'aliases' => array(), @@ -473,9 +473,9 @@ 'dev_requirement' => false, ), 'symfony/filesystem' => array( - 'pretty_version' => 'v6.4.24', - 'version' => '6.4.24.0', - 'reference' => '75ae2edb7cdcc0c53766c30b0a2512b8df574bd8', + 'pretty_version' => 'v7.3.6', + 'version' => '7.3.6.0', + 'reference' => 'e9bcfd7837928ab656276fe00464092cc9e1826a', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/filesystem', 'aliases' => array(), @@ -544,7 +544,7 @@ 'zotlabs/hubzilla' => array( 'pretty_version' => 'dev-10.6RC', 'version' => 'dev-10.6RC', - 'reference' => 'd11b05de71d84416aa085abd8570c038b1dc618a', + 'reference' => '6320506c2738258c0bab9a6778342fbdc958b022', 'type' => 'application', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index 6f978ee77..874843925 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 80100)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80200)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.'; } if (PHP_INT_SIZE !== 8) { diff --git a/vendor/paragonie/easy-ecc/psalm.xml b/vendor/paragonie/easy-ecc/psalm.xml index b8f8c5d36..a2889ccec 100644 --- a/vendor/paragonie/easy-ecc/psalm.xml +++ b/vendor/paragonie/easy-ecc/psalm.xml @@ -12,6 +12,10 @@ </projectFiles> <issueHandlers> + <MissingDependency errorLevel="info" /> + <PossiblyUnusedParam errorLevel="info" /> + <UndefinedClass errorLevel="info" /> + <UndefinedMethod errorLevel="info" /> <InvalidDocblock errorLevel="info" /> <PossiblyUnusedMethod errorLevel="info" /> <PropertyNotSetInConstructor errorLevel="suppress" /> diff --git a/vendor/paragonie/easy-ecc/src/Curve25519/X25519.php b/vendor/paragonie/easy-ecc/src/Curve25519/X25519.php index b5711cc5f..80c1edb72 100644 --- a/vendor/paragonie/easy-ecc/src/Curve25519/X25519.php +++ b/vendor/paragonie/easy-ecc/src/Curve25519/X25519.php @@ -26,7 +26,7 @@ final class X25519 implements EcDHInterface * @throws \SodiumException * @throws \TypeError */ - public function __construct(PrivateKeyInterface $sk = null, PublicKeyInterface $pk = null) + public function __construct(?PrivateKeyInterface $sk = null, ?PublicKeyInterface $pk = null) { if ($sk) { $this->setSenderKey($sk); diff --git a/vendor/symfony/filesystem/CHANGELOG.md b/vendor/symfony/filesystem/CHANGELOG.md index fcb7170ca..80818d1b5 100644 --- a/vendor/symfony/filesystem/CHANGELOG.md +++ b/vendor/symfony/filesystem/CHANGELOG.md @@ -1,6 +1,16 @@ CHANGELOG ========= +7.1 +--- + + * Add the `Filesystem::readFile()` method + +7.0 +--- + + * Add argument `$lock` to `Filesystem::appendToFile()` + 5.4 --- diff --git a/vendor/symfony/filesystem/Exception/IOException.php b/vendor/symfony/filesystem/Exception/IOException.php index df3a0850a..46ab8b4a5 100644 --- a/vendor/symfony/filesystem/Exception/IOException.php +++ b/vendor/symfony/filesystem/Exception/IOException.php @@ -20,12 +20,12 @@ namespace Symfony\Component\Filesystem\Exception; */ class IOException extends \RuntimeException implements IOExceptionInterface { - private ?string $path; - - public function __construct(string $message, int $code = 0, ?\Throwable $previous = null, ?string $path = null) - { - $this->path = $path; - + public function __construct( + string $message, + int $code = 0, + ?\Throwable $previous = null, + private ?string $path = null, + ) { parent::__construct($message, $code, $previous); } diff --git a/vendor/symfony/filesystem/Filesystem.php b/vendor/symfony/filesystem/Filesystem.php index 71628ceed..d08d99dda 100644 --- a/vendor/symfony/filesystem/Filesystem.php +++ b/vendor/symfony/filesystem/Filesystem.php @@ -31,12 +31,10 @@ class Filesystem * If the target file is newer, it is overwritten only when the * $overwriteNewerFiles option is set to true. * - * @return void - * * @throws FileNotFoundException When originFile doesn't exist * @throws IOException When copy fails */ - public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false) + public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false): void { $originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://'); if ($originIsLocal && !is_file($originFile)) { @@ -87,11 +85,9 @@ class Filesystem /** * Creates a directory recursively. * - * @return void - * * @throws IOException On any directory creation failure */ - public function mkdir(string|iterable $dirs, int $mode = 0777) + public function mkdir(string|iterable $dirs, int $mode = 0777): void { foreach ($this->toIterable($dirs) as $dir) { if (is_dir($dir)) { @@ -130,11 +126,9 @@ class Filesystem * @param int|null $time The touch time as a Unix timestamp, if not supplied the current system time is used * @param int|null $atime The access time as a Unix timestamp, if not supplied the current system time is used * - * @return void - * * @throws IOException When touch fails */ - public function touch(string|iterable $files, ?int $time = null, ?int $atime = null) + public function touch(string|iterable $files, ?int $time = null, ?int $atime = null): void { foreach ($this->toIterable($files) as $file) { if (!($time ? self::box('touch', $file, $time, $atime) : self::box('touch', $file))) { @@ -146,11 +140,9 @@ class Filesystem /** * Removes files or directories. * - * @return void - * * @throws IOException When removal fails */ - public function remove(string|iterable $files) + public function remove(string|iterable $files): void { if ($files instanceof \Traversable) { $files = iterator_to_array($files, false); @@ -214,11 +206,9 @@ class Filesystem * @param int $umask The mode mask (octal) * @param bool $recursive Whether change the mod recursively or not * - * @return void - * * @throws IOException When the change fails */ - public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool $recursive = false) + public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool $recursive = false): void { foreach ($this->toIterable($files) as $file) { if (!self::box('chmod', $file, $mode & ~$umask)) { @@ -240,11 +230,9 @@ class Filesystem * @param string|int $user A user name or number * @param bool $recursive Whether change the owner recursively or not * - * @return void - * * @throws IOException When the change fails */ - public function chown(string|iterable $files, string|int $user, bool $recursive = false) + public function chown(string|iterable $files, string|int $user, bool $recursive = false): void { foreach ($this->toIterable($files) as $file) { if ($recursive && is_dir($file) && !is_link($file)) { @@ -272,11 +260,9 @@ class Filesystem * @param string|int $group A group name or number * @param bool $recursive Whether change the group recursively or not * - * @return void - * * @throws IOException When the change fails */ - public function chgrp(string|iterable $files, string|int $group, bool $recursive = false) + public function chgrp(string|iterable $files, string|int $group, bool $recursive = false): void { foreach ($this->toIterable($files) as $file) { if ($recursive && is_dir($file) && !is_link($file)) { @@ -297,12 +283,10 @@ class Filesystem /** * Renames a file or a directory. * - * @return void - * * @throws IOException When target file or directory already exists * @throws IOException When origin cannot be renamed */ - public function rename(string $origin, string $target, bool $overwrite = false) + public function rename(string $origin, string $target, bool $overwrite = false): void { // we check that target does not exist if (!$overwrite && $this->isReadable($target)) { @@ -340,11 +324,9 @@ class Filesystem /** * Creates a symbolic link or copy a directory. * - * @return void - * * @throws IOException When symlink fails */ - public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false) + public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false): void { self::assertFunctionExists('symlink'); @@ -378,12 +360,10 @@ class Filesystem * * @param string|string[] $targetFiles The target file(s) * - * @return void - * * @throws FileNotFoundException When original file is missing or not a file * @throws IOException When link fails, including if link already exists */ - public function hardlink(string $originFile, string|iterable $targetFiles) + public function hardlink(string $originFile, string|iterable $targetFiles): void { self::assertFunctionExists('link'); @@ -537,11 +517,9 @@ class Filesystem * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false) * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false) * - * @return void - * * @throws IOException When file type is unknown */ - public function mirror(string $originDir, string $targetDir, ?\Traversable $iterator = null, array $options = []) + public function mirror(string $originDir, string $targetDir, ?\Traversable $iterator = null, array $options = []): void { $targetDir = rtrim($targetDir, '/\\'); $originDir = rtrim($originDir, '/\\'); @@ -598,17 +576,11 @@ class Filesystem } /** - * Returns whether the file path is an absolute path. + * Returns whether the given path is absolute. */ public function isAbsolutePath(string $file): bool { - return '' !== $file && (strspn($file, '/\\', 0, 1) - || (\strlen($file) > 3 && ctype_alpha($file[0]) - && ':' === $file[1] - && strspn($file, '/\\', 2, 1) - ) - || null !== parse_url($file, \PHP_URL_SCHEME) - ); + return Path::isAbsolute($file); } /** @@ -641,7 +613,7 @@ class Filesystem // Loop until we create a valid temp file or have reached 10 attempts for ($i = 0; $i < 10; ++$i) { // Create a unique filename - $tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true).$suffix; + $tmpFile = $dir.'/'.$prefix.bin2hex(random_bytes(4)).$suffix; // Use fopen instead of file_exists as some streams do not support stat // Use mode 'x+' to atomically check existence and create to avoid a TOCTOU vulnerability @@ -663,11 +635,9 @@ class Filesystem * * @param string|resource $content The data to write into the file * - * @return void - * * @throws IOException if the file cannot be written to */ - public function dumpFile(string $filename, $content) + public function dumpFile(string $filename, $content): void { if (\is_array($content)) { throw new \TypeError(\sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); @@ -714,11 +684,9 @@ class Filesystem * @param string|resource $content The content to append * @param bool $lock Whether the file should be locked when writing to it * - * @return void - * * @throws IOException If the file is not writable */ - public function appendToFile(string $filename, $content/* , bool $lock = false */) + public function appendToFile(string $filename, $content, bool $lock = false): void { if (\is_array($content)) { throw new \TypeError(\sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); @@ -730,13 +698,30 @@ class Filesystem $this->mkdir($dir); } - $lock = \func_num_args() > 2 && func_get_arg(2); - if (false === self::box('file_put_contents', $filename, $content, \FILE_APPEND | ($lock ? \LOCK_EX : 0))) { throw new IOException(\sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename); } } + /** + * Returns the content of a file as a string. + * + * @throws IOException If the file cannot be read + */ + public function readFile(string $filename): string + { + if (is_dir($filename)) { + throw new IOException(\sprintf('Failed to read file "%s": File is a directory.', $filename)); + } + + $content = self::box('file_get_contents', $filename); + if (false === $content) { + throw new IOException(\sprintf('Failed to read file "%s": ', $filename).self::$lastError, 0, null, $filename); + } + + return $content; + } + private function toIterable(string|iterable $files): iterable { return is_iterable($files) ? $files : [$files]; diff --git a/vendor/symfony/filesystem/Path.php b/vendor/symfony/filesystem/Path.php index 093d19f5e..ecf313580 100644 --- a/vendor/symfony/filesystem/Path.php +++ b/vendor/symfony/filesystem/Path.php @@ -346,50 +346,30 @@ final class Path $extension = ltrim($extension, '.'); // No extension for paths - if ('/' === substr($path, -1)) { + if (str_ends_with($path, '/')) { return $path; } // No actual extension in path - if (empty($actualExtension)) { - return $path.('.' === substr($path, -1) ? '' : '.').$extension; + if (!$actualExtension) { + return $path.(str_ends_with($path, '.') ? '' : '.').$extension; } return substr($path, 0, -\strlen($actualExtension)).$extension; } + /** + * Returns whether the given path is absolute. + */ public static function isAbsolute(string $path): bool { - if ('' === $path) { - return false; - } - - // Strip scheme - if (false !== ($schemeSeparatorPosition = strpos($path, '://')) && 1 !== $schemeSeparatorPosition) { - $path = substr($path, $schemeSeparatorPosition + 3); - } - - $firstCharacter = $path[0]; - - // UNIX root "/" or "\" (Windows style) - if ('/' === $firstCharacter || '\\' === $firstCharacter) { - return true; - } - - // Windows root - if (\strlen($path) > 1 && ctype_alpha($firstCharacter) && ':' === $path[1]) { - // Special case: "C:" - if (2 === \strlen($path)) { - return true; - } - - // Normal case: "C:/ or "C:\" - if ('/' === $path[2] || '\\' === $path[2]) { - return true; - } - } - - return false; + return '' !== $path && (strspn($path, '/\\', 0, 1) + || (\strlen($path) > 3 && ctype_alpha($path[0]) + && ':' === $path[1] + && strspn($path, '/\\', 2, 1) + ) + || null !== parse_url($path, \PHP_URL_SCHEME) + ); } public static function isRelative(string $path): bool @@ -668,7 +648,7 @@ final class Path } // Only add slash if previous part didn't end with '/' or '\' - if (!\in_array(substr($finalPath, -1), ['/', '\\'])) { + if (!\in_array(substr($finalPath, -1), ['/', '\\'], true)) { $finalPath .= '/'; } diff --git a/vendor/symfony/filesystem/composer.json b/vendor/symfony/filesystem/composer.json index fd75755b2..c781e55b1 100644 --- a/vendor/symfony/filesystem/composer.json +++ b/vendor/symfony/filesystem/composer.json @@ -16,12 +16,12 @@ } ], "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^5.4|^6.4|^7.0" + "symfony/process": "^6.4|^7.0" }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" }, |
