From 36b328a9fae1a91caee103c00c202cab4665cf68 Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Tue, 29 Jun 2021 09:11:51 -0700 Subject: [PATCH 1/3] Fix Worksheet Passwords Fix for issue #1897. The existing hashing code seems to work correctly almost all the time, but there are exceptions. It is replaced by an exact implementation of the spec, including a link to the spec in the comments. Cases known to fail are added to the unit test suite. The spec expects the string to be at most 255 bytes (yes, bytes not characters). The program had permitted any length; it will now throw an exception when the maximum length is exceeded. Xls does not support any hashing algorithm except basic. The Xls writer had, nevertheless, accepted the results of any of the other possible algorithms. This leads to (a) a worksheet that can't be unprotected, and (b) deprecation notices during the write (because it is using hexdec, which expects only hex characters, and the other algorithms generate non-hex characters). I have changed Xls writer to ignore passwords generated by other algorithms. An alternative would be to have the password hasher generate both an algorithmic password (for use by Xlsx) and a basic password (for use by Xls); I think that is too complex a solution, but can look into it if you think it worthwhile. I do not see any current support for Worksheet passwords in ODS Reader or Writer. I did not add support in this PR. I added a new test to confirm the password for reading a spreadsheet is consistent with the one used for writing it. As you can see from the comments for the new test, it had an unusual problem with a somewhat unusual solution. --- phpstan-baseline.neon | 5 -- src/PhpSpreadsheet/Shared/PasswordHasher.php | 43 ++++++++----- src/PhpSpreadsheet/Writer/Xls/Worksheet.php | 2 +- .../Shared/PasswordHasherTest.php | 4 ++ .../Shared/PasswordReloadTest.php | 63 +++++++++++++++++++ tests/data/Shared/PasswordHashes.php | 5 ++ 6 files changed, 99 insertions(+), 23 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Shared/PasswordReloadTest.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 3538d091..625c3429 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -4310,11 +4310,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Shared/OLERead.php - - - message: "#^Argument of an invalid type array\\\\|false supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/PasswordHasher.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:sanitizeUTF8\\(\\) should return string but returns string\\|false\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Shared/PasswordHasher.php b/src/PhpSpreadsheet/Shared/PasswordHasher.php index 9fefe88f..ba30fc31 100644 --- a/src/PhpSpreadsheet/Shared/PasswordHasher.php +++ b/src/PhpSpreadsheet/Shared/PasswordHasher.php @@ -2,11 +2,13 @@ namespace PhpOffice\PhpSpreadsheet\Shared; -use PhpOffice\PhpSpreadsheet\Exception; +use PhpOffice\PhpSpreadsheet\Exception as SpException; use PhpOffice\PhpSpreadsheet\Worksheet\Protection; class PasswordHasher { + const MAX_PASSWORD_LENGTH = 255; + /** * Get algorithm name for PHP. */ @@ -34,36 +36,40 @@ class PasswordHasher return $mapping[$algorithmName]; } - throw new Exception('Unsupported password algorithm: ' . $algorithmName); + throw new SpException('Unsupported password algorithm: ' . $algorithmName); } /** * Create a password hash from a given string. * - * This method is based on the algorithm provided by + * This method is based on the spec at: + * https://interoperability.blob.core.windows.net/files/MS-OFFCRYPTO/[MS-OFFCRYPTO].pdf + * 2.3.7.1 Binary Document Password Verifier Derivation Method 1 + * + * It replaces a method based on the algorithm provided by * Daniel Rentz of OpenOffice and the PEAR package * Spreadsheet_Excel_Writer by Xavier Noguer . * + * Scrutinizer will squawk at the use of bitwise operations here, + * but it should ultimately pass. + * * @param string $pPassword Password to hash */ private static function defaultHashPassword(string $pPassword): string { - $password = 0x0000; - $charPos = 1; // char position - - // split the plain text password in its component characters - $chars = preg_split('//', $pPassword, -1, PREG_SPLIT_NO_EMPTY); - foreach ($chars as $char) { - $value = ord($char) << $charPos++; // shifted ASCII value - $rotated_bits = $value >> 15; // rotated bits beyond bit 15 - $value &= 0x7fff; // first 15 bits - $password ^= ($value | $rotated_bits); + $verifier = 0; + $pwlen = strlen($pPassword); + $passwordArray = pack('c', $pwlen) . $pPassword; + for ($i = $pwlen; $i >= 0; --$i) { + $intermediate1 = (($verifier & 0x4000) === 0) ? 0 : 1; + $intermediate2 = 2 * $verifier; + $intermediate2 = $intermediate2 & 0x7fff; + $intermediate3 = $intermediate1 | $intermediate2; + $verifier = $intermediate3 ^ ord($passwordArray[$i]); } + $verifier ^= 0xCE4B; - $password ^= strlen($pPassword); - $password ^= 0xCE4B; - - return strtoupper(dechex($password)); + return strtoupper(dechex($verifier)); } /** @@ -82,6 +88,9 @@ class PasswordHasher */ public static function hashPassword(string $password, string $algorithm = '', string $salt = '', int $spinCount = 10000): string { + if (strlen($password) > self::MAX_PASSWORD_LENGTH) { + throw new SpException('Password exceeds ' . self::MAX_PASSWORD_LENGTH . ' characters'); + } $phpAlgorithm = self::getAlgorithm($algorithm); if (!$phpAlgorithm) { return self::defaultHashPassword($password); diff --git a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php index 6b5fa6fd..e8377ee9 100644 --- a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php @@ -2138,7 +2138,7 @@ class Worksheet extends BIFFwriter private function writePassword(): void { // Exit unless sheet protection and password have been specified - if (!$this->phpSheet->getProtection()->getSheet() || !$this->phpSheet->getProtection()->getPassword()) { + if (!$this->phpSheet->getProtection()->getSheet() || !$this->phpSheet->getProtection()->getPassword() || $this->phpSheet->getProtection()->getAlgorithm() !== '') { return; } diff --git a/tests/PhpSpreadsheetTests/Shared/PasswordHasherTest.php b/tests/PhpSpreadsheetTests/Shared/PasswordHasherTest.php index e85b9fa3..4b7923d8 100644 --- a/tests/PhpSpreadsheetTests/Shared/PasswordHasherTest.php +++ b/tests/PhpSpreadsheetTests/Shared/PasswordHasherTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Shared; +use PhpOffice\PhpSpreadsheet\Exception as SpException; use PhpOffice\PhpSpreadsheet\Shared\PasswordHasher; use PHPUnit\Framework\TestCase; @@ -14,6 +15,9 @@ class PasswordHasherTest extends TestCase */ public function testHashPassword($expectedResult, ...$args): void { + if ($expectedResult === 'exception') { + $this->expectException(SpException::class); + } $result = PasswordHasher::hashPassword(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Shared/PasswordReloadTest.php b/tests/PhpSpreadsheetTests/Shared/PasswordReloadTest.php new file mode 100644 index 00000000..6d127496 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Shared/PasswordReloadTest.php @@ -0,0 +1,63 @@ +getActiveSheet(); + $sheet->getCell('A1')->setValue(1); + $protection = $sheet->getProtection(); + $protection->setAlgorithm($algorithm); + $protection->setPassword($password); + $protection->setSheet(true); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + $resheet = $reloadedSpreadsheet->getActiveSheet(); + $reprot = $resheet->getProtection(); + $repassword = $reprot->getPassword(); + $hash = ''; + if ($supported) { + $readAlgorithm = $reprot->getAlgorithm(); + self::assertSame($algorithm, $readAlgorithm); + $salt = $reprot->getSalt(); + $spin = $reprot->getSpinCount(); + $hash = PasswordHasher::hashPassword($password, $readAlgorithm, $salt, $spin); + } + self::assertSame($repassword, $hash); + $spreadsheet->disconnectWorksheets(); + $reloadedSpreadsheet->disconnectWorksheets(); + } + + public function providerPasswords(): array + { + return [ + 'Xls basic algorithm' => ['Xls', ''], + 'Xls cannot use SHA512' => ['Xls', 'SHA-512', false], + 'Xlsx basic algorithm' => ['Xlsx', ''], + 'Xlsx can use SHA512' => ['Xlsx', 'SHA-512'], + ]; + } +} diff --git a/tests/data/Shared/PasswordHashes.php b/tests/data/Shared/PasswordHashes.php index 34c25cef..c46adf14 100644 --- a/tests/data/Shared/PasswordHashes.php +++ b/tests/data/Shared/PasswordHashes.php @@ -51,4 +51,9 @@ return [ 'Symbols_salt', 100000, ], + // Additional tests suggested by Issue #1897 + ['DCDF', 'ABCDEFGHIJKLMNOPQRSTUVW'], + ['ECD1', 'ABCDEFGHIJKLMNOPQRSTUVWX'], + ['88D2', 'ABCDEFGHIJKLMNOPQRSTUVWXY'], + 'password too long' => ['exception', str_repeat('x', 256)], ]; From 3bb574c302c7233b41555d51229f1b52b53ec063 Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Wed, 30 Jun 2021 11:33:35 -0700 Subject: [PATCH 2/3] Fix SettingsTest SettingsTest was changing the global LibXMLLoaderOptions without restoring the original. This caused problems for one of my new tests. --- tests/PhpSpreadsheetTests/SettingsTest.php | 2 ++ .../Shared/PasswordReloadTest.php | 12 ------------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/tests/PhpSpreadsheetTests/SettingsTest.php b/tests/PhpSpreadsheetTests/SettingsTest.php index 11b93ae6..80dc07ab 100644 --- a/tests/PhpSpreadsheetTests/SettingsTest.php +++ b/tests/PhpSpreadsheetTests/SettingsTest.php @@ -41,6 +41,7 @@ class SettingsTest extends TestCase public function testSetXMLSettings(): void { + $original = Settings::getLibXmlLoaderOptions(); Settings::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_DTDVALID); $result = Settings::getLibXmlLoaderOptions(); self::assertTrue((bool) ((LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_DTDVALID) & $result)); @@ -48,5 +49,6 @@ class SettingsTest extends TestCase if (\PHP_VERSION_ID < 80000) { self::assertFalse(libxml_disable_entity_loader()); } + Settings::setLibXmlLoaderOptions($original); } } diff --git a/tests/PhpSpreadsheetTests/Shared/PasswordReloadTest.php b/tests/PhpSpreadsheetTests/Shared/PasswordReloadTest.php index 6d127496..b6c28b17 100644 --- a/tests/PhpSpreadsheetTests/Shared/PasswordReloadTest.php +++ b/tests/PhpSpreadsheetTests/Shared/PasswordReloadTest.php @@ -9,18 +9,6 @@ use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional; class PasswordReloadTest extends AbstractFunctional { /** - * I don't know why separate process is needed for this test. - * I get a weird error without it, and I would rather just scrap the test - * than spend any more time debugging it. - * The test works fine without separate process (on Windows) with: - * php vendor\phpunit\phpunit\phpunit tests\PhpSpreadsheetTests\Shared\ - * But it fails with: - * php vendor\phpunit\phpunit\phpunit tests\PhpSpreadsheetTests\ - * The error is a mysterious: - * simplexml_load_string(): validity error : Validation failed: no DTD found ! - * - * @runInSeparateProcess - * @preserveGlobalState disabled * @dataProvider providerPasswords */ public function testPasswordReload(string $format, string $algorithm, bool $supported = true): void From 7b3585c76ace9d245db60f6b821245e546837470 Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Wed, 30 Jun 2021 13:15:20 -0700 Subject: [PATCH 3/3] Now That SettingsTest Is Well-Behaved 7 tests that needed to invoke Settings::setLibXmlLoaderOptions no longer need to do so. --- phpstan-baseline.neon | 25 ------------------- .../Worksheet/WorksheetNamedRangesTest.php | 3 --- .../Writer/Xlsx/ConditionalTest.php | 19 -------------- .../Writer/Xlsx/DrawingsTest.php | 19 -------------- .../Writer/Xlsx/FloatsRetainedTest.php | 2 -- .../Writer/Xlsx/StartsWithHashTest.php | 3 --- .../Writer/Xlsx/UnparsedDataCloneTest.php | 3 --- .../Writer/Xlsx/UnparsedDataTest.php | 1 - 8 files changed, 75 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 625c3429..527d89b5 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6930,11 +6930,6 @@ parameters: count: 1 path: tests/PhpSpreadsheetTests/Worksheet/RowCellIterator2Test.php - - - message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#" - count: 1 - path: tests/PhpSpreadsheetTests/Worksheet/WorksheetNamedRangesTest.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheetTests\\\\Writer\\\\Csv\\\\CsvEnclosureTest\\:\\:\\$cellValues has no typehint specified\\.$#" count: 1 @@ -6980,11 +6975,6 @@ parameters: count: 1 path: tests/PhpSpreadsheetTests/Writer/Html/ImagesRootTest.php - - - message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#" - count: 1 - path: tests/PhpSpreadsheetTests/Writer/Xlsx/FloatsRetainedTest.php - - message: "#^Parameter \\#2 \\$locale of function setlocale expects string\\|null, string\\|false given\\.$#" count: 1 @@ -6995,16 +6985,6 @@ parameters: count: 1 path: tests/PhpSpreadsheetTests/Writer/Xlsx/LocaleFloatsTest.php - - - message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#" - count: 2 - path: tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php - - - - message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#" - count: 2 - path: tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataCloneTest.php - - message: "#^Cannot call method getDrawingCollection\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#" count: 4 @@ -7015,11 +6995,6 @@ parameters: count: 4 path: tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataCloneTest.php - - - message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#" - count: 1 - path: tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataTest.php - - message: "#^Parameter \\#1 \\$data of function simplexml_load_string expects string, string\\|false given\\.$#" count: 2 diff --git a/tests/PhpSpreadsheetTests/Worksheet/WorksheetNamedRangesTest.php b/tests/PhpSpreadsheetTests/Worksheet/WorksheetNamedRangesTest.php index 1560f1ed..b367583b 100644 --- a/tests/PhpSpreadsheetTests/Worksheet/WorksheetNamedRangesTest.php +++ b/tests/PhpSpreadsheetTests/Worksheet/WorksheetNamedRangesTest.php @@ -4,7 +4,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Worksheet; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; -use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PHPUnit\Framework\TestCase; @@ -17,8 +16,6 @@ class WorksheetNamedRangesTest extends TestCase protected function setUp(): void { - Settings::setLibXmlLoaderOptions(null); // reset to default options - $reader = new Xlsx(); $this->spreadsheet = $reader->load('tests/data/Worksheet/namedRangeTest.xlsx'); } diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/ConditionalTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/ConditionalTest.php index 21df6ed6..21659dad 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/ConditionalTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/ConditionalTest.php @@ -2,7 +2,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx; -use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\Fill; @@ -11,24 +10,6 @@ use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional; class ConditionalTest extends AbstractFunctional { - /** - * @var int - */ - private $prevValue; - - protected function setUp(): void - { - $this->prevValue = Settings::getLibXmlLoaderOptions(); - - // Disable validating XML with the DTD - Settings::setLibXmlLoaderOptions($this->prevValue & ~LIBXML_DTDVALID & ~LIBXML_DTDATTR & ~LIBXML_DTDLOAD); - } - - protected function tearDown(): void - { - Settings::setLibXmlLoaderOptions($this->prevValue); - } - /** * Test check if conditional style with type 'notContainsText' works on xlsx. */ diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingsTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingsTest.php index 88c63306..012cdbcd 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingsTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingsTest.php @@ -4,30 +4,11 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Xlsx; -use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional; class DrawingsTest extends AbstractFunctional { - /** - * @var int - */ - private $prevValue; - - protected function setUp(): void - { - $this->prevValue = Settings::getLibXmlLoaderOptions(); - - // Disable validating XML with the DTD - Settings::setLibXmlLoaderOptions($this->prevValue & ~LIBXML_DTDVALID & ~LIBXML_DTDATTR & ~LIBXML_DTDLOAD); - } - - protected function tearDown(): void - { - Settings::setLibXmlLoaderOptions($this->prevValue); - } - /** * Test save and load XLSX file with drawing on 2nd worksheet. */ diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/FloatsRetainedTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/FloatsRetainedTest.php index 22f3284b..6ba8316b 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/FloatsRetainedTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/FloatsRetainedTest.php @@ -3,7 +3,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Reader\Xlsx as Reader; -use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx as Writer; @@ -19,7 +18,6 @@ class FloatsRetainedTest extends TestCase public function testIntyFloatsRetainedByWriter($value): void { $outputFilename = File::temporaryFilename(); - Settings::setLibXmlLoaderOptions(null); $sheet = new Spreadsheet(); $sheet->getActiveSheet()->getCell('A1')->setValue($value); diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php index 826c482d..ebc3c92f 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php @@ -4,7 +4,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Reader\Xlsx as Reader; -use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx as Writer; @@ -16,7 +15,6 @@ class StartsWithHashTest extends TestCase public function testStartWithHash(): void { $outputFilename = File::temporaryFilename(); - Settings::setLibXmlLoaderOptions(null); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValueExplicit('A1', '#define M', DataType::TYPE_STRING); @@ -41,7 +39,6 @@ class StartsWithHashTest extends TestCase { // Make sure raw data indicates A3 is an error, but A2 isn't. $outputFilename = File::temporaryFilename(); - Settings::setLibXmlLoaderOptions(null); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValueExplicit('A1', '#define M', DataType::TYPE_STRING); diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataCloneTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataCloneTest.php index def6f70e..9a801015 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataCloneTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataCloneTest.php @@ -2,7 +2,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx; -use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Shared\File; use PHPUnit\Framework\TestCase; use ZipArchive; @@ -16,7 +15,6 @@ class UnparsedDataCloneTest extends TestCase { $sampleFilename = 'tests/data/Writer/XLSX/drawing_on_2nd_page.xlsx'; $resultFilename = File::temporaryFilename(); - Settings::setLibXmlLoaderOptions(null); // reset to default options $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx(); $spreadsheet = $reader->load($sampleFilename); $spreadsheet->setActiveSheetIndex(1); @@ -63,7 +61,6 @@ class UnparsedDataCloneTest extends TestCase $resultFilename1 = File::temporaryFilename(); $resultFilename2 = File::temporaryFilename(); self::assertNotEquals($resultFilename1, $resultFilename2); - Settings::setLibXmlLoaderOptions(null); // reset to default options $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx(); $spreadsheet = $reader->load($sampleFilename); $sheet = $spreadsheet->setActiveSheetIndex(1); diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataTest.php index a2f21aef..56193419 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataTest.php @@ -17,7 +17,6 @@ class UnparsedDataTest extends TestCase { $sampleFilename = 'tests/data/Writer/XLSX/form_pass_print.xlsm'; $resultFilename = File::temporaryFilename(); - Settings::setLibXmlLoaderOptions(null); // reset to default options $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx(); $excel = $reader->load($sampleFilename);