From c175ed565a7550f3f59ae723a06b854ecb6ef140 Mon Sep 17 00:00:00 2001 From: Richard Webb Date: Sun, 23 Jun 2019 14:13:00 +0100 Subject: [PATCH 1/2] Change ZipFile.ReadEntries to always look for the Zip64 central directory --- src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs index 3583d0ccc..003881988 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs @@ -3408,6 +3408,7 @@ private void ReadEntries() } bool isZip64 = false; + bool requireZip64 = false; // Check if zip64 header information is required. if ((thisDiskNumber == 0xffff) || @@ -3417,13 +3418,22 @@ private void ReadEntries() (centralDirSize == 0xffffffff) || (offsetOfCentralDir == 0xffffffff)) { - isZip64 = true; + requireZip64 = true; + } - long offset = LocateBlockWithSignature(ZipConstants.Zip64CentralDirLocatorSignature, locatedEndOfCentralDir, 0, 0x1000); - if (offset < 0) + // #357 - always check for the existance of the Zip64 central directory. + long locatedZip64EndOfCentralDir = LocateBlockWithSignature(ZipConstants.Zip64CentralDirLocatorSignature, locatedEndOfCentralDir, 0, 0x1000); + if (locatedZip64EndOfCentralDir < 0) + { + if (requireZip64) { + // This is only an error in cases where the Zip64 directory is required. throw new ZipException("Cannot find Zip64 locator"); } + } + else + { + isZip64 = true; // number of the disk with the start of the zip64 end of central directory 4 bytes // relative offset of the zip64 end of central directory record 8 bytes From 285a808a0252aee5ae2c03068d50aa90014fd59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20ma=CC=8Ase=CC=81n?= Date: Fri, 26 Jul 2019 15:20:20 +0200 Subject: [PATCH 2/2] Add test for Zip64 preference --- .../Zip/ZipCorruptionHandling.cs | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipCorruptionHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipCorruptionHandling.cs index f8dccfcbb..07d192fb0 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipCorruptionHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipCorruptionHandling.cs @@ -1,15 +1,12 @@ using System; using System.IO; -using System.Runtime.InteropServices; -using System.Text; using System.Threading; -using ICSharpCode.SharpZipLib; using ICSharpCode.SharpZipLib.Zip; using NUnit.Framework; namespace ICSharpCode.SharpZipLib.Tests.Zip { - public class ZipCorruptionHandling + public class ZipCorruptionHandling { const string TestFileZeroCodeLength = "UEsDBBQA+AAIANwyZ0U5T8HwjQAAAL8AAAAIABUAbGltZXJpY2t" + @@ -52,6 +49,23 @@ public void ZeroCodeLengthZipFile() }); } - } + const string TestFileBadCDGoodCD64 = @"UEsDBC0AAAAIANhy+k4cj+r8//////////8IABQAdGVzdGZpbGUBABAAAAA + AAAAAAAAUAAAAAAAAACtJLS5Jy8xJVUjOzytJzSsp5gIAUEsBAjMALQAAAAgA2HL6ThyP6vz//////////wgAFAAAAAAAA + AAAAAAAAAAAAHRlc3RmaWxlAQAQABIAAAAAAAAAFAAAAAAAAABQSwUGAAAAAAEAAQBKAAAATgAAAAAA"; + + [Test] + [Category("Zip")] + public void CorruptCentralDirWithCorrectZip64CD() + { + var fileBytes = Convert.FromBase64String(TestFileBadCDGoodCD64); + using (var ms = new MemoryStream(fileBytes)) + using (var zip = new ZipFile(ms)) + { + Assert.AreEqual(1, zip.Count); + Assert.AreNotEqual(0, zip[0].Size, "Uncompressed file size read from corrupt CentralDir instead of CD64"); + } + } + + } } \ No newline at end of file