From 9552172b85fdeaab5574b1a01245ece401e68cce Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Wed, 27 Nov 2019 08:52:34 -0800 Subject: [PATCH] Do not confuse defined names and cell refs CALCULATION_REGEXP_CELLREF is not sufficiently robust. It treats some perfectly legal defined names, e.g. A1A, as cell refs. When the Xlsx Writer tries to save a worksheet which uses such a name in a formula in a cell, it throws an exception. The new DefinedNameConfusedForCellTest is a simple demonstration. The Regexp has been changed to ensure the name starts on a Word boundary, and to make sure it is not followed by a word character or period. This fixes the problem, and does not appear to cause any regression problems in the test suite. Closes #1263 --- .../Calculation/Calculation.php | 2 +- .../DefinedNameConfusedForCellTest.php | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/PhpSpreadsheetTests/Calculation/DefinedNameConfusedForCellTest.php diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 2cda7536..3bf592c9 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -25,7 +25,7 @@ class Calculation // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it) const CALCULATION_REGEXP_FUNCTION = '@?(?:_xlfn\.)?([A-Z][A-Z0-9\.]*)[\s]*\('; // Cell reference (cell or range of cells, with or without a sheet reference) - const CALCULATION_REGEXP_CELLREF = '((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'; + const CALCULATION_REGEXP_CELLREF = '((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?\b([a-z]{1,3})\$?(\d{1,7})(?![\w.])'; // Named Range of cells const CALCULATION_REGEXP_NAMEDRANGE = '((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)'; // Error diff --git a/tests/PhpSpreadsheetTests/Calculation/DefinedNameConfusedForCellTest.php b/tests/PhpSpreadsheetTests/Calculation/DefinedNameConfusedForCellTest.php new file mode 100644 index 00000000..54333afa --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/DefinedNameConfusedForCellTest.php @@ -0,0 +1,22 @@ +setActiveSheetIndex(0); + $sheet0->setCellValue('A1', 2); + $obj->addNamedRange(new \PhpOffice\PhpSpreadsheet\NamedRange('A1A', $sheet0, 'A1')); + $sheet0->setCellValue('B1', '=2*A1A'); + $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($obj, 'Xlsx'); + $filename = tempnam(File::sysGetTempDir(), 'phpspreadsheet-test'); + $writer->save($filename); + self::assertTrue(true); + } +}