@zip.js/zip.js 2.8.52 → 2.8.54

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 (49) hide show
  1. package/README.md +1 -1
  2. package/deno.json +2 -1
  3. package/dist/zip-core-external.js +839 -528
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +847 -527
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +880 -557
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +829 -538
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +880 -557
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +895 -558
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +894 -557
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +849 -529
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-native.js +849 -529
  20. package/dist/zip-native.min.js +1 -1
  21. package/dist/zip-web-worker-native.js +1 -1
  22. package/dist/zip-web-worker.js +1 -1
  23. package/dist/zip.js +848 -528
  24. package/dist/zip.min.js +1 -1
  25. package/eslint.config.mjs +2 -1
  26. package/index-native.cjs +895 -558
  27. package/index-native.min.js +1 -1
  28. package/index.cjs +894 -557
  29. package/index.d.cts +672 -78
  30. package/index.d.ts +672 -78
  31. package/index.min.js +1 -1
  32. package/lib/core/codec-worker-web.js +13 -4
  33. package/lib/core/configuration.js +62 -21
  34. package/lib/core/constants.js +16 -1
  35. package/lib/core/io.js +44 -29
  36. package/lib/core/options.js +46 -2
  37. package/lib/core/streams/aes-crypto-stream.js +12 -12
  38. package/lib/core/util/decode-text.js +11 -2
  39. package/lib/core/web-worker-base.js +3 -2
  40. package/lib/core/web-worker-inline-native.js +1 -1
  41. package/lib/core/web-worker-inline-wasm.js +1 -1
  42. package/lib/core/zip-entry.js +8 -0
  43. package/lib/core/zip-fs.js +38 -27
  44. package/lib/core/zip-reader.js +149 -60
  45. package/lib/core/zip-writer.js +329 -189
  46. package/lib/zip-core-base.js +6 -1
  47. package/lib/zip-core-reader.js +1 -0
  48. package/lib/zip-core-writer.js +5 -0
  49. package/package.json +11 -3
@@ -44,6 +44,7 @@
44
44
 
45
45
  const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
46
46
  const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
47
+ const TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE = 0x30304b50;
47
48
  const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
48
49
  const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
49
50
  const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
@@ -60,6 +61,7 @@
60
61
  const DATA_DESCRIPTOR_RECORD_LENGTH = 12;
61
62
  const DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH = 20;
62
63
  const DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH = 4;
64
+ const SPLIT_ZIP_FILE_SIGNATURE_LENGTH = 4;
63
65
 
64
66
  const EXTRAFIELD_TYPE_ZIP64 = 0x0001;
65
67
  const EXTRAFIELD_TYPE_AES = 0x9901;
@@ -101,6 +103,9 @@
101
103
  const VERSION_ZIP64 = 0x2D;
102
104
  const VERSION_AES = 0x33;
103
105
 
106
+ const VERSION_MADE_BY_MSDOS = 0x0014;
107
+ const VERSION_MADE_BY_UNIX = 0x0300;
108
+
104
109
  const DIRECTORY_SIGNATURE = "/";
105
110
 
106
111
  const HEADER_SIZE = 30;
@@ -108,6 +113,8 @@
108
113
  const HEADER_OFFSET_SIGNATURE = 10;
109
114
  const HEADER_OFFSET_COMPRESSED_SIZE = 14;
110
115
  const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18;
116
+ const HEADER_OFFSET_FILENAME_LENGTH = 22;
117
+ const HEADER_OFFSET_EXTRAFIELD_LENGTH = 24;
111
118
  const LOCAL_HEADER_COMMON_OFFSET = 4;
112
119
 
113
120
  const MAX_DATE = new Date(2107, 11, 31, 23, 59, 58);
@@ -120,9 +127,116 @@
120
127
  const OBJECT_TYPE = "object";
121
128
  const STRING_TYPE = "string";
122
129
  const NUMBER_TYPE = "number";
130
+ const BOOLEAN_TYPE = "boolean";
123
131
 
124
132
  const EMPTY_UINT8_ARRAY = new Uint8Array();
125
133
 
134
+ /*
135
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
136
+
137
+ Redistribution and use in source and binary forms, with or without
138
+ modification, are permitted provided that the following conditions are met:
139
+
140
+ 1. Redistributions of source code must retain the above copyright notice,
141
+ this list of conditions and the following disclaimer.
142
+
143
+ 2. Redistributions in binary form must reproduce the above copyright
144
+ notice, this list of conditions and the following disclaimer in
145
+ the documentation and/or other materials provided with the distribution.
146
+
147
+ 3. The names of the authors may not be used to endorse or promote products
148
+ derived from this software without specific prior written permission.
149
+
150
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
151
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
152
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
153
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
154
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
155
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
156
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
157
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
158
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
159
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
160
+ */
161
+
162
+
163
+ const OPTION_FILENAME_ENCODING = "filenameEncoding";
164
+ const OPTION_COMMENT_ENCODING = "commentEncoding";
165
+ const OPTION_DECODE_TEXT = "decodeText";
166
+ const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
167
+ const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
168
+ const OPTION_PASSWORD = "password";
169
+ const OPTION_RAW_PASSWORD = "rawPassword";
170
+ const OPTION_PASS_THROUGH = "passThrough";
171
+ const OPTION_SIGNAL = "signal";
172
+ const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
173
+ const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
174
+ const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
175
+ const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
176
+ const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
177
+ const OPTION_CHECK_SIGNATURE = "checkSignature";
178
+ const OPTION_CHECK_CRC32 = "checkCrc32";
179
+ const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
180
+ const OPTION_USE_WEB_WORKERS = "useWebWorkers";
181
+ const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
182
+ const OPTION_TRANSFER_STREAMS = "transferStreams";
183
+ const OPTION_PREVENT_CLOSE = "preventClose";
184
+ const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
185
+ const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
186
+ const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
187
+ const OPTION_KEEP_ORDER = "keepOrder";
188
+ const OPTION_LEVEL = "level";
189
+ const OPTION_BUFFERED_WRITE = "bufferedWrite";
190
+ const OPTION_CREATE_TEMP_STREAM = "createTempStream";
191
+ const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
192
+ const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
193
+ const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
194
+ const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
195
+ const OPTION_ENCODE_TEXT = "encodeText";
196
+ const OPTION_OFFSET = "offset";
197
+ const OPTION_USDZ = "usdz";
198
+ const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
199
+ const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
200
+ const OPTION_STRICTNESS = "strictness";
201
+ const OPTION_FILENAME_VALIDATION = "filenameValidation";
202
+ const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
203
+ const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
204
+ const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
205
+ const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
206
+ const TEXT_TYPE_FILENAME = "filename";
207
+ const TEXT_TYPE_COMMENT = "comment";
208
+ const STRICTNESS_STRICT = "strict";
209
+ const STRICTNESS_BALANCED = "balanced";
210
+ const STRICTNESS_TOLERANT = "tolerant";
211
+
212
+ const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
213
+ const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
214
+ const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
215
+
216
+ function checkFunctionOption(value) {
217
+ if (value && typeof value != FUNCTION_TYPE) {
218
+ throw new Error(ERR_INVALID_FUNCTION_OPTION);
219
+ }
220
+ return value;
221
+ }
222
+
223
+ function checkSignalOption(signal) {
224
+ if (signal && (typeof signal.addEventListener != FUNCTION_TYPE || typeof signal.aborted != BOOLEAN_TYPE)) {
225
+ throw new Error(ERR_INVALID_SIGNAL);
226
+ }
227
+ return signal || UNDEFINED_VALUE;
228
+ }
229
+
230
+ function checkPasswordOption(password, rawPassword) {
231
+ if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
232
+ throw new Error(ERR_INVALID_PASSWORD_TYPE);
233
+ }
234
+ }
235
+
236
+ function toNumber(value) {
237
+ return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
238
+ }
239
+
126
240
  /*
127
241
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
128
242
 
@@ -152,7 +266,9 @@
152
266
  */
153
267
 
154
268
 
269
+ const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
155
270
  const MINIMUM_CHUNK_SIZE = 64;
271
+ const MINIMUM_PROPERTY_VALUE = 1;
156
272
  let maxWorkers = 2;
