From b0bfdde164562935eb4af8aebb26712f9bf3cd11 Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Tue, 10 May 2022 07:20:22 -0700 Subject: [PATCH] Cleanup After Phpstan Upgrade (#2800) After Phpstan 1.6.3 upgrade, clean up some new problems that will show up if it runs under Php 8+. --- phpstan-baseline.neon | 5 --- phpstan-conditional.php | 7 ++++ .../Calculation/ExceptionHandler.php | 4 +- src/PhpSpreadsheet/Reader/Slk.php | 2 +- src/PhpSpreadsheet/Reader/Xls/MD5.php | 39 ++++++++++++------- 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 0b0d79dc..f862d205 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -360,11 +360,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Engineering/ErfC.php - - - message: "#^Parameter \\#1 \\$callback of function set_error_handler expects \\(callable\\(int, string, string, int, array\\)\\: bool\\)\\|null, array\\{'PhpOffice\\\\\\\\PhpSpreadsheet\\\\\\\\Calculation\\\\\\\\Exception', 'errorHandlerCallback'\\} given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/ExceptionHandler.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:ISPMT\\(\\) has no return type specified\\.$#" count: 1 diff --git a/phpstan-conditional.php b/phpstan-conditional.php index c5d28dd6..adb390da 100644 --- a/phpstan-conditional.php +++ b/phpstan-conditional.php @@ -46,6 +46,13 @@ if (PHP_VERSION_ID < 80000) { 'path' => __DIR__ . '/src/PhpSpreadsheet/Shared/StringHelper.php', 'count' => 1, ]; +} else { + // Flagged in Php8+ - unsure how to correct code + $config['parameters']['ignoreErrors'][] = [ + 'message' => '#^Binary operation "/" between float and array[|]float[|]int[|]string results in an error.#', + 'path' => __DIR__ . '/src/PhpSpreadsheet/Calculation/MathTrig/Combinations.php', + 'count' => 2, + ]; } return $config; diff --git a/src/PhpSpreadsheet/Calculation/ExceptionHandler.php b/src/PhpSpreadsheet/Calculation/ExceptionHandler.php index 41e51d4a..6461961a 100644 --- a/src/PhpSpreadsheet/Calculation/ExceptionHandler.php +++ b/src/PhpSpreadsheet/Calculation/ExceptionHandler.php @@ -9,7 +9,9 @@ class ExceptionHandler */ public function __construct() { - set_error_handler([Exception::class, 'errorHandlerCallback'], E_ALL); + /** @var callable */ + $callable = [Exception::class, 'errorHandlerCallback']; + set_error_handler($callable, E_ALL); } /** diff --git a/src/PhpSpreadsheet/Reader/Slk.php b/src/PhpSpreadsheet/Reader/Slk.php index c33f0202..9de4013a 100644 --- a/src/PhpSpreadsheet/Reader/Slk.php +++ b/src/PhpSpreadsheet/Reader/Slk.php @@ -450,7 +450,7 @@ class Slk extends BaseReader break; case 'M': - $formatArray['font']['size'] = substr($rowDatum, 1) / 20; + $formatArray['font']['size'] = ((float) substr($rowDatum, 1)) / 20; break; case 'L': diff --git a/src/PhpSpreadsheet/Reader/Xls/MD5.php b/src/PhpSpreadsheet/Reader/Xls/MD5.php index 947b5c44..f84dbee1 100644 --- a/src/PhpSpreadsheet/Reader/Xls/MD5.php +++ b/src/PhpSpreadsheet/Reader/Xls/MD5.php @@ -4,8 +4,6 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xls; class MD5 { - // Context - /** * @var int */ @@ -26,11 +24,17 @@ class MD5 */ private $d; + /** + * @var int + */ + private static $allOneBits; + /** * MD5 stream constructor. */ public function __construct() { + self::$allOneBits = self::signedInt(0xffffffff); $this->reset(); } @@ -40,8 +44,8 @@ class MD5 public function reset(): void { $this->a = 0x67452301; - $this->b = 0xEFCDAB89; - $this->c = 0x98BADCFE; + $this->b = self::signedInt(0xEFCDAB89); + $this->c = self::signedInt(0x98BADCFE); $this->d = 0x10325476; } @@ -156,10 +160,10 @@ class MD5 self::step($I, $C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb); self::step($I, $B, $C, $D, $A, $words[9], 21, 0xeb86d391); - $this->a = ($this->a + $A) & 0xffffffff; - $this->b = ($this->b + $B) & 0xffffffff; - $this->c = ($this->c + $C) & 0xffffffff; - $this->d = ($this->d + $D) & 0xffffffff; + $this->a = ($this->a + $A) & self::$allOneBits; + $this->b = ($this->b + $B) & self::$allOneBits; + $this->c = ($this->c + $C) & self::$allOneBits; + $this->d = ($this->d + $D) & self::$allOneBits; } private static function f(int $X, int $Y, int $Z): int @@ -182,18 +186,25 @@ class MD5 return $Y ^ ($X | (~$Z)); // Y XOR (X OR NOT Z) } - private static function step(callable $func, int &$A, int $B, int $C, int $D, int $M, int $s, int $t): void + /** @param float|int $t may be float on 32-bit system */ + private static function step(callable $func, int &$A, int $B, int $C, int $D, int $M, int $s, $t): void { - $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff; + $t = self::signedInt($t); + $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & self::$allOneBits; $A = self::rotate($A, $s); - $A = ($B + $A) & 0xffffffff; + $A = ($B + $A) & self::$allOneBits; } - /** @return float|int */ - private static function rotate(int $decimal, int $bits) + /** @param float|int $result may be float on 32-bit system */ + private static function signedInt($result): int + { + return is_int($result) ? $result : (int) (PHP_INT_MIN + $result - 1 - PHP_INT_MAX); + } + + private static function rotate(int $decimal, int $bits): int { $binary = str_pad(decbin($decimal), 32, '0', STR_PAD_LEFT); - return bindec(substr($binary, $bits) . substr($binary, 0, $bits)); + return self::signedInt(bindec(substr($binary, $bits) . substr($binary, 0, $bits))); } }