Skip to content

Commit

Permalink
Merge pull request #6 from mihula/dev
Browse files Browse the repository at this point in the history
Zip: omit Disk Start Number from the Zip64 Central Directory Entry
  • Loading branch information
mihula authored Mar 13, 2024
2 parents f8837b1 + 5ce3732 commit b9e060e
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions src/Zip/ZipEntry.Write.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,11 @@ this file starts
* that have a header set in Zip64, but doesn't have -1 value in
* appropriate fields of the record itself.
*
* Currently we always set 'Relative Header' and 'Disk Start' inside
* the Extra block for Zip64, meaning that we also need to make sure
* that their non-Zip64 counterparts would be -1 (0xFFFFFFFF
* and 0xFFFF respectively), regardless of the fact if the value fits
* into uint32/uint16 range or not.
* Currently we always set 'Relative Header' inside the Extra block
* for Zip64 and 'Disk Start' when necessary, meaning that we also
* need to make sure that their non-Zip64 counterparts would be -1
* (0xFFFFFFFF and 0xFFFF respectively), regardless of the fact if
* the value fits into uint32/uint16 range or not.
*/
bytes[i++] = 0xFF;
bytes[i++] = 0xFF;
Expand Down Expand Up @@ -384,7 +384,20 @@ private byte[] ConstructExtraField(bool forCentralDirectory)
{
// add extra field for zip64 here
// workitem 7924
int sz = 4 + (forCentralDirectory ? 28 : 16);
int sz = 4 + (forCentralDirectory ? 24 : 16);
// for segmented ZIP, the disk number goes into the extra field
// and ends up as 0xFFFF in the central directory.
// this should match WriteCentralDirectoryEntry to avoid issues
// with tools and libraries that do not fully support Zip64
// (by not putting the disk number in the extra field when
// it can be avoided.)
bool segmented = (this._container.ZipFile != null) &&
(this._container.ZipFile.MaxOutputSegmentSize64 != 0);
bool diskNumberInExtraField = segmented &&
(_presumeZip64 || _diskNumber > 0xFFFF);
if (forCentralDirectory && diskNumberInExtraField)
sz += 4;

block = new byte[sz];
int i = 0;

Expand All @@ -402,7 +415,7 @@ private byte[] ConstructExtraField(bool forCentralDirectory)
}

// DataSize
block[i++] = (byte)(sz - 4); // decimal 28 or 16 (workitem 7924)
block[i++] = (byte)(sz - 4); // decimal 24/28 or 16 (workitem 7924)
block[i++] = 0x00;

// The actual metadata - we may or may not have real values yet...
Expand All @@ -423,8 +436,11 @@ private byte[] ConstructExtraField(bool forCentralDirectory)
Array.Copy(BitConverter.GetBytes(_RelativeOffsetOfLocalHeader), 0, block, i, 8);
i += 8;

// starting disk number
Array.Copy(BitConverter.GetBytes(_diskNumber), 0, block, i, 4);
if (diskNumberInExtraField)
{
// starting disk number
Array.Copy(BitConverter.GetBytes(_diskNumber), 0, block, i, 4);
}
}

listOfBlocks.Add(block);
Expand Down

0 comments on commit b9e060e

Please sign in to comment.