@zip.js/zip.js 2.6.60 → 2.6.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs CHANGED
@@ -8531,12 +8531,9 @@ class ZipReader {
8531
8531
  const commentOffset = endOfDirectoryInfo.offset;
8532
8532
  const commentLength = getUint16(endOfDirectoryView, 20);
8533
8533
  const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
8534
- const lastDiskNumber = getUint16(endOfDirectoryView, 4);
8534
+ let lastDiskNumber = getUint16(endOfDirectoryView, 4);
8535
8535
  const expectedLastDiskNumber = reader.lastDiskNumber || 0;
8536
8536
  let diskNumber = getUint16(endOfDirectoryView, 6);
8537
- if (expectedLastDiskNumber != lastDiskNumber) {
8538
- throw new Error(ERR_SPLIT_ZIP_FILE);
8539
- }
8540
8537
  let filesLength = getUint16(endOfDirectoryView, 8);
8541
8538
  let prependedDataLength = 0;
8542
8539
  let startOffset = 0;
@@ -8560,8 +8557,11 @@ class ZipReader {
8560
8557
  if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
8561
8558
  throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
8562
8559
  }
8560
+ if (lastDiskNumber == MAX_16_BITS) {
8561
+ lastDiskNumber = getUint32(endOfDirectoryView, 16);
8562
+ }
8563
8563
  if (diskNumber == MAX_16_BITS) {
8564
- diskNumber = getUint32(endOfDirectoryView, 16);
8564
+ diskNumber = getUint32(endOfDirectoryView, 20);
8565
8565
  }
8566
8566
  if (filesLength == MAX_16_BITS) {
8567
8567
  filesLength = getBigUint64(endOfDirectoryView, 32);
@@ -8571,6 +8571,9 @@ class ZipReader {
8571
8571
  }
8572
8572
  directoryDataOffset -= directoryDataLength;
8573
8573
  }
8574
+ if (expectedLastDiskNumber != lastDiskNumber) {
8575
+ throw new Error(ERR_SPLIT_ZIP_FILE);
8576
+ }
8574
8577
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
8575
8578
  throw new Error(ERR_BAD_FORMAT);
8576
8579
  }
@@ -9067,7 +9070,6 @@ const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
9067
9070
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
9068
9071
 
9069
9072
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
9070
- const EXTRAFIELD_LENGTH_ZIP64 = 28;
9071
9073
 
9072
9074
  let workers = 0;
9073
9075
  const pendingEntries = [];
