@zip.js/zip.js 2.8.34 → 2.8.35

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.
Files changed (52) hide show
  1. package/README.md +13 -1
  2. package/deno.json +5 -2
  3. package/dist/README.md +3 -1
  4. package/dist/zip-core.js +472 -220
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core.js +449 -220
  7. package/dist/zip-fs-core.min.js +1 -1
  8. package/dist/zip-fs-native.js +476 -226
  9. package/dist/zip-fs-native.min.js +1 -1
  10. package/dist/zip-fs.js +478 -228
  11. package/dist/zip-fs.min.js +1 -1
  12. package/dist/zip-legacy.js +474 -222
  13. package/dist/zip-legacy.min.js +1 -1
  14. package/dist/zip-native.js +475 -223
  15. package/dist/zip-native.min.js +1 -1
  16. package/dist/zip-web-worker-native.js +1 -1
  17. package/dist/zip-web-worker.js +1 -1
  18. package/dist/zip.js +477 -225
  19. package/dist/zip.min.js +1 -1
  20. package/index-native.cjs +476 -226
  21. package/index-native.min.js +1 -1
  22. package/index.cjs +478 -228
  23. package/index.d.cts +53 -0
  24. package/index.d.ts +53 -0
  25. package/index.min.js +1 -1
  26. package/lib/core/codec-pool.js +2 -2
  27. package/lib/core/codec-worker.js +6 -2
  28. package/lib/core/configuration.js +22 -1
  29. package/lib/core/io.js +209 -56
  30. package/lib/core/streams/aes-crypto-stream.js +1 -10
  31. package/lib/core/streams/codec-stream.js +36 -15
  32. package/lib/core/streams/zip-entry-stream.js +19 -28
  33. package/lib/core/util/array.js +48 -0
  34. package/lib/core/web-worker-base.js +3 -3
  35. package/lib/core/web-worker-inline-native.js +1 -1
  36. package/lib/core/web-worker-inline-wasm.js +1 -1
  37. package/lib/core/zip-fs.js +2 -3
  38. package/lib/core/zip-reader.js +37 -40
  39. package/lib/core/zip-writer.js +58 -51
  40. package/lib/core/zlib-streams-inline.js +1 -1
  41. package/lib/zip-core-base.js +5 -3
  42. package/lib/zip-fs-native.js +2 -2
  43. package/lib/zip-fs-wasm.js +2 -2
  44. package/lib/zip-legacy.js +2 -2
  45. package/lib/zip-module-native.js +2 -2
  46. package/lib/zip-module-wasm.js +3 -3
  47. package/lib/zip-native.js +2 -2
  48. package/lib/zip-wasm.js +2 -2
  49. package/package.json +3 -3
  50. package/worker-message-property-names.js +3 -0
  51. package/.github/workflows/publish.yml +0 -30
  52. package/reserved-property-names.js +0 -50
@@ -85,10 +85,7 @@ import {
85
85
  FILE_ATTR_UNIX_STICKY_MASK,
86
86
  EMPTY_UINT8_ARRAY
87
87
  } from "./constants.js";
