From d8b4c3b26e4905efb4cc89b44abf3c3541c4cc72 Mon Sep 17 00:00:00 2001 From: oleibman Date: Fri, 19 Jun 2020 11:40:28 -0700 Subject: [PATCH] Fix for #1533 (#1534) Code assumes that formula whose result starts with # indicates error. Change to check entire result against error list in Functions. --- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 2 +- .../Writer/Xlsx/StartsWithHashTest.php | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index d101bb40..be064256 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1112,7 +1112,7 @@ class Worksheet extends WriterPart { $calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() ? $pCell->getCalculatedValue() : $cellValue; if (is_string($calculatedValue)) { - if (substr($calculatedValue, 0, 1) === '#') { + if (\PhpOffice\PhpSpreadsheet\Calculation\Functions::isError($calculatedValue)) { $this->writeCellError($objWriter, 'e', $cellValue, $calculatedValue); return; diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php new file mode 100644 index 00000000..d4fe5b22 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php @@ -0,0 +1,62 @@ +getActiveSheet(); + $sheet->setCellValueExplicit('A1', '#define M', DataType::TYPE_STRING); + $sheet->setCellValue('A2', '=A1'); + $sheet->setCellValue('A3', '=UNKNOWNFUNC()'); + + $writer = new Writer($spreadsheet); + $writer->save($outputFilename); + + $reader = new Reader(); + $sheet = $reader->load($outputFilename); + unlink($outputFilename); + + self::assertSame('#define M', $sheet->getActiveSheet()->getCell('A1')->getValue()); + self::assertSame('#define M', $sheet->getActiveSheet()->getCell('A2')->getCalculatedValue()); + self::assertSame('f', $sheet->getActiveSheet()->getCell('A3')->getDataType()); + self::assertSame('#NAME?', $sheet->getActiveSheet()->getCell('A3')->getCalculatedValue()); + self::assertSame('f', $sheet->getActiveSheet()->getCell('A3')->getDataType()); + } + + public function testStartWithHashReadRaw(): void + { + // Make sure raw data indicates A3 is an error, but A2 isn't. + $outputFilename = tempnam(File::sysGetTempDir(), 'phpspreadsheet-test'); + Settings::setLibXmlLoaderOptions(null); + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->setCellValueExplicit('A1', '#define M', DataType::TYPE_STRING); + $sheet->setCellValue('A2', '=A1'); + $sheet->setCellValue('A3', '=UNKNOWNFUNC()'); + + $writer = new Writer($spreadsheet); + $writer->save($outputFilename); + $zip = new ZipArchive(); + $zip->open($outputFilename); + $resultSheet1Raw = $zip->getFromName('xl/worksheets/sheet1.xml'); + $zip->close(); + unlink($outputFilename); + + self::assertStringContainsString('', $resultSheet1Raw); + self::assertStringContainsString('', $resultSheet1Raw); + } +}