package/qa/cppunit/data/pass/no_usb_2024-11-06.xlsx |binary
 package/qa/cppunit/data/tdf163818.odg               |binary
 package/qa/cppunit/test_zippackage.cxx              |   28 ++++++++++++++++
 package/source/zipapi/ZipFile.cxx                   |   33 +++++++++++++-------
 4 files changed, 51 insertions(+), 10 deletions(-)

New commits:
commit e53b822fd4bca0ce6f5b2b95be3ed0a932e69fc8
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Nov 8 18:08:58 2024 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Nov 11 14:24:55 2024 +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 <michael.st...@allotropia.de>
    Tested-by: Jenkins
    (cherry picked from commit 80cda6954adc88eac3b99171acafea004976915b)

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 4eabcd9d424d..f7da6738ac97 100644
--- a/package/qa/cppunit/test_zippackage.cxx
+++ b/package/qa/cppunit/test_zippackage.cxx
@@ -432,6 +432,34 @@ CPPUNIT_TEST_FIXTURE(ZipPackageTest, testTdf163341)
     }
 }
 
+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 - except on this old branch, Zip64 code is missing 
so this file fails...
+    try
+    {
+        uno::Sequence<uno::Any> const args2{
+            uno::Any(url), uno::Any(beans::NamedValue(u"RepairPackage", 
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&)
+    {
+    }
+}
+
 //CPPUNIT_TEST_SUITE_REGISTRATION(...);
 //CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/package/source/zipapi/ZipFile.cxx 
b/package/source/zipapi/ZipFile.cxx
index 2f29e32fbc7e..b8194a0ab071 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -1621,20 +1621,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 )
commit 06bb30e1c8f5698ea34e51634a4eaf9ea9a2f9b0
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Thu Nov 7 13:50:01 2024 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Nov 11 11:54:39 2024 +0100

    tdf#162944 package: try to detect Zip64 via version
    
    https://rzymek.github.io/post/excel-zip64/ claims that it's sufficient
    for the version number to be 45 (4.5 - File uses ZIP64 format
    extensions) for Excel to read a zip entry's data descriptor as
    Zip64, while the Zip APPNOTE seems to require a zip64 extended
    information extra field to be present (see 4.3.9.2).
    
    Let's try to use the "version needed to extract" to be able to read
    zip files produced by Apache POI Zip64Mode.Always.
    
    Change-Id: I20f10471e3a85eb42d21c0cb08e36e345ef8fc9a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176211
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    Tested-by: Jenkins
    (cherry picked from commit 0f39e6fbb48dae29778c305ddd576d698a8251ad)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176220
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>
    (cherry picked from commit cc530b1789eff756eaaded4f21595af1a169b0ce)

diff --git a/package/qa/cppunit/data/pass/no_usb_2024-11-06.xlsx 
b/package/qa/cppunit/data/pass/no_usb_2024-11-06.xlsx
new file mode 100644
index 000000000000..edba1807717e
Binary files /dev/null and 
b/package/qa/cppunit/data/pass/no_usb_2024-11-06.xlsx differ
diff --git a/package/source/zipapi/ZipFile.cxx 
b/package/source/zipapi/ZipFile.cxx
index 6b253c665399..2f29e32fbc7e 100644
--- a/package/source/zipapi/ZipFile.cxx
+++ b/package/source/zipapi/ZipFile.cxx
@@ -765,7 +765,8 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
     // Just verify the path and calculate the data offset and otherwise
     // rely on the central directory info.
 
-    aGrabber.ReadInt16(); // version - ignore any mismatch (Maven created JARs)
+    // version - ignore any mismatch (Maven created JARs)
+    sal_uInt16 const nVersion = aGrabber.ReadUInt16();
     sal_uInt16 const nLocFlag = aGrabber.ReadUInt16(); // general purpose bit 
flag
     sal_uInt16 const nLocMethod = aGrabber.ReadUInt16(); // compression method
     // Do *not* compare timestamps, since MSO 2010 can produce documents
@@ -831,6 +832,11 @@ sal_uInt64 ZipFile::readLOC(ZipEntry &rEntry)
                 bBroken = true; // this version does NOT support Zip64 files
             }
         }
+        if (!isZip64 && 45 <= nVersion)
+        {
+            // for Excel compatibility, assume Zip64 - 
https://rzymek.github.io/post/excel-zip64/
+            isZip64 = true;
+        }
 
         // Just plain ignore bits 1 & 2 of the flag field - they are either
         // purely informative, or even fully undefined (depending on method).

Reply via email to