Skip to content

Commit b9a9d5d

Browse files
committed
Upgrade Phpstan
A very rough month for Dependabot's attempt to upgrade Phpstan. Many changes involving regular expressions, most with non-trivial workarounds. I have also filed one bug report.
1 parent f7c183b commit b9a9d5d

20 files changed

+85
-55
lines changed

composer.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4180,8 +4180,10 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
41804180
}
41814181
}
41824182
} elseif ($expectedArgumentCount != '*') {
4183-
preg_match('/(\d*)([-+,])(\d*)/', $expectedArgumentCount, $argMatch);
4184-
switch ($argMatch[2] ?? '') {
4183+
if (1 !== preg_match('/(\d*)([-+,])(\d*)/', $expectedArgumentCount, $argMatch)) {
4184+
$argMatch = ['', '', '', ''];
4185+
}
4186+
switch ($argMatch[2]) {
41854187
case '+':
41864188
if ($argumentCount < $argMatch[1]) {
41874189
$argumentCountError = true;
@@ -4254,7 +4256,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
42544256
// do we now have a function/variable/number?
42554257
$expectingOperator = true;
42564258
$expectingOperand = false;
4257-
$val = $match[1];
4259+
$val = $match[1] ?? '';
42584260
$length = strlen($val);
42594261

42604262
if (preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $val, $matches)) {
@@ -4310,7 +4312,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
43104312
$rangeStartCellRef = $output[count($output) - 2]['value'] ?? '';
43114313
}
43124314
preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/miu', $rangeStartCellRef, $rangeStartMatches);
4313-
if ($rangeStartMatches[2] !== $matches[2]) {
4315+
if (isset($rangeStartMatches[2]) && $rangeStartMatches[2] !== $matches[2]) {
43144316
return $this->raiseFormulaError('3D Range references are not yet supported');
43154317
}
43164318
}
@@ -4400,7 +4402,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
44004402
$valx = $val;
44014403
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestDataColumn($valx) : AddressRange::MAX_COLUMN; // Max 16,384 columns for Excel2007
44024404
$val = "{$rangeWS2}{$endRowColRef}{$val}";
4403-
} elseif (ctype_alpha($val) && strlen($val ?? '') <= 3) {
4405+
} elseif (ctype_alpha($val) && is_string($val) && strlen($val) <= 3) {
44044406
// Column range
44054407
$stackItemType = 'Column Reference';
44064408
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestDataRow($val) : AddressRange::MAX_ROW; // Max 1,048,576 rows for Excel2007
@@ -4565,6 +4567,12 @@ private static function dataTestReference(array &$operandData): mixed
45654567
return $operand;
45664568
}
45674569

4570+
private static int $matchIndex8 = 8;
4571+
4572+
private static int $matchIndex9 = 9;
4573+
4574+
private static int $matchIndex10 = 10;
4575+
45684576
/**
45694577
* @return array<int, mixed>|false
45704578
*/
@@ -4928,12 +4936,17 @@ private function processTokenStack(mixed $tokens, ?string $cellID = null, ?Cell
49284936
} elseif (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/i', $token ?? '', $matches)) {
49294937
$cellRef = null;
49304938

4931-
if (isset($matches[8])) {
4939+
/* Phpstan says matches[8/9/10] is never set,
4940+
and code coverage report seems to confirm.
4941+
Appease PhpStan for now;
4942+
probably delete this block later.
4943+
*/
4944+
if (isset($matches[self::$matchIndex8])) {
49324945
if ($cell === null) {
49334946
// We can't access the range, so return a REF error
49344947
$cellValue = ExcelError::REF();
49354948
} else {
4936-
$cellRef = $matches[6] . $matches[7] . ':' . $matches[9] . $matches[10];
4949+
$cellRef = $matches[6] . $matches[7] . ':' . $matches[self::$matchIndex9] . $matches[self::$matchIndex10];
49374950
if ($matches[2] > '') {
49384951
$matches[2] = trim($matches[2], "\"'");
49394952
if ((str_contains($matches[2], '[')) || (str_contains($matches[2], ']'))) {

src/PhpSpreadsheet/Calculation/Functions.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,10 @@ public static function ifCondition(mixed $condition): string
164164

165165
return str_replace('""""', '""', '=' . $condition);
166166
}
167-
preg_match('/(=|<[>=]?|>=?)(.*)/', $condition, $matches);
168-
[, $operator, $operand] = $matches;
167+
$operator = $operand = '';
168+
if (1 === preg_match('/(=|<[>=]?|>=?)(.*)/', $condition, $matches)) {
169+
[, $operator, $operand] = $matches;
170+
}
169171

170172
$operand = self::operandSpecialHandling($operand);
171173
if (is_numeric(trim($operand, '"'))) {

src/PhpSpreadsheet/Calculation/Information/Value.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,11 @@ public static function isFormula(mixed $cellReference = '', ?Cell $cell = null):
210210

211211
$fullCellReference = Functions::trimTrailingRange($fullCellReference);
212212

213-
preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $fullCellReference, $matches);
214-
215-
$fullCellReference = $matches[6] . $matches[7];
216-
$worksheetName = str_replace("''", "'", trim($matches[2], "'"));
213+
$worksheetName = '';
214+
if (1 == preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $fullCellReference, $matches)) {
215+
$fullCellReference = $matches[6] . $matches[7];
216+
$worksheetName = str_replace("''", "'", trim($matches[2], "'"));
217+
}
217218

218219
$worksheet = (!empty($worksheetName))
219220
? $cell->getWorksheet()->getParentOrThrow()->getSheetByName($worksheetName)

src/PhpSpreadsheet/Calculation/LookupRef/Formula.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ public static function text(mixed $cellReference = '', ?Cell $cell = null): stri
2020
return ExcelError::REF();
2121
}
2222

23-
preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellReference, $matches);
24-
25-
$cellReference = $matches[6] . $matches[7];
26-
$worksheetName = trim($matches[3], "'");
27-
$worksheet = (!empty($worksheetName))
28-
? $cell->getWorksheet()->getParentOrThrow()->getSheetByName($worksheetName)
29-
: $cell->getWorksheet();
23+
$worksheet = null;
24+
if (1 === preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellReference, $matches)) {
25+
$cellReference = $matches[6] . $matches[7];
26+
$worksheetName = trim($matches[3], "'");
27+
$worksheet = (!empty($worksheetName))
28+
? $cell->getWorksheet()->getParentOrThrow()->getSheetByName($worksheetName)
29+
: $cell->getWorksheet();
30+
}
3031

3132
if (
3233
$worksheet === null

src/PhpSpreadsheet/Cell/AddressHelper.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,7 @@ public static function convertToR1C1(
136136
?int $currentRowNumber = null,
137137
?int $currentColumnNumber = null
138138
): string {
139-
$validityCheck = preg_match(Coordinate::A1_COORDINATE_REGEX, $address, $cellReference);
140-
141-
if ($validityCheck === 0) {
139+
if (1 !== preg_match(Coordinate::A1_COORDINATE_REGEX, $address, $cellReference)) {
142140
throw new Exception('Invalid A1-format Cell Reference');
143141
}
144142

src/PhpSpreadsheet/Cell/Cell.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,9 +481,10 @@ public function getCalculatedValue(bool $resetLog = true): mixed
481481
if (isset($matches[3])) {
482482
$minCol = $matches[1];
483483
$minRow = (int) $matches[2];
484-
$maxCol = $matches[4];
484+
// https://github.com/phpstan/phpstan/issues/11602
485+
$maxCol = $matches[4]; // @phpstan-ignore-line
485486
++$maxCol;
486-
$maxRow = (int) $matches[5];
487+
$maxRow = (int) $matches[5]; // @phpstan-ignore-line
487488
for ($row = $minRow; $row <= $maxRow; ++$row) {
488489
for ($col = $minCol; $col !== $maxCol; ++$col) {
489490
if ("$col$row" !== $coordinate) {

src/PhpSpreadsheet/Cell/Coordinate.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,7 @@ public static function getRangeBoundaries(string $range): array
271271
private static function validateReferenceAndGetData($reference): array
272272
{
273273
$data = [];
274-
preg_match(self::FULL_REFERENCE_REGEX, $reference, $matches);
275-
if (count($matches) === 0) {
274+
if (1 !== preg_match(self::FULL_REFERENCE_REGEX, $reference, $matches)) {
276275
return ['type' => 'invalid'];
277276
}
278277

src/PhpSpreadsheet/Helper/Size.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ class Size implements Stringable
88
{
99
const REGEXP_SIZE_VALIDATION = '/^(?P<size>\d*\.?\d+)(?P<unit>pt|px|em)?$/i';
1010

11-
protected bool $valid;
11+
protected bool $valid = false;
1212

1313
protected string $size = '';
1414

1515
protected string $unit = '';
1616

1717
public function __construct(string $size)
1818
{
19-
$this->valid = (bool) preg_match(self::REGEXP_SIZE_VALIDATION, $size, $matches);
20-
if ($this->valid) {
19+
if (1 === preg_match(self::REGEXP_SIZE_VALIDATION, $size, $matches)) {
20+
$this->valid = true;
2121
$this->size = $matches['size'];
2222
$this->unit = $matches['unit'] ?? 'pt';
2323
}

src/PhpSpreadsheet/Reader/Xlsx.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2346,8 +2346,9 @@ private function processIgnoredErrors(SimpleXMLElement $xml, Worksheet $sheet):
23462346
$firstRow = $matches[2];
23472347
$firstCol = $matches[1];
23482348
if (array_key_exists(3, $matches)) {
2349-
$lastCol = $matches[4];
2350-
$lastRow = $matches[5];
2349+
// https://github.com/phpstan/phpstan/issues/11602
2350+
$lastCol = $matches[4]; // @phpstan-ignore-line
2351+
$lastRow = $matches[5]; // @phpstan-ignore-line
23512352
} else {
23522353
$lastCol = $firstCol;
23532354
$lastRow = $firstRow;

src/PhpSpreadsheet/ReferenceHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ private function updateCellReferencesAllWorksheets(string $formula, int $numberO
759759
$column = $columns[$splitCount][0];
760760
$row = $rows[$splitCount][0];
761761

762-
if (!empty($column) && $column[0] !== '$') {
762+
if ($column[0] !== '$') {
763763
$column = ((Coordinate::columnIndexFromString($column) + $numberOfColumns) % AddressRange::MAX_COLUMN_INT) ?: AddressRange::MAX_COLUMN_INT;
764764
$column = Coordinate::stringFromColumnIndex($column);
765765
$rowOffset -= ($columnLength - strlen($column));

src/PhpSpreadsheet/Style/NumberFormat/FractionFormatter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ public static function format(mixed $value, string $format): string
2525
$decimalDivisor = 10 ** $decimalLength;
2626

2727
preg_match('/(#?.*\?)\/(\?+|\d+)/', $format, $matches);
28-
$formatIntegerPart = $matches[1];
28+
$formatIntegerPart = $matches[1] ?? '0';
2929

30-
if (is_numeric($matches[2])) {
30+
if (isset($matches[2]) && is_numeric($matches[2])) {
3131
$fractionDivisor = 100 / (int) $matches[2];
3232
} else {
3333
/** @var float $fractionDivisor */

src/PhpSpreadsheet/Style/NumberFormat/Wizard/NumberBase.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private function validateLocale(string $locale): string
6060

6161
['language' => $language, 'script' => $script, 'country' => $country] = $matches;
6262
// Set case and separator to match standardised locale case
63-
$language = strtolower($language ?? '');
63+
$language = strtolower($language);
6464
$script = ($script === null) ? null : ucfirst(strtolower($script));
6565
$country = ($country === null) ? null : strtoupper($country);
6666

src/PhpSpreadsheet/Writer/BaseWriter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ protected function processFlags(int $flags): void
100100
*/
101101
public function openFileHandle($filename): void
102102
{
103-
if (is_resource($filename)) {
103+
if (!is_string($filename)) {
104104
$this->fileHandle = $filename;
105105
$this->shouldCloseFile = false;
106106

src/PhpSpreadsheet/Writer/Ods/Content.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,11 @@ private function writeCells(XMLWriter $objWriter, RowCellIterator $cells): void
238238
$matrixColSpan = 1;
239239
if (isset($matches[3])) {
240240
$minRow = (int) $matches[2];
241-
$maxRow = (int) $matches[5];
241+
// https://github.com/phpstan/phpstan/issues/11602
242+
$maxRow = (int) $matches[5]; // @phpstan-ignore-line
242243
$matrixRowSpan = $maxRow - $minRow + 1;
243244
$minCol = Coordinate::columnIndexFromString($matches[1]);
244-
$maxCol = Coordinate::columnIndexFromString($matches[4]);
245+
$maxCol = Coordinate::columnIndexFromString($matches[4]); // @phpstan-ignore-line
245246
$matrixColSpan = $maxCol - $minCol + 1;
246247
}
247248
$objWriter->writeAttribute('table:number-matrix-columns-spanned', "$matrixColSpan");

src/PhpSpreadsheet/Writer/Ods/Formula.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ private function convertCellReferences(string $formula, string $worksheetName):
102102
}
103103
$newRange .= '.';
104104

105-
if (!empty($column)) {
106-
$newRange .= $column;
107-
}
105+
//if (!empty($column)) { // phpstan says always true
106+
$newRange .= $column;
107+
//}
108108
if (!empty($row)) {
109109
$newRange .= $row;
110110
}

src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ private function convertAddress(DefinedName $definedName, string $address): stri
118118
$newRange = "'" . str_replace("'", "''", $worksheet) . "'.";
119119
}
120120

121-
if (!empty($column)) {
122-
$newRange .= $column;
123-
}
121+
//if (!empty($column)) { // phpstan says always true
122+
$newRange .= $column;
123+
//}
124124
if (!empty($row)) {
125125
$newRange .= $row;
126126
}

src/PhpSpreadsheet/Writer/Xls/Parser.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,11 @@ private function cellToPackedRowcol(string $cell): array
894894
*/
895895
private function rangeToPackedRange(string $range): array
896896
{
897-
preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match);
897+
if (preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match) !== 1) {
898+
// @codeCoverageIgnoreStart
899+
throw new WriterException('Regexp failure in rangeToPackedRange');
900+
// @codeCoverageIgnoreEnd
901+
}
898902
// return absolute rows if there is a $ in the ref
899903
$row1_rel = empty($match[1]) ? 1 : 0;
900904
$row1 = $match[2];
@@ -933,7 +937,11 @@ private function rangeToPackedRange(string $range): array
933937
*/
934938
private function cellToRowcol(string $cell): array
935939
{
936-
preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/', $cell, $match);
940+
if (preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/', $cell, $match) !== 1) {
941+
// @codeCoverageIgnoreStart
942+
throw new WriterException('Regexp failure in cellToRowcol');
943+
// @codeCoverageIgnoreEnd
944+
}
937945
// return absolute column if there is a $ in the ref
938946
$col_rel = empty($match[1]) ? 1 : 0;
939947
$col_ref = $match[2];

src/PhpSpreadsheet/Writer/Xlsx/Drawing.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,11 @@ public function writeVMLHeaderFooterImages(\PhpOffice\PhpSpreadsheet\Worksheet\W
501501
private function writeVMLHeaderFooterImage(XMLWriter $objWriter, string $reference, HeaderFooterDrawing $image): void
502502
{
503503
// Calculate object id
504-
preg_match('{(\d+)}', md5($reference), $m);
504+
if (preg_match('{(\d+)}', md5($reference), $m) !== 1) {
505+
// @codeCoverageIgnoreStart
506+
throw new WriterException('Regexp failure in writeVMLHeaderFooterImage');
507+
// @codeCoverageIgnoreEnd
508+
}
505509
$id = 1500 + ((int) substr($m[1], 0, 2) * 1);
506510

507511
// Calculate offset

src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,10 +1542,11 @@ private function parseRef(string $coordinate, string $ref): string
15421542
return $coordinate;
15431543
}
15441544
$minRow = (int) $matches[2];
1545-
$maxRow = (int) $matches[5];
1545+
// https://github.com/phpstan/phpstan/issues/11602
1546+
$maxRow = (int) $matches[5]; // @phpstan-ignore-line
15461547
$rows = $maxRow - $minRow + 1;
15471548
$minCol = Coordinate::columnIndexFromString($matches[1]);
1548-
$maxCol = Coordinate::columnIndexFromString($matches[4]);
1549+
$maxCol = Coordinate::columnIndexFromString($matches[4]); // @phpstan-ignore-line
15491550
$cols = $maxCol - $minCol + 1;
15501551
$firstCellArray = Coordinate::indexesFromString($coordinate);
15511552
$lastRow = $firstCellArray[1] + $rows - 1;

0 commit comments

Comments
 (0)