@@ -9210,6 +9212,7 @@ async function addFile(zipWriter, name, reader, options) {
9210
9212
  let maximumCompressedSize = 0;
9211
9213
  let maximumEntrySize = 0;
9212
9214
  let uncompressedSize = 0;
9215
+ const zip64Enabled = zip64 === true;
9213
9216
  if (reader) {
9214
9217
  reader = initReader(reader);
9215
9218
  await initStream(reader);
@@ -9225,10 +9228,12 @@ async function addFile(zipWriter, name, reader, options) {
9225
9228
  }
9226
9229
  }
9227
9230
  const { diskOffset, diskNumber, maxSize } = zipWriter.writer;
9228
- if (zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset >= MAX_32_BITS ||
9229
- uncompressedSize >= MAX_32_BITS ||
9230
- maximumCompressedSize >= MAX_32_BITS ||
9231
- diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) >= MAX_16_BITS) {
9231
+ const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
9232
+ const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
9233
+ const zip64Offset = zip64Enabled || zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset >= MAX_32_BITS;
9234
+ const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
9235
+ const zip64DiskNumberStart = (supportZip64SplitFile && zip64Enabled) || diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) >= MAX_16_BITS;
9236
+ if (zip64Offset || zip64UncompressedSize || zip64CompressedSize || zip64DiskNumberStart) {
9232
9237
  if (zip64 === false || !keepOrder) {
9233
9238
  throw new Error(ERR_UNSUPPORTED_FORMAT);
9234
9239
  } else {
@@ -9246,6 +9251,10 @@ async function addFile(zipWriter, name, reader, options) {
9246
9251
  creationDate,
9247
9252
  rawExtraField,
9248
9253
  zip64,
9254
+ zip64UncompressedSize,
9255
+ zip64CompressedSize,
9256
+ zip64Offset,
9257
+ zip64DiskNumberStart,
9249
9258
  password,
9250
9259
  level,
9251
9260
  useWebWorkers,
@@ -9343,7 +9352,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
9343
9352
  await requestLockWriter();
9344
9353
  writingBufferedEntryData = true;
9345
9354
  if (!dataDescriptor) {
9346
- blob = await writeMissingHeaderInfo(fileEntry, blob, writable, options);
9355
+ blob = await writeExtraHeaderInfo(fileEntry, blob, writable, options);
9347
9356
  }
9348
9357
  await skipDiskIfNeeded(writable);
9349
9358
  fileEntry.diskNumberStart = writer.diskNumber;
@@ -9354,7 +9363,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
9354
9363
  }
9355
9364
  fileEntry.offset = zipWriter.offset - diskOffset;
9356
9365
  if (fileEntry.zip64) {
9357
- setZip64OffsetInfo(fileEntry);
9366
+ setZip64ExtraInfo(fileEntry, options);
9358
9367
  } else if (fileEntry.offset >= MAX_32_BITS) {
9359
9368
  throw new Error(ERR_UNSUPPORTED_FORMAT);
9360
9369
  }
@@ -9392,7 +9401,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
9392
9401
 
9393
9402
  async function requestLockWriter() {
9394
9403
  zipWriter.writerLocked = true;
9395
- const { lockWriter } = zipWriter;
9404
+ const { lockWriter } = zipWriter;
9396
9405
  zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
9397
9406
  zipWriter.writerLocked = false;
9398
9407
  resolve();
@@ -9434,6 +9443,10 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
9434
9443
  password,
9435
9444
  level,
9436
9445
  zip64,
9446
+ zip64UncompressedSize,
9447
+ zip64CompressedSize,
9448
+ zip64Offset,
9449
+ zip64DiskNumberStart,
9437
9450
  zipCrypto,
9438
9451
  dataDescriptor,
9439
9452
  directory,
@@ -9506,7 +9519,25 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
9506
9519
  } else {
9507
9520
  await writeData(writable, localHeaderArray);
9508
9521
  }
9509
- const rawExtraFieldZip64 = zip64 ? new Uint8Array(EXTRAFIELD_LENGTH_ZIP64 + 4) : new Uint8Array();
9522
+ let rawExtraFieldZip64;
9523
+ if (zip64) {
9524
+ let rawExtraFieldZip64Length = 4;
9525
+ if (zip64UncompressedSize) {
9526
+ rawExtraFieldZip64Length += 8;
9527
+ }
9528
+ if (zip64CompressedSize) {
9529
+ rawExtraFieldZip64Length += 8;
9530
+ }
9531
+ if (zip64Offset) {
9532
+ rawExtraFieldZip64Length += 8;
9533
+ }
9534
+ if (zip64DiskNumberStart) {
9535
+ rawExtraFieldZip64Length += 4;
9536
+ }
9537
+ rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length);
9538
+ } else {
9539
+ rawExtraFieldZip64 = new Uint8Array();
9540
+ }
9510
9541
  if (reader) {
9511
9542
  setEntryInfo({
9512
9543
  signature,
@@ -9521,6 +9552,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
9521
9552
  await writeData(writable, dataDescriptorArray);
9522
9553
  }
9523
9554
  Object.assign(fileEntry, {
9555
+ uncompressedSize,
9524
9556
  compressedSize,
9525
9557
  lastModDate,
9526
9558
  rawLastModDate,
@@ -9532,7 +9564,11 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
9532
9564
  version,
9533
9565
  headerArray,
9534
9566
  signature,
9535
- rawExtraFieldZip64
9567
+ rawExtraFieldZip64,
9568
+ zip64UncompressedSize,
9569
+ zip64CompressedSize,
9570
+ zip64Offset,
9571
+ zip64DiskNumberStart
9536
9572
  });
9537
9573
  return fileEntry;
9538
9574
  }
@@ -9709,6 +9745,8 @@ function setEntryInfo(entryInfo, options) {
9709
9745
  } = dataDescriptorInfo;
9710
9746
  const {
9711
9747
  zip64,
9748
+ zip64UncompressedSize,
9749
+ zip64CompressedSize,
9712
9750
  zipCrypto,
9713
9751
  dataDescriptor
9714
9752
  } = options;
@@ -9721,11 +9759,17 @@ function setEntryInfo(entryInfo, options) {
9721
9759
  if (zip64) {
9722
9760
  const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
9723
9761
  setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
9724
- setUint16(rawExtraFieldZip64View, 2, EXTRAFIELD_LENGTH_ZIP64);
9725
- setUint32(headerView, 14, MAX_32_BITS);
9726
- setBigUint64(rawExtraFieldZip64View, 12, BigInt(compressedSize));
9727
- setUint32(headerView, 18, MAX_32_BITS);
9728
- setBigUint64(rawExtraFieldZip64View, 4, BigInt(uncompressedSize));
9762
+ setUint16(rawExtraFieldZip64View, 2, rawExtraFieldZip64.length - 4);
9763
+ let rawExtraFieldZip64Offset = 4;
9764
+ if (zip64UncompressedSize) {
9765
+ setUint32(headerView, 18, MAX_32_BITS);
9766
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
9767
+ rawExtraFieldZip64Offset += 8;
9768
+ }
9769
+ if (zip64CompressedSize) {
9770
+ setUint32(headerView, 14, MAX_32_BITS);
9771
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
9772
+ }
9729
9773
  if (dataDescriptor) {
9730
9774
  setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
9731
9775
  setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
@@ -9740,7 +9784,7 @@ function setEntryInfo(entryInfo, options) {
9740
9784
  }
9741
9785
  }
9742
9786
 
9743
- async function writeMissingHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
9787
+ async function writeExtraHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
9744
9788
  const arrayBuffer = await sliceAsArrayBuffer(entryData, 0, 26);
9745
9789
  const arrayBufferView = new DataView(arrayBuffer);
9746
9790
  if (!fileEntry.encrypted || zipCrypto) {
@@ -9757,11 +9801,24 @@ async function writeMissingHeaderInfo(fileEntry, entryData, writable, { zipCrypt
9757
9801
  return entryData.slice(arrayBuffer.byteLength);
9758
9802
  }
9759
9803
 
9760
- function setZip64OffsetInfo(fileEntry) {
9804
+ function setZip64ExtraInfo(fileEntry, options) {
9761
9805
  const { rawExtraFieldZip64, offset, diskNumberStart } = fileEntry;
9806
+ const { zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart } = options;
9762
9807
  const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
9763
- setBigUint64(rawExtraFieldZip64View, 20, BigInt(offset));
9764
- setUint32(rawExtraFieldZip64View, 28, diskNumberStart);
9808
+ let rawExtraFieldZip64Offset = 4;
9809
+ if (zip64UncompressedSize) {
9810
+ rawExtraFieldZip64Offset += 8;
9811
+ }
9812
+ if (zip64CompressedSize) {
9813
+ rawExtraFieldZip64Offset += 8;
9814
+ }
9815
+ if (zip64Offset) {
9816
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
9817
+ rawExtraFieldZip64Offset += 8;
9818
+ }
9819
+ if (zip64DiskNumberStart) {
9820
+ setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
9821
+ }
9765
9822
  }
9766
9823
 
9767
9824
  async function closeFile(zipWriter, comment, options) {
@@ -9808,12 +9865,18 @@ async function closeFile(zipWriter, comment, options) {
9808
9865
  headerArray,
9809
9866
  directory,
9810
9867
  zip64,
9868
+ zip64UncompressedSize,
9869
+ zip64CompressedSize,
9870
+ zip64DiskNumberStart,
9871
+ zip64Offset,
9811
9872
  msDosCompatible,
9812
9873
  internalFileAttribute,
9813
9874
  externalFileAttribute,
9814
9875
  extendedTimestamp,
9815
9876
  lastModDate,
9816
- diskNumberStart
9877
+ diskNumberStart,
9878
+ uncompressedSize,
9879
+ compressedSize
9817
9880
  } = fileEntry;
9818
9881
  let rawExtraFieldExtendedTimestamp;
9819
9882
  if (extendedTimestamp) {
@@ -9829,17 +9892,24 @@ async function closeFile(zipWriter, comment, options) {
9829
9892
  const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
9830
9893
  setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
9831
9894
  setUint16(directoryView, offset + 4, versionMadeBy);
9895
+ const headerView = getDataView(headerArray);
9896
+ if (!zip64UncompressedSize) {
9897
+ setUint32(headerView, 18, uncompressedSize);
9898
+ }
9899
+ if (!zip64CompressedSize) {
9900
+ setUint32(headerView, 14, compressedSize);
9901
+ }
9832
9902
  arraySet(directoryArray, headerArray, offset + 6);
9833
9903
  setUint16(directoryView, offset + 30, extraFieldLength);
9834
9904
  setUint16(directoryView, offset + 32, getLength(rawComment));
9835
- setUint16(directoryView, offset + 34, zip64 ? MAX_16_BITS : diskNumberStart);
9905
+ setUint16(directoryView, offset + 34, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
9836
9906
  setUint16(directoryView, offset + 36, internalFileAttribute);
9837
9907
  if (externalFileAttribute) {
9838
9908
  setUint32(directoryView, offset + 38, externalFileAttribute);
9839
9909
  } else if (directory && msDosCompatible) {
9840
9910
  setUint8(directoryView, offset + 38, FILE_ATTR_MSDOS_DIR_MASK);
9841
9911
  }
9842
- setUint32(directoryView, offset + 42, zip64 ? MAX_32_BITS : fileEntryOffset);
9912
+ setUint32(directoryView, offset + 42, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
9843
9913
  arraySet(directoryArray, rawFilename, offset + 46);
9844
9914
  arraySet(directoryArray, rawExtraFieldZip64, offset + 46 + getLength(rawFilename));
9845
9915
  arraySet(directoryArray, rawExtraFieldAES, offset + 46 + getLength(rawFilename, rawExtraFieldZip64));
@@ -9893,7 +9963,11 @@ async function closeFile(zipWriter, comment, options) {
9893
9963
  setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
9894
9964
  setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength));
9895
9965
  setUint32(endOfdirectoryView, 72, lastDiskNumber + 1);
9896
- diskNumber = MAX_16_BITS;
9966
+ const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
9967
+ if (supportZip64SplitFile) {
9968
+ lastDiskNumber = MAX_16_BITS;
9969
+ diskNumber = MAX_16_BITS;
9970
+ }
9897
9971
  filesLength = MAX_16_BITS;
9898
9972
  directoryOffset = MAX_32_BITS;
9899
9973
  directoryDataLength = MAX_32_BITS;
package/index.d.ts CHANGED
@@ -1106,6 +1106,12 @@ interface ZipWriterConstructorOptions {
1106
1106
  * @defaultValue 0
1107
1107
  */
1108
1108
  internalFileAttribute?: number
1109
+ /**
1110
+ * `false` to never write disk numbers in zip64 data.
1111
+ *
1112
+ * @defaultValue true
1113
+ */
1114
+ supportZip64SplitFile?: boolean
1109
1115
  }
1110
1116
 
1111
1117
  /**
@@ -165,12 +165,9 @@ class ZipReader {
165
165
  const commentOffset = endOfDirectoryInfo.offset;
166
166
  const commentLength = getUint16(endOfDirectoryView, 20);
167
167
  const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
168
- const lastDiskNumber = getUint16(endOfDirectoryView, 4);
168
+ let lastDiskNumber = getUint16(endOfDirectoryView, 4);
169
169
  const expectedLastDiskNumber = reader.lastDiskNumber || 0;
170
170
  let diskNumber = getUint16(endOfDirectoryView, 6);
171
- if (expectedLastDiskNumber != lastDiskNumber) {
172
- throw new Error(ERR_SPLIT_ZIP_FILE);
173
- }
174
171
  let filesLength = getUint16(endOfDirectoryView, 8);
175
172
  let prependedDataLength = 0;
176
173
  let startOffset = 0;
@@ -194,8 +191,11 @@ class ZipReader {
194
191
  if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
195
192
  throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
196
193
  }
194
+ if (lastDiskNumber == MAX_16_BITS) {
195
+ lastDiskNumber = getUint32(endOfDirectoryView, 16);
196
+ }
197
197
  if (diskNumber == MAX_16_BITS) {
198
- diskNumber = getUint32(endOfDirectoryView, 16);
198
+ diskNumber = getUint32(endOfDirectoryView, 20);
199
199
  }
200
200
  if (filesLength == MAX_16_BITS) {
201
201
  filesLength = getBigUint64(endOfDirectoryView, 32);
@@ -205,6 +205,9 @@ class ZipReader {
205
205
  }
206
206
  directoryDataOffset -= directoryDataLength;
207
207
  }
208
+ if (expectedLastDiskNumber != lastDiskNumber) {
209
+ throw new Error(ERR_SPLIT_ZIP_FILE);
210
+ }
208
211
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
209
212
  throw new Error(ERR_BAD_FORMAT);
210
213
  }
@@ -101,7 +101,6 @@ const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
101
101
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
102
102
 
103
103
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
104
- const EXTRAFIELD_LENGTH_ZIP64 = 28;
105
104
 
106
105
  let workers = 0;
107
106
  const pendingEntries = [];
@@ -257,6 +256,7 @@ async function addFile(zipWriter, name, reader, options) {
257
256
  let maximumCompressedSize = 0;
258
257
  let maximumEntrySize = 0;
259
258
  let uncompressedSize = 0;
259
+ const zip64Enabled = zip64 === true;
260
260
  if (reader) {
261
261
  reader = initReader(reader);
262
262
  await initStream(reader);
@@ -272,10 +272,12 @@ async function addFile(zipWriter, name, reader, options) {
272
272
  }
273
273
  }
274
274
  const { diskOffset, diskNumber, maxSize } = zipWriter.writer;
275
- if (zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset >= MAX_32_BITS ||
276
- uncompressedSize >= MAX_32_BITS ||
277
- maximumCompressedSize >= MAX_32_BITS ||
278
- diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) >= MAX_16_BITS) {
275
+ const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
276
+ const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
277
+ const zip64Offset = zip64Enabled || zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset >= MAX_32_BITS;
278
+ const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
279
+ const zip64DiskNumberStart = (supportZip64SplitFile && zip64Enabled) || diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) >= MAX_16_BITS;
280
+ if (zip64Offset || zip64UncompressedSize || zip64CompressedSize || zip64DiskNumberStart) {
279
281
  if (zip64 === false || !keepOrder) {
280
282
  throw new Error(ERR_UNSUPPORTED_FORMAT);
281
283
  } else {
@@ -293,6 +295,10 @@ async function addFile(zipWriter, name, reader, options) {
293
295
  creationDate,
294
296
  rawExtraField,
295
297
  zip64,
298
+ zip64UncompressedSize,
299
+ zip64CompressedSize,
300
+ zip64Offset,
301
+ zip64DiskNumberStart,
296
302
  password,
297
303
  level,
298
304
  useWebWorkers,
@@ -390,7 +396,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
390
396
  await requestLockWriter();
391
397
  writingBufferedEntryData = true;
392
398
  if (!dataDescriptor) {
393
- blob = await writeMissingHeaderInfo(fileEntry, blob, writable, options);
399
+ blob = await writeExtraHeaderInfo(fileEntry, blob, writable, options);
394
400
  }
395
401
  await skipDiskIfNeeded(writable);
396
402
  fileEntry.diskNumberStart = writer.diskNumber;
@@ -401,7 +407,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
401
407
  }
402
408
  fileEntry.offset = zipWriter.offset - diskOffset;
403
409
  if (fileEntry.zip64) {
404
- setZip64OffsetInfo(fileEntry);
410
+ setZip64ExtraInfo(fileEntry, options);
405
411
  } else if (fileEntry.offset >= MAX_32_BITS) {
406
412
  throw new Error(ERR_UNSUPPORTED_FORMAT);
407
413
  }
@@ -439,7 +445,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
439
445
 
440
446
  async function requestLockWriter() {
441
447
  zipWriter.writerLocked = true;
442
- const { lockWriter } = zipWriter;
448
+ const { lockWriter } = zipWriter;
443
449
  zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
444
450
  zipWriter.writerLocked = false;
445
451
  resolve();
@@ -481,6 +487,10 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
481
487
  password,
482
488
  level,
483
489
  zip64,
490
+ zip64UncompressedSize,
491
+ zip64CompressedSize,
492
+ zip64Offset,
493
+ zip64DiskNumberStart,
484
494
  zipCrypto,
485
495
  dataDescriptor,
486
496
  directory,
@@ -553,7 +563,25 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
553
563
  } else {
554
564
  await writeData(writable, localHeaderArray);
555
565
  }
556
- const rawExtraFieldZip64 = zip64 ? new Uint8Array(EXTRAFIELD_LENGTH_ZIP64 + 4) : new Uint8Array();
566
+ let rawExtraFieldZip64;
567
+ if (zip64) {
568
+ let rawExtraFieldZip64Length = 4;
569
+ if (zip64UncompressedSize) {
570
+ rawExtraFieldZip64Length += 8;
571
+ }
572
+ if (zip64CompressedSize) {
573
+ rawExtraFieldZip64Length += 8;
574
+ }
575
+ if (zip64Offset) {
576
+ rawExtraFieldZip64Length += 8;
577
+ }
578
+ if (zip64DiskNumberStart) {
579
+ rawExtraFieldZip64Length += 4;
580
+ }
581
+ rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length);
582
+ } else {
583
+ rawExtraFieldZip64 = new Uint8Array();
584
+ }
557
585
  if (reader) {
558
586
  setEntryInfo({
559
587
  signature,
@@ -568,6 +596,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
568
596
  await writeData(writable, dataDescriptorArray);
569
597
  }
570
598
  Object.assign(fileEntry, {
599
+ uncompressedSize,
571
600
  compressedSize,
572
601
  lastModDate,
573
602
  rawLastModDate,
@@ -579,7 +608,11 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
579
608
  version,
580
609
  headerArray,
581
610
  signature,
582
- rawExtraFieldZip64
611
+ rawExtraFieldZip64,
612
+ zip64UncompressedSize,
613
+ zip64CompressedSize,
614
+ zip64Offset,
615
+ zip64DiskNumberStart
583
616
  });
584
617
  return fileEntry;
585
618
  }
@@ -756,6 +789,8 @@ function setEntryInfo(entryInfo, options) {
756
789
  } = dataDescriptorInfo;
757
790
  const {
758
791
  zip64,
792
+ zip64UncompressedSize,
793
+ zip64CompressedSize,
759
794
  zipCrypto,
760
795
  dataDescriptor
761
796
  } = options;
@@ -768,11 +803,17 @@ function setEntryInfo(entryInfo, options) {
768
803
  if (zip64) {
769
804
  const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
770
805
  setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
771
- setUint16(rawExtraFieldZip64View, 2, EXTRAFIELD_LENGTH_ZIP64);
772
- setUint32(headerView, 14, MAX_32_BITS);
773
- setBigUint64(rawExtraFieldZip64View, 12, BigInt(compressedSize));
774
- setUint32(headerView, 18, MAX_32_BITS);
775
- setBigUint64(rawExtraFieldZip64View, 4, BigInt(uncompressedSize));
806
+ setUint16(rawExtraFieldZip64View, 2, rawExtraFieldZip64.length - 4);
807
+ let rawExtraFieldZip64Offset = 4;
808
+ if (zip64UncompressedSize) {
809
+ setUint32(headerView, 18, MAX_32_BITS);
810
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
811
+ rawExtraFieldZip64Offset += 8;
812
+ }
813
+ if (zip64CompressedSize) {
814
+ setUint32(headerView, 14, MAX_32_BITS);
815
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
816
+ }
776
817
  if (dataDescriptor) {
777
818
  setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
778
819
  setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
@@ -787,7 +828,7 @@ function setEntryInfo(entryInfo, options) {
787
828
  }
788
829
  }
789
830
 
790
- async function writeMissingHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
831
+ async function writeExtraHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
791
832
  const arrayBuffer = await sliceAsArrayBuffer(entryData, 0, 26);
792
833
  const arrayBufferView = new DataView(arrayBuffer);
793
834
  if (!fileEntry.encrypted || zipCrypto) {
@@ -804,11 +845,24 @@ async function writeMissingHeaderInfo(fileEntry, entryData, writable, { zipCrypt
804
845
  return entryData.slice(arrayBuffer.byteLength);
805
846
  }
806
847
 
807
- function setZip64OffsetInfo(fileEntry) {
848
+ function setZip64ExtraInfo(fileEntry, options) {
808
849
  const { rawExtraFieldZip64, offset, diskNumberStart } = fileEntry;
850
+ const { zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart } = options;
809
851
  const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
810
- setBigUint64(rawExtraFieldZip64View, 20, BigInt(offset));
811
- setUint32(rawExtraFieldZip64View, 28, diskNumberStart);
852
+ let rawExtraFieldZip64Offset = 4;
853
+ if (zip64UncompressedSize) {
854
+ rawExtraFieldZip64Offset += 8;
855
+ }
856
+ if (zip64CompressedSize) {
857
+ rawExtraFieldZip64Offset += 8;
858
+ }
859
+ if (zip64Offset) {
860
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
861
+ rawExtraFieldZip64Offset += 8;
862
+ }
863
+ if (zip64DiskNumberStart) {
864
+ setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
865
+ }
812
866
  }
813
867
 
814
868
  async function closeFile(zipWriter, comment, options) {
@@ -855,12 +909,18 @@ async function closeFile(zipWriter, comment, options) {
855
909
  headerArray,
856
910
  directory,
857
911
  zip64,
912
+ zip64UncompressedSize,
913
+ zip64CompressedSize,
914
+ zip64DiskNumberStart,
915
+ zip64Offset,
858
916
  msDosCompatible,
859
917
  internalFileAttribute,
860
918
  externalFileAttribute,
861
919
  extendedTimestamp,
862
920
  lastModDate,
863
- diskNumberStart
921
+ diskNumberStart,
922
+ uncompressedSize,
923
+ compressedSize
864
924
  } = fileEntry;
865
925
  let rawExtraFieldExtendedTimestamp;
866
926
  if (extendedTimestamp) {
@@ -876,17 +936,24 @@ async function closeFile(zipWriter, comment, options) {
876
936
  const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
877
937
  setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
878
938
  setUint16(directoryView, offset + 4, versionMadeBy);
939
+ const headerView = getDataView(headerArray);
940
+ if (!zip64UncompressedSize) {
941
+ setUint32(headerView, 18, uncompressedSize);
942
+ }
943
+ if (!zip64CompressedSize) {
944
+ setUint32(headerView, 14, compressedSize);
945
+ }
879
946
  arraySet(directoryArray, headerArray, offset + 6);
880
947
  setUint16(directoryView, offset + 30, extraFieldLength);
881
948
  setUint16(directoryView, offset + 32, getLength(rawComment));
882
- setUint16(directoryView, offset + 34, zip64 ? MAX_16_BITS : diskNumberStart);
949
+ setUint16(directoryView, offset + 34, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
883
950
  setUint16(directoryView, offset + 36, internalFileAttribute);
884
951
  if (externalFileAttribute) {
885
952
  setUint32(directoryView, offset + 38, externalFileAttribute);
886
953
  } else if (directory && msDosCompatible) {
887
954
  setUint8(directoryView, offset + 38, FILE_ATTR_MSDOS_DIR_MASK);
888
955
  }
889
- setUint32(directoryView, offset + 42, zip64 ? MAX_32_BITS : fileEntryOffset);
956
+ setUint32(directoryView, offset + 42, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
890
957
  arraySet(directoryArray, rawFilename, offset + 46);
891
958
  arraySet(directoryArray, rawExtraFieldZip64, offset + 46 + getLength(rawFilename));
892
959
  arraySet(directoryArray, rawExtraFieldAES, offset + 46 + getLength(rawFilename, rawExtraFieldZip64));
@@ -940,7 +1007,11 @@ async function closeFile(zipWriter, comment, options) {
940
1007
  setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
941
1008
  setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength));
942
1009
  setUint32(endOfdirectoryView, 72, lastDiskNumber + 1);
943
- diskNumber = MAX_16_BITS;
1010
+ const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
1011
+ if (supportZip64SplitFile) {
1012
+ lastDiskNumber = MAX_16_BITS;
1013
+ diskNumber = MAX_16_BITS;
1014
+ }
944
1015
  filesLength = MAX_16_BITS;
945
1016
  directoryOffset = MAX_32_BITS;
946
1017
  directoryDataLength = MAX_32_BITS;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "A JavaScript library to zip and unzip files in the browser, Deno and Node.js",
4
4
  "author": "Gildas Lormeau",
5
5
  "license": "BSD-3-Clause",
6
- "version": "2.6.60",
6
+ "version": "2.6.61",
7
7
  "type": "module",
8
8
  "keywords": [
9
9
  "zip",