Skip to content
This repository was archived by the owner on May 15, 2024. It is now read-only.

Commit

Permalink
Added parsing of Disk Start Number from Zip64 header if available
Browse files Browse the repository at this point in the history
  • Loading branch information
darkms committed Mar 17, 2020
1 parent bbea98c commit b292535
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 11 deletions.
17 changes: 17 additions & 0 deletions src/Zip Tests/Zip64Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,24 @@ public void Zip64_Winzip_Zip_Huge()
System.Threading.Thread.Sleep(120);
}

[TestMethod]
public void Zip64_ExtractZip64Archives()
{
File.Delete(@"C:\tmp\test.zip");
File.WriteAllText(@"C:\tmp\content.txt", "someContent");

using (ZipFile zipFile = new ZipFile(@"C:\tmp\test.zip"))
{
zipFile.AddFile(@"C:\tmp\content.txt");

zipFile.UseZip64WhenSaving = Zip64Option.Always;
zipFile.MaxOutputSegmentSize = 700 * 984540;
zipFile.Save();
}

var extractedZipFile = ZipFile.Read(@"C:\tmp\test.zip");
extractedZipFile.ExtractAll(@"C:\tmp\extracted", ExtractExistingFileAction.OverwriteSilently);
}

[TestMethod, Timeout((int)(2 * 60*60*1000))] // 60*60*1000 = 1 hr
public void Zip64_Winzip_Setup()
Expand Down
40 changes: 29 additions & 11 deletions src/Zip.Shared/ZipEntry.Read.cs
Original file line number Diff line number Diff line change
Expand Up @@ -615,14 +615,14 @@ private int ProcessExtraFieldZip64(byte[] buffer, int j, UInt16 dataSize, long p
dataSize, posn));
int remainingData = dataSize;

var slurp = new Func<Int64>( () => {
if (remainingData < 8)
throw new BadReadException(String.Format(" Missing data for ZIP64 extra field, position 0x{0:X16}", posn));
var x = BitConverter.ToInt64(buffer, j);
j+= 8;
remainingData -= 8;
return x;
});
var slurp = new Func<Int64>(() => {
if (remainingData < 8)
throw new BadReadException(String.Format(" Missing data for ZIP64 extra field, position 0x{0:X16}", posn));
var x = BitConverter.ToInt64(buffer, j);
j += 8;
remainingData -= 8;
return x;
});

if (this._UncompressedSize == 0xFFFFFFFF)
this._UncompressedSize = slurp();
Expand All @@ -633,9 +633,27 @@ private int ProcessExtraFieldZip64(byte[] buffer, int j, UInt16 dataSize, long p
if (this._RelativeOffsetOfLocalHeader == 0xFFFFFFFF)
this._RelativeOffsetOfLocalHeader = slurp();

// Ignore anything else. Potentially there are 4 more bytes for the
// disk start number. DotNetZip currently doesn't handle multi-disk
// archives.
// From PKWare docs:
// the fields MUST
// only appear if the corresponding Local or Central
// directory record field is set to 0xFFFF or 0xFFFFFFFF.
//
// Even though spec prescribes that it'll always be there
// if disk number in Local/Central entry header has a value
// of 65535 (0xFFFF), but let's only do so if the data is
// actually available in Zip64 header and tolerate a missing
// value here to offer more interopability with other
// less common tools.
//
// Note: this can happen even with non-spanning zips if
// Zip64 header is emmited (ex: file size over int32 range)
if (this._diskNumber == 0xFFFF && remainingData >= 4)
{
this._diskNumber = BitConverter.ToUInt32(buffer, j);
j += 4;
remainingData -= 4;
}

return j;
}

Expand Down

0 comments on commit b292535

Please sign in to comment.