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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