Skip to content

Commit

Permalink
Merge #408: When searching for the Zip64 end of central directory loc…
Browse files Browse the repository at this point in the history
…ator, pay attention to its fixed size

* Add a ZipConstants entry for the size of the zip64 end of central directory locator
* When looking for Zip64CentralDirLocatorSignature, take account of the blocks fixed size. refs #403/#375
* Add a simple test case for issue 403
  • Loading branch information
Numpsy authored and piksel committed Jan 27, 2020
1 parent 20c10a5 commit 6ee0f12
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,11 @@ public static class ZipConstants
[Obsolete("Use CryptoHeaderSize instead")]
public const int CRYPTO_HEADER_SIZE = 12;

/// <summary>
/// The size of the Zip64 central directory locator.
/// </summary>
public const int Zip64EndOfCentralDirectoryLocatorSize = 20;

#endregion Header Sizes

#region Header Signatures
Expand Down
12 changes: 10 additions & 2 deletions src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3427,8 +3427,16 @@ private void ReadEntries()
}

// #357 - always check for the existance of the Zip64 central directory.
long locatedZip64EndOfCentralDir = LocateBlockWithSignature(ZipConstants.Zip64CentralDirLocatorSignature, locatedEndOfCentralDir, 0, 0x1000);
if (locatedZip64EndOfCentralDir < 0)
// #403 - Take account of the fixed size of the locator when searching.
// Subtract from locatedEndOfCentralDir so that the endLocation is the location of EndOfCentralDirectorySignature,
// rather than the data following the signature.
long locatedZip64EndOfCentralDirLocator = LocateBlockWithSignature(
ZipConstants.Zip64CentralDirLocatorSignature,
locatedEndOfCentralDir - 4,
ZipConstants.Zip64EndOfCentralDirectoryLocatorSize,
0);

if (locatedZip64EndOfCentralDirLocator < 0)
{
if (requireZip64)
{
Expand Down
35 changes: 35 additions & 0 deletions test/ICSharpCode.SharpZipLib.Tests/Zip/ZipFileHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,41 @@ public void Zip64Update()
}
}

/// <summary>
/// Test for issue #403 - zip64 locator signature bytes being present in a contained file,
/// when the outer zip file isn't using zip64
/// </summary>
[Test]
[Category("Zip")]
public void FakeZip64Locator()
{
using (var memStream = new MemoryStream())
{
// set the file contents to the zip 64 directory locator signature
var locatorValue = ZipConstants.Zip64CentralDirLocatorSignature;
var locatorBytes = new byte[] { (byte)(locatorValue & 0xff), (byte)((locatorValue >> 8) & 0xff), (byte)((locatorValue >> 16) & 0xff), (byte)((locatorValue >> 24) & 0xff) };

using (ZipFile f = new ZipFile(memStream, leaveOpen: true))
{
var m = new MemoryDataSource(locatorBytes);

// Add the entry - set compression method to stored so the signature bytes remain as expected
f.BeginUpdate(new MemoryArchiveStorage());
f.Add(m, "a.dat", CompressionMethod.Stored);
f.CommitUpdate();
Assert.IsTrue(f.TestArchive(true));
}

memStream.Seek(0, SeekOrigin.Begin);

// Check that the archive is readable.
using (ZipFile f = new ZipFile(memStream, leaveOpen: true))
{
Assert.That(f.Count, Is.EqualTo(1), "Archive should have 1 entry");
}
}
}

[Test]
[Category("Zip")]
[Explicit]
Expand Down

0 comments on commit 6ee0f12

Please sign in to comment.