@@ -230,11 +230,11 @@ this file starts
230
230
* that have a header set in Zip64, but doesn't have -1 value in
231
231
* appropriate fields of the record itself.
232
232
*
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.
238
238
*/
239
239
bytes [ i ++ ] = 0xFF ;
240
240
bytes [ i ++ ] = 0xFF ;
@@ -384,7 +384,20 @@ private byte[] ConstructExtraField(bool forCentralDirectory)
384
384
{
385
385
// add extra field for zip64 here
386
386
// 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
+
388
401
block = new byte [ sz ] ;
389
402
int i = 0 ;
390
403
@@ -402,7 +415,7 @@ private byte[] ConstructExtraField(bool forCentralDirectory)
402
415
}
403
416
404
417
// 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)
406
419
block [ i ++ ] = 0x00 ;
407
420
408
421
// The actual metadata - we may or may not have real values yet...
@@ -423,8 +436,11 @@ private byte[] ConstructExtraField(bool forCentralDirectory)
423
436
Array . Copy ( BitConverter . GetBytes ( _RelativeOffsetOfLocalHeader ) , 0 , block , i , 8 ) ;
424
437
i += 8 ;
425
438
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
+ }
428
444
}
429
445
430
446
listOfBlocks . Add ( block ) ;
0 commit comments