package/qa/cppunit/data/tdf163364.ods |binary package/qa/cppunit/test_zippackage.cxx | 28 ++++++++++++++++++++++++++++ package/source/zippackage/ZipPackage.cxx | 8 ++++++++ 3 files changed, 36 insertions(+)
New commits: commit 3efad499bf4f7623610a54f9f14622de4954352f Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Mon Oct 14 12:04:05 2024 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Mon Oct 14 15:01:41 2024 +0200 tdf#163364 package: ask to recover for this invalid ODF package Bugdoc has a data descriptor on a folder entry, which is very odd and entirely pointless. Which is also the first entry, so it's an invalid ODF package anyway. ZipPackageFolder throws UnknownPropertyException for "WasEncrypted", which results in General I/O error, but we want to ask the user if the file should be opened in recovery mode. (regression from commit 32cad89592ec04ab552399095c91dd76afb3002c) Change-Id: Iafe610d507cf92d2fd2e9c3040592c3e638a30dd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174889 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/package/qa/cppunit/data/tdf163364.ods b/package/qa/cppunit/data/tdf163364.ods new file mode 100644 index 000000000000..a772aebdbc7e Binary files /dev/null and b/package/qa/cppunit/data/tdf163364.ods differ diff --git a/package/qa/cppunit/test_zippackage.cxx b/package/qa/cppunit/test_zippackage.cxx index 624457ab7bcf..892f2979cd61 100644 --- a/package/qa/cppunit/test_zippackage.cxx +++ b/package/qa/cppunit/test_zippackage.cxx @@ -384,6 +384,34 @@ CPPUNIT_TEST_FIXTURE(ZipPackageTest, testZip64End) } } +CPPUNIT_TEST_FIXTURE(ZipPackageTest, testTdf163364) +{ + auto const url(m_directories.getURLFromSrc(u"/package/qa/cppunit/data/tdf163364.ods")); + uno::Sequence<uno::Any> const args{ + uno::Any(url), + uno::Any(beans::NamedValue("StorageFormat", uno::Any(embed::StorageFormats::PACKAGE))) + }; + + // don't load corrupted zip file + CPPUNIT_ASSERT_THROW(m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + ZipPackage, args, m_xContext), + css::packages::zip::ZipIOException); + + try + { + uno::Sequence<uno::Any> const args2{ + uno::Any(url), uno::Any(beans::NamedValue(u"RepairPackage"_ustr, uno::Any(true))), + uno::Any(beans::NamedValue("StorageFormat", uno::Any(embed::StorageFormats::ZIP))) + }; + m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(ZipPackage, args2, + m_xContext); + } + catch (css::packages::zip::ZipIOException const&) + { + // check that this doesn't crash, it doesn't matter if it succeeds or not + } +} + //CPPUNIT_TEST_SUITE_REGISTRATION(...); //CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index 0ddc0906e02a..371f37807be9 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -192,6 +192,14 @@ void ZipPackage::checkZipEntriesWithDD() { uno::Reference<XPropertySet> xStream; getByHierarchicalName(rEntry.sPath) >>= xStream; + uno::Reference<XServiceInfo> const xStreamSI{xStream, uno::UNO_QUERY_THROW}; + if (!xStreamSI->supportsService("com.sun.star.packages.PackageStream")) + { + SAL_INFO("package", "entry STORED with data descriptor is folder: \"" << rEntry.sPath << "\""); + throw ZipIOException( + THROW_WHERE + "entry STORED with data descriptor is folder"); + } if (!xStream->getPropertyValue("WasEncrypted").get<bool>()) { SAL_INFO("package", "entry STORED with data descriptor but not encrypted: \"" << rEntry.sPath << "\"");