157
273
  try {
158
274
  if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
@@ -164,7 +280,7 @@
164
280
  const DEFAULT_CONFIGURATION = {
165
281
  workerURI: "./core/web-worker-wasm.js",
166
282
  wasmURI: "./core/streams/zlib-wasm/zlib-streams.wasm",
167
- chunkSize: 64 * 1024,
283
+ chunkSize: DEFAULT_CHUNK_SIZE$1,
168
284
  maxWorkers,
169
285
  terminateWorkerTimeout: 5000,
170
286
  workerStarvationTimeout: 5000,
@@ -183,7 +299,12 @@
183
299
  }
184
300
 
185
301
  function getChunkSize(config) {
186
- return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
302
+ return normalizeChunkSize(config.chunkSize);
303
+ }
304
+
305
+ function normalizeChunkSize(chunkSize) {
306
+ chunkSize = toNumber(chunkSize);
307
+ return Number.isInteger(chunkSize) && chunkSize >= MINIMUM_PROPERTY_VALUE ? Math.max(chunkSize, MINIMUM_CHUNK_SIZE) : DEFAULT_CHUNK_SIZE$1;
187
308
  }
188
309
 
189
310
  /*
@@ -317,6 +438,96 @@
317
438
  });
318
439
  }
319
440
 
441
+ /*
442
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
443
+
444
+ Redistribution and use in source and binary forms, with or without
445
+ modification, are permitted provided that the following conditions are met:
446
+
447
+ 1. Redistributions of source code must retain the above copyright notice,
448
+ this list of conditions and the following disclaimer.
449
+
450
+ 2. Redistributions in binary form must reproduce the above copyright
451
+ notice, this list of conditions and the following disclaimer in
452
+ the documentation and/or other materials provided with the distribution.
453
+
454
+ 3. The names of the authors may not be used to endorse or promote products
455
+ derived from this software without specific prior written permission.
456
+
457
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
458
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
459
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
460
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
461
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
462
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
463
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
464
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
465
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
466
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
467
+ */
468
+
469
+ /* global TextDecoder */
470
+
471
+ const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
472
+ const VALID_CP437 = CP437.length == 256;
473
+
474
+ function decodeCP437(stringValue) {
475
+ if (VALID_CP437) {
476
+ let result = "";
477
+ for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
478
+ result += CP437[stringValue[indexCharacter]];
479
+ }
480
+ return result;
481
+ } else {
482
+ return new TextDecoder().decode(stringValue);
483
+ }
484
+ }
485
+
486
+ /*
487
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
488
+
489
+ Redistribution and use in source and binary forms, with or without
490
+ modification, are permitted provided that the following conditions are met:
491
+
492
+ 1. Redistributions of source code must retain the above copyright notice,
493
+ this list of conditions and the following disclaimer.
494
+
495
+ 2. Redistributions in binary form must reproduce the above copyright
496
+ notice, this list of conditions and the following disclaimer in
497
+ the documentation and/or other materials provided with the distribution.
498
+
499
+ 3. The names of the authors may not be used to endorse or promote products
500
+ derived from this software without specific prior written permission.
501
+
502
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
503
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
504
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
505
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
506
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
507
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
508
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
509
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
510
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
511
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
512
+ */
513
+
514
+
515
+ function decodeText(value, encoding) {
516
+ return decode(value, encoding, true);
517
+ }
518
+
519
+ function decodeTextRemovingBOM(value, encoding) {
520
+ return decode(value, encoding, false);
521
+ }
522
+
523
+ function decode(value, encoding, ignoreBOM) {
524
+ if (encoding && encoding.trim().toLowerCase() == "cp437") {
525
+ return decodeCP437(value);
526
+ } else {
527
+ return new TextDecoder(encoding, { ignoreBOM }).decode(value);
528
+ }
529
+ }
530
+
320
531
  /*
321
532
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
322
533
 
@@ -389,6 +600,7 @@
389
600
  createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
390
601
  const reader = this;
391
602
  let chunkOffset = 0;
603
+ chunkSize = normalizeChunkSize(chunkSize);
392
604
  return new ReadableStream({
393
605
  async pull(controller) {
394
606
  const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
@@ -396,7 +608,7 @@
396
608
  if (data.length) {
397
609
  controller.enqueue(data);
398
610
  }
399
- if ((chunkOffset + chunkSize >= size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
611
+ if ((chunkOffset + chunkSize >= size) || (!data.length && dataSize)) {
400
612
  controller.close();
401
613
  } else {
402
614
  chunkOffset += chunkSize;
@@ -476,31 +688,31 @@
476
688
  Object.assign(this, {
477
689
  contentType,
478
690
  data: "data:" + (contentType || "") + ";base64,",
479
- pending: []
691
+ pendingCharacters: ""
480
692
  });
481
693
  }
482
694
 
483
695
  writeUint8Array(array) {
484
696
  const writer = this;
485
697
  let indexArray;
486
- let dataString = writer.pending;
487
- const delta = writer.pending.length;
488
- writer.pending = "";
698
+ let dataString = writer.pendingCharacters;
699
+ const delta = writer.pendingCharacters.length;
700
+ writer.pendingCharacters = "";
489
701
  for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
490
702
  dataString += String.fromCharCode(array[indexArray]);
491
703
  }
492
704
  for (; indexArray < array.length; indexArray++) {
493
- writer.pending += String.fromCharCode(array[indexArray]);
705
+ writer.pendingCharacters += String.fromCharCode(array[indexArray]);
494
706
  }
495
707
  if (dataString.length > 2) {
496
708
  writer.data += btoa(dataString);
497
709
  } else {
498
- writer.pending = dataString + writer.pending;
710
+ writer.pendingCharacters = dataString + writer.pendingCharacters;
499
711
  }
500
712
  }
501
713
 
502
714
  getData() {
503
- return this.data + btoa(this.pending);
715
+ return this.data + btoa(this.pendingCharacters);
504
716
  }
505
717
  }
506
718
 
@@ -530,7 +742,7 @@
530
742
  constructor(blob) {
531
743
  super();
532
744
  Object.assign(this, {
533
- blob,
745
+ sourceBlob: blob,
534
746
  size: blob.size
535
747
  });
536
748
  if (!blobSliceProbe) {
@@ -540,13 +752,13 @@
540
752
 
541
753
  createReadable(options) {
542
754
  const reader = this;
543
- const { blob, size } = reader;
755
+ const { sourceBlob, size } = reader;
544
756
  const { offset = 0, size: readSize = size - offset } = options || {};
545
757
  if (!offset && readSize >= size) {
546
- return toCompatibleReadable(blob.stream());
758
+ return toCompatibleReadable(sourceBlob.stream());
547
759
  }
548
760
  if (blobSliceReliable) {
549
- return toCompatibleReadable(blob.slice(offset, offset + readSize).stream());
761
+ return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
550
762
  }
551
763
  return super.createReadable(options);
552
764
  }
@@ -555,7 +767,7 @@
555
767
  const reader = this;
556
768
  const offsetEnd = offset + length;
557
769
  const readsWholeBlob = !offset && offsetEnd >= reader.size;
558
- const blob = readsWholeBlob ? reader.blob : reader.blob.slice(offset, offsetEnd);
770
+ const blob = readsWholeBlob ? reader.sourceBlob : reader.sourceBlob.slice(offset, offsetEnd);
559
771
  let arrayBuffer = await blob.arrayBuffer();
560
772
  const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
561
773
  if (sliceIgnoredByBuggyImplementation) {
@@ -577,12 +789,12 @@
577
789
  }
578
790
  });
579
791
  writer.contentType = contentType;
580
- writer.blob = streamToBlob(transformStream.readable, contentType);
581
- writer.blob.catch(() => { });
792
+ writer.blobPromise = streamToBlob(transformStream.readable, contentType);
793
+ writer.blobPromise.catch(() => { });
582
794
  }
583
795
 
584
796
  getData() {
585
- return this.blob;
797
+ return this.blobPromise;
586
798
  }
587
799
  }
588
800
 
@@ -616,7 +828,7 @@
616
828
  class TextWriter extends BlobWriter {
617
829
 
618
830
  constructor(encoding) {
619
- super(encoding);
831
+ super();
620
832
  Object.assign(this, {
621
833
  encoding,
622
834
  utf8: !encoding || encoding.toLowerCase() == "utf-8"
@@ -632,14 +844,7 @@
632
844
  if (blob.text && utf8) {
633
845
  return blob.text();
634
846
  } else {
635
- const reader = new FileReader();
636
- return new Promise((resolve, reject) => {
637
- Object.assign(reader, {
638
- onload: ({ target }) => resolve(target.result),
639
- onerror: () => reject(reader.error)
640
- });
641
- reader.readAsText(blob, encoding);
642
- });
847
+ return decodeTextRemovingBOM(new Uint8Array(await blob.arrayBuffer()), encoding);
643
848
  }
644
849
  }
645
850
  }
@@ -1090,9 +1295,8 @@
1090
1295
 
1091
1296
  async init() {
1092
1297
  const reader = this;
1093
- const { readers } = reader;
1094
1298
  reader.lastDiskNumber = 0;
1095
- await Promise.all(readers.map(diskReader => initStream(diskReader)));
1299
+ const readers = reader.readers = await Promise.all(reader.readers.map(initDiskReader));
1096
1300
  reader.diskOffsets = readers.map(diskReader => {
1097
1301
  const diskOffset = reader.size;
1098
1302
  reader.size += diskReader.size;
@@ -1287,10 +1491,30 @@
1287
1491
  }
1288
1492
  }
1289
1493
 
1494
+ async function initDiskReader(diskReader) {
1495
+ diskReader = new GenericReader(diskReader);
1496
+ await initStream(diskReader);
1497
+ if (diskReader.size === UNDEFINED_VALUE || !diskReader.readUint8Array) {
1498
+ diskReader = new BlobReader(await streamToBlob(diskReader.readable));
1499
+ await initStream(diskReader);
1500
+ }
1501
+ return diskReader;
1502
+ }
1503
+
1290
1504
  function readUint8Array(reader, offset, size) {
1291
1505
  return reader.readUint8Array(offset, size);
1292
1506
  }
1293
1507
 
1508
+ function createReadable(reader, options) {
1509
+ if (reader.createReadable) {
1510
+ return reader.createReadable(options);
1511
+ } else if (reader.readUint8Array) {
1512
+ return Reader.prototype.createReadable.call(reader, options);
1513
+ } else {
1514
+ return reader.readable;
1515
+ }
1516
+ }
1517
+
1294
1518
  /*
1295
1519
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
1296
1520
 
@@ -2448,13 +2672,13 @@
2448
2672
  const {
2449
2673
  ctr,
2450
2674
  hmac,
2451
- pending,
2675
+ pendingInput,
2452
2676
  ready
2453
2677
  } = this;
2454
2678
  if (hmac && ctr) {
2455
2679
  await ready;
2456
- const chunkToDecrypt = subarray(pending, 0, pending.length - AUTHENTICATION_CODE_LENGTH);
2457
- const originalAuthenticationCode = subarray(pending, pending.length - AUTHENTICATION_CODE_LENGTH);
2680
+ const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
2681
+ const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
2458
2682
  let decryptedChunkArray = EMPTY_UINT8_ARRAY;
2459
2683
  if (chunkToDecrypt.length) {
2460
2684
  const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
@@ -2463,7 +2687,7 @@
2463
2687
  decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
2464
2688
  }
2465
2689
  const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
2466
- let invalidAuthenticationCode = pending.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
2690
+ let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
2467
2691
  for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
2468
2692
  invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
2469
2693
  }
@@ -2507,14 +2731,14 @@
2507
2731
  const {
2508
2732
  ctr,
2509
2733
  hmac,
2510
- pending,
2734
+ pendingInput,
2511
2735
  ready
2512
2736
  } = this;
2513
2737
  if (hmac && ctr) {
2514
2738
  await ready;
2515
2739
  let encryptedChunkArray = EMPTY_UINT8_ARRAY;
2516
- if (pending.length) {
2517
- const encryptedChunk = ctr.update(toBits(codecBytes, pending));
2740
+ if (pendingInput.length) {
2741
+ const encryptedChunk = ctr.update(toBits(codecBytes, pendingInput));
2518
2742
  hmac.update(encryptedChunk);
2519
2743
  encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
2520
2744
  }
@@ -2531,7 +2755,7 @@
2531
2755
  ready: new Promise(resolve => aesCrypto.resolveReady = resolve),
2532
2756
  password: encodePassword(password, rawPassword),
2533
2757
  strength: encryptionStrength - 1,
2534
- pending: EMPTY_UINT8_ARRAY
2758
+ pendingInput: EMPTY_UINT8_ARRAY
2535
2759
  });
2536
2760
  }
2537
2761
 
@@ -2539,10 +2763,10 @@
2539
2763
  const {
2540
2764
  ctr,
2541
2765
  hmac,
2542
- pending
2766
+ pendingInput
2543
2767
  } = aesCrypto;
2544
- if (pending.length) {
2545
- input = concat(pending, input);
2768
+ if (pendingInput.length) {
2769
+ input = concat(pendingInput, input);
2546
2770
  }
2547
2771
  const inputLength = input.length - paddingEnd;
2548
2772
  output = expand(output, paddingStart + (inputLength - (inputLength % BLOCK_LENGTH)));
@@ -2558,7 +2782,7 @@
2558
2782
  }
2559
2783
  output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
2560
2784
  }
2561
- aesCrypto.pending = subarray(input, offset);
2785
+ aesCrypto.pendingInput = subarray(input, offset);
2562
2786
  return output;
2563
2787
  }
2564
2788
 
@@ -3682,88 +3906,6 @@
3682
3906
  }
3683
3907
  }
3684
3908
 
3685
- /*
3686
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
3687
-
3688
- Redistribution and use in source and binary forms, with or without
3689
- modification, are permitted provided that the following conditions are met:
3690
-
3691
- 1. Redistributions of source code must retain the above copyright notice,
3692
- this list of conditions and the following disclaimer.
3693
-
3694
- 2. Redistributions in binary form must reproduce the above copyright
3695
- notice, this list of conditions and the following disclaimer in
3696
- the documentation and/or other materials provided with the distribution.
3697
-
3698
- 3. The names of the authors may not be used to endorse or promote products
3699
- derived from this software without specific prior written permission.
3700
-
3701
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
3702
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
3703
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
3704
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
3705
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3706
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
3707
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3708
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3709
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
3710
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3711
- */
3712
-
3713
- /* global TextDecoder */
3714
-
3715
- const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
3716
- const VALID_CP437 = CP437.length == 256;
3717
-
3718
- function decodeCP437(stringValue) {
3719
- if (VALID_CP437) {
3720
- let result = "";
3721
- for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
3722
- result += CP437[stringValue[indexCharacter]];
3723
- }
3724
- return result;
3725
- } else {
3726
- return new TextDecoder().decode(stringValue);
3727
- }
3728
- }
3729
-
3730
- /*
3731
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
3732
-
3733
- Redistribution and use in source and binary forms, with or without
3734
- modification, are permitted provided that the following conditions are met:
3735
-
3736
- 1. Redistributions of source code must retain the above copyright notice,
3737
- this list of conditions and the following disclaimer.
3738
-
3739
- 2. Redistributions in binary form must reproduce the above copyright
3740
- notice, this list of conditions and the following disclaimer in
3741
- the documentation and/or other materials provided with the distribution.
3742
-
3743
- 3. The names of the authors may not be used to endorse or promote products
3744
- derived from this software without specific prior written permission.
3745
-
3746
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
3747
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
3748
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
3749
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
3750
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3751
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
3752
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3753
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3754
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
3755
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3756
- */
3757
-
3758
-
3759
- function decodeText(value, encoding) {
3760
- if (encoding && encoding.trim().toLowerCase() == "cp437") {
3761
- return decodeCP437(value);
3762
- } else {
3763
- return new TextDecoder(encoding, { ignoreBOM: true }).decode(value);
3764
- }
3765
- }
3766
-
3767
3909
  /*
3768
3910
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
3769
3911
 
@@ -3836,6 +3978,10 @@
3836
3978
  const PROPERTY_NAME_SETGID = "setgid";
3837
3979
  const PROPERTY_NAME_STICKY = "sticky";
3838
3980
  const PROPERTY_NAME_BITFLAG = "bitFlag";
3981
+ const PROPERTY_NAME_RAW_BITFLAG = "rawBitFlag";
3982
+ const PROPERTY_NAME_FILENAME_LENGTH = "filenameLength";
3983
+ const PROPERTY_NAME_EXTRA_FIELD_LENGTH = "extraFieldLength";
3984
+ const PROPERTY_NAME_UNIX_EXTERNAL_UPPER = "unixExternalUpper";
3839
3985
  const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
3840
3986
  const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
3841
3987
  const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
@@ -3888,10 +4034,14 @@
3888
4034
  PROPERTY_NAME_UID,
3889
4035
  PROPERTY_NAME_GID,
3890
4036
  PROPERTY_NAME_UNIX_MODE,
4037
+ PROPERTY_NAME_UNIX_EXTERNAL_UPPER,
3891
4038
  PROPERTY_NAME_SETUID,
3892
4039
  PROPERTY_NAME_SETGID,
3893
4040
  PROPERTY_NAME_STICKY,
3894
4041
  PROPERTY_NAME_BITFLAG,
4042
+ PROPERTY_NAME_RAW_BITFLAG,
4043
+ PROPERTY_NAME_FILENAME_LENGTH,
4044
+ PROPERTY_NAME_EXTRA_FIELD_LENGTH,
3895
4045
  PROPERTY_NAME_FILENAME_UTF8,
3896
4046
  PROPERTY_NAME_COMMENT_UTF8,
3897
4047
  PROPERTY_NAME_RAW_EXTRA_FIELD,
@@ -3912,82 +4062,6 @@
3912
4062
 
3913
4063
  }
3914
4064
 
3915
- /*
3916
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
3917
-
3918
- Redistribution and use in source and binary forms, with or without
3919
- modification, are permitted provided that the following conditions are met:
3920
-
3921
- 1. Redistributions of source code must retain the above copyright notice,
3922
- this list of conditions and the following disclaimer.
3923
-
3924
- 2. Redistributions in binary form must reproduce the above copyright
3925
- notice, this list of conditions and the following disclaimer in
3926
- the documentation and/or other materials provided with the distribution.
3927
-
3928
- 3. The names of the authors may not be used to endorse or promote products
3929
- derived from this software without specific prior written permission.
3930
-
3931
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
3932
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
3933
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
3934
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
3935
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3936
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
3937
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3938
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3939
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
3940
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3941
- */
3942
-
3943
- const OPTION_FILENAME_ENCODING = "filenameEncoding";
3944
- const OPTION_COMMENT_ENCODING = "commentEncoding";
3945
- const OPTION_DECODE_TEXT = "decodeText";
3946
- const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
3947
- const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
3948
- const OPTION_PASSWORD = "password";
3949
- const OPTION_RAW_PASSWORD = "rawPassword";
3950
- const OPTION_PASS_THROUGH = "passThrough";
3951
- const OPTION_SIGNAL = "signal";
3952
- const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
3953
- const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
3954
- const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
3955
- const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
3956
- const OPTION_CHECK_SIGNATURE = "checkSignature";
3957
- const OPTION_CHECK_CRC32 = "checkCrc32";
3958
- const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
3959
- const OPTION_USE_WEB_WORKERS = "useWebWorkers";
3960
- const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
3961
- const OPTION_TRANSFER_STREAMS = "transferStreams";
3962
- const OPTION_PREVENT_CLOSE = "preventClose";
3963
- const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
3964
- const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
3965
- const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
3966
- const OPTION_KEEP_ORDER = "keepOrder";
3967
- const OPTION_LEVEL = "level";
3968
- const OPTION_BUFFERED_WRITE = "bufferedWrite";
3969
- const OPTION_CREATE_TEMP_STREAM = "createTempStream";
3970
- const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
3971
- const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
3972
- const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
3973
- const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
3974
- const OPTION_ENCODE_TEXT = "encodeText";
3975
- const OPTION_OFFSET = "offset";
3976
- const OPTION_USDZ = "usdz";
3977
- const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
3978
- const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
3979
- const OPTION_STRICTNESS = "strictness";
3980
- const OPTION_FILENAME_VALIDATION = "filenameValidation";
3981
- const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
3982
- const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
3983
- const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
3984
- const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
3985
- const TEXT_TYPE_FILENAME = "filename";
3986
- const TEXT_TYPE_COMMENT = "comment";
3987
- const STRICTNESS_STRICT = "strict";
3988
- const STRICTNESS_BALANCED = "balanced";
3989
- const STRICTNESS_TOLERANT = "tolerant";
3990
-
3991
4065
  /*
3992
4066
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
3993
4067
 
@@ -4028,6 +4102,7 @@
4028
4102
  const ERR_UNSUPPORTED_COMPRESSION$1 = "Compression method not supported";
4029
4103
  const ERR_SPLIT_ZIP_FILE = "Split zip file";
4030
4104
  const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
4105
+ const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
4031
4106
  const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
4032
4107
  const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
4033
4108
  const ERR_UNSAFE_FILENAME = "Unsafe filename";
@@ -4048,7 +4123,7 @@
4048
4123
  ];
4049
4124
  const ZIP64_EXTRACTION = {
4050
4125
  [MAX_16_BITS]: {
4051
- getValue: getUint32,
4126
+ getValue: getUint32$1,
4052
4127
  bytes: 4
4053
4128
  },
4054
4129
  [MAX_32_BITS]: {
@@ -4057,6 +4132,7 @@
4057
4132
  }
4058
4133
  };
4059
4134
  const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
4135
+ const MAX_DEFLATE_EXPANSION_RATIO = 1032;
4060
4136
  const CENTRAL_DIRECTORY_UNREACHABLE = 0;
4061
4137
  const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
4062
4138
  const CENTRAL_DIRECTORY_REACHABLE = 2;
@@ -4067,7 +4143,6 @@
4067
4143
  Object.assign(this, {
4068
4144
  reader: new GenericReader(reader),
4069
4145
  options,
4070
- config: getConfiguration(),
4071
4146
  readRanges: new Map()
4072
4147
  });
4073
4148
  }
@@ -4075,7 +4150,6 @@
4075
4150
  async* getEntriesGenerator(options = {}) {
4076
4151
  const zipReader = this;
4077
4152
  let { reader } = zipReader;
4078
- const { config } = zipReader;
4079
4153
  await initStream(reader);
4080
4154
  if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
4081
4155
  reader = new BlobReader(await streamToBlob(reader.readable));
@@ -4084,7 +4158,7 @@
4084
4158
  if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
4085
4159
  throw new Error(ERR_BAD_FORMAT);
4086
4160
  }
4087
- const strictness = getStrictness(getOptionValue$1(zipReader, options, OPTION_STRICTNESS), getOptionValue$1(zipReader, options, OPTION_CHECK_AMBIGUITY));
4161
+ const strictness = getStrictness(options, zipReader.options);
4088
4162
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4089
4163
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
4090
4164
  const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
@@ -4092,9 +4166,7 @@
4092
4166
  const normalizeFilename = getOptionValue$1(zipReader, options, OPTION_NORMALIZE_FILENAME);
4093
4167
  const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
4094
4168
  if (!endOfDirectoryInfo) {
4095
- const signatureArray = await readUint8Array(reader, 0, 4);
4096
- const signatureView = getDataView(signatureArray);
4097
- if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
4169
+ if (await startsWithSplitZipSignature$1(reader)) {
4098
4170
  throw new Error(ERR_SPLIT_ZIP_FILE);
4099
4171
  } else {
4100
4172
  throw new Error(ERR_EOCDR_NOT_FOUND);
@@ -4104,18 +4176,18 @@
4104
4176
  throwAmbiguousArchive("multiple end of central directory records");
4105
4177
  }
4106
4178
  const endOfDirectoryView = getDataView(endOfDirectoryInfo);
4107
- let directoryDataLength = getUint32(endOfDirectoryView, 12);
4108
- let directoryDataOffset = getUint32(endOfDirectoryView, 16);
4179
+ let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
4180
+ let directoryDataOffset = getUint32$1(endOfDirectoryView, 16);
4109
4181
  const commentOffset = endOfDirectoryInfo.offset;
4110
- const commentLength = getUint16(endOfDirectoryView, 20);
4182
+ const commentLength = getUint16$1(endOfDirectoryView, 20);
4111
4183
  const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
4112
4184
  if (reader.size - appendedDataOffset > maxAppendedDataSize) {
4113
4185
  throwAmbiguousArchive("appended data");
4114
4186
  }
4115
- let lastDiskNumber = getUint16(endOfDirectoryView, 4);
4187
+ let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
4116
4188
  const expectedLastDiskNumber = reader.lastDiskNumber || 0;
4117
- let diskNumber = getUint16(endOfDirectoryView, 6);
4118
- let filesLength = getUint16(endOfDirectoryView, 10);
4189
+ let diskNumber = getUint16$1(endOfDirectoryView, 6);
4190
+ let filesLength = getUint16$1(endOfDirectoryView, 10);
4119
4191
  let prependedDataLength = 0;
4120
4192
  let startOffset;
4121
4193
  let zip64EndOfDirectory;
@@ -4131,12 +4203,12 @@
4131
4203
  EMPTY_UINT8_ARRAY;
4132
4204
  const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
4133
4205
  if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
4134
- getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
4135
- directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
4206
+ getUint32$1(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
4207
+ directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
4136
4208
  let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4137
4209
  let endOfDirectoryView = getDataView(endOfDirectoryArray);
4138
4210
  const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
4139
- if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
4211
+ if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
4140
4212
  directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
4141
4213
  const originalDirectoryDataOffset = directoryDataOffset;
4142
4214
  directoryDataOffset = expectedDirectoryDataOffset;
@@ -4146,7 +4218,7 @@
4146
4218
  endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4147
4219
  endOfDirectoryView = getDataView(endOfDirectoryArray);
4148
4220
  }
4149
- if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
4221
+ if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
4150
4222
  throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
4151
4223
  }
4152
4224
  zip64EndOfDirectory = true;
@@ -4161,13 +4233,13 @@
4161
4233
  }
4162
4234
  }
4163
4235
  if (lastDiskNumber == MAX_16_BITS) {
4164
- lastDiskNumber = getUint32(endOfDirectoryView, 16);
4165
- } else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
4236
+ lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
4237
+ } else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
4166
4238
  throwAmbiguousArchive("mismatched zip64 end of central directory record");
4167
4239
  }
4168
4240
  if (diskNumber == MAX_16_BITS) {
4169
- diskNumber = getUint32(endOfDirectoryView, 20);
4170
- } else if (checkAmbiguity && diskNumber != getUint32(endOfDirectoryView, 20)) {
4241
+ diskNumber = getUint32$1(endOfDirectoryView, 20);
4242
+ } else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
4171
4243
  throwAmbiguousArchive("mismatched zip64 end of central directory record");
4172
4244
  }
4173
4245
  if (filesLength == MAX_16_BITS) {
@@ -4205,11 +4277,11 @@
4205
4277
  }
4206
4278
  const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
4207
4279
  if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
4208
- const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
4280
+ const storedPointsAtDirectory = getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
4209
4281
  let reconcile = !storedPointsAtDirectory;
4210
4282
  if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
4211
4283
  const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
4212
- reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
4284
+ reconcile = getUint32$1(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
4213
4285
  }
4214
4286
  if (reconcile) {
4215
4287
  const originalDirectoryDataOffset = directoryDataOffset;
@@ -4233,10 +4305,10 @@
4233
4305
  }
4234
4306
  zipReader.directoryOffset = directoryDataOffset;
4235
4307
  zipReader.directoryLength = declaredDirectoryDataLength;
4236
- const decryptCentralDirectory = getOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4308
+ const decryptCentralDirectory = getFunctionOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4237
4309
  let decryptedDirectory;
4238
4310
  if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
4239
- getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4311
+ getUint32$1(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4240
4312
  (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4241
4313
  directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
4242
4314
  directoryView = getDataView(directoryArray);
@@ -4249,8 +4321,8 @@
4249
4321
  const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
4250
4322
  let duplicateFilename;
4251
4323
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4252
- const fileEntry = new ZipEntry$1(reader, config, zipReader.options);
4253
- if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4324
+ const fileEntry = new ZipEntry$1(reader, zipReader.options);
4325
+ if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4254
4326
  if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4255
4327
  throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
4256
4328
  }
@@ -4261,16 +4333,16 @@
4261
4333
  const filenameOffset = offset + CENTRAL_FILE_HEADER_LENGTH;
4262
4334
  const extraFieldOffset = filenameOffset + fileEntry.filenameLength;
4263
4335
  const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
4264
- const versionMadeBy = getUint16(directoryView, offset + 4);
4336
+ const versionMadeBy = getUint16$1(directoryView, offset + 4);
4265
4337
  const msDosCompatible = versionMadeBy >> 8 == 0;
4266
4338
  const unixCompatible = versionMadeBy >> 8 == 3;
4267
4339
  const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
4268
- const commentLength = getUint16(directoryView, offset + 32);
4340
+ const commentLength = getUint16$1(directoryView, offset + 32);
4269
4341
  const endOffset = commentOffset + commentLength;
4270
4342
  const rawComment = directoryArray.subarray(commentOffset, endOffset);
4271
4343
  const filenameUTF8 = languageEncodingFlag;
4272
4344
  const commentUTF8 = languageEncodingFlag;
4273
- const externalFileAttributes = getUint32(directoryView, offset + 38);
4345
+ const externalFileAttributes = getUint32$1(directoryView, offset + 38);
4274
4346
  const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
4275
4347
  const msdosAttributes = {
4276
4348
  readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
@@ -4279,8 +4351,8 @@
4279
4351
  directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
4280
4352
  archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
4281
4353
  };
4282
- const offsetFileEntry = getUint32(directoryView, offset + 42);
4283
- const decode = getOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
4354
+ const offsetFileEntry = getUint32$1(directoryView, offset + 42);
4355
+ const decode = getFunctionOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
4284
4356
  const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
4285
4357
  const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
4286
4358
  let filename = decode(rawFilename, rawFilenameEncoding, TEXT_TYPE_FILENAME);
@@ -4306,12 +4378,13 @@
4306
4378
  index: indexFile,
4307
4379
  versionMadeBy,
4308
4380
  msDosCompatible,
4381
+ zip64: false,
4309
4382
  compressedSize: 0,
4310
4383
  uncompressedSize: 0,
4311
4384
  commentLength,
4312
4385
  offset: offsetFileEntry,
4313
- diskNumberStart: getUint16(directoryView, offset + 34),
4314
- internalFileAttributes: getUint16(directoryView, offset + 36),
4386
+ diskNumberStart: getUint16$1(directoryView, offset + 34),
4387
+ internalFileAttributes: getUint16$1(directoryView, offset + 36),
4315
4388
  externalFileAttributes,
4316
4389
  msdosAttributesRaw,
4317
4390
  msdosAttributes,
@@ -4379,8 +4452,8 @@
4379
4452
  yield entry;
4380
4453
  }
4381
4454
  let offsetAfterSignature = offset;
4382
- if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
4383
- const signatureDataLength = getUint16(directoryView, offset + 4);
4455
+ if (offset + 6 <= directoryArray.length && getUint32$1(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
4456
+ const signatureDataLength = getUint16$1(directoryView, offset + 4);
4384
4457
  if (offset + 6 + signatureDataLength <= directoryArray.length) {
4385
4458
  zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
4386
4459
  offsetAfterSignature = offset + 6 + signatureDataLength;
@@ -4392,13 +4465,17 @@
4392
4465
  if (duplicateFilename) {
4393
4466
  throwAmbiguousArchive("duplicate filename");
4394
4467
  }
4395
- if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > 0))) {
4396
- throwAmbiguousArchive("prepended data");
4397
- }
4398
4468
  const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
4399
4469
  const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
4470
+ const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
4471
+ startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
4472
+ if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
4473
+ throwAmbiguousArchive("prepended data");
4474
+ }
4400
4475
  if (extractPrependedData) {
4401
- zipReader.prependedData = startOffset > 0 ? await readUint8Array(reader, 0, startOffset) : EMPTY_UINT8_ARRAY;
4476
+ zipReader.prependedData = startOffset > splitZipSignatureLength ?
4477
+ await readUint8Array(reader, splitZipSignatureLength, startOffset - splitZipSignatureLength) :
4478
+ EMPTY_UINT8_ARRAY;
4402
4479
  }
4403
4480
  zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : EMPTY_UINT8_ARRAY;
4404
4481
  if (extractAppendedData) {
@@ -4425,16 +4502,16 @@
4425
4502
 
4426
4503
  let ZipEntry$1 = class ZipEntry {
4427
4504
 
4428
- constructor(reader, config, options) {
4505
+ constructor(reader, options) {
4429
4506
  Object.assign(this, {
4430
4507
  reader,
4431
- config,
4432
4508
  options
4433
4509
  });
4434
4510
  }
4435
4511
 
4436
4512
  async getData(writer, fileEntry, readRanges, options = {}) {
4437
4513
  const zipEntry = this;
4514
+ const config = getConfiguration();
4438
4515
  const {
4439
4516
  reader,
4440
4517
  index,
@@ -4443,7 +4520,6 @@
4443
4520
  extraFieldAES,
4444
4521
  extraFieldZip64,
4445
4522
  compressionMethod,
4446
- config,
4447
4523
  bitFlag,
4448
4524
  rawBitFlag,
4449
4525
  crc32,
@@ -4461,6 +4537,7 @@
4461
4537
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
4462
4538
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
4463
4539
  const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
4540
+ checkPasswordOption(password, rawPassword);
4464
4541
  password = password && password.length && password;
4465
4542
  rawPassword = rawPassword && rawPassword.length && rawPassword;
4466
4543
  if (extraFieldAES) {
@@ -4468,7 +4545,7 @@
4468
4545
  throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
4469
4546
  }
4470
4547
  }
4471
- if (dataArray.length < HEADER_SIZE || getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
4548
+ if (dataArray.length < HEADER_SIZE || getUint32$1(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
4472
4549
  throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
4473
4550
  }
4474
4551
  readCommonHeader(localDirectory, dataView, 4);
@@ -4476,9 +4553,12 @@
4476
4553
  extraFieldLength,
4477
4554
  filenameLength
4478
4555
  } = localDirectory;
4479
- const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
4556
+ const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
4557
+ const entryStrictness = getStrictness(options, zipEntry.options);
4558
+ const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
4559
+ const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
4480
4560
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
4481
- if (checkAmbiguity && (filenameLength || extraFieldLength)) {
4561
+ if (checkLocalFilename && (filenameLength || extraFieldLength)) {
4482
4562
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
4483
4563
  rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
4484
4564
  localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
@@ -4487,17 +4567,26 @@
4487
4567
  await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
4488
4568
  EMPTY_UINT8_ARRAY;
4489
4569
  }
4570
+ if (checkLocalFilename) {
4571
+ localDirectory.rawFilename = rawLocalFilename;
4572
+ }
4490
4573
  readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
4491
- if (checkAmbiguity) {
4492
- checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename);
4574
+ if (checkLocalDirectory) {
4575
+ validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
4493
4576
  }
4494
- const { lastAccessDate, creationDate } = localDirectory;
4577
+ const { lastAccessDate, creationDate, uid, gid } = localDirectory;
4495
4578
  if (lastAccessDate) {
4496
4579
  fileEntry.lastAccessDate = lastAccessDate;
4497
4580
  }
4498
4581
  if (creationDate) {
4499
4582
  fileEntry.creationDate = creationDate;
4500
4583
  }
4584
+ if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
4585
+ fileEntry.uid = uid;
4586
+ }
4587
+ if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
4588
+ fileEntry.gid = gid;
4589
+ }
4501
4590
  const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
4502
4591
  const zipCrypto = encrypted && !extraFieldAES;
4503
4592
  if (!passThrough) {
@@ -4518,9 +4607,12 @@
4518
4607
  }
4519
4608
  }
4520
4609
  const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
4610
+ if (dataOffset + compressedSize > reader.size) {
4611
+ throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
4612
+ }
4521
4613
  const size = compressedSize;
4522
4614
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
4523
- const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
4615
+ const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
4524
4616
  const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
4525
4617
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
4526
4618
  const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
@@ -4528,6 +4620,8 @@
4528
4620
  checkOverlappingEntry = true;
4529
4621
  }
4530
4622
  const { onstart, onprogress, onend } = options;
4623
+ const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
4624
+ const outputSize = passThrough ? compressedSize : uncompressedSize;
4531
4625
  const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
4532
4626
  let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
4533
4627
  if (deflate64) {
@@ -4548,9 +4642,9 @@
4548
4642
  checkCrc32,
4549
4643
  checkAuthenticationCode: getOptionValue$1(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
4550
4644
  passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((crc32 >>> 24) & MAX_8_BITS)),
4551
- outputSize: passThrough ? compressedSize : uncompressedSize,
4645
+ outputSize,
4552
4646
  crc32,
4553
- compressed: compressionMethod != 0 && !passThrough,
4647
+ compressed,
4554
4648
  encrypted,
4555
4649
  useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
4556
4650
  useCompressionStream,
@@ -4587,11 +4681,11 @@
4587
4681
  writer = new WritableStream();
4588
4682
  }
4589
4683
  writer = new GenericWriter(writer);
4590
- await initStream(writer, passThrough ? compressedSize : uncompressedSize);
4684
+ await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
4591
4685
  ({ writable } = writer);
4592
- const { outputSize } = await runWorker({ readable, writable }, workerOptions);
4593
- writer.size += outputSize;
4594
- if (outputSize != (passThrough ? compressedSize : uncompressedSize)) {
4686
+ const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
4687
+ writer.size += writtenSize;
4688
+ if (writtenSize != outputSize) {
4595
4689
  throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
4596
4690
  }
4597
4691
  }
@@ -4625,7 +4719,7 @@
4625
4719
  function detectEncryptedCentralDirectory(directoryView) {
4626
4720
  const maxOffset = Math.min(directoryView.byteLength, 1024) - 3;
4627
4721
  for (let offset = 0; offset < maxOffset; offset++) {
4628
- if (getUint32(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
4722
+ if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
4629
4723
  return true;
4630
4724
  }
4631
4725
  }
@@ -4636,15 +4730,15 @@
4636
4730
  const directoryEncryptionInfo = { rawExtensibleData };
4637
4731
  if (rawExtensibleData.length >= 28) {
4638
4732
  const extensibleDataView = getDataView(rawExtensibleData);
4639
- const hashDataLength = getUint16(extensibleDataView, 26);
4733
+ const hashDataLength = getUint16$1(extensibleDataView, 26);
4640
4734
  Object.assign(directoryEncryptionInfo, {
4641
- compressionMethod: getUint16(extensibleDataView, 0),
4735
+ compressionMethod: getUint16$1(extensibleDataView, 0),
4642
4736
  compressedSize: Number(getBigUint64(extensibleDataView, 2)),
4643
4737
  uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
4644
- encryptionAlgorithm: getUint16(extensibleDataView, 18),
4645
- bitLength: getUint16(extensibleDataView, 20),
4646
- flags: getUint16(extensibleDataView, 22),
4647
- hashAlgorithm: getUint16(extensibleDataView, 24),
4738
+ encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
4739
+ bitLength: getUint16$1(extensibleDataView, 20),
4740
+ flags: getUint16$1(extensibleDataView, 22),
4741
+ hashAlgorithm: getUint16$1(extensibleDataView, 24),
4648
4742
  hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
4649
4743
  });
4650
4744
  }
@@ -4652,12 +4746,12 @@
4652
4746
  }
4653
4747
 
4654
4748
  function readCommonHeader(directory, dataView, offset) {
4655
- const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
4749
+ const rawBitFlag = directory.rawBitFlag = getUint16$1(dataView, offset + 2);
4656
4750
  const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
4657
- const rawLastModDate = getUint32(dataView, offset + 6);
4751
+ const rawLastModDate = getUint32$1(dataView, offset + 6);
4658
4752
  Object.assign(directory, {
4659
4753
  encrypted,
4660
- version: getUint16(dataView, offset),
4754
+ version: getUint16$1(dataView, offset),
4661
4755
  bitFlag: {
4662
4756
  level: (rawBitFlag & BITFLAG_LEVEL) >> 1,
4663
4757
  dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR,
@@ -4665,8 +4759,8 @@
4665
4759
  },
4666
4760
  rawLastModDate,
4667
4761
  lastModDate: getDate(rawLastModDate),
4668
- filenameLength: getUint16(dataView, offset + 22),
4669
- extraFieldLength: getUint16(dataView, offset + 24)
4762
+ filenameLength: getUint16$1(dataView, offset + 22),
4763
+ extraFieldLength: getUint16$1(dataView, offset + 24)
4670
4764
  });
4671
4765
  }
4672
4766
 
@@ -4677,8 +4771,8 @@
4677
4771
  let offsetExtraField = 0;
4678
4772
  try {
4679
4773
  while (offsetExtraField < rawExtraField.length) {
4680
- const type = getUint16(rawExtraFieldView, offsetExtraField);
4681
- const size = getUint16(rawExtraFieldView, offsetExtraField + 2);
4774
+ const type = getUint16$1(rawExtraFieldView, offsetExtraField);
4775
+ const size = getUint16$1(rawExtraFieldView, offsetExtraField + 2);
4682
4776
  extraField.set(type, {
4683
4777
  type,
4684
4778
  data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size)
@@ -4688,12 +4782,12 @@
4688
4782
  } catch {
4689
4783
  // ignored
4690
4784
  }
4691
- const compressionMethod = getUint16(dataView, offset + 4);
4785
+ const compressionMethod = getUint16$1(dataView, offset + 4);
4692
4786
  Object.assign(directory, {
4693
- signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
4694
- crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
4695
- compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
4696
- uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
4787
+ signature: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
4788
+ crc32: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
4789
+ compressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
4790
+ uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
4697
4791
  });
4698
4792
  const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
4699
4793
  if (extraFieldZip64) {
@@ -4733,10 +4827,12 @@
4733
4827
  directory.extraFieldNTFS = extraFieldNTFS;
4734
4828
  }
4735
4829
  const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
4830
+ let unixIdsRead;
4736
4831
  if (extraFieldUnix) {
4737
- readExtraFieldUnix(extraFieldUnix, directory, false);
4832
+ unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
4738
4833
  directory.extraFieldUnix = extraFieldUnix;
4739
- } else {
4834
+ }
4835
+ if (!unixIdsRead) {
4740
4836
  const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
4741
4837
  if (extraFieldInfoZip) {
4742
4838
  readExtraFieldUnix(extraFieldInfoZip, directory, true);
@@ -4780,11 +4876,11 @@
4780
4876
  computedCrc32.append(fileEntry[rawPropertyName]);
4781
4877
  const computedCrc32View = getDataView(new Uint8Array(4));
4782
4878
  computedCrc32View.setUint32(0, computedCrc32.get(), true);
4783
- const nameCrc32 = getUint32(extraFieldView, 1);
4879
+ const nameCrc32 = getUint32$1(extraFieldView, 1);
4784
4880
  Object.assign(extraFieldUnicode, {
4785
4881
  version: getUint8(extraFieldView, 0),
4786
4882
  [propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
4787
- valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32(computedCrc32View, 0)
4883
+ valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
4788
4884
  });
4789
4885
  if (extraFieldUnicode.valid) {
4790
4886
  directory[propertyName] = extraFieldUnicode[propertyName];
@@ -4800,7 +4896,7 @@
4800
4896
  vendorId: getUint8(extraFieldView, 2),
4801
4897
  strength,
4802
4898
  originalCompressionMethod: compressionMethod,
4803
- compressionMethod: getUint16(extraFieldView, 5)
4899
+ compressionMethod: getUint16$1(extraFieldView, 5)
4804
4900
  });
4805
4901
  directory.compressionMethod = extraFieldAES.compressionMethod;
4806
4902
  if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1$1) {
@@ -4814,8 +4910,8 @@
4814
4910
  let tag1Data;
4815
4911
  try {
4816
4912
  while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) {
4817
- const tagValue = getUint16(extraFieldView, offsetExtraField);
4818
- const attributeSize = getUint16(extraFieldView, offsetExtraField + 2);
4913
+ const tagValue = getUint16$1(extraFieldView, offsetExtraField);
4914
+ const attributeSize = getUint16$1(extraFieldView, offsetExtraField + 2);
4819
4915
  if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) {
4820
4916
  tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize);
4821
4917
  }
@@ -4839,7 +4935,7 @@
4839
4935
  const creationDate = getDateNTFS(rawCreationDate);
4840
4936
  const extraFieldData = { lastModDate, lastAccessDate, creationDate };
4841
4937
  Object.assign(extraFieldNTFS, extraFieldData);
4842
- Object.assign(directory, extraFieldData);
4938
+ Object.assign(directory, extraFieldData, { rawLastAccessDate, rawCreationDate });
4843
4939
  }
4844
4940
  }
4845
4941
 
@@ -4848,12 +4944,12 @@
4848
4944
  return;
4849
4945
  }
4850
4946
  const extraFieldView = getDataView(extraField.data);
4851
- const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
4852
- const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
4947
+ const lastAccessDate = new Date((getUint32$1(extraFieldView, 0) | 0) * 1000);
4948
+ const lastModDate = new Date((getUint32$1(extraFieldView, 4) | 0) * 1000);
4853
4949
  const extraFieldData = { lastAccessDate, lastModDate };
4854
4950
  if (extraField.data.length >= 12) {
4855
- extraFieldData.uid = getUint16(extraFieldView, 8);
4856
- extraFieldData.gid = getUint16(extraFieldView, 10);
4951
+ extraFieldData.uid = getUint16$1(extraFieldView, 8);
4952
+ extraFieldData.gid = getUint16$1(extraFieldView, 10);
4857
4953
  }
4858
4954
  Object.assign(extraField, extraFieldData);
4859
4955
  Object.assign(directory, extraFieldData);
@@ -4873,8 +4969,8 @@
4873
4969
  gid = unpackUnixId(extraField.data.subarray(offset, offset + gidSize));
4874
4970
  Object.assign(extraField, { version, uid, gid });
4875
4971
  } else if (extraField.data.length >= 4) {
4876
- uid = getUint16(view, 0);
4877
- gid = getUint16(view, 2);
4972
+ uid = getUint16$1(view, 0);
4973
+ gid = getUint16$1(view, 2);
4878
4974
  Object.assign(extraField, { uid, gid });
4879
4975
  }
4880
4976
  if (uid !== UNDEFINED_VALUE) {
@@ -4883,6 +4979,7 @@
4883
4979
  if (gid !== UNDEFINED_VALUE) {
4884
4980
  directory.gid = gid;
4885
4981
  }
4982
+ return uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE;
4886
4983
  } catch {
4887
4984
  // ignored
4888
4985
  }
@@ -4923,7 +5020,7 @@
4923
5020
  let offset = 1;
4924
5021
  timeProperties.forEach((propertyName, indexProperty) => {
4925
5022
  if (extraFieldExtendedTimestamp.data.length >= offset + 4) {
4926
- const time = getUint32(extraFieldView, offset);
5023
+ const time = getUint32$1(extraFieldView, offset);
4927
5024
  directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date((time | 0) * 1000);
4928
5025
  const rawPropertyName = timeRawProperties[indexProperty];
4929
5026
  extraFieldExtendedTimestamp[rawPropertyName] = time;
@@ -4955,26 +5052,25 @@
4955
5052
  }
4956
5053
  if (dataDescriptorLength) {
4957
5054
  const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
4958
- const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
4959
- getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
4960
- if (dataDescriptorSignature) {
4961
- const readCrc32 = getUint32(getDataView(dataDescriptorArray), 4);
4962
- let readCompressedSize;
4963
- let readUncompressedSize;
4964
- if (extraFieldZip64) {
4965
- readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
4966
- readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
4967
- } else {
4968
- readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
4969
- readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
4970
- }
4971
- const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
5055
+ const dataDescriptorView = getDataView(dataDescriptorArray);
5056
+ let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
5057
+ getUint32$1(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5058
+ if (signature) {
5059
+ const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
5060
+ const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
4972
5061
  if (matchCrc32 &&
4973
- readCompressedSize == compressedSize &&
4974
- readUncompressedSize == uncompressedSize) {
5062
+ signedDataDescriptor.compressedSize == compressedSize &&
5063
+ signedDataDescriptor.uncompressedSize == uncompressedSize) {
4975
5064
  dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
5065
+ } else {
5066
+ signature = false;
4976
5067
  }
4977
5068
  }
5069
+ if (dataDescriptorArray.length >= dataDescriptorLength) {
5070
+ const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
5071
+ localDataDescriptor.signature = signature;
5072
+ fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
5073
+ }
4978
5074
  }
4979
5075
  const range = {
4980
5076
  start: offset,
@@ -4991,22 +5087,80 @@
4991
5087
  readRanges.set(index, range);
4992
5088
  }
4993
5089
 
5090
+ function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
5091
+ const crc32 = getUint32$1(dataDescriptorView, offset);
5092
+ let compressedSize;
5093
+ let uncompressedSize;
5094
+ if (extraFieldZip64) {
5095
+ compressedSize = getBigUint64(dataDescriptorView, offset + 4);
5096
+ uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
5097
+ } else {
5098
+ compressedSize = getUint32$1(dataDescriptorView, offset + 4);
5099
+ uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
5100
+ }
5101
+ return { crc32, compressedSize, uncompressedSize };
5102
+ }
5103
+
4994
5104
  function getDiskOffset$1(reader, diskNumber) {
4995
5105
  return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
4996
5106
  }
4997
5107
 
5108
+ async function startsWithSplitZipSignature$1(reader) {
5109
+ return await getFirstSignature(reader) == SPLIT_ZIP_FILE_SIGNATURE;
5110
+ }
5111
+
5112
+ async function startsWithSplitZipMarker(reader) {
5113
+ const signature = await getFirstSignature(reader);
5114
+ return signature == SPLIT_ZIP_FILE_SIGNATURE || signature == TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE;
5115
+ }
5116
+
5117
+ async function getFirstSignature(reader) {
5118
+ const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
5119
+ return getUint32$1(getDataView(signatureArray));
5120
+ }
5121
+
4998
5122
  function isStrictnessValue(value) {
4999
5123
  return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
5000
5124
  }
5001
5125
 
5002
- function getStrictness(strictness, checkAmbiguity) {
5003
- if (strictness === UNDEFINED_VALUE) {
5004
- return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
5126
+ function getDecodableOutputSize(outputSize, compressedSize, compressed) {
5127
+ return Math.min(outputSize, compressed ? compressedSize * MAX_DEFLATE_EXPANSION_RATIO : compressedSize);
5128
+ }
5129
+
5130
+ function getStrictness(options, inheritedOptions) {
5131
+ return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
5132
+ }
5133
+
5134
+ function resolveStrictness(options, inheritedStrictness) {
5135
+ const strictness = options[OPTION_STRICTNESS];
5136
+ if (strictness !== UNDEFINED_VALUE) {
5137
+ if (!isStrictnessValue(strictness)) {
5138
+ throw new Error(ERR_INVALID_STRICTNESS);
5139
+ }
5140
+ return strictness;
5141
+ }
5142
+ const checkAmbiguity = options[OPTION_CHECK_AMBIGUITY];
5143
+ if (checkAmbiguity === UNDEFINED_VALUE) {
5144
+ return inheritedStrictness;
5145
+ }
5146
+ if (checkAmbiguity) {
5147
+ return STRICTNESS_STRICT;
5148
+ }
5149
+ return inheritedStrictness == STRICTNESS_TOLERANT ? STRICTNESS_TOLERANT : STRICTNESS_BALANCED;
5150
+ }
5151
+
5152
+ function getCheckLocalDirectory(checkLocalDirectory, strictness) {
5153
+ if (checkLocalDirectory === UNDEFINED_VALUE) {
5154
+ return strictness != STRICTNESS_TOLERANT;
5005
5155
  }
5006
- if (!isStrictnessValue(strictness)) {
5007
- throw new Error(ERR_INVALID_STRICTNESS);
5156
+ return Boolean(checkLocalDirectory);
5157
+ }
5158
+
5159
+ function getCheckLocalFilename(checkLocalFilename, strictness) {
5160
+ if (checkLocalFilename === UNDEFINED_VALUE) {
5161
+ return strictness == STRICTNESS_STRICT;
5008
5162
  }
5009
- return strictness;
5163
+ return Boolean(checkLocalFilename);
5010
5164
  }
5011
5165
 
5012
5166
  function getFilenameValidation(filenameValidation, strictness) {
@@ -5035,7 +5189,7 @@
5035
5189
 
5036
5190
  function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
5037
5191
  if (maxAppendedDataSize !== UNDEFINED_VALUE) {
5038
- const size = toNumber$1(maxAppendedDataSize);
5192
+ const size = toNumber(maxAppendedDataSize);
5039
5193
  if (typeof size != NUMBER_TYPE || Number.isNaN(size) || size < 0) {
5040
5194
  throw new Error(ERR_INVALID_MAX_APPENDED_DATA_SIZE);
5041
5195
  }
@@ -5058,7 +5212,7 @@
5058
5212
  let plausibleEndOfDirectoryInfo;
5059
5213
  let endOfDirectoryReachingEndCount = 0;
5060
5214
  for await (const [anchoredView, anchoredOffset, anchoredArray, indexByte, offset] of scanEndOfCentralDirectory(reader, anchoredLength)) {
5061
- const commentLength = getUint16(anchoredView, indexByte + 20);
5215
+ const commentLength = getUint16$1(anchoredView, indexByte + 20);
5062
5216
  if (offset + END_OF_CENTRAL_DIR_LENGTH + commentLength == size) {
5063
5217
  const reachability = await getCentralDirectoryReachability(reader, anchoredView, anchoredOffset, indexByte, offset, size, remoteProbeBudget);
5064
5218
  if (reachability == CENTRAL_DIRECTORY_REACHABLE) {
@@ -5109,7 +5263,7 @@
5109
5263
  const scanArray = await readUint8Array(reader, scanOffset, scanLength);
5110
5264
  const scanView = getDataView(scanArray);
5111
5265
  for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
5112
- if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
5266
+ if (getUint32$1(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
5113
5267
  yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
5114
5268
  }
5115
5269
  }
@@ -5120,9 +5274,9 @@
5120
5274
  }
5121
5275
 
5122
5276
  async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
5123
- const filesLength = getUint16(view, indexByte + 10);
5124
- const directoryDataLength = getUint32(view, indexByte + 12);
5125
- const directoryDataOffset = getUint32(view, indexByte + 16);
5277
+ const filesLength = getUint16$1(view, indexByte + 10);
5278
+ const directoryDataLength = getUint32$1(view, indexByte + 12);
5279
+ const directoryDataOffset = getUint32$1(view, indexByte + 16);
5126
5280
  if (filesLength == MAX_16_BITS || directoryDataLength == MAX_32_BITS || directoryDataOffset == MAX_32_BITS) {
5127
5281
  const locatorSignature = await readSignature(reader, view, anchoredOffset, offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, size, remoteProbeBudget);
5128
5282
  return locatorSignature == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE ? CENTRAL_DIRECTORY_REACHABLE : CENTRAL_DIRECTORY_UNREACHABLE;
@@ -5130,7 +5284,7 @@
5130
5284
  if (!filesLength && !directoryDataLength) {
5131
5285
  return CENTRAL_DIRECTORY_PLAUSIBLE;
5132
5286
  }
5133
- const directoryDiskNumber = getUint16(view, indexByte + 6);
5287
+ const directoryDiskNumber = getUint16$1(view, indexByte + 6);
5134
5288
  for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
5135
5289
  if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
5136
5290
  return CENTRAL_DIRECTORY_REACHABLE;
@@ -5144,20 +5298,21 @@
5144
5298
  return UNDEFINED_VALUE;
5145
5299
  }
5146
5300
  if (signatureOffset >= anchoredOffset) {
5147
- return getUint32(view, signatureOffset - anchoredOffset);
5301
+ return getUint32$1(view, signatureOffset - anchoredOffset);
5148
5302
  }
5149
5303
  if (remoteProbeBudget.count > 0) {
5150
5304
  remoteProbeBudget.count--;
5151
5305
  const signatureArray = await readUint8Array(reader, signatureOffset, 4);
5152
- return getUint32(getDataView(signatureArray), 0);
5306
+ return getUint32$1(getDataView(signatureArray), 0);
5153
5307
  }
5154
5308
  return UNDEFINED_VALUE;
5155
5309
  }
5156
5310
 
5157
- function checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename) {
5311
+ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
5158
5312
  const { rawFilename } = zipEntry;
5159
- if (rawLocalFilename.length != rawFilename.length ||
5160
- rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte])) {
5313
+ if (checkLocalFilename &&
5314
+ (rawLocalFilename.length != rawFilename.length ||
5315
+ rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
5161
5316
  throwAmbiguousArchive("mismatched local file header (filename)");
5162
5317
  }
5163
5318
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
@@ -5185,10 +5340,11 @@
5185
5340
  return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
5186
5341
  }
5187
5342
 
5188
- function toNumber$1(value) {
5189
- return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
5343
+ function getFunctionOptionValue$1(zipReader, options, name) {
5344
+ return checkFunctionOption(getOptionValue$1(zipReader, options, name));
5190
5345
  }
5191
5346
 
5347
+
5192
5348
  function getDate(timeRaw) {
5193
5349
  const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
5194
5350
  return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
@@ -5202,11 +5358,11 @@
5202
5358
  return view.getUint8(offset);
5203
5359
  }
5204
5360
 
5205
- function getUint16(view, offset) {
5361
+ function getUint16$1(view, offset) {
5206
5362
  return view.getUint16(offset, true);
5207
5363
  }
5208
5364
 
5209
- function getUint32(view, offset) {
5365
+ function getUint32$1(view, offset) {
5210
5366
  return view.getUint32(offset, true);
5211
5367
  }
5212
5368
 
@@ -5221,6 +5377,7 @@
5221
5377
  ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
5222
5378
  ERR_ENCRYPTED: ERR_ENCRYPTED,
5223
5379
  ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
5380
+ ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
5224
5381
  ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
5225
5382
  ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
5226
5383
  ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
@@ -5273,13 +5430,18 @@
5273
5430
 
5274
5431
  const ERR_DUPLICATED_NAME = "File already exists";
5275
5432
  const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
5433
+ const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
5276
5434
  const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
5435
+ const ERR_INVALID_ENTRY_COMMENT_TYPE = "Invalid file entry comment (must be a string)";
5436
+ const ERR_INVALID_DATE = "Invalid date (must be a valid Date instance)";
5277
5437
  const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
5278
5438
  const ERR_INVALID_VERSION = "Version exceeds 65535";
5279
5439
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
5280
5440
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
5281
5441
  const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
5282
- const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
5442
+ const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
5443
+ const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
5444
+ const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
5283
5445
  const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
5284
5446
  const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
5285
5447
  const MIN_UNIX_TIME = -2147483648;
@@ -5299,7 +5461,6 @@
5299
5461
  const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
5300
5462
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
5301
5463
  const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
5302
- const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
5303
5464
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
5304
5465
 
5305
5466
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
@@ -5324,8 +5485,7 @@
5324
5485
  writer,
5325
5486
  addSplitZipSignature,
5326
5487
  options,
5327
- config: getConfiguration(),
5328
- files: new Map(),
5488
+ fileEntries: new Map(),
5329
5489
  filenames: new Set(),
5330
5490
  offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
5331
5491
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
@@ -5341,15 +5501,28 @@
5341
5501
  }
5342
5502
  reader = new GenericReader(reader);
5343
5503
  await initStream(reader);
5504
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
5505
+ reader = new BlobReader(await streamToBlob(reader.readable));
5506
+ await initStream(reader);
5507
+ }
5344
5508
  const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
5345
- const zipReader$1 = new ZipReader(reader.readable);
5509
+ const zipReader$1 = new ZipReader(reader);
5346
5510
  const entries = await zipReader$1.getEntries();
5347
5511
  await zipReader$1.close();
5348
5512
  await initStream(this.writer);
5349
- await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
5350
- this.writer.size = this.offset = reader.size;
5513
+ const { directoryOffset } = zipReader$1;
5514
+ let splitZipSignatureLength = 0;
5515
+ if (this.addSplitZipSignature) {
5516
+ delete this.addSplitZipSignature;
5517
+ if (!await startsWithSplitZipSignature(reader)) {
5518
+ await writeData(this.writer, getSplitZipSignatureArray());
5519
+ splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
5520
+ this.offset += splitZipSignatureLength;
5521
+ }
5522
+ }
5523
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
5351
5524
  this.filenames = new Set(entries.map(entry => entry.filename));
5352
- this.files = new Map(entries.map(entry => {
5525
+ this.fileEntries = new Map(entries.map(entry => {
5353
5526
  const {
5354
5527
  version,
5355
5528
  rawLastModDate,
@@ -5404,11 +5577,12 @@
5404
5577
  if (crc32 !== UNDEFINED_VALUE) {
5405
5578
  setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
5406
5579
  }
5580
+ const { offset, diskNumberStart } = entryPositions.get(entry);
5407
5581
  Object.assign(entry, {
5408
5582
  zip64UncompressedSize,
5409
5583
  zip64CompressedSize,
5410
- zip64Offset: zip64 && entry.offset >= MAX_32_BITS,
5411
- diskNumberStart: 0,
5584
+ offset,
5585
+ diskNumberStart,
5412
5586
  zip64DiskNumberStart: false,
5413
5587
  rawExtraFieldZip64,
5414
5588
  rawExtraFieldAES,
@@ -5428,11 +5602,8 @@
5428
5602
  async add(name = "", reader, options = {}) {
5429
5603
  const zipWriter = this;
5430
5604
  options = Object.assign({}, options);
5431
- const {
5432
- pendingAddFileCalls,
5433
- config
5434
- } = zipWriter;
5435
- if (workers < config.maxWorkers) {
5605
+ const { pendingAddFileCalls } = zipWriter;
5606
+ if (workers < getConfiguration().maxWorkers) {
5436
5607
  workers++;
5437
5608
  } else {
5438
5609
  await new Promise(resolve => pendingEntries.push(resolve));
@@ -5469,16 +5640,16 @@
5469
5640
  }
5470
5641
 
5471
5642
  remove(entry) {
5472
- const { filenames, files } = this;
5643
+ const { filenames, fileEntries } = this;
5473
5644
  // deno-lint-ignore valid-typeof
5474
5645
  if (typeof entry == STRING_TYPE) {
5475
- entry = files.get(entry);
5646
+ entry = fileEntries.get(entry);
5476
5647
  }
5477
5648
  if (entry && entry.filename !== UNDEFINED_VALUE) {
5478
5649
  const { filename } = entry;
5479
- if (filenames.has(filename) && files.has(filename)) {
5650
+ if (filenames.has(filename) && fileEntries.has(filename)) {
5480
5651
  filenames.delete(filename);
5481
- files.delete(filename);
5652
+ fileEntries.delete(filename);
5482
5653
  return true;
5483
5654
  }
5484
5655
  }
@@ -5489,6 +5660,9 @@
5489
5660
  const zipWriter = this;
5490
5661
  const { pendingAddFileCalls, writer } = this;
5491
5662
  const { writable } = writer;
5663
+ if (!(comment instanceof Uint8Array)) {
5664
+ throw new Error(ERR_INVALID_COMMENT_TYPE);
5665
+ }
5492
5666
  if (getLength(comment) > MAX_16_BITS) {
5493
5667
  throw new Error(ERR_INVALID_COMMENT);
5494
5668
  }
@@ -5510,12 +5684,12 @@
5510
5684
  const metadataInfo = resolveMetadata(zipWriter, name, options);
5511
5685
  const { comment } = metadataInfo;
5512
5686
  const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
5513
- zipWriter.files.set(name, UNDEFINED_VALUE);
5687
+ zipWriter.fileEntries.set(name, UNDEFINED_VALUE);
5514
5688
  let fileEntry;
5515
5689
  try {
5516
5690
  const { resolvedOptions } = metadataInfo;
5517
5691
  if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
5518
- !resolvedOptions.passThrough && !(await supportsDeflate(zipWriter.config))) {
5692
+ !resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
5519
5693
  resolvedOptions.level = 0;
5520
5694
  }
5521
5695
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
@@ -5523,8 +5697,6 @@
5523
5697
  const diskOffset = getDiskOffset(zipWriter.writer);
5524
5698
  const diskNumber = getDiskNumber(zipWriter.writer);
5525
5699
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
5526
- internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
5527
- externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
5528
5700
  signature: options[PROPERTY_NAME_SIGNATURE],
5529
5701
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
5530
5702
  offset: zipWriter.offset - diskOffset,
@@ -5535,17 +5707,23 @@
5535
5707
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
5536
5708
  fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
5537
5709
  } catch (error) {
5538
- zipWriter.files.delete(name);
5710
+ zipWriter.fileEntries.delete(name);
5539
5711
  throw error;
5540
5712
  }
5541
- Object.assign(fileEntry, { name, comment, extraField });
5713
+ Object.assign(fileEntry, {
5714
+ name,
5715
+ comment,
5716
+ extraField,
5717
+ [PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
5718
+ [PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
5719
+ });
5542
5720
  return new Entry(fileEntry);
5543
5721
  }
5544
5722
 
5545
5723
  function resolveAttributes(zipWriter, name, options) {
5546
5724
  name = name.trim();
5547
5725
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
5548
- let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
5726
+ let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
5549
5727
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
5550
5728
  const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
5551
5729
  const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
@@ -5573,21 +5751,21 @@
5573
5751
  if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
5574
5752
  unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
5575
5753
  }
5576
- let msdosAttributesRaw = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
5754
+ let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
5577
5755
  let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
5578
- const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
5756
+ const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType || executable;
5579
5757
  const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
5580
5758
  if (hasUnixMetadata) {
5581
5759
  msDosCompatible = false;
5582
- versionMadeBy = (versionMadeBy & MAX_16_BITS) | (3 << 8);
5760
+ versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
5583
5761
  } else if (hasMsDosProvided) {
5584
5762
  msDosCompatible = true;
5585
5763
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
5586
5764
  }
5587
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
5765
+ if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
5588
5766
  throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
5589
5767
  }
5590
- if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
5768
+ if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
5591
5769
  throw new Error(ERR_INVALID_MSDOS_DATA);
5592
5770
  }
5593
5771
  if (versionMadeBy > MAX_16_BITS) {
@@ -5619,11 +5797,10 @@
5619
5797
  externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
5620
5798
  }
5621
5799
  }
5622
- let unixExternalUpper;
5623
5800
  if (!msDosCompatible) {
5624
5801
  const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
5625
- unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
5626
- unixMode = unixMode === UNDEFINED_VALUE ? unixExternalUpper : (unixMode & MAX_16_BITS);
5802
+ const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
5803
+ unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
5627
5804
  if (setuid) {
5628
5805
  unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
5629
5806
  } else {
@@ -5652,17 +5829,20 @@
5652
5829
  if (hasMsDosProvided) {
5653
5830
  externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
5654
5831
  }
5832
+ const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
5833
+ const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
5655
5834
  return {
5656
5835
  name,
5657
5836
  resolvedOptions: {
5658
5837
  versionMadeBy,
5659
- msDosCompatible,
5838
+ msDosCompatible: Boolean(msDosCompatible),
5660
5839
  externalFileAttributes,
5661
5840
  unixExternalUpper,
5662
5841
  uid,
5663
5842
  gid,
5664
5843
  unixMode,
5665
5844
  unixExtraFieldType,
5845
+ symlink,
5666
5846
  setuid,
5667
5847
  setgid,
5668
5848
  sticky,
@@ -5673,7 +5853,7 @@
5673
5853
  }
5674
5854
 
5675
5855
  function resolveMetadata(zipWriter, name, options) {
5676
- const encode = getOptionValue(zipWriter, options, OPTION_ENCODE_TEXT, encodeText);
5856
+ const encode = getFunctionOptionValue(zipWriter, options, OPTION_ENCODE_TEXT) || encodeText;
5677
5857
  let rawFilename = encode(name, TEXT_TYPE_FILENAME);
5678
5858
  if (rawFilename === UNDEFINED_VALUE) {
5679
5859
  rawFilename = encodeText(name);
@@ -5682,6 +5862,10 @@
5682
5862
  throw new Error(ERR_INVALID_ENTRY_NAME);
5683
5863
  }
5684
5864
  const comment = options[PROPERTY_NAME_COMMENT] || "";
5865
+ // deno-lint-ignore valid-typeof
5866
+ if (typeof comment != STRING_TYPE) {
5867
+ throw new Error(ERR_INVALID_ENTRY_COMMENT_TYPE);
5868
+ }
5685
5869
  let rawComment = encode(comment, TEXT_TYPE_COMMENT);
5686
5870
  if (rawComment === UNDEFINED_VALUE) {
5687
5871
  rawComment = encodeText(comment);
@@ -5693,16 +5877,14 @@
5693
5877
  if (version > MAX_16_BITS) {
5694
5878
  throw new Error(ERR_INVALID_VERSION);
5695
5879
  }
5696
- const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
5697
- const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
5698
- const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
5880
+ const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
5881
+ const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
5882
+ const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
5699
5883
  const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
5700
5884
  const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
5701
5885
  const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
5702
5886
  const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
5703
- if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
5704
- throw new Error(ERR_INVALID_PASSWORD_TYPE);
5705
- }
5887
+ checkPasswordOption(password, rawPassword);
5706
5888
  const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
5707
5889
  const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
5708
5890
  const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
@@ -5711,9 +5893,9 @@
5711
5893
  const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
5712
5894
  const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
5713
5895
  const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
5714
- const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
5896
+ const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
5715
5897
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
5716
- const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
5898
+ const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
5717
5899
  const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
5718
5900
  const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
5719
5901
  const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
@@ -5793,18 +5975,26 @@
5793
5975
  if (!extraField) {
5794
5976
  return EMPTY_UINT8_ARRAY;
5795
5977
  }
5978
+ if (!(extraField instanceof Map)) {
5979
+ throw new Error(ERR_INVALID_EXTRAFIELD);
5980
+ }
5796
5981
  let extraFieldSize = 0;
5797
5982
  let offset = 0;
5798
- extraField.forEach(data => extraFieldSize += 4 + getLength(data));
5799
- const rawExtraField = new Uint8Array(extraFieldSize);
5800
- const rawExtraFieldView = getDataView(rawExtraField);
5801
5983
  extraField.forEach((data, type) => {
5802
- if (type > MAX_16_BITS) {
5984
+ if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
5803
5985
  throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
5804
5986
  }
5987
+ if (!(data instanceof Uint8Array)) {
5988
+ throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
5989
+ }
5805
5990
  if (getLength(data) > MAX_16_BITS) {
5806
5991
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
5807
5992
  }
5993
+ extraFieldSize += 4 + getLength(data);
5994
+ });
5995
+ const rawExtraField = new Uint8Array(extraFieldSize);
5996
+ const rawExtraFieldView = getDataView(rawExtraField);
5997
+ extraField.forEach((data, type) => {
5808
5998
  setUint16(rawExtraFieldView, offset, type);
5809
5999
  setUint16(rawExtraFieldView, offset + 2, getLength(data));
5810
6000
  arraySet(rawExtraField, data, offset + 4);
@@ -5891,10 +6081,13 @@
5891
6081
  }
5892
6082
 
5893
6083
  async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
5894
- const zipWriter = { options: writerOptions, config: getConfiguration() };
5895
- if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
6084
+ const zipWriter = { options: writerOptions };
6085
+ if (checkFunctionOption(writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY])) {
5896
6086
  throw new Error(ERR_UNDETERMINED_SIZE);
5897
6087
  }
6088
+ if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
6089
+ throw new Error(ERR_INVALID_COMMENT_TYPE);
6090
+ }
5898
6091
  const commentLength = getLength(comment);
5899
6092
  if (commentLength > MAX_16_BITS) {
5900
6093
  throw new Error(ERR_INVALID_COMMENT);
@@ -5915,7 +6108,7 @@
5915
6108
  ({ name } = attributesInfo);
5916
6109
  const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
5917
6110
  if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
5918
- !metadata.passThrough && !(await supportsDeflate(zipWriter.config))) {
6111
+ !metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
5919
6112
  metadata.level = 0;
5920
6113
  }
5921
6114
  const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
@@ -5964,7 +6157,7 @@
5964
6157
 
5965
6158
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
5966
6159
  const {
5967
- files,
6160
+ fileEntries,
5968
6161
  writer
5969
6162
  } = zipWriter;
5970
6163
  const {
@@ -5986,12 +6179,12 @@
5986
6179
  let writerSizeBeforeEntry;
5987
6180
  let flushedBufferedSize = 0;
5988
6181
  let fileWriter;
5989
- files.set(name, fileEntry);
6182
+ fileEntries.set(name, fileEntry);
5990
6183
  zipWriter.lastFileEntry = fileEntry;
5991
6184
  try {
5992
6185
  let lockPreviousFileEntry;
5993
6186
  if (keepOrder) {
5994
- lockPreviousFileEntry = previousFileEntry && previousFileEntry.lock;
6187
+ lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
5995
6188
  requestLockCurrentFileEntry();
5996
6189
  }
5997
6190
  if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
@@ -6012,11 +6205,8 @@
6012
6205
  const diskOffset = getDiskOffset(writer);
6013
6206
  if (zipWriter.addSplitZipSignature) {
6014
6207
  delete zipWriter.addSplitZipSignature;
6015
- const signatureArray = new Uint8Array(4);
6016
- const signatureArrayView = getDataView(signatureArray);
6017
- setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
6018
- await writeData(writer, signatureArray);
6019
- zipWriter.offset += 4;
6208
+ await writeData(writer, getSplitZipSignatureArray());
6209
+ zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6020
6210
  }
6021
6211
  if (usdz && !bufferedWrite) {
6022
6212
  appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
@@ -6034,11 +6224,11 @@
6034
6224
  writerSizeBeforeEntry = writer.size;
6035
6225
  await writeData(fileWriter, localHeaderArray);
6036
6226
  }
6037
- fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, zipWriter.config, options);
6227
+ fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, getConfiguration(), options);
6038
6228
  if (!bufferedWrite) {
6039
6229
  writingEntryData = false;
6040
6230
  }
6041
- files.set(name, fileEntry);
6231
+ fileEntries.set(name, fileEntry);
6042
6232
  fileEntry.filename = name;
6043
6233
  if (bufferedWrite) {
6044
6234
  await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
@@ -6079,7 +6269,7 @@
6079
6269
  zipWriter.offset += flushedBufferedSize;
6080
6270
  }
6081
6271
  }
6082
- files.delete(name);
6272
+ fileEntries.delete(name);
6083
6273
  throw error;
6084
6274
  } finally {
6085
6275
  if (bufferedWrite) {
@@ -6101,7 +6291,7 @@
6101
6291
  }
6102
6292
 
6103
6293
  function requestLockCurrentFileEntry() {
6104
- fileEntry.lock = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
6294
+ fileEntry.lockFileEntry = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
6105
6295
  }
6106
6296
 
6107
6297
  async function requestLockWriter() {
@@ -6121,7 +6311,7 @@
6121
6311
  }
6122
6312
  }
6123
6313
 
6124
- async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryInfo, config, options) {
6314
+ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry }, entryInfo, config, options) {
6125
6315
  const {
6126
6316
  headerInfo,
6127
6317
  dataDescriptorInfo,
@@ -6176,6 +6366,7 @@
6176
6366
  uid,
6177
6367
  gid,
6178
6368
  unixMode,
6369
+ symlink,
6179
6370
  setuid,
6180
6371
  setgid,
6181
6372
  sticky,
@@ -6188,7 +6379,7 @@
6188
6379
  codecURI
6189
6380
  } = options;
6190
6381
  const fileEntry = {
6191
- lock,
6382
+ lockFileEntry,
6192
6383
  versionMadeBy,
6193
6384
  zip64,
6194
6385
  directory: Boolean(directory),
@@ -6212,6 +6403,7 @@
6212
6403
  uid,
6213
6404
  gid,
6214
6405
  unixMode,
6406
+ symlink: Boolean(symlink),
6215
6407
  setuid,
6216
6408
  setgid,
6217
6409
  sticky,
@@ -6229,7 +6421,7 @@
6229
6421
  }
6230
6422
  const { writable } = writer;
6231
6423
  if (reader) {
6232
- const readable = toCompatibleReadable(reader.createReadable ? reader.createReadable() : reader.readable);
6424
+ const readable = toCompatibleReadable(createReadable(reader));
6233
6425
  const size = reader.size;
6234
6426
  const workerOptions = {
6235
6427
  options: {
@@ -6292,8 +6484,8 @@
6292
6484
  rawLastModDate,
6293
6485
  creationDate,
6294
6486
  lastAccessDate,
6295
- encrypted,
6296
- zipCrypto,
6487
+ encrypted: Boolean(encrypted),
6488
+ zipCrypto: Boolean(zipCrypto),
6297
6489
  size: metadataSize + compressedSize,
6298
6490
  compressionMethod,
6299
6491
  version,
@@ -6341,14 +6533,14 @@
6341
6533
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
6342
6534
  const length = 4 + 16;
6343
6535
  const extraFieldZip64 = createRecordWriter(length);
6344
- extraFieldZip64.uint16(EXTRAFIELD_TYPE_ZIP64);
6345
- extraFieldZip64.uint16(length - 4);
6536
+ extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
6537
+ extraFieldZip64.writeUint16(length - 4);
6346
6538
  rawLocalExtraFieldZip64 = extraFieldZip64.array;
6347
6539
  if (zip64ExtraFieldComplete) {
6348
- extraFieldZip64.uint64(uncompressedSize);
6540
+ extraFieldZip64.writeUint64(uncompressedSize);
6349
6541
  if (uncompressedFile) {
6350
6542
  const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
6351
- extraFieldZip64.uint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
6543
+ extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
6352
6544
  }
6353
6545
  }
6354
6546
  } else {
@@ -6357,8 +6549,8 @@
6357
6549
  let rawExtraFieldAES;
6358
6550
  if (encrypted && !zipCrypto) {
6359
6551
  const extraFieldAES = createRecordWriter(getLength(EXTRAFIELD_DATA_AES) + 2);
6360
- extraFieldAES.uint16(EXTRAFIELD_TYPE_AES);
6361
- extraFieldAES.bytes(EXTRAFIELD_DATA_AES);
6552
+ extraFieldAES.writeUint16(EXTRAFIELD_TYPE_AES);
6553
+ extraFieldAES.writeBytes(EXTRAFIELD_DATA_AES);
6362
6554
  rawExtraFieldAES = extraFieldAES.array;
6363
6555
  rawExtraFieldAES[8] = encryptionStrength;
6364
6556
  } else {
@@ -6374,15 +6566,15 @@
6374
6566
  const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
6375
6567
  const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
6376
6568
  extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
6377
- extraFieldTimestamp.uint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
6378
- extraFieldTimestamp.uint16(extraFieldTimestampLength - 4);
6379
- extraFieldTimestamp.uint8(extraFieldExtendedTimestampFlag);
6380
- extraFieldTimestamp.uint32(lastModTimeUnix);
6569
+ extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
6570
+ extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
6571
+ extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
6572
+ extraFieldTimestamp.writeUint32(lastModTimeUnix);
6381
6573
  if (lastAccessDate) {
6382
- extraFieldTimestamp.uint32(clampUnixTime(getTimeUnix(lastAccessDate)));
6574
+ extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(lastAccessDate)));
6383
6575
  }
6384
6576
  if (creationDate) {
6385
- extraFieldTimestamp.uint32(clampUnixTime(getTimeUnix(creationDate)));
6577
+ extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(creationDate)));
6386
6578
  }
6387
6579
  rawExtraFieldExtendedTimestamp = extraFieldTimestamp.array;
6388
6580
  } else {
@@ -6395,14 +6587,14 @@
6395
6587
  try {
6396
6588
  const lastModTimeNTFS = getTimeNTFS(lastModDate);
6397
6589
  const extraFieldNTFS = createRecordWriter(36);
6398
- extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS);
6399
- extraFieldNTFS.uint16(32);
6590
+ extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS);
6591
+ extraFieldNTFS.writeUint16(32);
6400
6592
  extraFieldNTFS.skip(4);
6401
- extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS_TAG1);
6402
- extraFieldNTFS.uint16(24);
6403
- extraFieldNTFS.uint64(lastModTimeNTFS);
6404
- extraFieldNTFS.uint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
6405
- extraFieldNTFS.uint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
6593
+ extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS_TAG1);
6594
+ extraFieldNTFS.writeUint16(24);
6595
+ extraFieldNTFS.writeUint64(lastModTimeNTFS);
6596
+ extraFieldNTFS.writeUint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
6597
+ extraFieldNTFS.writeUint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
6406
6598
  rawExtraFieldNTFS = extraFieldNTFS.array;
6407
6599
  } catch {
6408
6600
  rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
@@ -6421,20 +6613,20 @@
6421
6613
  const gidBytes = packUnixId(gid);
6422
6614
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
6423
6615
  const extraFieldUnix = createRecordWriter(4 + payloadLength);
6424
- extraFieldUnix.uint16(EXTRAFIELD_TYPE_INFOZIP);
6425
- extraFieldUnix.uint16(payloadLength);
6426
- extraFieldUnix.uint8(1);
6427
- extraFieldUnix.uint8(uidBytes.length);
6428
- extraFieldUnix.bytes(uidBytes);
6429
- extraFieldUnix.uint8(gidBytes.length);
6430
- extraFieldUnix.bytes(gidBytes);
6616
+ extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
6617
+ extraFieldUnix.writeUint16(payloadLength);
6618
+ extraFieldUnix.writeUint8(1);
6619
+ extraFieldUnix.writeUint8(uidBytes.length);
6620
+ extraFieldUnix.writeBytes(uidBytes);
6621
+ extraFieldUnix.writeUint8(gidBytes.length);
6622
+ extraFieldUnix.writeBytes(gidBytes);
6431
6623
  rawExtraFieldUnix = extraFieldUnix.array;
6432
6624
  } else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
6433
6625
  const extraFieldUnix = createRecordWriter(8);
6434
- extraFieldUnix.uint16(EXTRAFIELD_TYPE_UNIX);
6435
- extraFieldUnix.uint16(4);
6436
- extraFieldUnix.uint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
6437
- extraFieldUnix.uint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
6626
+ extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
6627
+ extraFieldUnix.writeUint16(4);
6628
+ extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
6629
+ extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
6438
6630
  rawExtraFieldUnix = extraFieldUnix.array;
6439
6631
  } else {
6440
6632
  rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
@@ -6484,18 +6676,18 @@
6484
6676
  const localHeader = createRecordWriter(HEADER_SIZE + getLength(rawFilename) + extraFieldLength);
6485
6677
  const localHeaderArray = localHeader.array;
6486
6678
  const localHeaderView = getDataView(localHeaderArray);
6487
- localHeader.uint32(LOCAL_FILE_HEADER_SIGNATURE);
6488
- localHeader.bytes(headerArray);
6489
- localHeader.bytes(rawFilename);
6679
+ localHeader.writeUint32(LOCAL_FILE_HEADER_SIGNATURE);
6680
+ localHeader.writeBytes(headerArray);
6681
+ localHeader.writeBytes(rawFilename);
6490
6682
  if (writeLocalExtraFieldZip64) {
6491
- localHeader.bytes(rawLocalExtraFieldZip64);
6492
- }
6493
- localHeader.bytes(rawExtraFieldAES);
6494
- localHeader.bytes(rawExtraFieldExtendedTimestamp);
6495
- localHeader.bytes(rawExtraFieldNTFS);
6496
- localHeader.bytes(rawExtraFieldUnix);
6497
- localHeader.bytes(rawExtraField);
6498
- localHeader.bytes(rawLocalExtraField);
6683
+ localHeader.writeBytes(rawLocalExtraFieldZip64);
6684
+ }
6685
+ localHeader.writeBytes(rawExtraFieldAES);
6686
+ localHeader.writeBytes(rawExtraFieldExtendedTimestamp);
6687
+ localHeader.writeBytes(rawExtraFieldNTFS);
6688
+ localHeader.writeBytes(rawExtraFieldUnix);
6689
+ localHeader.writeBytes(rawExtraField);
6690
+ localHeader.writeBytes(rawLocalExtraField);
6499
6691
  if (dataDescriptor) {
6500
6692
  if (!zip64CompressedSize) {
6501
6693
  setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, 0);
@@ -6685,7 +6877,7 @@
6685
6877
 
6686
6878
 
6687
6879
  async function closeFile(zipWriter, comment, options) {
6688
- const directoryDataLength = createDirectoryRecords(zipWriter.files);
6880
+ const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
6689
6881
  const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
6690
6882
  const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
6691
6883
  await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
@@ -6715,19 +6907,19 @@
6715
6907
  if (zip64Offset || zip64DiskNumberStart || zip64UncompressedSize || zip64CompressedSize) {
6716
6908
  const length = 4 + (zip64UncompressedSize ? 8 : 0) + (zip64CompressedSize ? 8 : 0) + (zip64Offset ? 8 : 0) + (zip64DiskNumberStart ? 4 : 0);
6717
6909
  const extraFieldZip64 = createRecordWriter(length);
6718
- extraFieldZip64.uint16(EXTRAFIELD_TYPE_ZIP64);
6719
- extraFieldZip64.uint16(length - 4);
6910
+ extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
6911
+ extraFieldZip64.writeUint16(length - 4);
6720
6912
  if (zip64UncompressedSize) {
6721
- extraFieldZip64.uint64(uncompressedSize);
6913
+ extraFieldZip64.writeUint64(uncompressedSize);
6722
6914
  }
6723
6915
  if (zip64CompressedSize) {
6724
- extraFieldZip64.uint64(compressedSize);
6916
+ extraFieldZip64.writeUint64(compressedSize);
6725
6917
  }
6726
6918
  if (zip64Offset) {
6727
- extraFieldZip64.uint64(fileEntry.offset);
6919
+ extraFieldZip64.writeUint64(fileEntry.offset);
6728
6920
  }
6729
6921
  if (zip64DiskNumberStart) {
6730
- extraFieldZip64.uint32(fileEntry.diskNumberStart);
6922
+ extraFieldZip64.writeUint32(fileEntry.diskNumberStart);
6731
6923
  }
6732
6924
  rawExtraFieldZip64 = extraFieldZip64.array;
6733
6925
  } else {
@@ -6740,10 +6932,10 @@
6740
6932
  const lastModTimeUnix = getTimeUnix(lastModDate);
6741
6933
  if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
6742
6934
  const extraFieldTimestamp = createRecordWriter(9);
6743
- extraFieldTimestamp.uint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
6744
- extraFieldTimestamp.uint16(5);
6745
- extraFieldTimestamp.uint8(extraFieldExtendedTimestampFlag);
6746
- extraFieldTimestamp.uint32(lastModTimeUnix);
6935
+ extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
6936
+ extraFieldTimestamp.writeUint16(5);
6937
+ extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
6938
+ extraFieldTimestamp.writeUint32(lastModTimeUnix);
6747
6939
  rawExtraFieldTimestamp = extraFieldTimestamp.array;
6748
6940
  } else {
6749
6941
  rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
@@ -6765,14 +6957,14 @@
6765
6957
  }
6766
6958
 
6767
6959
  async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
6768
- const { files, writer } = zipWriter;
6960
+ const { fileEntries, writer } = zipWriter;
6769
6961
  const directoryArray = new Uint8Array(directoryDataLength);
6770
6962
  await initStream(writer);
6771
6963
  let offset = 0;
6772
6964
  let directoryDiskOffset = 0;
6773
6965
  let directoryStartDiskNumber = getDiskNumber(writer);
6774
6966
  let directoryStartDiskOffset = getDiskOffset(writer);
6775
- for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
6967
+ for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
6776
6968
  const {
6777
6969
  offset: fileEntryOffset,
6778
6970
  rawFilename,
@@ -6817,28 +7009,28 @@
6817
7009
  setUint16(headerView, HEADER_OFFSET_VERSION, VERSION_ZIP64);
6818
7010
  }
6819
7011
  const directoryRecord = createRecordWriter(directoryRecordLength);
6820
- directoryRecord.uint32(CENTRAL_FILE_HEADER_SIGNATURE);
6821
- directoryRecord.uint16(versionMadeBy);
6822
- directoryRecord.bytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
6823
- directoryRecord.uint16(extraFieldLength);
6824
- directoryRecord.uint16(getLength(rawComment));
6825
- directoryRecord.uint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
6826
- directoryRecord.uint16(internalFileAttributes);
6827
- directoryRecord.uint32(externalFileAttributes);
6828
- directoryRecord.uint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
6829
- directoryRecord.bytes(rawFilename);
6830
- directoryRecord.bytes(rawExtraFieldZip64);
6831
- directoryRecord.bytes(rawExtraFieldAES);
6832
- directoryRecord.bytes(rawExtraFieldExtendedTimestamp);
6833
- directoryRecord.bytes(rawExtraFieldNTFS);
6834
- directoryRecord.bytes(rawExtraFieldUnix);
6835
- directoryRecord.bytes(rawExtraField);
6836
- directoryRecord.bytes(rawComment);
7012
+ directoryRecord.writeUint32(CENTRAL_FILE_HEADER_SIGNATURE);
7013
+ directoryRecord.writeUint16(versionMadeBy);
7014
+ directoryRecord.writeBytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
7015
+ directoryRecord.writeUint16(extraFieldLength);
7016
+ directoryRecord.writeUint16(getLength(rawComment));
7017
+ directoryRecord.writeUint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
7018
+ directoryRecord.writeUint16(internalFileAttributes);
7019
+ directoryRecord.writeUint32(externalFileAttributes);
7020
+ directoryRecord.writeUint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
7021
+ directoryRecord.writeBytes(rawFilename);
7022
+ directoryRecord.writeBytes(rawExtraFieldZip64);
7023
+ directoryRecord.writeBytes(rawExtraFieldAES);
7024
+ directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
7025
+ directoryRecord.writeBytes(rawExtraFieldNTFS);
7026
+ directoryRecord.writeBytes(rawExtraFieldUnix);
7027
+ directoryRecord.writeBytes(rawExtraField);
7028
+ directoryRecord.writeBytes(rawComment);
6837
7029
  arraySet(directoryArray, directoryRecord.array, offset);
6838
7030
  offset += directoryRecordLength;
6839
7031
  if (options.onprogress) {
6840
7032
  try {
6841
- await options.onprogress(indexFileEntry + 1, files.size, new Entry(fileEntry));
7033
+ await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
6842
7034
  } catch {
6843
7035
  // ignored
6844
7036
  }
@@ -6852,7 +7044,7 @@
6852
7044
  }
6853
7045
 
6854
7046
  async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
6855
- const signCentralDirectory = getOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
7047
+ const signCentralDirectory = getFunctionOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
6856
7048
  if (signCentralDirectory) {
6857
7049
  const signatureData = await signCentralDirectory(directoryArray);
6858
7050
  const signatureDataLength = getLength(signatureData);
@@ -6860,9 +7052,9 @@
6860
7052
  throw new Error(ERR_INVALID_SIGNATURE_DATA);
6861
7053
  }
6862
7054
  const signatureRecord = createRecordWriter(6 + signatureDataLength);
6863
- signatureRecord.uint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
6864
- signatureRecord.uint16(signatureDataLength);
6865
- signatureRecord.bytes(signatureData);
7055
+ signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7056
+ signatureRecord.writeUint16(signatureDataLength);
7057
+ signatureRecord.writeBytes(signatureData);
6866
7058
  await writeData(zipWriter.writer, signatureRecord.array);
6867
7059
  return 6 + signatureDataLength;
6868
7060
  }
@@ -6873,7 +7065,7 @@
6873
7065
  const { writer } = zipWriter;
6874
7066
  const { directoryStart, signatureLength } = cdInfo;
6875
7067
  let { directoryDataLength } = cdInfo;
6876
- let filesLength = zipWriter.files.size;
7068
+ let fileEntriesLength = zipWriter.fileEntries.size;
6877
7069
  let diskNumber = directoryStart.diskNumber;
6878
7070
  let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
6879
7071
  let lastDiskNumber = getDiskNumber(writer);
@@ -6881,7 +7073,7 @@
6881
7073
  lastDiskNumber++;
6882
7074
  }
6883
7075
  let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
6884
- if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || filesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
7076
+ if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
6885
7077
  if (zip64 === false) {
6886
7078
  throw new Error(ERR_UNSUPPORTED_FORMAT);
6887
7079
  } else {
@@ -6898,37 +7090,37 @@
6898
7090
  }
6899
7091
  lastDiskNumber = getDiskNumber(writer);
6900
7092
  if (zip64) {
6901
- endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
6902
- endOfdirectoryRecord.uint64(44);
6903
- endOfdirectoryRecord.uint16(45);
6904
- endOfdirectoryRecord.uint16(45);
6905
- endOfdirectoryRecord.uint32(lastDiskNumber);
6906
- endOfdirectoryRecord.uint32(diskNumber);
6907
- endOfdirectoryRecord.uint64(filesLength);
6908
- endOfdirectoryRecord.uint64(filesLength);
6909
- endOfdirectoryRecord.uint64(directoryDataLength);
6910
- endOfdirectoryRecord.uint64(directoryOffset);
6911
- endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
6912
- endOfdirectoryRecord.uint32(lastDiskNumber);
6913
- endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
6914
- endOfdirectoryRecord.uint32(lastDiskNumber + 1);
7093
+ endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
7094
+ endOfdirectoryRecord.writeUint64(44);
7095
+ endOfdirectoryRecord.writeUint16(45);
7096
+ endOfdirectoryRecord.writeUint16(45);
7097
+ endOfdirectoryRecord.writeUint32(lastDiskNumber);
7098
+ endOfdirectoryRecord.writeUint32(diskNumber);
7099
+ endOfdirectoryRecord.writeUint64(fileEntriesLength);
7100
+ endOfdirectoryRecord.writeUint64(fileEntriesLength);
7101
+ endOfdirectoryRecord.writeUint64(directoryDataLength);
7102
+ endOfdirectoryRecord.writeUint64(directoryOffset);
7103
+ endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
7104
+ endOfdirectoryRecord.writeUint32(lastDiskNumber);
7105
+ endOfdirectoryRecord.writeUint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
7106
+ endOfdirectoryRecord.writeUint32(lastDiskNumber + 1);
6915
7107
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
6916
7108
  if (supportZip64SplitFile) {
6917
7109
  lastDiskNumber = MAX_16_BITS;
6918
7110
  diskNumber = MAX_16_BITS;
6919
7111
  }
6920
- filesLength = MAX_16_BITS;
7112
+ fileEntriesLength = MAX_16_BITS;
6921
7113
  directoryOffset = MAX_32_BITS;
6922
7114
  directoryDataLength = MAX_32_BITS;
6923
7115
  }
6924
- endOfdirectoryRecord.uint32(END_OF_CENTRAL_DIR_SIGNATURE);
6925
- endOfdirectoryRecord.uint16(lastDiskNumber);
6926
- endOfdirectoryRecord.uint16(diskNumber);
6927
- endOfdirectoryRecord.uint16(filesLength);
6928
- endOfdirectoryRecord.uint16(filesLength);
6929
- endOfdirectoryRecord.uint32(directoryDataLength);
6930
- endOfdirectoryRecord.uint32(directoryOffset);
6931
- endOfdirectoryRecord.uint16(commentLength);
7116
+ endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
7117
+ endOfdirectoryRecord.writeUint16(lastDiskNumber);
7118
+ endOfdirectoryRecord.writeUint16(diskNumber);
7119
+ endOfdirectoryRecord.writeUint16(fileEntriesLength);
7120
+ endOfdirectoryRecord.writeUint16(fileEntriesLength);
7121
+ endOfdirectoryRecord.writeUint32(directoryDataLength);
7122
+ endOfdirectoryRecord.writeUint32(directoryOffset);
7123
+ endOfdirectoryRecord.writeUint16(commentLength);
6932
7124
  await writeData(writer, endOfdirectoryRecord.array);
6933
7125
  if (commentLength) {
6934
7126
  await writeData(writer, comment);
@@ -6941,11 +7133,11 @@
6941
7133
  let offset = 0;
6942
7134
  return {
6943
7135
  array,
6944
- uint8: value => { setUint8(view, offset, value); offset += 1; },
6945
- uint16: value => { setUint16(view, offset, value); offset += 2; },
6946
- uint32: value => { setUint32(view, offset, value); offset += 4; },
6947
- uint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
6948
- bytes: value => { arraySet(array, value, offset); offset += getLength(value); },
7136
+ writeUint8: value => { setUint8(view, offset, value); offset += 1; },
7137
+ writeUint16: value => { setUint16(view, offset, value); offset += 2; },
7138
+ writeUint32: value => { setUint32(view, offset, value); offset += 4; },
7139
+ writeUint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
7140
+ writeBytes: value => { arraySet(array, value, offset); offset += getLength(value); },
6949
7141
  skip: count => offset += count
6950
7142
  };
6951
7143
  }
@@ -6969,6 +7161,71 @@
6969
7161
  return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
6970
7162
  }
6971
7163
 
7164
+ async function startsWithSplitZipSignature(reader) {
7165
+ const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
7166
+ return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7167
+ }
7168
+
7169
+ async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7170
+ const { writer } = zipWriter;
7171
+ const entryPositions = new Map();
7172
+ if (writer.closeDisk) {
7173
+ const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
7174
+ getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
7175
+ let copiedLength = 0;
7176
+ for (const entry of sortedEntries) {
7177
+ const sourceOffset = getSourceOffset(reader, entry);
7178
+ await copyData(zipWriter, reader, copiedLength, sourceOffset - copiedLength);
7179
+ if (exceedsAvailableSize(writer, await getLocalHeaderLength(reader, sourceOffset))) {
7180
+ await writer.closeDisk();
7181
+ }
7182
+ entryPositions.set(entry, {
7183
+ offset: getSegmentOffset(zipWriter, writer),
7184
+ diskNumberStart: getDiskNumber(writer)
7185
+ });
7186
+ copiedLength = sourceOffset;
7187
+ }
7188
+ await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7189
+ } else {
7190
+ await copyData(zipWriter, reader, 0, directoryOffset);
7191
+ entries.forEach(entry => entryPositions.set(entry, {
7192
+ offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7193
+ diskNumberStart: 0
7194
+ }));
7195
+ }
7196
+ return entryPositions;
7197
+ }
7198
+
7199
+ async function copyData(zipWriter, reader, offset, size) {
7200
+ if (size > 0) {
7201
+ const { writer } = zipWriter;
7202
+ await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
7203
+ writer.size += size;
7204
+ zipWriter.offset += size;
7205
+ }
7206
+ }
7207
+
7208
+ async function getLocalHeaderLength(reader, offset) {
7209
+ const headerArray = await readUint8Array(reader, offset, HEADER_SIZE);
7210
+ if (getLength(headerArray) < HEADER_SIZE) {
7211
+ return HEADER_SIZE;
7212
+ }
7213
+ const headerView = getDataView(headerArray);
7214
+ return HEADER_SIZE +
7215
+ getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
7216
+ getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
7217
+ }
7218
+
7219
+ function getSourceOffset(reader, { offset, diskNumberStart }) {
7220
+ return offset + (reader.getDiskOffset ? reader.getDiskOffset(diskNumberStart) : 0);
7221
+ }
7222
+
7223
+ function getSplitZipSignatureArray() {
7224
+ const signatureArray = new Uint8Array(SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
7225
+ setUint32(getDataView(signatureArray), 0, SPLIT_ZIP_FILE_SIGNATURE);
7226
+ return signatureArray;
7227
+ }
7228
+
6972
7229
  async function writeData(writer, array) {
6973
7230
  const { writable } = writer;
6974
7231
  const streamWriter = writable.getWriter();
@@ -7020,6 +7277,21 @@
7020
7277
  return result === UNDEFINED_VALUE ? defaultValue : result;
7021
7278
  }
7022
7279
 
7280
+ function getDateOptionValue(zipWriter, options, name, defaultValue) {
7281
+ const date = getOptionValue(zipWriter, options, name, defaultValue);
7282
+ if (date === null) {
7283
+ return defaultValue;
7284
+ }
7285
+ if (date !== UNDEFINED_VALUE && (typeof date.getTime != FUNCTION_TYPE || Number.isNaN(date.getTime()))) {
7286
+ throw new Error(ERR_INVALID_DATE);
7287
+ }
7288
+ return date;
7289
+ }
7290
+
7291
+ function getFunctionOptionValue(zipWriter, options, name) {
7292
+ return checkFunctionOption(getOptionValue(zipWriter, options, name));
7293
+ }
7294
+
7023
7295
  function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
7024
7296
  const value = getAliasedValue(options, name, deprecatedName);
7025
7297
  const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
@@ -7034,9 +7306,6 @@
7034
7306
  return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
7035
7307
  }
7036
7308
 
7037
- function toNumber(value) {
7038
- return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
7039
- }
7040
7309
 
7041
7310
  function getMaximumCompressedSize(uncompressedSize) {
7042
7311
  return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
@@ -7048,6 +7317,14 @@
7048
7317
  : compressionMethod !== COMPRESSION_METHOD_STORE;
7049
7318
  }
7050
7319
 
7320
+ function getUint16(view, offset) {
7321
+ return view.getUint16(offset, true);
7322
+ }
7323
+
7324
+ function getUint32(view, offset) {
7325
+ return view.getUint32(offset, true);
7326
+ }
7327
+
7051
7328
  function setUint8(view, offset, value) {
7052
7329
  view.setUint8(offset, value);
7053
7330
  }
@@ -7091,9 +7368,9 @@
7091
7368
  const headerRecord = createRecordWriter(HEADER_SIZE - 4);
7092
7369
  const headerArray = headerRecord.array;
7093
7370
  const headerView = getDataView(headerArray);
7094
- headerRecord.uint16(version);
7095
- headerRecord.uint16(bitFlag);
7096
- headerRecord.uint16(compressionMethod);
7371
+ headerRecord.writeUint16(version);
7372
+ headerRecord.writeUint16(bitFlag);
7373
+ headerRecord.writeUint16(compressionMethod);
7097
7374
  if (rawLastModDate === UNDEFINED_VALUE) {
7098
7375
  const dateArray = new Uint32Array(1);
7099
7376
  const dateView = getDataView(dateArray);
@@ -7101,20 +7378,20 @@
7101
7378
  setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
7102
7379
  rawLastModDate = dateArray[0];
7103
7380
  }
7104
- headerRecord.uint32(rawLastModDate);
7381
+ headerRecord.writeUint32(rawLastModDate);
7105
7382
  headerRecord.skip(4);
7106
7383
  if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
7107
- headerRecord.uint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
7384
+ headerRecord.writeUint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
7108
7385
  } else {
7109
7386
  headerRecord.skip(4);
7110
7387
  }
7111
7388
  if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
7112
- headerRecord.uint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
7389
+ headerRecord.writeUint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
7113
7390
  } else {
7114
7391
  headerRecord.skip(4);
7115
7392
  }
7116
- headerRecord.uint16(getLength(rawFilename));
7117
- headerRecord.uint16(extraFieldLength);
7393
+ headerRecord.writeUint16(getLength(rawFilename));
7394
+ headerRecord.writeUint16(extraFieldLength);
7118
7395
  return {
7119
7396
  headerArray,
7120
7397
  headerView,
@@ -7179,6 +7456,7 @@
7179
7456
  const ERR_ENTRY_EXISTS = "Entry filename already exists";
7180
7457
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
7181
7458
  const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
7459
+ const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
7182
7460
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
7183
7461
  const ERR_ABORTED = "The operation was aborted";
7184
7462
  const ABORT_ERROR_NAME = "AbortError";
@@ -7211,13 +7489,14 @@
7211
7489
  fs,
7212
7490
  name,
7213
7491
  data: params.data,
7214
- options: params.options,
7492
+ options: params.options && Object.assign({}, params.options),
7215
7493
  id: fs.entryIdCounter++,
7216
7494
  parent,
7217
7495
  children: [],
7218
7496
  uncompressedSize: params.uncompressedSize || 0,
7219
7497
  undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
7220
- passThrough: params.passThrough
7498
+ passThrough: params.passThrough,
7499
+ defaultLastModDate: params.defaultLastModDate || new Date()
7221
7500
  });
7222
7501
  if (parent || !fs.root) {
7223
7502
  fs.entries[zipEntry.id] = zipEntry;
@@ -7227,12 +7506,6 @@
7227
7506
  }
7228
7507
  }
7229
7508
 
7230
- moveTo(target) {
7231
- // deprecated
7232
- const zipEntry = this;
7233
- zipEntry.fs.move(zipEntry, target);
7234
- }
7235
-
7236
7509
  getFullname() {
7237
7510
  return this.getRelativeName();
7238
7511
  }
@@ -7264,6 +7537,11 @@
7264
7537
  this.name = name;
7265
7538
  }
7266
7539
  }
7540
+
7541
+ setOptions(options) {
7542
+ const entryOptions = Object.assign({}, this.options, options);
7543
+ this.options = Object.fromEntries(Object.entries(entryOptions).filter(([, value]) => value !== UNDEFINED_VALUE));
7544
+ }
7267
7545
  }
7268
7546
 
7269
7547
  class ZipFileEntry extends ZipEntry {
@@ -7290,7 +7568,7 @@
7290
7568
  const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
7291
7569
  const dataSize = zipEntry.uncompressedSize || reader.size;
7292
7570
  await Promise.all([initStream(reader), initStream(writer, dataSize)]);
7293
- const { signal } = options;
7571
+ const signal = checkSignalOption(options.signal);
7294
7572
  const readable = createProgressReadable(zipEntry, reader, options, signal);
7295
7573
  const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
7296
7574
  zipEntry.uncompressedSize = reader.size;
@@ -7508,10 +7786,6 @@
7508
7786
  });
7509
7787
  }
7510
7788
 
7511
- addData(name, params) {
7512
- return addChild(this, name, params);
7513
- }
7514
-
7515
7789
  importBlob(blob, options) {
7516
7790
  return this.importZip(new BlobReader(blob), options);
7517
7791
  }
@@ -7625,7 +7899,7 @@
7625
7899
  if (options.bufferedWrite === UNDEFINED_VALUE) {
7626
7900
  options.bufferedWrite = true;
7627
7901
  }
7628
- const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
7902
+ const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
7629
7903
  const zipWriter = new ZipWriter(writer, options);
7630
7904
  await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
7631
7905
  await zipWriter.close(options.globalComment);
@@ -7635,12 +7909,13 @@
7635
7909
  getExportedSize(options = {}) {
7636
7910
  const zipEntry = this;
7637
7911
  options = Object.assign({}, options);
7912
+ checkReaderOptions(options.readerOptions);
7638
7913
  if (options.bufferedWrite === UNDEFINED_VALUE) {
7639
7914
  options.bufferedWrite = true;
7640
7915
  }
7641
7916
  const writeOrderGuaranteed = !options.bufferedWrite ||
7642
7917
  (options.keepOrder !== false && zipEntry.children.every(child => !child.children.length));
7643
- return getEntriesSize(options, Array.from(zipEntry.getChildren({ recursive: true }), child => {
7918
+ return getEntriesSize(options, zipEntry.getChildren({ recursive: true }).filter(child => !isImplicitDirectory(child)).map(child => {
7644
7919
  const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
7645
7920
  return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
7646
7921
  }), writeOrderGuaranteed, options.globalComment);
@@ -7679,7 +7954,7 @@
7679
7954
  }
7680
7955
 
7681
7956
 
7682
- class FS {
7957
+ class ZipFS {
7683
7958
 
7684
7959
  constructor() {
7685
7960
  resetFS(this);
@@ -7795,10 +8070,6 @@
7795
8070
  return this.root.addFile(file, options);
7796
8071
  }
7797
8072
 
7798
- addData(name, params) {
7799
- return this.root.addData(name, params);
7800
- }
7801
-
7802
8073
  importBlob(blob, options) {
7803
8074
  resetFS(this);
7804
8075
  return this.root.importBlob(blob, options);
@@ -7866,7 +8137,7 @@
7866
8137
  }
7867
8138
  }
7868
8139
 
7869
- const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
8140
+ const fs = { FS: ZipFS, ZipDirectoryEntry, ZipFileEntry };
7870
8141
 
7871
8142
  function getTotalSize(entries, getEntrySize) {
7872
8143
  let size = 0;
@@ -8010,7 +8281,7 @@
8010
8281
  }
8011
8282
 
8012
8283
  function forwardAbort(signal, abortController) {
8013
- if (!signal) {
8284
+ if (!checkSignalOption(signal)) {
8014
8285
  return () => { };
8015
8286
  }
8016
8287
  if (signal.aborted) {
@@ -8106,7 +8377,7 @@
8106
8377
  };
8107
8378
  }
8108
8379
  }
8109
- const entryOptions = Object.assign({}, zipEntryMetadata, options, passThroughOptions, childOptions, { directory: child.directory });
8380
+ const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
8110
8381
  if (!child.directory && entryOptions.passThrough && entryOptions.uncompressedSize === UNDEFINED_VALUE) {
8111
8382
  throw new Error(ERR_INVALID_PASS_THROUGH);
8112
8383
  }
@@ -8121,11 +8392,22 @@
8121
8392
  return child.undeterminedSize ? UNDEFINED_VALUE : getExtractedSize(child, passThrough);
8122
8393
  }
8123
8394
 
8395
+ function checkReaderOptions(readerOptions) {
8396
+ if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
8397
+ throw new Error(ERR_INVALID_READER_OPTIONS);
8398
+ }
8399
+ return readerOptions;
8400
+ }
8401
+
8124
8402
  function isPassThrough(child, options) {
8125
8403
  const { readerOptions } = options;
8126
8404
  return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
8127
8405
  }
8128
8406
 
8407
+ function isImplicitDirectory(child) {
8408
+ return child.directory && child.data === null;
8409
+ }
8410
+
8129
8411
  function getUserExtraField(extraField) {
8130
8412
  if (extraField) {
8131
8413
  const userExtraField = new Map();
@@ -8143,7 +8425,7 @@
8143
8425
  async function exportZip(zipWriter, entry, totalSize, options, readers) {
8144
8426
  const { onstart, onprogress, onend, onentryprogress } = options;
8145
8427
  const selectedEntry = entry;
8146
- const totalEntries = getTotalSize(entry.children, () => 1);
8428
+ const totalEntries = getTotalSize(entry.children, child => isImplicitDirectory(child) ? 0 : 1);
8147
8429
  let writtenSize = 0;
8148
8430
  let writtenEntries = 0;
8149
8431
  if (onstart) {
@@ -8172,6 +8454,9 @@
8172
8454
  }
8173
8455
 
8174
8456
  async function addChild(child) {
8457
+ if (isImplicitDirectory(child)) {
8458
+ return;
8459
+ }
8175
8460
  const { name, entryOptions } = getChildEntryOptions(child, selectedEntry, options);
8176
8461
  let entryWrittenSize = 0;
8177
8462
  const entryMetadata = await zipWriter.add(name, readers.get(child), Object.assign(entryOptions, {
@@ -8205,7 +8490,7 @@
8205
8490
  if (handle.kind == "file") {
8206
8491
  const file = await handle.getFile();
8207
8492
  addedEntries.push(
8208
- parentEntry.addData(file.name, {
8493
+ addChild(parentEntry, file.name, {
8209
8494
  Reader: function () {
8210
8495
  const readable = file.stream();
8211
8496
  const size = file.size;
@@ -8239,10 +8524,11 @@
8239
8524
 
8240
8525
  async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
8241
8526
  const { onstart, onprogress, onend } = options;
8527
+ const readerOptions = checkReaderOptions(options.readerOptions);
8242
8528
  const abortController = new AbortController();
8243
8529
  const { signal } = abortController;
8244
8530
  const releaseSignal = forwardAbort(options.signal, abortController);
8245
- const getDataOptions = Object.assign({}, options, options.readerOptions, {
8531
+ const getDataOptions = Object.assign({}, options, readerOptions, {
8246
8532
  signal,
8247
8533
  onstart: UNDEFINED_VALUE,
8248
8534
  onprogress: UNDEFINED_VALUE,
@@ -8439,7 +8725,12 @@
8439
8725
  exports.ERR_ABORTED = ERR_ABORTED;
8440
8726
  exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
8441
8727
  exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
8728
+ exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
8442
8729
  exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
8730
+ exports.ZipDirectoryEntry = ZipDirectoryEntry;
8731
+ exports.ZipEntry = ZipEntry;
8732
+ exports.ZipFS = ZipFS;
8733
+ exports.ZipFileEntry = ZipFileEntry;
8443
8734
  exports.fs = fs;
8444
8735
 
8445
8736
  }));