package/qa/cppunit/data/tdf163818.odg  |binary
 package/qa/cppunit/test_zippackage.cxx |   22 ++++++++++++++++++++++
 package/source/zipapi/ZipFile.cxx      |   25 ++++++++++++++++---------
 3 files changed, 38 insertions(+), 9 deletions(-)

New commits:
commit 1fa83b45b15c773eb745c83680840a077987c47c
Author:     Michael Stahl <[email protected]>
AuthorDate: Fri Nov 8 18:08:58 2024 +0100
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Wed Jan 28 10:44:53 2026 +0100

    tdf#163818 package: fix recovery of zip entry local header with ...
    
    ... compressed size = 0.
    
    The problem is that vector::data() on a vector of size 0 returns
    nullptr, and osl_readFile into a nullptr buffer returns E_INVAL, which
    causes an exception to be thrown.
    
    Catch the exception, so that there is a chance to read the values from
    the data descriptor instead.
    
    (regression from commit 32cad89592ec04ab552399095c91dd76afb3002c
     and/or commit a6ad198d097fb4a503c8d5831d484ff46721134b)
    
    Change-Id: I9b2d9a930997146faf224d8033955b142fe93f58
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176289
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit 80cda6954adc88eac3b99171acafea004976915b)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198226
    Reviewed-by: Stephan Bergmann <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/package/qa/cppunit/data/tdf163818.odg 
b/package/qa/cppunit/data/tdf163818.odg
new file mode 100644
index 000000000000..a01424acc27d
Binary files /dev/null and b/package/qa/cppunit/data/tdf163818.odg differ
diff --git a/package/qa/cppunit/test_zippackage.cxx 
b/package/qa/cppunit/test_zippackage.cxx
index e8f3f910bb5a..354429576032 100644
--- a/package/qa/cppunit/test_zippackage.cxx
+++ b/package/qa/cppunit/test_zippackage.cxx
@@ -425,6 +425,28 @@ CPPUNIT_TEST_FIXTURE(ZipPackageTest, testTdf163341)
                                                                            
m_xContext);
 }
 
+CPPUNIT_TEST_FIXTURE(ZipPackageTest, testTdf163818)
+{
+    auto const 
url(m_directories.getURLFromSrc(u"/package/qa/cppunit/data/tdf163818.odg"));
+    uno::Sequence<uno::Any> const args{
+        uno::Any(url),
+        uno::Any(beans::NamedValue("StorageFormat", 
uno::Any(embed::StorageFormats::PACKAGE)))
+    };
+
+    // unclear if this should be allowed?
+    
CPPUNIT_ASSERT_THROW(m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+                             ZipPackage, args, m_xContext),
+                         css::packages::zip::ZipIOException);
+
+    // recovery should work
+    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);
+}
+
 //CPPUNIT_TEST_SUITE_REGISTRATION(...);
 //CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/package/source/zipapi/ZipFile.cxx 
b/package/source/zipapi/ZipFile.cxx
index 1723b8c1de30..778af131c624 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -1838,20 +1838,27 @@ bool ZipFile::checkSizeAndCRC( const ZipEntry& aEntry )
 {
     ::osl::MutexGuard aGuard( m_aMutexHolder->GetMutex() );
 
-    sal_Int32 nCRC = 0;
-    sal_Int64 nSize = 0;
+    try
+    {
+        sal_Int32 nCRC = 0;
+        sal_Int64 nSize = 0;
 
-    if( aEntry.nMethod == STORED )
-        return ( getCRC( aEntry.nOffset, aEntry.nSize ) == aEntry.nCrc );
+        if( aEntry.nMethod == STORED )
+            return ( getCRC( aEntry.nOffset, aEntry.nSize ) == aEntry.nCrc );
 
-    if (aEntry.nCompressedSize < 0)
+        if (aEntry.nCompressedSize < 0)
+        {
+            SAL_WARN("package", "bogus compressed size of: " << 
aEntry.nCompressedSize);
+            return false;
+        }
+
+        getSizeAndCRC( aEntry.nOffset, aEntry.nCompressedSize, &nSize, &nCRC );
+        return ( aEntry.nSize == nSize && aEntry.nCrc == nCRC );
+    }
+    catch (uno::Exception const&)
     {
-        SAL_WARN("package", "bogus compressed size of: " << 
aEntry.nCompressedSize);
         return false;
     }
-
-    getSizeAndCRC( aEntry.nOffset, aEntry.nCompressedSize, &nSize, &nCRC );
-    return ( aEntry.nSize == nSize && aEntry.nCrc == nCRC );
 }
 
 sal_Int32 ZipFile::getCRC( sal_Int64 nOffset, sal_Int64 nSize )

Reply via email to