88
- import {
89
- getConfiguration,
90
- getChunkSize
91
- } from "./configuration.js";
88
+ import { getConfiguration } from "./configuration.js";
92
89
  import {
93
90
  runWorker,
94
91
  CODEC_INFLATE,
@@ -106,6 +103,7 @@ import {
106
103
  GenericWriter
107
104
  } from "./io.js";
108
105
  import { decodeText } from "./util/decode-text.js";
106
+ import { getDataView } from "./util/array.js";
109
107
  import { Crc32 } from "./streams/codecs/crc32.js";
110
108
  import {
111
109
  PROPERTY_NAME_RAW_FILENAME,
@@ -239,17 +237,21 @@ class ZipReader {
239
237
  let prependedDataLength = 0;
240
238
  let startOffset;
241
239
  let zip64EndOfDirectory;
242
- if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS) {
240
+ const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
241
+ if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
242
+ directoryDataOffset += getDiskOffset(reader, diskNumber);
243
+ }
244
+ if (requiresZip64) {
243
245
  const endOfDirectoryLocatorArray = endOfDirectoryInfo.offset >= ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH ?
244
246
  await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH) :
245
247
  EMPTY_UINT8_ARRAY;
246
248
  const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
247
249
  if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
248
250
  getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
249
- directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8);
250
- let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
251
+ directoryDataOffset = getDiskOffset(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
252
+ let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
251
253
  let endOfDirectoryView = getDataView(endOfDirectoryArray);
252
- const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH - (reader.lastDiskOffset || 0);
254
+ const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
253
255
  if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
254
256
  directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
255
257
  const originalDirectoryDataOffset = directoryDataOffset;
@@ -257,7 +259,7 @@ class ZipReader {
257
259
  if (directoryDataOffset > originalDirectoryDataOffset) {
258
260
  prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
259
261
  }
260
- endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
262
+ endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
261
263
  endOfDirectoryView = getDataView(endOfDirectoryArray);
262
264
  }
263
265
  if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
@@ -284,7 +286,7 @@ class ZipReader {
284
286
  } else if (checkAmbiguity && directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
285
287
  throwAmbiguousArchive("mismatched zip64 end of central directory record");
286
288
  }
287
- directoryDataOffset = getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
289
+ directoryDataOffset = getDiskOffset(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
288
290
  }
289
291
  }
290
292
  const declaredDirectoryDataLength = directoryDataLength;
@@ -301,18 +303,18 @@ class ZipReader {
301
303
  throw new Error(ERR_BAD_FORMAT);
302
304
  }
303
305
  let offset = 0;
304
- let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
306
+ let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
305
307
  let directoryView = getDataView(directoryArray);
306
308
  if (directoryDataLength) {
307
309
  if (directoryArray.length < 4) {
308
310
  throw new Error(ERR_BAD_FORMAT);
309
311
  }
310
- const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength - (reader.lastDiskOffset || 0);
312
+ const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
311
313
  if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
312
314
  const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
313
315
  let reconcile = !storedPointsAtDirectory;
314
316
  if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
315
- const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4, diskNumber);
317
+ const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
316
318
  reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
317
319
  }
318
320
  if (reconcile) {
@@ -321,15 +323,15 @@ class ZipReader {
321
323
  if (directoryDataOffset > originalDirectoryDataOffset) {
322
324
  prependedDataLength += directoryDataOffset - originalDirectoryDataOffset;
323
325
  }
324
- directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
326
+ directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
325
327
  directoryView = getDataView(directoryArray);
326
328
  }
327
329
  }
328
330
  }
329
- const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset - (reader.lastDiskOffset || 0);
331
+ const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
330
332
  if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
331
333
  directoryDataLength = expectedDirectoryDataLength;
332
- directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
334
+ directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
333
335
  directoryView = getDataView(directoryArray);
334
336
  }
335
337
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
@@ -403,7 +405,7 @@ class ZipReader {
403
405
  });
404
406
  readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
405
407
  fileEntry.offset += prependedDataLength;
