Skip to content

Commit b9e060e

Browse files
authored
Merge pull request #6 from mihula/dev
Zip: omit Disk Start Number from the Zip64 Central Directory Entry
2 parents f8837b1 + 5ce3732 commit b9e060e

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

Diff for: src/Zip/ZipEntry.Write.cs

+25-9
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,11 @@ this file starts
230230
* that have a header set in Zip64, but doesn't have -1 value in
231231
* appropriate fields of the record itself.
232232
*
233-
* Currently we always set 'Relative Header' and 'Disk Start' inside
234-
* the Extra block for Zip64, meaning that we also need to make sure
235-
* that their non-Zip64 counterparts would be -1 (0xFFFFFFFF
236-
* and 0xFFFF respectively), regardless of the fact if the value fits
237-
* into uint32/uint16 range or not.
233+
* Currently we always set 'Relative Header' inside the Extra block
234+
* for Zip64 and 'Disk Start' when necessary, meaning that we also
235+
* need to make sure that their non-Zip64 counterparts would be -1
236+
* (0xFFFFFFFF and 0xFFFF respectively), regardless of the fact if
237+
* the value fits into uint32/uint16 range or not.
238238
*/
239239
bytes[i++] = 0xFF;
240240
bytes[i++] = 0xFF;
@@ -384,7 +384,20 @@ private byte[] ConstructExtraField(bool forCentralDirectory)
384384
{
385385
// add extra field for zip64 here
386386
// workitem 7924
387-
int sz = 4 + (forCentralDirectory ? 28 : 16);
387+
int sz = 4 + (forCentralDirectory ? 24 : 16);
388+
// for segmented ZIP, the disk number goes into the extra field
389+
// and ends up as 0xFFFF in the central directory.
390+
// this should match WriteCentralDirectoryEntry to avoid issues
391+
// with tools and libraries that do not fully support Zip64
392+
// (by not putting the disk number in the extra field when
393+
// it can be avoided.)
394+
bool segmented = (this._container.ZipFile != null) &&
395+
(this._container.ZipFile.MaxOutputSegmentSize64 != 0);
396+
bool diskNumberInExtraField = segmented &&
397+
(_presumeZip64 || _diskNumber > 0xFFFF);
398+
if (forCentralDirectory && diskNumberInExtraField)
399+
sz += 4;
400+
388401
block = new byte[sz];
389402
int i = 0;
390403

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

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

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

426-
// starting disk number
427-
Array.Copy(BitConverter.GetBytes(_diskNumber), 0, block, i, 4);
439+
if (diskNumberInExtraField)
440+
{
441+
// starting disk number
442+
Array.Copy(BitConverter.GetBytes(_diskNumber), 0, block, i, 4);
443+
}
428444
}
429445

430446
listOfBlocks.Add(block);

0 commit comments

Comments
 (0)