diff --git a/docs/changes/2.x/2.0.0.md b/docs/changes/2.x/2.0.0.md index 2d4b3b9cca..bb4eadec99 100644 --- a/docs/changes/2.x/2.0.0.md +++ b/docs/changes/2.x/2.0.0.md @@ -17,6 +17,7 @@ - bug: TemplateProcessor fix multiline values [@gimler](https://github.com/gimler) fixing [#268](https://github.com/PHPOffice/PHPWord/issues/268), [#2323](https://github.com/PHPOffice/PHPWord/issues/2323) and [#2486](https://github.com/PHPOffice/PHPWord/issues/2486) in [#2522](https://github.com/PHPOffice/PHPWord/pull/2522) - 32-bit Problem in PasswordEncoder [@oleibman](https://github.com/oleibman) fixing [#2550](https://github.com/PHPOffice/PHPWord/issues/2550) in [#2551](https://github.com/PHPOffice/PHPWord/pull/2551) - Typo : Fix hardcoded macro chars in TemplateProcessor method [@glafarge](https://github.com/glafarge) in [#2618](https://github.com/PHPOffice/PHPWord/pull/2618) +- XML Reader : Prevent fatal errors when opening corrupt files or "doc" files [@mmcev106](https://github.com/mmcev106) in [#2626](https://github.com/PHPOffice/PHPWord/pull/2626) ### Miscellaneous diff --git a/src/PhpWord/Shared/XMLReader.php b/src/PhpWord/Shared/XMLReader.php index 1c95a64426..e836607d29 100644 --- a/src/PhpWord/Shared/XMLReader.php +++ b/src/PhpWord/Shared/XMLReader.php @@ -61,7 +61,15 @@ public function getDomFromZip($zipFile, $xmlFile) } $zip = new ZipArchive(); - $zip->open($zipFile); + $openStatus = $zip->open($zipFile); + if ($openStatus !== true) { + /** + * Throw an exception since making further calls on the ZipArchive would cause a fatal error. + * This prevents fatal errors on corrupt archives and attempts to open old "doc" files. + */ + throw new Exception("The archive failed to load with the following error code: $openStatus"); + } + $content = $zip->getFromName(ltrim($xmlFile, '/')); $zip->close(); diff --git a/tests/PhpWordTests/Shared/XMLReaderTest.php b/tests/PhpWordTests/Shared/XMLReaderTest.php index 4cbe92a5e2..cc15c85f01 100644 --- a/tests/PhpWordTests/Shared/XMLReaderTest.php +++ b/tests/PhpWordTests/Shared/XMLReaderTest.php @@ -85,6 +85,33 @@ public function testThrowsExceptionOnNonExistingArchive(): void $reader->getDomFromZip($archiveFile, 'test.xml'); } + /** + * Test that read from invalid archive throws exception. + */ + public function testThrowsExceptionOnZipArchiveOpenErrors(): void + { + /** + * @var string + */ + $tempPath = tempnam(sys_get_temp_dir(), 'PhpWord'); + + // Simulate a corrupt archive + file_put_contents($tempPath, mt_rand()); + + $exceptionMessage = null; + + try { + $reader = new XMLReader(); + $reader->getDomFromZip($tempPath, 'test.xml'); + } catch (Exception $e) { + $exceptionMessage = $e->getMessage(); + } + + self::assertNotNull($exceptionMessage); + + unlink($tempPath); + } + /** * Test elements count. */