406
- startOffset = Math.min(fileEntry.offset, startOffset);
408
+ startOffset = Math.min(getDiskOffset(reader, fileEntry.diskNumberStart) + fileEntry.offset, startOffset);
407
409
  if (checkAmbiguity) {
408
410
  if (filenames.has(fileEntry.filename)) {
409
411
  duplicateFilename = true;
@@ -578,7 +580,8 @@ class ZipEntry {
578
580
  dataDescriptor
579
581
  } = bitFlag;
580
582
  const localDirectory = fileEntry.localDirectory = {};
581
- const dataArray = await readUint8Array(reader, offset, HEADER_SIZE, diskNumberStart);
583
+ const localHeaderOffset = getDiskOffset(reader, diskNumberStart) + offset;
584
+ const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
582
585
  const dataView = getDataView(dataArray);
583
586
  let password = getOptionValue(zipEntry, options, OPTION_PASSWORD);
584
587
  let rawPassword = getOptionValue(zipEntry, options, OPTION_RAW_PASSWORD);
@@ -604,12 +607,12 @@ class ZipEntry {
604
607
  const checkAmbiguity = getStrictness(getOptionValue(zipEntry, options, OPTION_STRICTNESS), getOptionValue(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
605
608
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
606
609
  if (checkAmbiguity && (filenameLength || extraFieldLength)) {
607
- const trailingDataArray = await readUint8Array(reader, offset + HEADER_SIZE, filenameLength + extraFieldLength, diskNumberStart);
610
+ const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
608
611
  rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
609
612
  localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
610
613
  } else {
611
614
  localDirectory.rawExtraField = extraFieldLength ?
612
- await readUint8Array(reader, offset + HEADER_SIZE + filenameLength, extraFieldLength, diskNumberStart) :
615
+ await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
613
616
  EMPTY_UINT8_ARRAY;
614
617
  }
615
618
  readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
@@ -635,9 +638,9 @@ class ZipEntry {
635
638
  throw new Error(ERR_ENCRYPTED);
636
639
  }
637
640
  }
638
- const dataOffset = offset + HEADER_SIZE + filenameLength + extraFieldLength;
641
+ const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
639
642
  const size = compressedSize;
640
- const readable = reader.createReadable({ offset: dataOffset, size, diskNumberStart, chunkSize: getChunkSize(config) });
643
+ const readable = reader.createReadable({ offset: dataOffset, size });
641
644
  const signal = getOptionValue(zipEntry, options, OPTION_SIGNAL);
642
645
  const checkPasswordOnly = getOptionValue(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
643
646
  let checkOverlappingEntry = getOptionValue(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
@@ -678,8 +681,7 @@ class ZipEntry {
678
681
  reader,
679
682
  fileEntry,
680
683
  index,
681
- offset,
682
- diskNumberStart,
684
+ offset: localHeaderOffset,
683
685
  signature,
684
686
  compressedSize,
685
687
  uncompressedSize,
@@ -743,7 +745,7 @@ function readCommonHeader(directory, dataView, offset) {
743
745
  function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory) {
744
746
  const { rawExtraField } = directory;
745
747
  const extraField = directory.extraField = new Map();
746
- const rawExtraFieldView = getDataView(new Uint8Array(rawExtraField));
748
+ const rawExtraFieldView = getDataView(rawExtraField);
747
749
  let offsetExtraField = 0;
748
750
  try {
749
751
  while (offsetExtraField < rawExtraField.length) {
@@ -905,7 +907,7 @@ function readExtraFieldNTFS(extraFieldNTFS, directory) {
905
907
 
906
908
  function readExtraFieldUnix(extraField, directory, isInfoZip) {
907
909
  try {
908
- const view = getDataView(new Uint8Array(extraField.data));
910
+ const view = getDataView(extraField.data);
909
911
  let uid, gid;
910
912
  if (isInfoZip) {
911
913
  let offset = 0;
@@ -981,7 +983,6 @@ async function detectOverlappingEntry({
981
983
  fileEntry,
982
984
  index,
983
985
  offset,
984
- diskNumberStart,
985
986
  signature,
986
987
  compressedSize,
987
988
  uncompressedSize,
@@ -990,12 +991,6 @@ async function detectOverlappingEntry({
990
991
  extraFieldZip64,
991
992
  readRanges
992
993
  }) {
993
- let diskOffset = 0;
994
- if (diskNumberStart && reader.readers) {
995
- for (let indexReader = 0; indexReader < Math.min(diskNumberStart, reader.readers.length); indexReader++) {
996
- diskOffset += reader.readers[indexReader].size;
997
- }
998
- }
999
994
  let dataDescriptorLength = 0;
1000
995
  if (dataDescriptor) {
1001
996
  if (extraFieldZip64) {
@@ -1005,7 +1000,7 @@ async function detectOverlappingEntry({
1005
1000
  }
1006
1001
  }
1007
1002
  if (dataDescriptorLength) {
1008
- const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, diskNumberStart);
1003
+ const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
1009
1004
  const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
1010
1005
  getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
1011
1006
  if (dataDescriptorSignature) {
@@ -1028,8 +1023,8 @@ async function detectOverlappingEntry({
1028
1023
  }
1029
1024
  }
1030
1025
  const range = {
1031
- start: diskOffset + offset,
1032
- end: diskOffset + dataOffset + compressedSize + dataDescriptorLength,
1026
+ start: offset,
1027
+ end: dataOffset + compressedSize + dataDescriptorLength,
1033
1028
  fileEntry
1034
1029
  };
1035
1030
  for (const [otherIndex, otherRange] of readRanges) {
@@ -1042,6 +1037,10 @@ async function detectOverlappingEntry({
1042
1037
  readRanges.set(index, range);
1043
1038
  }
1044
1039
 
1040
+ function getDiskOffset(reader, diskNumber) {
1041
+ return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
1042
+ }
1043
+
1045
1044
  function getStrictness(strictness, checkAmbiguity) {
1046
1045
  if (strictness === UNDEFINED_VALUE) {
1047
1046
  return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
@@ -1148,7 +1147,8 @@ async function getCentralDirectoryReachability(reader, view, anchoredOffset, ind
1148
1147
  if (!filesLength && !directoryDataLength) {
1149
1148
  return CENTRAL_DIRECTORY_PLAUSIBLE;
1150
1149
  }
1151
- for (const centralDirectoryOffset of [offset - directoryDataLength, directoryDataOffset]) {
1150
+ const directoryDiskNumber = getUint16(view, indexByte + 6);
1151
+ for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset(reader, directoryDiskNumber) + directoryDataOffset]) {
1152
1152
  if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
1153
1153
  return CENTRAL_DIRECTORY_REACHABLE;
1154
1154
  }
@@ -1231,6 +1231,3 @@ function getBigUint64(view, offset) {
1231
1231
  return Number(view.getBigUint64(offset, true));
1232
1232
  }
1233
1233
 
1234
- function getDataView(array) {
1235
- return new DataView(array.buffer, array.byteOffset, array.byteLength);
1236
- }
@@ -44,9 +44,10 @@
44
44
  * the other segments do not, see getSegmentOffset().
45
45
  * - For split archives, `writer.diskOffset` is the total size of the closed segments and
46
46
  * `writer.diskNumber` the index of the current segment. `writer.availableSize` is the remaining
47
- * capacity of the current segment (Infinity otherwise); setting it to 0 and writing an empty
48
- * chunk starts a new segment. This is how header records are kept whole within a segment, as
49
- * required by APPNOTE section 8.5.2.
47
+ * capacity of the current segment; `writer.closeDisk()` ends it, the next segment being opened
48
+ * when more data is written. This is how header records are kept whole within a segment, as
49
+ * required by APPNOTE section 8.5.2. These properties only exist on split writers; the
50
+ * getDiskNumber(), getDiskOffset() and exceedsAvailableSize() accessors default them otherwise.
50
51
  * - The segment coordinates of an entry (`diskNumberStart` and `offset`) must be read after
51
52
  * calling skipDiskIfNeeded() and while holding the writer lock; they are unstable otherwise.
52
53
  *
@@ -140,10 +141,7 @@ import {
140
141
  OBJECT_TYPE,
141
142
  EMPTY_UINT8_ARRAY
142
143
  } from "./constants.js";
143
- import {
144
- getConfiguration,
145
- getChunkSize
146
- } from "./configuration.js";
144
+ import { getConfiguration } from "./configuration.js";
147
145
  import {
148
146
  CODEC_DEFLATE,
149
147
  runWorker
@@ -154,6 +152,7 @@ import {
154
152
  GenericReader
155
153
  } from "./io.js";
156
154
  import { encodeText } from "./util/encode-text.js";
155
+ import { getDataView } from "./util/array.js";
157
156
  import {
158
157
  PROPERTY_NAME_LAST_MODIFICATION_DATE,
159
158
  PROPERTY_NAME_LAST_ACCESS_DATE,
@@ -207,9 +206,6 @@ import {
207
206
  OPTION_USDZ,
208
207
  OPTION_UNIX_EXTRA_FIELD_TYPE
209
208
  } from "./options.js";
210
- import {
211
- ZipReader
212
- } from "./zip-reader.js";
213
209
 
214
210
  const ERR_DUPLICATED_NAME = "File already exists";
215
211
  const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
@@ -245,9 +241,10 @@ class ZipWriter {
245
241
 
246
242
  constructor(writer, options = {}) {
247
243
  writer = new GenericWriter(writer);
244
+ const { availableSize = INFINITY_VALUE, maxSize = INFINITY_VALUE } = writer;
248
245
  const addSplitZipSignature =
249
- writer.availableSize !== UNDEFINED_VALUE && writer.availableSize > 0 && writer.availableSize !== INFINITY_VALUE &&
250
- writer.maxSize !== UNDEFINED_VALUE && writer.maxSize > 0 && writer.maxSize !== INFINITY_VALUE;
246
+ availableSize > 0 && availableSize !== INFINITY_VALUE &&
247
+ maxSize > 0 && maxSize !== INFINITY_VALUE;
251
248
  Object.assign(this, {
252
249
  writer,
253
250
  addSplitZipSignature,
@@ -269,6 +266,7 @@ class ZipWriter {
269
266
  }
270
267
  reader = new GenericReader(reader);
271
268
  await initStream(reader);
269
+ const { ZipReader } = await import("./zip-reader.js");
272
270
  const zipReader = new ZipReader(reader.readable);
273
271
  const entries = await zipReader.getEntries();
274
272
  await zipReader.close();
@@ -287,8 +285,6 @@ class ZipWriter {
287
285
  encrypted,
288
286
  uncompressedSize,
289
287
  compressedSize,
290
- diskOffset,
291
- diskNumber,
292
288
  zip64
293
289
  } = entry;
294
290
  let {
@@ -336,8 +332,9 @@ class ZipWriter {
336
332
  Object.assign(entry, {
337
333
  zip64UncompressedSize,
338
334
  zip64CompressedSize,
339
- zip64Offset: zip64 && this.offset - diskOffset >= MAX_32_BITS,
340
- zip64DiskNumberStart: zip64 && diskNumber >= MAX_16_BITS,
335
+ zip64Offset: zip64 && entry.offset >= MAX_32_BITS,
336
+ diskNumberStart: 0,
337
+ zip64DiskNumberStart: false,
341
338
  rawExtraFieldZip64,
342
339
  rawExtraFieldAES,
343
340
  rawExtraFieldExtendedTimestamp,
@@ -521,7 +518,8 @@ async function addFile(zipWriter, name, reader, options) {
521
518
  try {
522
519
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
523
520
  ({ reader } = sizesInfo);
524
- const { diskOffset, diskNumber } = zipWriter.writer;
521
+ const diskOffset = getDiskOffset(zipWriter.writer);
522
+ const diskNumber = getDiskNumber(zipWriter.writer);
525
523
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
526
524
  internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
527
525
  externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
@@ -698,7 +696,7 @@ function resolveMetadata(zipWriter, name, options) {
698
696
  const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
699
697
  const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
700
698
  const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
701
- const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS, true);
699
+ const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
702
700
  const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
703
701
  const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
704
702
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
@@ -896,7 +894,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
896
894
  await requestLockWriter();
897
895
  }
898
896
  await initStream(fileWriter);
899
- const { diskOffset } = writer;
897
+ const diskOffset = getDiskOffset(writer);
900
898
  if (zipWriter.addSplitZipSignature) {
901
899
  delete zipWriter.addSplitZipSignature;
902
900
  const signatureArray = new Uint8Array(4);
@@ -913,7 +911,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
913
911
  await lockPreviousFileEntry;
914
912
  await skipDiskIfNeeded();
915
913
  }
916
- const diskNumberStart = writer.diskNumber;
914
+ const diskNumberStart = getDiskNumber(writer);
917
915
  const entryOffset = getSegmentOffset(zipWriter, writer);
918
916
  fileEntry.diskNumberStart = diskNumberStart;
919
917
  if (!bufferedWrite) {
@@ -933,11 +931,11 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
933
931
  writingBufferedEntryData = true;
934
932
  writerSizeBeforeEntry = writer.size;
935
933
  await skipDiskIfNeeded();
936
- fileEntry.diskNumberStart = writer.diskNumber;
934
+ fileEntry.diskNumberStart = getDiskNumber(writer);
937
935
  fileEntry.offset = getSegmentOffset(zipWriter, writer);
938
936
  if (usdz) {
939
937
  const previousMetadataSize = entryInfo.metadataSize;
940
- appendExtraFieldUSDZ(entryInfo, zipWriter.offset - writer.diskOffset);
938
+ appendExtraFieldUSDZ(entryInfo, zipWriter.offset - getDiskOffset(writer));
941
939
  fileEntry.size += entryInfo.metadataSize - previousMetadataSize;
942
940
  }
943
941
  updateLocalHeader(fileEntry, headerInfo.localHeaderView, options);
@@ -1002,9 +1000,8 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
1002
1000
  }
1003
1001
 
1004
1002
  async function skipDiskIfNeeded() {
1005
- if (getLength(headerInfo.localHeaderArray) > writer.availableSize) {
1006
- writer.availableSize = 0;
1007
- await writeData(writer, EMPTY_UINT8_ARRAY);
1003
+ if (exceedsAvailableSize(writer, getLength(headerInfo.localHeaderArray))) {
1004
+ await writer.closeDisk();
1008
1005
  }
1009
1006
  }
1010
1007
  }
@@ -1115,7 +1112,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
1115
1112
  }
1116
1113
  const { writable } = writer;
1117
1114
  if (reader) {
1118
- const readable = reader.createReadable ? reader.createReadable({ chunkSize: getChunkSize(config) }) : reader.readable;
1115
+ const readable = reader.createReadable ? reader.createReadable() : reader.readable;
1119
1116
  const size = reader.size;
1120
1117
  const workerOptions = {
1121
1118
  options: {
@@ -1547,8 +1544,8 @@ function updateLocalHeader({
1547
1544
 
1548
1545
  async function closeFile(zipWriter, comment, options) {
1549
1546
  const directoryDataLength = createDirectoryRecords(zipWriter.files);
1550
- const { cdStartDiskNumber, cdStartDiskOffset } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
1551
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { cdStartDiskNumber, cdStartDiskOffset, directoryDataLength });
1547
+ const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
1548
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
1552
1549
  }
1553
1550
 
1554
1551
  function createDirectoryRecords(files) {
@@ -1630,8 +1627,8 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
1630
1627
  await initStream(writer);
1631
1628
  let offset = 0;
1632
1629
  let directoryDiskOffset = 0;
1633
- let cdStartDiskNumber = writer.diskNumber;
1634
- let cdStartDiskOffset = writer.diskOffset;
1630
+ let directoryStartDiskNumber = getDiskNumber(writer);
1631
+ let directoryStartDiskOffset = getDiskOffset(writer);
1635
1632
  for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
1636
1633
  const {
1637
1634
  offset: fileEntryOffset,
@@ -1658,15 +1655,14 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
1658
1655
  } = fileEntry;
1659
1656
  const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
1660
1657
  const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
1661
- if (offset + directoryRecordLength - directoryDiskOffset > writer.availableSize) {
1658
+ if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
1662
1659
  await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
1663
1660
  directoryDiskOffset = offset;
1664
- writer.availableSize = 0;
1665
- await writeData(writer, EMPTY_UINT8_ARRAY);
1661
+ await writer.closeDisk();
1666
1662
  }
1667
1663
  if (indexFileEntry == 0) {
1668
- cdStartDiskNumber = writer.diskNumber;
1669
- cdStartDiskOffset = writer.diskOffset;
1664
+ directoryStartDiskNumber = getDiskNumber(writer);
1665
+ directoryStartDiskOffset = getDiskOffset(writer);
1670
1666
  }
1671
1667
  if (!zip64UncompressedSize) {
1672
1668
  setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
@@ -1706,18 +1702,18 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
1706
1702
  }
1707
1703
  }
1708
1704
  await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
1709
- return { cdStartDiskNumber, cdStartDiskOffset };
1705
+ return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
1710
1706
  }
1711
1707
 
1712
1708
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
1713
1709
  const { writer } = zipWriter;
1714
- const { cdStartDiskNumber, cdStartDiskOffset } = cdInfo;
1710
+ const { directoryStart } = cdInfo;
1715
1711
  let { directoryDataLength } = cdInfo;
1716
1712
  let filesLength = zipWriter.files.size;
1717
- let diskNumber = cdStartDiskNumber;
1718
- let directoryOffset = zipWriter.offset - cdStartDiskOffset - (cdStartDiskNumber ? zipWriter.initialOffset : 0);
1719
- let lastDiskNumber = writer.diskNumber;
1720
- if (writer.availableSize < END_OF_CENTRAL_DIR_LENGTH) {
1713
+ let diskNumber = directoryStart.diskNumber;
1714
+ let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
1715
+ let lastDiskNumber = getDiskNumber(writer);
1716
+ if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
1721
1717
  lastDiskNumber++;
1722
1718
  }
1723
1719
  let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
@@ -1733,11 +1729,10 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
1733
1729
  throw new Error(ERR_INVALID_COMMENT);
1734
1730
  }
1735
1731
  const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
1736
- if (getLength(endOfdirectoryRecord.array) + commentLength > writer.availableSize) {
1737
- writer.availableSize = 0;
1738
- await writeData(writer, EMPTY_UINT8_ARRAY);
1732
+ if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
1733
+ await writer.closeDisk();
1739
1734
  }
1740
- lastDiskNumber = writer.diskNumber;
1735
+ lastDiskNumber = getDiskNumber(writer);
1741
1736
  if (zip64) {
1742
1737
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
1743
1738
  endOfdirectoryRecord.uint64(44);
@@ -1751,7 +1746,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
1751
1746
  endOfdirectoryRecord.uint64(directoryOffset);
1752
1747
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
1753
1748
  endOfdirectoryRecord.uint32(lastDiskNumber);
1754
- endOfdirectoryRecord.uint64(BigInt(zipWriter.offset) + BigInt(directoryDataLength) - BigInt(writer.diskOffset) - BigInt(writer.diskNumber ? zipWriter.initialOffset : 0));
1749
+ endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
1755
1750
  endOfdirectoryRecord.uint32(lastDiskNumber + 1);
1756
1751
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
1757
1752
  if (supportZip64SplitFile) {
@@ -1791,8 +1786,23 @@ function createRecordWriter(length) {
1791
1786
  };
1792
1787
  }
1793
1788
 
1794
- function getSegmentOffset(zipWriter, writer) {
1795
- return zipWriter.offset - writer.diskOffset - (writer.diskNumber ? zipWriter.initialOffset : 0);
1789
+ function getDiskNumber(writer) {
1790
+ const { diskNumber = 0 } = writer;
1791
+ return diskNumber;
1792
+ }
1793
+
1794
+ function getDiskOffset(writer) {
1795
+ const { diskOffset = 0 } = writer;
1796
+ return diskOffset;
1797
+ }
1798
+
1799
+ function exceedsAvailableSize(writer, length) {
1800
+ const { availableSize = INFINITY_VALUE } = writer;
1801
+ return length > availableSize;
1802
+ }
1803
+
1804
+ function getSegmentOffset(zipWriter, { diskNumber = 0, diskOffset = 0 }) {
1805
+ return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
1796
1806
  }
1797
1807
 
1798
1808
  async function writeData(writer, array) {
@@ -1869,9 +1879,6 @@ function arraySet(array, typedArray, offset) {
1869
1879
  array.set(typedArray, offset);
1870
1880
  }
1871
1881
 
1872
- function getDataView(array) {
1873
- return new DataView(array.buffer, array.byteOffset, array.byteLength);
1874
- }
1875
1882
 
1876
1883
  function getLength(...arrayLikes) {
1877
1884
  let result = 0;