From 26e17277e150e56b4922980e151a6b1f4345673d Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Mon, 21 Nov 2022 15:31:13 -0800 Subject: [PATCH] Eliminate Some Scrutinizer 'Major' Problems Part 5 (#3161) * Eliminate Some Scrutinizer 'Major' Problems Part 5 More of the same. 2 or 3 of these still to go after this. Note one deprecation. Shared/Drawing has a method imagecreatefrombmp. However, that was introduced as a native PHP function with 7.2, so the method is no longer needed. * More Silliness Keep trying. * If At First You Don't Succeed Try, try again. --- phpstan-baseline.neon | 26 +---- samples/Basic/27_Images_Xlsx.php | 13 +++ samples/templates/27template.xlsx | Bin 267537 -> 248266 bytes .../Calculation/Engineering/ConvertUOM.php | 2 +- .../Calculation/Statistical/Conditional.php | 13 +-- .../Statistical/Distributions/Beta.php | 2 + .../Calculation/TextData/Extract.php | 6 +- .../Calculation/TextData/Replace.php | 13 +-- src/PhpSpreadsheet/Helper/Sample.php | 4 +- src/PhpSpreadsheet/Helper/TextGrid.php | 4 +- src/PhpSpreadsheet/Reader/Csv.php | 2 +- src/PhpSpreadsheet/Reader/Xls.php | 2 - src/PhpSpreadsheet/Reader/Xlsx/Chart.php | 1 + src/PhpSpreadsheet/Reader/Xlsx/Styles.php | 2 +- src/PhpSpreadsheet/Reader/Xml.php | 2 +- src/PhpSpreadsheet/Shared/Drawing.php | 108 ++---------------- src/PhpSpreadsheet/Shared/Font.php | 4 +- src/PhpSpreadsheet/Shared/PasswordHasher.php | 2 +- src/PhpSpreadsheet/Shared/Trend/BestFit.php | 17 ++- src/PhpSpreadsheet/Spreadsheet.php | 12 +- .../Style/NumberFormat/DateFormatter.php | 2 +- src/PhpSpreadsheet/Worksheet/PageSetup.php | 7 +- src/PhpSpreadsheet/Writer/Xls.php | 15 ++- .../Writer/Xls/XlsGifBmpTest.php | 9 +- 24 files changed, 89 insertions(+), 179 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 5a68f5579..c32d9fd3e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -930,7 +930,7 @@ parameters: path: src/PhpSpreadsheet/Reader/Xls.php - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 8 + count: 7 path: src/PhpSpreadsheet/Reader/Xls.php - @@ -974,10 +974,6 @@ parameters: message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\Run\\:\\:\\$font \\(PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" count: 1 path: src/PhpSpreadsheet/RichText/Run.php - - - message: "#^Cannot access offset 1 on array\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Drawing.php - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\:\\:getDgId\\(\\) has no return type specified\\.$#" count: 1 @@ -1422,26 +1418,6 @@ parameters: message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has parameter \\$yValues with no type specified\\.$#" count: 1 path: src/PhpSpreadsheet/Shared/Trend/Trend.php - - - message: "#^Call to function is_array\\(\\) with string will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Spreadsheet.php - - - message: "#^Parameter \\#1 \\$worksheet of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getIndex\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet, PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Spreadsheet.php - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:\\$workbookViewVisibilityValues has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Spreadsheet.php - - - message: "#^Strict comparison using \\=\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet and null will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Spreadsheet.php - - - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 1 - path: src/PhpSpreadsheet/Spreadsheet.php - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalDataBar\\:\\:setConditionalFormattingRuleExt\\(\\) has no return type specified\\.$#" count: 1 diff --git a/samples/Basic/27_Images_Xlsx.php b/samples/Basic/27_Images_Xlsx.php index dc129e46c..ebeab3c55 100644 --- a/samples/Basic/27_Images_Xlsx.php +++ b/samples/Basic/27_Images_Xlsx.php @@ -1,13 +1,26 @@ log('Load Xlsx template file'); $reader = IOFactory::createReader('Xlsx'); +// Note that Xlsx converts bmp to png, so it needs to be added +// programmatically rather than in template. +// Also note Xls converts both bmp and gif to png. $spreadsheet = $reader->load(__DIR__ . '/../templates/27template.xlsx'); +$sheet = $spreadsheet->getActiveSheet(); +$drawing = new Drawing(); +$drawing->setName('Test BMP'); +$drawing->setPath(__DIR__ . '/../images/bmp.bmp'); +$drawing->setCoordinates('G17'); +$drawing->setWorksheet($sheet); + +$sheet->getCell('G16')->setValue('BMP'); +$sheet->getStyle('G16')->getFont()->setName('Arial Black')->setBold(true); // Save $helper->write($spreadsheet, __FILE__); diff --git a/samples/templates/27template.xlsx b/samples/templates/27template.xlsx index f897d2e059ee08bfa307a63bceea2845ca95568b..9651f173555b973e862011e196cdaba2abbc2ce6 100644 GIT binary patch delta 5470 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 delta 24862 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 I_!#`Z03DrboB#j- diff --git a/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php b/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php index b7c298dbc..8541a6cc1 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php @@ -564,7 +564,7 @@ class ConvertUOM } elseif ($fromUOM === $toUOM) { return $value / $toMultiplier; } elseif ($fromCategory === self::CATEGORY_TEMPERATURE) { - return self::convertTemperature($fromUOM, $toUOM, $value); + return self::convertTemperature($fromUOM, $toUOM, /** @scrutinizer ignore-type */ $value); } $baseValue = $value * (1.0 / self::$unitConversions[$fromCategory][$fromUOM]); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php b/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php index 51e6b0043..0f39c0465 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php @@ -218,7 +218,8 @@ class Conditional { $conditions = self::buildConditions(1, ...$args); - return array_map(null, ...$conditions); + // Scrutinizer thinks first parameter of array_map can't be null. It is wrong. + return array_map(/** @scrutinizer ignore-type */ null, ...$conditions); } private static function buildConditionSetForValueRange(...$args): array @@ -234,7 +235,7 @@ class Conditional ); } - return array_map(null, ...$conditions); + return array_map(/** @scrutinizer ignore-type */ null, ...$conditions); } private static function buildConditions(int $startOffset, ...$args): array @@ -281,7 +282,7 @@ class Conditional ++$pairCount; } - return array_map(null, ...$database); + return array_map(/** @scrutinizer ignore-type */ null, ...$database); } private static function databaseFromRangeAndValue(array $range, array $valueRange = []): array @@ -293,11 +294,7 @@ class Conditional $valueRange = $range; } - $database = array_map( - null, - array_merge([self::CONDITION_COLUMN_NAME], $range), - array_merge([self::VALUE_COLUMN_NAME], $valueRange) - ); + $database = array_map(/** @scrutinizer ignore-type */ null, array_merge([self::CONDITION_COLUMN_NAME], $range), array_merge([self::VALUE_COLUMN_NAME], $valueRange)); return $database; } diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php index 51cb6411b..8b41ac87f 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php @@ -268,6 +268,7 @@ class Beta return $frac; } + /* private static function betaValue(float $a, float $b): float { return (Gamma::gammaValue($a) * Gamma::gammaValue($b)) / @@ -278,4 +279,5 @@ class Beta { return self::incompleteBeta($value, $a, $b) / self::betaValue($a, $b); } + */ } diff --git a/src/PhpSpreadsheet/Calculation/TextData/Extract.php b/src/PhpSpreadsheet/Calculation/TextData/Extract.php index ee7e31b77..4d0a8ab9e 100644 --- a/src/PhpSpreadsheet/Calculation/TextData/Extract.php +++ b/src/PhpSpreadsheet/Calculation/TextData/Extract.php @@ -138,7 +138,7 @@ class Extract $matchEnd = (int) $matchEnd; $split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); - if (is_array($split) === false) { + if (is_string($split)) { return $split; } if (Helpers::extractString(Functions::flattenSingleValue($delimiter ?? '')) === '') { @@ -196,7 +196,7 @@ class Extract $matchEnd = (int) $matchEnd; $split = self::validateTextBeforeAfter($text, $delimiter, $instance, $matchMode, $matchEnd, $ifNotFound); - if (is_array($split) === false) { + if (is_string($split)) { return $split; } if (Helpers::extractString(Functions::flattenSingleValue($delimiter ?? '')) === '') { @@ -222,7 +222,7 @@ class Extract * @param int $matchEnd * @param mixed $ifNotFound * - * @return string|string[] + * @return array|string */ private static function validateTextBeforeAfter(string $text, $delimiter, int $instance, $matchMode, $matchEnd, $ifNotFound) { diff --git a/src/PhpSpreadsheet/Calculation/TextData/Replace.php b/src/PhpSpreadsheet/Calculation/TextData/Replace.php index 03b663211..124f00170 100644 --- a/src/PhpSpreadsheet/Calculation/TextData/Replace.php +++ b/src/PhpSpreadsheet/Calculation/TextData/Replace.php @@ -102,24 +102,17 @@ class Replace return $returnValue; } - /** - * @return string - */ - private static function executeSubstitution(string $text, string $fromText, string $toText, int $instance) + private static function executeSubstitution(string $text, string $fromText, string $toText, int $instance): string { $pos = -1; while ($instance > 0) { $pos = mb_strpos($text, $fromText, $pos + 1, 'UTF-8'); if ($pos === false) { - break; + return $text; } --$instance; } - if ($pos !== false) { - return Functions::scalar(self::REPLACE($text, ++$pos, StringHelper::countCharacters($fromText), $toText)); - } - - return $text; + return Functions::scalar(self::REPLACE($text, ++$pos, StringHelper::countCharacters($fromText), $toText)); } } diff --git a/src/PhpSpreadsheet/Helper/Sample.php b/src/PhpSpreadsheet/Helper/Sample.php index a0063bd33..5ca546e07 100644 --- a/src/PhpSpreadsheet/Helper/Sample.php +++ b/src/PhpSpreadsheet/Helper/Sample.php @@ -131,7 +131,7 @@ class Sample $writer = IOFactory::createWriter($spreadsheet, $writerType); $callStartTime = microtime(true); $writer->save($path); - $this->logWrite($writer, $path, $callStartTime); + $this->logWrite($writer, $path, /** @scrutinizer ignore-type */ $callStartTime); } $this->logEndingNotes(); @@ -169,7 +169,7 @@ class Sample { $originalExtension = pathinfo($filename, PATHINFO_EXTENSION); - return $this->getTemporaryFolder() . '/' . str_replace('.' . $originalExtension, '.' . $extension, basename($filename)); + return $this->getTemporaryFolder() . '/' . str_replace('.' . /** @scrutinizer ignore-type */ $originalExtension, '.' . $extension, basename($filename)); } /** diff --git a/src/PhpSpreadsheet/Helper/TextGrid.php b/src/PhpSpreadsheet/Helper/TextGrid.php index acb9ae60e..ed146a55d 100644 --- a/src/PhpSpreadsheet/Helper/TextGrid.php +++ b/src/PhpSpreadsheet/Helper/TextGrid.php @@ -52,7 +52,7 @@ class TextGrid $maxRow = max($this->rows); $maxRowLength = strlen((string) $maxRow) + 1; - $columnWidths = $this->getColumnWidths($this->matrix); + $columnWidths = $this->getColumnWidths(); $this->renderColumnHeader($maxRowLength, $columnWidths); $this->renderRows($maxRowLength, $columnWidths); @@ -108,7 +108,7 @@ class TextGrid $this->gridDisplay .= '+' . PHP_EOL; } - private function getColumnWidths(array $matrix): array + private function getColumnWidths(): array { $columnCount = count($this->matrix, COUNT_RECURSIVE) / count($this->matrix); $columnWidths = []; diff --git a/src/PhpSpreadsheet/Reader/Csv.php b/src/PhpSpreadsheet/Reader/Csv.php index 65a71edb0..4f128d6f0 100644 --- a/src/PhpSpreadsheet/Reader/Csv.php +++ b/src/PhpSpreadsheet/Reader/Csv.php @@ -555,7 +555,7 @@ class Csv extends BaseReader fclose($this->fileHandle); // Trust file extension if any - $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + $extension = strtolower(/** @scrutinizer ignore-type */ pathinfo($filename, PATHINFO_EXTENSION)); if (in_array($extension, ['csv', 'tsv'])) { return true; } diff --git a/src/PhpSpreadsheet/Reader/Xls.php b/src/PhpSpreadsheet/Reader/Xls.php index a79a20a9c..bdec4c93c 100644 --- a/src/PhpSpreadsheet/Reader/Xls.php +++ b/src/PhpSpreadsheet/Reader/Xls.php @@ -4947,8 +4947,6 @@ class Xls extends BaseReader case 0x28: // TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007 return; - - break; } } } diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Chart.php b/src/PhpSpreadsheet/Reader/Xlsx/Chart.php index 93e0c5d98..d42df9a37 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/Chart.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/Chart.php @@ -832,6 +832,7 @@ class Chart foreach ($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) { foreach ($seriesLevel as $seriesValueIdx => $seriesValue) { + $seriesValue = Xlsx::testSimpleXml($seriesValue); switch ($seriesValueIdx) { case 'ptCount': $pointCount = self::getAttribute($seriesValue, 'val', 'integer'); diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Styles.php b/src/PhpSpreadsheet/Reader/Xlsx/Styles.php index 8d380907a..5b089fa87 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/Styles.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/Styles.php @@ -278,7 +278,7 @@ class Styles extends BaseParserClass */ public function readStyle(Style $docStyle, $style): void { - if ($style->numFmt instanceof SimpleXMLElement) { + if ($style instanceof SimpleXMLElement) { $this->readNumberFormat($docStyle->getNumberFormat(), $style->numFmt); } else { $docStyle->getNumberFormat()->setFormatCode(self::formatGeneral((string) $style->numFmt)); diff --git a/src/PhpSpreadsheet/Reader/Xml.php b/src/PhpSpreadsheet/Reader/Xml.php index d8f0d9dcd..565a5af75 100644 --- a/src/PhpSpreadsheet/Reader/Xml.php +++ b/src/PhpSpreadsheet/Reader/Xml.php @@ -278,7 +278,7 @@ class Xml extends BaseReader if ( isset($this->loadSheetsOnly, $worksheet_ss['Name']) && - (!in_array($worksheet_ss['Name'], $this->loadSheetsOnly)) + (!in_array($worksheet_ss['Name'], /** @scrutinizer ignore-type */ $this->loadSheetsOnly)) ) { continue; } diff --git a/src/PhpSpreadsheet/Shared/Drawing.php b/src/PhpSpreadsheet/Shared/Drawing.php index 3378958c8..f69310fc6 100644 --- a/src/PhpSpreadsheet/Shared/Drawing.php +++ b/src/PhpSpreadsheet/Shared/Drawing.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Shared; use GdImage; +use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException; use SimpleXMLElement; class Drawing @@ -159,109 +160,18 @@ class Drawing * @param string $bmpFilename Path to Windows DIB (BMP) image * * @return GdImage|resource + * + * @deprecated 1.26 use Php function imagecreatefrombmp instead + * + * @codeCoverageIgnore */ public static function imagecreatefrombmp($bmpFilename) { - // Load the image into a string - $file = fopen($bmpFilename, 'rb'); - /** @phpstan-ignore-next-line */ - $read = fread($file, 10); - // @phpstan-ignore-next-line - while (!feof($file) && ($read != '')) { - // @phpstan-ignore-next-line - $read .= fread($file, 1024); + $retVal = @imagecreatefrombmp($bmpFilename); + if ($retVal === false) { + throw new ReaderException("Unable to create image from $bmpFilename"); } - /** @phpstan-ignore-next-line */ - $temp = unpack('H*', $read); - $hex = $temp[1]; - $header = substr($hex, 0, 108); - - // Process the header - // Structure: http://www.fastgraph.com/help/bmp_header_format.html - $width = 0; - $height = 0; - if (substr($header, 0, 4) == '424d') { - // Cut it in parts of 2 bytes - $header_parts = str_split($header, 2); - - // Get the width 4 bytes - $width = hexdec($header_parts[19] . $header_parts[18]); - - // Get the height 4 bytes - $height = hexdec($header_parts[23] . $header_parts[22]); - - // Unset the header params - unset($header_parts); - } - - // Define starting X and Y - $x = 0; - $y = 1; - - // Create newimage - - /** @phpstan-ignore-next-line */ - $image = imagecreatetruecolor($width, $height); - - // Grab the body from the image - $body = substr($hex, 108); - - // Calculate if padding at the end-line is needed - // Divided by two to keep overview. - // 1 byte = 2 HEX-chars - $body_size = (strlen($body) / 2); - $header_size = ($width * $height); - - // Use end-line padding? Only when needed - $usePadding = ($body_size > ($header_size * 3) + 4); - - // Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption - // Calculate the next DWORD-position in the body - for ($i = 0; $i < $body_size; $i += 3) { - // Calculate line-ending and padding - if ($x >= $width) { - // If padding needed, ignore image-padding - // Shift i to the ending of the current 32-bit-block - if ($usePadding) { - $i += $width % 4; - } - - // Reset horizontal position - $x = 0; - - // Raise the height-position (bottom-up) - ++$y; - - // Reached the image-height? Break the for-loop - if ($y > $height) { - break; - } - } - - // Calculation of the RGB-pixel (defined as BGR in image-data) - // Define $i_pos as absolute position in the body - $i_pos = $i * 2; - $r = hexdec($body[$i_pos + 4] . $body[$i_pos + 5]); - $g = hexdec($body[$i_pos + 2] . $body[$i_pos + 3]); - $b = hexdec($body[$i_pos] . $body[$i_pos + 1]); - - // Calculate and draw the pixel - - /** @phpstan-ignore-next-line */ - $color = imagecolorallocate($image, $r, $g, $b); - // @phpstan-ignore-next-line - imagesetpixel($image, $x, $height - $y, $color); - - // Raise the horizontal position - ++$x; - } - - // Unset the body / free the memory - unset($body); - - // Return image-object - // @phpstan-ignore-next-line - return $image; + return $retVal; } } diff --git a/src/PhpSpreadsheet/Shared/Font.php b/src/PhpSpreadsheet/Shared/Font.php index e90c679b6..dfe9f77ae 100644 --- a/src/PhpSpreadsheet/Shared/Font.php +++ b/src/PhpSpreadsheet/Shared/Font.php @@ -348,8 +348,8 @@ class Font } // Special case if there are one or more newline characters ("\n") - $cellText = $cellText ?? ''; - if (strpos(/** @scrutinizer ignore-type */ $cellText, "\n") !== false) { + $cellText = (string) $cellText; + if (strpos($cellText, "\n") !== false) { $lineTexts = explode("\n", $cellText); $lineWidths = []; foreach ($lineTexts as $lineText) { diff --git a/src/PhpSpreadsheet/Shared/PasswordHasher.php b/src/PhpSpreadsheet/Shared/PasswordHasher.php index 0d58a8686..e9414f97e 100644 --- a/src/PhpSpreadsheet/Shared/PasswordHasher.php +++ b/src/PhpSpreadsheet/Shared/PasswordHasher.php @@ -99,7 +99,7 @@ class PasswordHasher $saltValue = base64_decode($salt); $encodedPassword = mb_convert_encoding($password, 'UCS-2LE', 'UTF-8'); - $hashValue = hash($phpAlgorithm, $saltValue . $encodedPassword, true); + $hashValue = hash($phpAlgorithm, $saltValue . /** @scrutinizer ignore-type */ $encodedPassword, true); for ($i = 0; $i < $spinCount; ++$i) { $hashValue = hash($phpAlgorithm, $hashValue . pack('L', $i), true); } diff --git a/src/PhpSpreadsheet/Shared/Trend/BestFit.php b/src/PhpSpreadsheet/Shared/Trend/BestFit.php index 7df489533..b2b0d9440 100644 --- a/src/PhpSpreadsheet/Shared/Trend/BestFit.php +++ b/src/PhpSpreadsheet/Shared/Trend/BestFit.php @@ -332,9 +332,21 @@ abstract class BestFit return $this->yBestFitValues; } + /** @var mixed */ + private static $scrutinizerZeroPointZero = 0.0; + + /** + * @param mixed $x + * @param mixed $y + */ + private static function scrutinizerLooseCompare($x, $y): bool + { + return $x == $y; + } + protected function calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const): void { - $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0; + $SSres = $SScov = $SStot = $SSsex = 0.0; foreach ($this->xValues as $xKey => $xValue) { $bestFitY = $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); @@ -360,7 +372,8 @@ abstract class BestFit } else { $this->stdevOfResiduals = sqrt($SSres / $this->DFResiduals); } - if (($SStot == 0.0) || ($SSres == $SStot)) { + // Scrutinizer thinks $SSres == $SStot is always true. It is wrong. + if ($SStot == self::$scrutinizerZeroPointZero || self::scrutinizerLooseCompare($SSres, $SStot)) { $this->goodnessOfFit = 1; } else { $this->goodnessOfFit = 1 - ($SSres / $SStot); diff --git a/src/PhpSpreadsheet/Spreadsheet.php b/src/PhpSpreadsheet/Spreadsheet.php index 364700e25..4624ec0ad 100644 --- a/src/PhpSpreadsheet/Spreadsheet.php +++ b/src/PhpSpreadsheet/Spreadsheet.php @@ -21,7 +21,7 @@ class Spreadsheet private const DEFINED_NAME_IS_RANGE = false; private const DEFINED_NAME_IS_FORMULA = true; - private static $workbookViewVisibilityValues = [ + private const WORKBOOK_VIEW_VISIBILITY_VALUES = [ self::VISIBILITY_VISIBLE, self::VISIBILITY_HIDDEN, self::VISIBILITY_VERY_HIDDEN, @@ -376,7 +376,7 @@ class Spreadsheet { $extension = pathinfo($path, PATHINFO_EXTENSION); - return is_array($extension) ? '' : $extension; + return substr(/** @scrutinizer ignore-type */$extension, 0); } /** @@ -393,8 +393,6 @@ class Spreadsheet switch ($what) { case 'all': return $this->ribbonBinObjects; - - break; case 'names': case 'data': if (is_array($this->ribbonBinObjects) && isset($this->ribbonBinObjects[$what])) { @@ -644,7 +642,7 @@ class Spreadsheet } } - if ($worksheet->getParent() === null) { + if ($worksheet->getParent() === null) { // @phpstan-ignore-line $worksheet->rebindParent($this); } @@ -763,7 +761,7 @@ class Spreadsheet */ public function setIndexByName($worksheetName, $newIndexPosition) { - $oldIndex = $this->getIndex($this->getSheetByName($worksheetName)); + $oldIndex = $this->getIndex($this->getSheetByNameOrThrow($worksheetName)); $worksheet = array_splice( $this->workSheetCollection, $oldIndex, @@ -1582,7 +1580,7 @@ class Spreadsheet $visibility = self::VISIBILITY_VISIBLE; } - if (in_array($visibility, self::$workbookViewVisibilityValues)) { + if (in_array($visibility, self::WORKBOOK_VIEW_VISIBILITY_VALUES)) { $this->visibility = $visibility; } else { throw new Exception('Invalid visibility value.'); diff --git a/src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php b/src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php index 6c4d9d6ba..ba54b5359 100644 --- a/src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php +++ b/src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php @@ -177,6 +177,6 @@ class DateFormatter private static function escapeQuotesCallback(array $matches): string { - return '\\' . implode('\\', str_split($matches[1])); + return '\\' . implode('\\', /** @scrutinizer ignore-type */ str_split($matches[1])); } } diff --git a/src/PhpSpreadsheet/Worksheet/PageSetup.php b/src/PhpSpreadsheet/Worksheet/PageSetup.php index 07c4b4127..93030dbd1 100644 --- a/src/PhpSpreadsheet/Worksheet/PageSetup.php +++ b/src/PhpSpreadsheet/Worksheet/PageSetup.php @@ -746,15 +746,14 @@ class PageSetup if ($index == 0) { $this->printArea = $this->printArea ? ($this->printArea . ',' . $value) : $value; } else { - /** @phpstan-ignore-next-line */ - $printAreas = explode(',', $this->printArea); + $printAreas = explode(',', (string) $this->printArea); if ($index < 0) { - $index = abs($index) - 1; + $index = (int) abs($index) - 1; } if ($index > count($printAreas)) { throw new PhpSpreadsheetException('Invalid index for setting print range.'); } - $printAreas = array_merge(array_slice($printAreas, 0, /** @scrutinizer ignore-type */ $index), [$value], array_slice($printAreas, /** @scrutinizer ignore-type */ $index)); + $printAreas = array_merge(array_slice($printAreas, 0, $index), [$value], array_slice($printAreas, $index)); $this->printArea = implode(',', $printAreas); } } else { diff --git a/src/PhpSpreadsheet/Writer/Xls.php b/src/PhpSpreadsheet/Writer/Xls.php index 69457357b..b740b6ffe 100644 --- a/src/PhpSpreadsheet/Writer/Xls.php +++ b/src/PhpSpreadsheet/Writer/Xls.php @@ -8,7 +8,6 @@ use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\RichText\Run; -use PhpOffice\PhpSpreadsheet\Shared\Drawing as SharedDrawing; use PhpOffice\PhpSpreadsheet\Shared\Escher; use PhpOffice\PhpSpreadsheet\Shared\Escher\DgContainer; use PhpOffice\PhpSpreadsheet\Shared\Escher\DgContainer\SpgrContainer; @@ -435,9 +434,12 @@ class Xls extends BaseWriter switch ($imageFormat) { case 1: // GIF, not supported by BIFF8, we convert to PNG $blipType = BSE::BLIPTYPE_PNG; + $newImage = @imagecreatefromgif($filename); + if ($newImage === false) { + throw new Exception("Unable to create image from $filename"); + } ob_start(); - // @phpstan-ignore-next-line - imagepng(imagecreatefromgif($filename)); + imagepng($newImage); $blipData = ob_get_contents(); ob_end_clean(); @@ -454,9 +456,12 @@ class Xls extends BaseWriter break; case 6: // Windows DIB (BMP), we convert to PNG $blipType = BSE::BLIPTYPE_PNG; + $newImage = @imagecreatefrombmp($filename); + if ($newImage === false) { + throw new Exception("Unable to create image from $filename"); + } ob_start(); - // @phpstan-ignore-next-line - imagepng(SharedDrawing::imagecreatefrombmp($filename)); + imagepng($newImage); $blipData = ob_get_contents(); ob_end_clean(); diff --git a/tests/PhpSpreadsheetTests/Writer/Xls/XlsGifBmpTest.php b/tests/PhpSpreadsheetTests/Writer/Xls/XlsGifBmpTest.php index d1353fa35..412ca45be 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xls/XlsGifBmpTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xls/XlsGifBmpTest.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xls; use DateTime; +use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing; @@ -40,13 +41,13 @@ class XlsGifBmpTest extends AbstractFunctional $drawing->setCoordinates('A1'); $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xls'); + $spreadsheet->disconnectWorksheets(); $creationDatestamp = $reloadedSpreadsheet->getProperties()->getCreated(); $filstart = $creationDatestamp; $worksheet = $reloadedSpreadsheet->getActiveSheet(); $drawings = $worksheet->getDrawingCollection(); self::assertCount(1, $drawings); foreach ($worksheet->getDrawingCollection() as $drawing) { - // See if Scrutinizer approves this $mimeType = ($drawing instanceof MemoryDrawing) ? $drawing->getMimeType() : 'notmemorydrawing'; self::assertEquals('image/png', $mimeType); } @@ -55,6 +56,7 @@ class XlsGifBmpTest extends AbstractFunctional self::assertLessThanOrEqual($pgmend, $pgmstart); self::assertLessThanOrEqual($pgmend, $filstart); self::assertLessThanOrEqual($filstart, $pgmstart); + $reloadedSpreadsheet->disconnectWorksheets(); } public function testGif(): void @@ -71,6 +73,7 @@ class XlsGifBmpTest extends AbstractFunctional $drawing->setCoordinates('A1'); $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xls'); + $spreadsheet->disconnectWorksheets(); $worksheet = $reloadedSpreadsheet->getActiveSheet(); $drawings = $worksheet->getDrawingCollection(); self::assertCount(1, $drawings); @@ -78,11 +81,13 @@ class XlsGifBmpTest extends AbstractFunctional $mimeType = ($drawing instanceof MemoryDrawing) ? $drawing->getMimeType() : 'notmemorydrawing'; self::assertEquals('image/png', $mimeType); } + $reloadedSpreadsheet->disconnectWorksheets(); } public function testInvalidTimestamp(): void { - $this->expectException(\PhpOffice\PhpSpreadsheet\Reader\Exception::class); + $this->expectException(ReaderException::class); + $this->expectExceptionMessage('Expecting 8 byte string'); \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE2LocalDate(' '); } }