Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 20 additions & 7 deletions src/PhpSpreadsheet/Calculation/Calculation.php
Original file line number Diff line number Diff line change
Expand Up @@ -4160,8 +4160,10 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
}
}
} elseif ($expectedArgumentCount != '*') {
preg_match('/(\d*)([-+,])(\d*)/', $expectedArgumentCount, $argMatch);
switch ($argMatch[2] ?? '') {
if (1 !== preg_match('/(\d*)([-+,])(\d*)/', $expectedArgumentCount, $argMatch)) {
$argMatch = ['', '', '', ''];
}
switch ($argMatch[2]) {
case '+':
if ($argumentCount < $argMatch[1]) {
$argumentCountError = true;
Expand Down Expand Up @@ -4234,7 +4236,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
// do we now have a function/variable/number?
$expectingOperator = true;
$expectingOperand = false;
$val = $match[1];
$val = $match[1] ?? '';
$length = strlen($val);

if (preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $val, $matches)) {
Expand Down Expand Up @@ -4290,7 +4292,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
$rangeStartCellRef = $output[count($output) - 2]['value'] ?? '';
}
preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/miu', $rangeStartCellRef, $rangeStartMatches);
if ($rangeStartMatches[2] !== $matches[2]) {
if (isset($rangeStartMatches[2]) && $rangeStartMatches[2] !== $matches[2]) {
return $this->raiseFormulaError('3D Range references are not yet supported');
}
}
Expand Down Expand Up @@ -4380,7 +4382,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
$valx = $val;
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestDataColumn($valx) : AddressRange::MAX_COLUMN; // Max 16,384 columns for Excel2007
$val = "{$rangeWS2}{$endRowColRef}{$val}";
} elseif (ctype_alpha($val) && strlen($val ?? '') <= 3) {
} elseif (ctype_alpha($val) && is_string($val) && strlen($val) <= 3) {
// Column range
$stackItemType = 'Column Reference';
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestDataRow($val) : AddressRange::MAX_ROW; // Max 1,048,576 rows for Excel2007
Expand Down Expand Up @@ -4545,6 +4547,12 @@ private static function dataTestReference(array &$operandData): mixed
return $operand;
}

private static int $matchIndex8 = 8;

private static int $matchIndex9 = 9;

private static int $matchIndex10 = 10;

/**
* @return array<int, mixed>|false
*/
Expand Down Expand Up @@ -4908,12 +4916,17 @@ private function processTokenStack(mixed $tokens, ?string $cellID = null, ?Cell
} elseif (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/i', $token ?? '', $matches)) {
$cellRef = null;

if (isset($matches[8])) {
/* Phpstan says matches[8/9/10] is never set,
and code coverage report seems to confirm.
Appease PhpStan for now;
probably delete this block later.
*/
if (isset($matches[self::$matchIndex8])) {
if ($cell === null) {
// We can't access the range, so return a REF error
$cellValue = ExcelError::REF();
} else {
$cellRef = $matches[6] . $matches[7] . ':' . $matches[9] . $matches[10];
$cellRef = $matches[6] . $matches[7] . ':' . $matches[self::$matchIndex9] . $matches[self::$matchIndex10];
if ($matches[2] > '') {
$matches[2] = trim($matches[2], "\"'");
if ((str_contains($matches[2], '[')) || (str_contains($matches[2], ']'))) {
Expand Down
6 changes: 4 additions & 2 deletions src/PhpSpreadsheet/Calculation/Functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,10 @@ public static function ifCondition(mixed $condition): string

return str_replace('""""', '""', '=' . $condition);
}
preg_match('/(=|<[>=]?|>=?)(.*)/', $condition, $matches);
[, $operator, $operand] = $matches;
$operator = $operand = '';
if (1 === preg_match('/(=|<[>=]?|>=?)(.*)/', $condition, $matches)) {
[, $operator, $operand] = $matches;
}

$operand = self::operandSpecialHandling($operand);
if (is_numeric(trim($operand, '"'))) {
Expand Down
9 changes: 5 additions & 4 deletions src/PhpSpreadsheet/Calculation/Information/Value.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,11 @@ public static function isFormula(mixed $cellReference = '', ?Cell $cell = null):

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

preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $fullCellReference, $matches);

$fullCellReference = $matches[6] . $matches[7];
$worksheetName = str_replace("''", "'", trim($matches[2], "'"));
$worksheetName = '';
if (1 == preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $fullCellReference, $matches)) {
$fullCellReference = $matches[6] . $matches[7];
$worksheetName = str_replace("''", "'", trim($matches[2], "'"));
}

$worksheet = (!empty($worksheetName))
? $cell->getWorksheet()->getParentOrThrow()->getSheetByName($worksheetName)
Expand Down
15 changes: 8 additions & 7 deletions src/PhpSpreadsheet/Calculation/LookupRef/Formula.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ public static function text(mixed $cellReference = '', ?Cell $cell = null): stri
return ExcelError::REF();
}

preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellReference, $matches);

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

if (
$worksheet === null
Expand Down
4 changes: 1 addition & 3 deletions src/PhpSpreadsheet/Cell/AddressHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,7 @@ public static function convertToR1C1(
?int $currentRowNumber = null,
?int $currentColumnNumber = null
): string {
$validityCheck = preg_match(Coordinate::A1_COORDINATE_REGEX, $address, $cellReference);

if ($validityCheck === 0) {
if (1 !== preg_match(Coordinate::A1_COORDINATE_REGEX, $address, $cellReference)) {
throw new Exception('Invalid A1-format Cell Reference');
}

Expand Down
5 changes: 3 additions & 2 deletions src/PhpSpreadsheet/Cell/Cell.php
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,10 @@ public function getCalculatedValue(bool $resetLog = true): mixed
if (isset($matches[3])) {
$minCol = $matches[1];
$minRow = (int) $matches[2];
$maxCol = $matches[4];
// https://github.com/phpstan/phpstan/issues/11602
$maxCol = $matches[4]; // @phpstan-ignore-line
++$maxCol;
$maxRow = (int) $matches[5];
$maxRow = (int) $matches[5]; // @phpstan-ignore-line
for ($row = $minRow; $row <= $maxRow; ++$row) {
for ($col = $minCol; $col !== $maxCol; ++$col) {
if ("$col$row" !== $coordinate) {
Expand Down
3 changes: 1 addition & 2 deletions src/PhpSpreadsheet/Cell/Coordinate.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,7 @@ public static function getRangeBoundaries(string $range): array
private static function validateReferenceAndGetData($reference): array
{
$data = [];
preg_match(self::FULL_REFERENCE_REGEX, $reference, $matches);
if (count($matches) === 0) {
if (1 !== preg_match(self::FULL_REFERENCE_REGEX, $reference, $matches)) {
return ['type' => 'invalid'];
}

Expand Down
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Helper/Size.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ class Size implements Stringable
{
const REGEXP_SIZE_VALIDATION = '/^(?P<size>\d*\.?\d+)(?P<unit>pt|px|em)?$/i';

protected bool $valid;
protected bool $valid = false;

protected string $size = '';

protected string $unit = '';

public function __construct(string $size)
{
$this->valid = (bool) preg_match(self::REGEXP_SIZE_VALIDATION, $size, $matches);
if ($this->valid) {
if (1 === preg_match(self::REGEXP_SIZE_VALIDATION, $size, $matches)) {
$this->valid = true;
$this->size = $matches['size'];
$this->unit = $matches['unit'] ?? 'pt';
}
Expand Down
5 changes: 3 additions & 2 deletions src/PhpSpreadsheet/Reader/Xlsx.php
Original file line number Diff line number Diff line change
Expand Up @@ -2359,8 +2359,9 @@ private function processIgnoredErrors(SimpleXMLElement $xml, Worksheet $sheet):
$firstRow = $matches[2];
$firstCol = $matches[1];
if (array_key_exists(3, $matches)) {
$lastCol = $matches[4];
$lastRow = $matches[5];
// https://github.com/phpstan/phpstan/issues/11602
$lastCol = $matches[4]; // @phpstan-ignore-line
$lastRow = $matches[5]; // @phpstan-ignore-line
} else {
$lastCol = $firstCol;
$lastRow = $firstRow;
Expand Down
2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/ReferenceHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ private function updateCellReferencesAllWorksheets(string $formula, int $numberO
$column = $columns[$splitCount][0];
$row = $rows[$splitCount][0];

if (!empty($column) && $column[0] !== '$') {
if ($column[0] !== '$') {
$column = ((Coordinate::columnIndexFromString($column) + $numberOfColumns) % AddressRange::MAX_COLUMN_INT) ?: AddressRange::MAX_COLUMN_INT;
$column = Coordinate::stringFromColumnIndex($column);
$rowOffset -= ($columnLength - strlen($column));
Expand Down
4 changes: 2 additions & 2 deletions src/PhpSpreadsheet/Style/NumberFormat/FractionFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ public static function format(mixed $value, string $format): string
$decimalDivisor = 10 ** $decimalLength;

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

if (is_numeric($matches[2])) {
if (isset($matches[2]) && is_numeric($matches[2])) {
$fractionDivisor = 100 / (int) $matches[2];
} else {
/** @var float $fractionDivisor */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private function validateLocale(string $locale): string

['language' => $language, 'script' => $script, 'country' => $country] = $matches;
// Set case and separator to match standardised locale case
$language = strtolower($language ?? '');
$language = strtolower($language);
$script = ($script === null) ? null : ucfirst(strtolower($script));
$country = ($country === null) ? null : strtoupper($country);

Expand Down
2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/Writer/BaseWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ protected function processFlags(int $flags): void
*/
public function openFileHandle($filename): void
{
if (is_resource($filename)) {
if (!is_string($filename)) {
$this->fileHandle = $filename;
$this->shouldCloseFile = false;

Expand Down
5 changes: 3 additions & 2 deletions src/PhpSpreadsheet/Writer/Ods/Content.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,11 @@ private function writeCells(XMLWriter $objWriter, RowCellIterator $cells): void
$matrixColSpan = 1;
if (isset($matches[3])) {
$minRow = (int) $matches[2];
$maxRow = (int) $matches[5];
// https://github.com/phpstan/phpstan/issues/11602
$maxRow = (int) $matches[5]; // @phpstan-ignore-line
$matrixRowSpan = $maxRow - $minRow + 1;
$minCol = Coordinate::columnIndexFromString($matches[1]);
$maxCol = Coordinate::columnIndexFromString($matches[4]);
$maxCol = Coordinate::columnIndexFromString($matches[4]); // @phpstan-ignore-line
$matrixColSpan = $maxCol - $minCol + 1;
}
$objWriter->writeAttribute('table:number-matrix-columns-spanned', "$matrixColSpan");
Expand Down
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Writer/Ods/Formula.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ private function convertCellReferences(string $formula, string $worksheetName):
}
$newRange .= '.';

if (!empty($column)) {
$newRange .= $column;
}
//if (!empty($column)) { // phpstan says always true
$newRange .= $column;
//}
if (!empty($row)) {
$newRange .= $row;
}
Expand Down
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ private function convertAddress(DefinedName $definedName, string $address): stri
$newRange = "'" . str_replace("'", "''", $worksheet) . "'.";
}

if (!empty($column)) {
$newRange .= $column;
}
//if (!empty($column)) { // phpstan says always true
$newRange .= $column;
//}
if (!empty($row)) {
$newRange .= $row;
}
Expand Down
12 changes: 10 additions & 2 deletions src/PhpSpreadsheet/Writer/Xls/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,11 @@ private function cellToPackedRowcol(string $cell): array
*/
private function rangeToPackedRange(string $range): array
{
preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match);
if (preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match) !== 1) {
// @codeCoverageIgnoreStart
throw new WriterException('Regexp failure in rangeToPackedRange');
// @codeCoverageIgnoreEnd
}
// return absolute rows if there is a $ in the ref
$row1_rel = empty($match[1]) ? 1 : 0;
$row1 = $match[2];
Expand Down Expand Up @@ -933,7 +937,11 @@ private function rangeToPackedRange(string $range): array
*/
private function cellToRowcol(string $cell): array
{
preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/', $cell, $match);
if (preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/', $cell, $match) !== 1) {
// @codeCoverageIgnoreStart
throw new WriterException('Regexp failure in cellToRowcol');
// @codeCoverageIgnoreEnd
}
// return absolute column if there is a $ in the ref
$col_rel = empty($match[1]) ? 1 : 0;
$col_ref = $match[2];
Expand Down
6 changes: 5 additions & 1 deletion src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,11 @@ public function writeVMLHeaderFooterImages(\PhpOffice\PhpSpreadsheet\Worksheet\W
private function writeVMLHeaderFooterImage(XMLWriter $objWriter, string $reference, HeaderFooterDrawing $image): void
{
// Calculate object id
preg_match('{(\d+)}', md5($reference), $m);
if (preg_match('{(\d+)}', md5($reference), $m) !== 1) {
// @codeCoverageIgnoreStart
throw new WriterException('Regexp failure in writeVMLHeaderFooterImage');
// @codeCoverageIgnoreEnd
}
$id = 1500 + ((int) substr($m[1], 0, 2) * 1);

// Calculate offset
Expand Down
5 changes: 3 additions & 2 deletions src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -1542,10 +1542,11 @@ private function parseRef(string $coordinate, string $ref): string
return $coordinate;
}
$minRow = (int) $matches[2];
$maxRow = (int) $matches[5];
// https://github.com/phpstan/phpstan/issues/11602
$maxRow = (int) $matches[5]; // @phpstan-ignore-line
$rows = $maxRow - $minRow + 1;
$minCol = Coordinate::columnIndexFromString($matches[1]);
$maxCol = Coordinate::columnIndexFromString($matches[4]);
$maxCol = Coordinate::columnIndexFromString($matches[4]); // @phpstan-ignore-line
$cols = $maxCol - $minCol + 1;
$firstCellArray = Coordinate::indexesFromString($coordinate);
$lastRow = $firstCellArray[1] + $rows - 1;
Expand Down
Loading