From 73f880ff19a448345d8ff543cc34312eb15e94dc Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Tue, 7 Mar 2023 07:51:20 -0800 Subject: [PATCH] Correct Xlsx Parsing of quotePrefix="0" (#3438) * Correct Xlsx Parsing of quotePrefix="0" Fix #3435. Mis-parsed attribute is not normally generated by Excel or PhpSpreadsheet, but some 3rd-party software (correctly) generates it. * Update Issue3435Test.php --- src/PhpSpreadsheet/Reader/Xlsx.php | 4 +- .../Reader/Xlsx/Issue3435Test.php | 44 ++++++++++++++++++ tests/data/Reader/XLSX/issue.3435.xlsx | Bin 0 -> 10093 bytes 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Reader/Xlsx/Issue3435Test.php create mode 100644 tests/data/Reader/XLSX/issue.3435.xlsx diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index bf89084706..4d8a4933f7 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -618,7 +618,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet $numFmt = NumberFormat::builtInFormatCode((int) $xf['numFmtId']); } } - $quotePrefix = (bool) ($xf['quotePrefix'] ?? false); + $quotePrefix = (bool) (string) ($xf['quotePrefix'] ?? ''); $style = (object) [ 'numFmt' => $numFmt ?? NumberFormat::FORMAT_GENERAL, @@ -653,7 +653,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet } } - $quotePrefix = (bool) ($xf['quotePrefix'] ?? false); + $quotePrefix = (bool) (string) ($xf['quotePrefix'] ?? ''); $cellStyle = (object) [ 'numFmt' => $numFmt, diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue3435Test.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue3435Test.php new file mode 100644 index 0000000000..9d997dee39 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/Issue3435Test.php @@ -0,0 +1,44 @@ + + + + EOF; + self::assertStringContainsString($expected, $data); + } + } + + public function testQuotePrefix(): void + { + // Parsing of quotePrefix="0" was incorrect, now corrected. + $reader = new Xlsx(); + $spreadsheet = $reader->load(self::$testbook); + $sheet = $spreadsheet->getActiveSheet(); + self::assertTrue($sheet->getStyle('A1')->getQuotePrefix()); + self::assertFalse($sheet->getStyle('A2')->getQuotePrefix()); + self::assertFalse($sheet->getStyle('A3')->getQuotePrefix()); + $spreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Reader/XLSX/issue.3435.xlsx b/tests/data/Reader/XLSX/issue.3435.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..36f529977babef8969d1cd66b8af797e45ee1ee9 GIT binary patch literal 10093 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