@zip.js/zip.js 2.8.53 → 2.8.55

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 (48) hide show
  1. package/README.md +1 -1
  2. package/deno.json +2 -1
  3. package/dist/zip-core-external.js +737 -491
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +745 -490
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +776 -525
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +738 -510
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +776 -525
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +790 -525
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +791 -526
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +746 -491
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-native.js +746 -491
  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 +747 -492
  24. package/dist/zip.min.js +1 -1
  25. package/eslint.config.mjs +1 -0
  26. package/index-native.cjs +790 -525
  27. package/index-native.min.js +1 -1
  28. package/index.cjs +791 -526
  29. package/index.d.cts +422 -49
  30. package/index.d.ts +422 -49
  31. package/index.min.js +1 -1
  32. package/lib/core/configuration.js +62 -21
  33. package/lib/core/constants.js +13 -1
  34. package/lib/core/io.js +33 -27
  35. package/lib/core/options.js +44 -2
  36. package/lib/core/streams/aes-crypto-stream.js +12 -12
  37. package/lib/core/util/decode-text.js +11 -2
  38. package/lib/core/web-worker-base.js +3 -2
  39. package/lib/core/web-worker-inline-native.js +1 -1
  40. package/lib/core/web-worker-inline-wasm.js +1 -1
  41. package/lib/core/zip-fs.js +39 -32
  42. package/lib/core/zip-reader.js +100 -38
  43. package/lib/core/zip-writer.js +301 -177
  44. package/lib/core/zlib-streams-inline.js +1 -1
  45. package/lib/zip-core-base.js +6 -1
  46. package/lib/zip-core-reader.js +1 -0
  47. package/lib/zip-core-writer.js +5 -0
  48. package/package.json +8 -2
@@ -36,6 +36,7 @@ const COMPRESSION_METHOD_AES = 0x63;
36
36
 
37
37
  const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
38
38
  const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
39
+ const TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE = 0x30304b50;
39
40
  const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
40
41
  const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
41
42
  const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
@@ -52,6 +53,7 @@ const ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH = END_OF_CENTRAL_DIR_LENGTH + ZIP64_
52
53
  const DATA_DESCRIPTOR_RECORD_LENGTH = 12;
53
54
  const DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH = 20;
54
55
  const DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH = 4;
56
+ const SPLIT_ZIP_FILE_SIGNATURE_LENGTH = 4;
55
57
 
56
58
  const EXTRAFIELD_TYPE_ZIP64 = 0x0001;
57
59
  const EXTRAFIELD_TYPE_AES = 0x9901;
@@ -74,6 +76,7 @@ const BITFLAG_LEVEL_SUPER_FAST_MASK = 0b110;
74
76
  const BITFLAG_DATA_DESCRIPTOR = 0b1000;
75
77
  const BITFLAG_STRONG_ENCRYPTION = 0b1000000;
76
78
  const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
79
+ const BITFLAG_MASKED_LOCAL_HEADERS = 0b10000000000000;
77
80
  const FILE_ATTR_MSDOS_DIR_MASK = 0b10000;
78
81
  const FILE_ATTR_MSDOS_READONLY_MASK = 0x01;
79
82
  const FILE_ATTR_MSDOS_HIDDEN_MASK = 0x02;
@@ -103,6 +106,8 @@ const HEADER_OFFSET_VERSION = 0;
103
106
  const HEADER_OFFSET_SIGNATURE = 10;
104
107
  const HEADER_OFFSET_COMPRESSED_SIZE = 14;
105
108
  const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18;
109
+ const HEADER_OFFSET_FILENAME_LENGTH = 22;
110
+ const HEADER_OFFSET_EXTRAFIELD_LENGTH = 24;
106
111
  const LOCAL_HEADER_COMMON_OFFSET = 4;
107
112
 
108
113
  const MAX_DATE = new Date(2107, 11, 31, 23, 59, 58);
@@ -115,9 +120,116 @@ const FUNCTION_TYPE = "function";
115
120
  const OBJECT_TYPE = "object";
116
121
  const STRING_TYPE = "string";
117
122
  const NUMBER_TYPE = "number";
123
+ const BOOLEAN_TYPE = "boolean";
118
124
 
119
125
  const EMPTY_UINT8_ARRAY = new Uint8Array();
120
126
 
127
+ /*
128
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
129
+
130
+ Redistribution and use in source and binary forms, with or without
131
+ modification, are permitted provided that the following conditions are met:
132
+
133
+ 1. Redistributions of source code must retain the above copyright notice,
134
+ this list of conditions and the following disclaimer.
135
+
136
+ 2. Redistributions in binary form must reproduce the above copyright
137
+ notice, this list of conditions and the following disclaimer in
138
+ the documentation and/or other materials provided with the distribution.
139
+
140
+ 3. The names of the authors may not be used to endorse or promote products
141
+ derived from this software without specific prior written permission.
142
+
143
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
144
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
145
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
146
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
147
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
148
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
149
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
150
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
151
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
152
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153
+ */
154
+
155
+
156
+ const OPTION_FILENAME_ENCODING = "filenameEncoding";
157
+ const OPTION_COMMENT_ENCODING = "commentEncoding";
158
+ const OPTION_DECODE_TEXT = "decodeText";
159
+ const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
160
+ const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
161
+ const OPTION_PASSWORD = "password";
162
+ const OPTION_RAW_PASSWORD = "rawPassword";
163
+ const OPTION_PASS_THROUGH = "passThrough";
164
+ const OPTION_SIGNAL = "signal";
165
+ const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
166
+ const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
167
+ const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
168
+ const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
169
+ const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
170
+ const OPTION_CHECK_SIGNATURE = "checkSignature";
171
+ const OPTION_CHECK_CRC32 = "checkCrc32";
172
+ const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
173
+ const OPTION_USE_WEB_WORKERS = "useWebWorkers";
174
+ const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
175
+ const OPTION_TRANSFER_STREAMS = "transferStreams";
176
+ const OPTION_PREVENT_CLOSE = "preventClose";
177
+ const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
178
+ const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
179
+ const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
180
+ const OPTION_KEEP_ORDER = "keepOrder";
181
+ const OPTION_LEVEL = "level";
182
+ const OPTION_BUFFERED_WRITE = "bufferedWrite";
183
+ const OPTION_CREATE_TEMP_STREAM = "createTempStream";
184
+ const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
185
+ const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
186
+ const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
187
+ const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
188
+ const OPTION_ENCODE_TEXT = "encodeText";
189
+ const OPTION_OFFSET = "offset";
190
+ const OPTION_USDZ = "usdz";
191
+ const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
192
+ const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
193
+ const OPTION_STRICTNESS = "strictness";
194
+ const OPTION_FILENAME_VALIDATION = "filenameValidation";
195
+ const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
196
+ const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
197
+ const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
198
+ const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
199
+ const TEXT_TYPE_FILENAME = "filename";
200
+ const TEXT_TYPE_COMMENT = "comment";
201
+ const STRICTNESS_STRICT = "strict";
202
+ const STRICTNESS_BALANCED = "balanced";
203
+ const STRICTNESS_TOLERANT = "tolerant";
204
+
205
+ const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
206
+ const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
207
+ const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
208
+
209
+ function checkFunctionOption(value) {
210
+ if (value && typeof value != FUNCTION_TYPE) {
211
+ throw new Error(ERR_INVALID_FUNCTION_OPTION);
212
+ }
213
+ return value;
214
+ }
215
+
216
+ function checkSignalOption(signal) {
217
+ if (signal && (typeof signal.addEventListener != FUNCTION_TYPE || typeof signal.aborted != BOOLEAN_TYPE)) {
218
+ throw new Error(ERR_INVALID_SIGNAL);
219
+ }
220
+ return signal || UNDEFINED_VALUE;
221
+ }
222
+
223
+ function checkPasswordOption(password, rawPassword) {
224
+ if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
225
+ throw new Error(ERR_INVALID_PASSWORD_TYPE);
226
+ }
227
+ }
228
+
229
+ function toNumber(value) {
230
+ return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
231
+ }
232
+
121
233
  /*
122
234
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
123
235
 
@@ -147,7 +259,10 @@ const EMPTY_UINT8_ARRAY = new Uint8Array();
147
259
  */
148
260
 
149
261
 
262
+ const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
150
263
  const MINIMUM_CHUNK_SIZE = 64;
264
+ const MINIMUM_PROPERTY_VALUE = 1;
265
+ const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
151
266
  let maxWorkers = 2;
152
267
  try {
153
268
  if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
@@ -159,7 +274,7 @@ try {
159
274
  const DEFAULT_CONFIGURATION = {
160
275
  workerURI: "./core/web-worker-wasm.js",
161
276
  wasmURI: "./core/streams/zlib-wasm/zlib-streams.wasm",
162
- chunkSize: 64 * 1024,
277
+ chunkSize: DEFAULT_CHUNK_SIZE$1,
163
278
  maxWorkers,
164
279
  terminateWorkerTimeout: 5000,
165
280
  workerStarvationTimeout: 5000,
@@ -171,24 +286,38 @@ const DEFAULT_CONFIGURATION = {
171
286
  DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
172
287
  };
173
288
 
174
- const CONFIGURABLE_PROPERTY_NAMES = [
289
+ const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
290
+
291
+ const STRING_PROPERTY_NAMES = [
175
292
  "baseURI",
176
293
  "wasmURI",
177
- "workerURI",
178
- "createWorker",
294
+ "workerURI"
295
+ ];
296
+ const BOOLEAN_PROPERTY_NAMES = [
297
+ "useCompressionStream",
298
+ "useWebWorkers",
299
+ "transferStreams"
300
+ ];
301
+ const NUMBER_PROPERTY_NAMES = [
179
302
  "chunkSize",
180
- "maxWorkers",
303
+ PROPERTY_NAME_MAX_WORKERS,
181
304
  "terminateWorkerTimeout",
182
305
  "workerStarvationTimeout",
183
- "workerStartupTimeout",
184
- "useCompressionStream",
185
- "useWebWorkers",
186
- "transferStreams",
306
+ "workerStartupTimeout"
307
+ ];
308
+ const FUNCTION_PROPERTY_NAMES = [
309
+ "createWorker",
187
310
  "CompressionStream",
188
311
  "DecompressionStream",
189
312
  "CompressionStreamFallback",
190
313
  "DecompressionStreamFallback"
191
314
  ];
315
+ const CONFIGURABLE_PROPERTY_NAMES = [
316
+ ...STRING_PROPERTY_NAMES,
317
+ ...BOOLEAN_PROPERTY_NAMES,
318
+ ...NUMBER_PROPERTY_NAMES,
319
+ ...FUNCTION_PROPERTY_NAMES
320
+ ];
192
321
 
193
322
  const config = { ...DEFAULT_CONFIGURATION };
194
323
 
@@ -197,20 +326,43 @@ function getConfiguration() {
197
326
  }
198
327
 
199
328
  function getChunkSize(config) {
200
- return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
329
+ return normalizeChunkSize(config.chunkSize);
330
+ }
331
+
332
+ function normalizeChunkSize(chunkSize) {
333
+ chunkSize = toNumber(chunkSize);
334
+ return Number.isInteger(chunkSize) && chunkSize >= MINIMUM_PROPERTY_VALUE ? Math.max(chunkSize, MINIMUM_CHUNK_SIZE) : DEFAULT_CHUNK_SIZE$1;
201
335
  }
202
336
 
203
337
  function configure(configuration) {
204
- configuration = normalizeConfiguration(configuration);
338
+ Object.assign(config, checkConfiguration(normalizeConfiguration(configuration)));
339
+ }
340
+
341
+ function checkConfiguration(configuration) {
342
+ const checkedConfiguration = {};
205
343
  for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
206
344
  const propertyValue = configuration[propertyName];
207
345
  if (propertyValue !== UNDEFINED_VALUE) {
208
- config[propertyName] = propertyValue;
346
+ checkedConfiguration[propertyName] = checkPropertyValue(propertyName, propertyValue);
209
347
  }
210
348
  }
349
+ return checkedConfiguration;
350
+ }
351
+
352
+ function checkPropertyValue(propertyName, propertyValue) {
353
+ if (NUMBER_PROPERTY_NAMES.includes(propertyName)) {
354
+ propertyValue = toNumber(propertyValue);
355
+ if (propertyName == PROPERTY_NAME_MAX_WORKERS && (!Number.isInteger(propertyValue) || propertyValue < MINIMUM_PROPERTY_VALUE)) {
356
+ throw new Error(ERR_INVALID_MAX_WORKERS);
357
+ }
358
+ } else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
359
+ checkFunctionOption(propertyValue);
360
+ }
361
+ return propertyValue;
211
362
  }
212
363
 
213
364
  function normalizeConfiguration(configuration) {
365
+ configuration = configuration || {};
214
366
  const { CompressionStreamZlib, DecompressionStreamZlib } = configuration;
215
367
  if (CompressionStreamZlib === UNDEFINED_VALUE && DecompressionStreamZlib === UNDEFINED_VALUE) {
216
368
  return configuration;
@@ -226,14 +378,9 @@ function normalizeConfiguration(configuration) {
226
378
  }
227
379
 
228
380
  function setDefaultConfiguration(configuration) {
229
- configuration = normalizeConfiguration(configuration);
230
- for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
231
- const propertyValue = configuration[propertyName];
232
- if (propertyValue !== UNDEFINED_VALUE) {
233
- DEFAULT_CONFIGURATION[propertyName] = propertyValue;
234
- }
235
- }
236
- configure(configuration);
381
+ const checkedConfiguration = checkConfiguration(normalizeConfiguration(configuration));
382
+ Object.assign(DEFAULT_CONFIGURATION, checkedConfiguration);
383
+ Object.assign(config, checkedConfiguration);
237
384
  }
238
385
 
239
386
  function resetConfiguration() {
@@ -1425,13 +1572,13 @@ class AESDecryptionStream extends TransformStream {
1425
1572
  const {
1426
1573
  ctr,
1427
1574
  hmac,
1428
- pending,
1575
+ pendingInput,
1429
1576
  ready
1430
1577
  } = this;
1431
1578
  if (hmac && ctr) {
1432
1579
  await ready;
1433
- const chunkToDecrypt = subarray(pending, 0, pending.length - AUTHENTICATION_CODE_LENGTH);
1434
- const originalAuthenticationCode = subarray(pending, pending.length - AUTHENTICATION_CODE_LENGTH);
1580
+ const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
1581
+ const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
1435
1582
  let decryptedChunkArray = EMPTY_UINT8_ARRAY;
1436
1583
  if (chunkToDecrypt.length) {
1437
1584
  const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
@@ -1440,7 +1587,7 @@ class AESDecryptionStream extends TransformStream {
1440
1587
  decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
1441
1588
  }
1442
1589
  const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
1443
- let invalidAuthenticationCode = pending.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
1590
+ let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
1444
1591
  for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
1445
1592
  invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
1446
1593
  }
@@ -1484,14 +1631,14 @@ class AESEncryptionStream extends TransformStream {
1484
1631
  const {
1485
1632
  ctr,
1486
1633
  hmac,
1487
- pending,
1634
+ pendingInput,
1488
1635
  ready
1489
1636
  } = this;
1490
1637
  if (hmac && ctr) {
1491
1638
  await ready;
1492
1639
  let encryptedChunkArray = EMPTY_UINT8_ARRAY;
1493
- if (pending.length) {
1494
- const encryptedChunk = ctr.update(toBits(codecBytes, pending));
1640
+ if (pendingInput.length) {
1641
+ const encryptedChunk = ctr.update(toBits(codecBytes, pendingInput));
1495
1642
  hmac.update(encryptedChunk);
1496
1643
  encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
1497
1644
  }
@@ -1508,7 +1655,7 @@ function initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength) {
1508
1655
  ready: new Promise(resolve => aesCrypto.resolveReady = resolve),
1509
1656
  password: encodePassword(password, rawPassword),
1510
1657
  strength: encryptionStrength - 1,
1511
- pending: EMPTY_UINT8_ARRAY
1658
+ pendingInput: EMPTY_UINT8_ARRAY
1512
1659
  });
1513
1660
  }
1514
1661
 
@@ -1516,10 +1663,10 @@ function append(aesCrypto, input, output, paddingStart, paddingEnd, verifyAuthen
1516
1663
  const {
1517
1664
  ctr,
1518
1665
  hmac,
1519
- pending
1666
+ pendingInput
1520
1667
  } = aesCrypto;
1521
- if (pending.length) {
1522
- input = concat(pending, input);
1668
+ if (pendingInput.length) {
1669
+ input = concat(pendingInput, input);
1523
1670
  }
1524
1671
  const inputLength = input.length - paddingEnd;
1525
1672
  output = expand(output, paddingStart + (inputLength - (inputLength % BLOCK_LENGTH)));
@@ -1535,7 +1682,7 @@ function append(aesCrypto, input, output, paddingStart, paddingEnd, verifyAuthen
1535
1682
  }
1536
1683
  output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
1537
1684
  }
1538
- aesCrypto.pending = subarray(input, offset);
1685
+ aesCrypto.pendingInput = subarray(input, offset);
1539
1686
  return output;
1540
1687
  }
1541
1688
 
@@ -3312,6 +3459,96 @@ async function terminateWorkers() {
3312
3459
  resetWebWorkerSupport();
3313
3460
  }
3314
3461
 
3462
+ /*
3463
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
3464
+
3465
+ Redistribution and use in source and binary forms, with or without
3466
+ modification, are permitted provided that the following conditions are met:
3467
+
3468
+ 1. Redistributions of source code must retain the above copyright notice,
3469
+ this list of conditions and the following disclaimer.
3470
+
3471
+ 2. Redistributions in binary form must reproduce the above copyright
3472
+ notice, this list of conditions and the following disclaimer in
3473
+ the documentation and/or other materials provided with the distribution.
3474
+
3475
+ 3. The names of the authors may not be used to endorse or promote products
3476
+ derived from this software without specific prior written permission.
3477
+
3478
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
3479
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
3480
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
3481
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
3482
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3483
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
3484
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3485
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3486
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
3487
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3488
+ */
3489
+
3490
+ /* global TextDecoder */
3491
+
3492
+ const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
3493
+ const VALID_CP437 = CP437.length == 256;
3494
+
3495
+ function decodeCP437(stringValue) {
3496
+ if (VALID_CP437) {
3497
+ let result = "";
3498
+ for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
3499
+ result += CP437[stringValue[indexCharacter]];
3500
+ }
3501
+ return result;
3502
+ } else {
3503
+ return new TextDecoder().decode(stringValue);
3504
+ }
3505
+ }
3506
+
3507
+ /*
3508
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
3509
+
3510
+ Redistribution and use in source and binary forms, with or without
3511
+ modification, are permitted provided that the following conditions are met:
3512
+
3513
+ 1. Redistributions of source code must retain the above copyright notice,
3514
+ this list of conditions and the following disclaimer.
3515
+
3516
+ 2. Redistributions in binary form must reproduce the above copyright
3517
+ notice, this list of conditions and the following disclaimer in
3518
+ the documentation and/or other materials provided with the distribution.
3519
+
3520
+ 3. The names of the authors may not be used to endorse or promote products
3521
+ derived from this software without specific prior written permission.
3522
+
3523
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
3524
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
3525
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
3526
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
3527
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3528
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
3529
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3530
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3531
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
3532
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3533
+ */
3534
+
3535
+
3536
+ function decodeText(value, encoding) {
3537
+ return decode(value, encoding, true);
3538
+ }
3539
+
3540
+ function decodeTextRemovingBOM(value, encoding) {
3541
+ return decode(value, encoding, false);
3542
+ }
3543
+
3544
+ function decode(value, encoding, ignoreBOM) {
3545
+ if (encoding && encoding.trim().toLowerCase() == "cp437") {
3546
+ return decodeCP437(value);
3547
+ } else {
3548
+ return new TextDecoder(encoding, { ignoreBOM }).decode(value);
3549
+ }
3550
+ }
3551
+
3315
3552
  /*
3316
3553
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
3317
3554
 
@@ -3384,6 +3621,7 @@ class Reader extends Stream {
3384
3621
  createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
3385
3622
  const reader = this;
3386
3623
  let chunkOffset = 0;
3624
+ chunkSize = normalizeChunkSize(chunkSize);
3387
3625
  return new ReadableStream({
3388
3626
  async pull(controller) {
3389
3627
  const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
@@ -3391,7 +3629,7 @@ class Reader extends Stream {
3391
3629
  if (data.length) {
3392
3630
  controller.enqueue(data);
3393
3631
  }
3394
- if ((chunkOffset + chunkSize >= size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
3632
+ if ((chunkOffset + chunkSize >= size) || (!data.length && dataSize)) {
3395
3633
  controller.close();
3396
3634
  } else {
3397
3635
  chunkOffset += chunkSize;
@@ -3471,31 +3709,31 @@ class Data64URIWriter extends Writer {
3471
3709
  Object.assign(this, {
3472
3710
  contentType,
3473
3711
  data: "data:" + (contentType || "") + ";base64,",
3474
- pending: []
3712
+ pendingCharacters: ""
3475
3713
  });
3476
3714
  }
3477
3715
 
3478
3716
  writeUint8Array(array) {
3479
3717
  const writer = this;
3480
3718
  let indexArray;
3481
- let dataString = writer.pending;
3482
- const delta = writer.pending.length;
3483
- writer.pending = "";
3719
+ let dataString = writer.pendingCharacters;
3720
+ const delta = writer.pendingCharacters.length;
3721
+ writer.pendingCharacters = "";
3484
3722
  for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
3485
3723
  dataString += String.fromCharCode(array[indexArray]);
3486
3724
  }
3487
3725
  for (; indexArray < array.length; indexArray++) {
3488
- writer.pending += String.fromCharCode(array[indexArray]);
3726
+ writer.pendingCharacters += String.fromCharCode(array[indexArray]);
3489
3727
  }
3490
3728
  if (dataString.length > 2) {
3491
3729
  writer.data += btoa(dataString);
3492
3730
  } else {
3493
- writer.pending = dataString + writer.pending;
3731
+ writer.pendingCharacters = dataString + writer.pendingCharacters;
3494
3732
  }
3495
3733
  }
3496
3734
 
3497
3735
  getData() {
3498
- return this.data + btoa(this.pending);
3736
+ return this.data + btoa(this.pendingCharacters);
3499
3737
  }
3500
3738
  }
3501
3739
 
@@ -3525,7 +3763,7 @@ class BlobReader extends Reader {
3525
3763
  constructor(blob) {
3526
3764
  super();
3527
3765
  Object.assign(this, {
3528
- blob,
3766
+ sourceBlob: blob,
3529
3767
  size: blob.size
3530
3768
  });
3531
3769
  if (!blobSliceProbe) {
@@ -3535,13 +3773,13 @@ class BlobReader extends Reader {
3535
3773
 
3536
3774
  createReadable(options) {
3537
3775
  const reader = this;
3538
- const { blob, size } = reader;
3776
+ const { sourceBlob, size } = reader;
3539
3777
  const { offset = 0, size: readSize = size - offset } = options || {};
3540
3778
  if (!offset && readSize >= size) {
3541
- return toCompatibleReadable(blob.stream());
3779
+ return toCompatibleReadable(sourceBlob.stream());
3542
3780
  }
3543
3781
  if (blobSliceReliable) {
3544
- return toCompatibleReadable(blob.slice(offset, offset + readSize).stream());
3782
+ return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
3545
3783
  }
3546
3784
  return super.createReadable(options);
3547
3785
  }
@@ -3550,7 +3788,7 @@ class BlobReader extends Reader {
3550
3788
  const reader = this;
3551
3789
  const offsetEnd = offset + length;
3552
3790
  const readsWholeBlob = !offset && offsetEnd >= reader.size;
3553
- const blob = readsWholeBlob ? reader.blob : reader.blob.slice(offset, offsetEnd);
3791
+ const blob = readsWholeBlob ? reader.sourceBlob : reader.sourceBlob.slice(offset, offsetEnd);
3554
3792
  let arrayBuffer = await blob.arrayBuffer();
3555
3793
  const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
3556
3794
  if (sliceIgnoredByBuggyImplementation) {
@@ -3572,12 +3810,12 @@ class BlobWriter extends Stream {
3572
3810
  }
3573
3811
  });
3574
3812
  writer.contentType = contentType;
3575
- writer.blob = streamToBlob(transformStream.readable, contentType);
3576
- writer.blob.catch(() => { });
3813
+ writer.blobPromise = streamToBlob(transformStream.readable, contentType);
3814
+ writer.blobPromise.catch(() => { });
3577
3815
  }
3578
3816
 
3579
3817
  getData() {
3580
- return this.blob;
3818
+ return this.blobPromise;
3581
3819
  }
3582
3820
  }
3583
3821
 
@@ -3611,7 +3849,7 @@ function getTextSize(text) {
3611
3849
  class TextWriter extends BlobWriter {
3612
3850
 
3613
3851
  constructor(encoding) {
3614
- super(encoding);
3852
+ super();
3615
3853
  Object.assign(this, {
3616
3854
  encoding,
3617
3855
  utf8: !encoding || encoding.toLowerCase() == "utf-8"
@@ -3627,14 +3865,7 @@ class TextWriter extends BlobWriter {
3627
3865
  if (blob.text && utf8) {
3628
3866
  return blob.text();
3629
3867
  } else {
3630
- const reader = new FileReader();
3631
- return new Promise((resolve, reject) => {
3632
- Object.assign(reader, {
3633
- onload: ({ target }) => resolve(target.result),
3634
- onerror: () => reject(reader.error)
3635
- });
3636
- reader.readAsText(blob, encoding);
3637
- });
3868
+ return decodeTextRemovingBOM(new Uint8Array(await blob.arrayBuffer()), encoding);
3638
3869
  }
3639
3870
  }
3640
3871
  }
@@ -4302,85 +4533,13 @@ function readUint8Array(reader, offset, size) {
4302
4533
  return reader.readUint8Array(offset, size);
4303
4534
  }
4304
4535
 
4305
- /*
4306
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
4307
-
4308
- Redistribution and use in source and binary forms, with or without
4309
- modification, are permitted provided that the following conditions are met:
4310
-
4311
- 1. Redistributions of source code must retain the above copyright notice,
4312
- this list of conditions and the following disclaimer.
4313
-
4314
- 2. Redistributions in binary form must reproduce the above copyright
4315
- notice, this list of conditions and the following disclaimer in
4316
- the documentation and/or other materials provided with the distribution.
4317
-
4318
- 3. The names of the authors may not be used to endorse or promote products
4319
- derived from this software without specific prior written permission.
4320
-
4321
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4322
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4323
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4324
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4325
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4326
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4327
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4328
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4329
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4330
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4331
- */
4332
-
4333
- /* global TextDecoder */
4334
-
4335
- const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
4336
- const VALID_CP437 = CP437.length == 256;
4337
-
4338
- function decodeCP437(stringValue) {
4339
- if (VALID_CP437) {
4340
- let result = "";
4341
- for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
4342
- result += CP437[stringValue[indexCharacter]];
4343
- }
4344
- return result;
4345
- } else {
4346
- return new TextDecoder().decode(stringValue);
4347
- }
4348
- }
4349
-
4350
- /*
4351
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
4352
-
4353
- Redistribution and use in source and binary forms, with or without
4354
- modification, are permitted provided that the following conditions are met:
4355
-
4356
- 1. Redistributions of source code must retain the above copyright notice,
4357
- this list of conditions and the following disclaimer.
4358
-
4359
- 2. Redistributions in binary form must reproduce the above copyright
4360
- notice, this list of conditions and the following disclaimer in
4361
- the documentation and/or other materials provided with the distribution.
4362
-
4363
- 3. The names of the authors may not be used to endorse or promote products
4364
- derived from this software without specific prior written permission.
4365
-
4366
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4367
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4368
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4369
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4370
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4371
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4372
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4373
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4374
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4375
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4376
- */
4377
-
4378
-
4379
- function decodeText(value, encoding) {
4380
- if (encoding && encoding.trim().toLowerCase() == "cp437") {
4381
- return decodeCP437(value);
4536
+ function createReadable(reader, options) {
4537
+ if (reader.createReadable) {
4538
+ return reader.createReadable(options);
4539
+ } else if (reader.readUint8Array) {
4540
+ return Reader.prototype.createReadable.call(reader, options);
4382
4541
  } else {
4383
- return new TextDecoder(encoding, { ignoreBOM: true }).decode(value);
4542
+ return reader.readable;
4384
4543
  }
4385
4544
  }
4386
4545
 
@@ -4540,83 +4699,6 @@ class Entry {
4540
4699
 
4541
4700
  }
4542
4701
 
4543
- /*
4544
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
4545
-
4546
- Redistribution and use in source and binary forms, with or without
4547
- modification, are permitted provided that the following conditions are met:
4548
-
4549
- 1. Redistributions of source code must retain the above copyright notice,
4550
- this list of conditions and the following disclaimer.
4551
-
4552
- 2. Redistributions in binary form must reproduce the above copyright
4553
- notice, this list of conditions and the following disclaimer in
4554
- the documentation and/or other materials provided with the distribution.
4555
-
4556
- 3. The names of the authors may not be used to endorse or promote products
4557
- derived from this software without specific prior written permission.
4558
-
4559
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4560
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4561
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4562
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4563
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4564
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4565
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4566
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4567
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4568
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4569
- */
4570
-
4571
- const OPTION_FILENAME_ENCODING = "filenameEncoding";
4572
- const OPTION_COMMENT_ENCODING = "commentEncoding";
4573
- const OPTION_DECODE_TEXT = "decodeText";
4574
- const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
4575
- const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
4576
- const OPTION_PASSWORD = "password";
4577
- const OPTION_RAW_PASSWORD = "rawPassword";
4578
- const OPTION_PASS_THROUGH = "passThrough";
4579
- const OPTION_SIGNAL = "signal";
4580
- const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
4581
- const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
4582
- const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
4583
- const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
4584
- const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
4585
- const OPTION_CHECK_SIGNATURE = "checkSignature";
4586
- const OPTION_CHECK_CRC32 = "checkCrc32";
4587
- const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
4588
- const OPTION_USE_WEB_WORKERS = "useWebWorkers";
4589
- const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
4590
- const OPTION_TRANSFER_STREAMS = "transferStreams";
4591
- const OPTION_PREVENT_CLOSE = "preventClose";
4592
- const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
4593
- const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
4594
- const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
4595
- const OPTION_KEEP_ORDER = "keepOrder";
4596
- const OPTION_LEVEL = "level";
4597
- const OPTION_BUFFERED_WRITE = "bufferedWrite";
4598
- const OPTION_CREATE_TEMP_STREAM = "createTempStream";
4599
- const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
4600
- const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
4601
- const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
4602
- const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
4603
- const OPTION_ENCODE_TEXT = "encodeText";
4604
- const OPTION_OFFSET = "offset";
4605
- const OPTION_USDZ = "usdz";
4606
- const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
4607
- const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
4608
- const OPTION_STRICTNESS = "strictness";
4609
- const OPTION_FILENAME_VALIDATION = "filenameValidation";
4610
- const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
4611
- const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
4612
- const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
4613
- const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
4614
- const TEXT_TYPE_FILENAME = "filename";
4615
- const TEXT_TYPE_COMMENT = "comment";
4616
- const STRICTNESS_STRICT = "strict";
4617
- const STRICTNESS_BALANCED = "balanced";
4618
- const STRICTNESS_TOLERANT = "tolerant";
4619
-
4620
4702
  /*
4621
4703
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4622
4704
 
@@ -4657,6 +4739,7 @@ const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
4657
4739
  const ERR_UNSUPPORTED_COMPRESSION$1 = "Compression method not supported";
4658
4740
  const ERR_SPLIT_ZIP_FILE = "Split zip file";
4659
4741
  const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
4742
+ const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
4660
4743
  const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
4661
4744
  const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
4662
4745
  const ERR_UNSAFE_FILENAME = "Unsafe filename";
@@ -4677,7 +4760,7 @@ const ZIP64_PROPERTIES = [
4677
4760
  ];
4678
4761
  const ZIP64_EXTRACTION = {
4679
4762
  [MAX_16_BITS]: {
4680
- getValue: getUint32,
4763
+ getValue: getUint32$1,
4681
4764
  bytes: 4
4682
4765
  },
4683
4766
  [MAX_32_BITS]: {
@@ -4686,6 +4769,7 @@ const ZIP64_EXTRACTION = {
4686
4769
  }
4687
4770
  };
4688
4771
  const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
4772
+ const MAX_DEFLATE_EXPANSION_RATIO = 1032;
4689
4773
  const CENTRAL_DIRECTORY_UNREACHABLE = 0;
4690
4774
  const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
4691
4775
  const CENTRAL_DIRECTORY_REACHABLE = 2;
@@ -4696,7 +4780,6 @@ class ZipReader {
4696
4780
  Object.assign(this, {
4697
4781
  reader: new GenericReader(reader),
4698
4782
  options,
4699
- config: getConfiguration(),
4700
4783
  readRanges: new Map()
4701
4784
  });
4702
4785
  }
@@ -4704,7 +4787,6 @@ class ZipReader {
4704
4787
  async* getEntriesGenerator(options = {}) {
4705
4788
  const zipReader = this;
4706
4789
  let { reader } = zipReader;
4707
- const { config } = zipReader;
4708
4790
  await initStream(reader);
4709
4791
  if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
4710
4792
  reader = new BlobReader(await streamToBlob(reader.readable));
@@ -4721,9 +4803,7 @@ class ZipReader {
4721
4803
  const normalizeFilename = getOptionValue$1(zipReader, options, OPTION_NORMALIZE_FILENAME);
4722
4804
  const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
4723
4805
  if (!endOfDirectoryInfo) {
4724
- const signatureArray = await readUint8Array(reader, 0, 4);
4725
- const signatureView = getDataView(signatureArray);
4726
- if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
4806
+ if (await startsWithSplitZipSignature$1(reader)) {
4727
4807
  throw new Error(ERR_SPLIT_ZIP_FILE);
4728
4808
  } else {
4729
4809
  throw new Error(ERR_EOCDR_NOT_FOUND);
@@ -4733,22 +4813,23 @@ class ZipReader {
4733
4813
  throwAmbiguousArchive("multiple end of central directory records");
4734
4814
  }
4735
4815
  const endOfDirectoryView = getDataView(endOfDirectoryInfo);
4736
- let directoryDataLength = getUint32(endOfDirectoryView, 12);
4737
- let directoryDataOffset = getUint32(endOfDirectoryView, 16);
4816
+ let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
4817
+ let directoryDataOffset = getUint32$1(endOfDirectoryView, 16);
4738
4818
  const commentOffset = endOfDirectoryInfo.offset;
4739
- const commentLength = getUint16(endOfDirectoryView, 20);
4819
+ const commentLength = getUint16$1(endOfDirectoryView, 20);
4740
4820
  const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
4741
4821
  if (reader.size - appendedDataOffset > maxAppendedDataSize) {
4742
4822
  throwAmbiguousArchive("appended data");
4743
4823
  }
4744
- let lastDiskNumber = getUint16(endOfDirectoryView, 4);
4824
+ let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
4745
4825
  const expectedLastDiskNumber = reader.lastDiskNumber || 0;
4746
- let diskNumber = getUint16(endOfDirectoryView, 6);
4747
- let filesLength = getUint16(endOfDirectoryView, 10);
4826
+ let diskNumber = getUint16$1(endOfDirectoryView, 6);
4827
+ let filesLength = getUint16$1(endOfDirectoryView, 10);
4748
4828
  let prependedDataLength = 0;
4749
4829
  let startOffset;
4750
4830
  let zip64EndOfDirectory;
4751
4831
  let zip64EndOfDirectoryVersion2;
4832
+ let zip64EndOfDirectoryLength = ZIP64_END_OF_CENTRAL_DIR_LENGTH;
4752
4833
  let directoryEncryptionInfo;
4753
4834
  const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
4754
4835
  if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
@@ -4760,12 +4841,12 @@ class ZipReader {
4760
4841
  EMPTY_UINT8_ARRAY;
4761
4842
  const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
4762
4843
  if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
4763
- getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
4764
- directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
4844
+ getUint32$1(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
4845
+ directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
4765
4846
  let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4766
4847
  let endOfDirectoryView = getDataView(endOfDirectoryArray);
4767
4848
  const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
4768
- if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
4849
+ if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
4769
4850
  directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
4770
4851
  const originalDirectoryDataOffset = directoryDataOffset;
4771
4852
  directoryDataOffset = expectedDirectoryDataOffset;
@@ -4775,7 +4856,7 @@ class ZipReader {
4775
4856
  endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4776
4857
  endOfDirectoryView = getDataView(endOfDirectoryArray);
4777
4858
  }
4778
- if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
4859
+ if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
4779
4860
  throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
4780
4861
  }
4781
4862
  zip64EndOfDirectory = true;
@@ -4785,18 +4866,19 @@ class ZipReader {
4785
4866
  Number(getBigUint64(endOfDirectoryView, 4)) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
4786
4867
  reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4787
4868
  if (extensibleDataLength > 0) {
4869
+ zip64EndOfDirectoryLength += extensibleDataLength;
4788
4870
  const rawExtensibleData = await readUint8Array(reader, directoryDataOffset + ZIP64_END_OF_CENTRAL_DIR_LENGTH, extensibleDataLength);
4789
4871
  directoryEncryptionInfo = getDirectoryEncryptionInfo(rawExtensibleData);
4790
4872
  }
4791
4873
  }
4792
4874
  if (lastDiskNumber == MAX_16_BITS) {
4793
- lastDiskNumber = getUint32(endOfDirectoryView, 16);
4794
- } else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
4875
+ lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
4876
+ } else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
4795
4877
  throwAmbiguousArchive("mismatched zip64 end of central directory record");
4796
4878
  }
4797
4879
  if (diskNumber == MAX_16_BITS) {
4798
- diskNumber = getUint32(endOfDirectoryView, 20);
4799
- } else if (checkAmbiguity && diskNumber != getUint32(endOfDirectoryView, 20)) {
4880
+ diskNumber = getUint32$1(endOfDirectoryView, 20);
4881
+ } else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
4800
4882
  throwAmbiguousArchive("mismatched zip64 end of central directory record");
4801
4883
  }
4802
4884
  if (filesLength == MAX_16_BITS) {
@@ -4814,7 +4896,7 @@ class ZipReader {
4814
4896
  }
4815
4897
  let declaredDirectoryDataLength = directoryDataLength;
4816
4898
  const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
4817
- (zip64EndOfDirectory ? ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
4899
+ (zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
4818
4900
  if (directoryDataOffset >= reader.size) {
4819
4901
  prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
4820
4902
  directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
@@ -4834,11 +4916,13 @@ class ZipReader {
4834
4916
  }
4835
4917
  const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
4836
4918
  if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
4837
- const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
4919
+ const storedPointsAtDirectory = getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
4920
+ Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
4921
+ detectEncryptedCentralDirectory(directoryView);
4838
4922
  let reconcile = !storedPointsAtDirectory;
4839
4923
  if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
4840
4924
  const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
4841
- reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
4925
+ reconcile = getUint32$1(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
4842
4926
  }
4843
4927
  if (reconcile) {
4844
4928
  const originalDirectoryDataOffset = directoryDataOffset;
@@ -4862,12 +4946,14 @@ class ZipReader {
4862
4946
  }
4863
4947
  zipReader.directoryOffset = directoryDataOffset;
4864
4948
  zipReader.directoryLength = declaredDirectoryDataLength;
4865
- const decryptCentralDirectory = getOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4866
- let decryptedDirectory;
4949
+ const decryptCentralDirectory = getFunctionOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4950
+ let decryptedDirectory, dataAfterEncryptedDirectory;
4867
4951
  if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
4868
- getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4952
+ getUint32$1(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4869
4953
  (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4870
- directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
4954
+ const encryptedDirectoryDataLength = getEncryptedDirectoryDataLength(directoryEncryptionInfo, declaredDirectoryDataLength, directoryArray.length);
4955
+ dataAfterEncryptedDirectory = directoryArray.subarray(encryptedDirectoryDataLength);
4956
+ directoryArray = await decryptCentralDirectory(directoryArray.subarray(0, encryptedDirectoryDataLength), directoryEncryptionInfo);
4871
4957
  directoryView = getDataView(directoryArray);
4872
4958
  declaredDirectoryDataLength = directoryArray.length;
4873
4959
  decryptedDirectory = true;
@@ -4878,8 +4964,8 @@ class ZipReader {
4878
4964
  const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
4879
4965
  let duplicateFilename;
4880
4966
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4881
- const fileEntry = new ZipEntry$1(reader, config, zipReader.options);
4882
- if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4967
+ const fileEntry = new ZipEntry$1(reader, zipReader.options);
4968
+ if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4883
4969
  if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4884
4970
  throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
4885
4971
  }
@@ -4890,16 +4976,16 @@ class ZipReader {
4890
4976
  const filenameOffset = offset + CENTRAL_FILE_HEADER_LENGTH;
4891
4977
  const extraFieldOffset = filenameOffset + fileEntry.filenameLength;
4892
4978
  const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
4893
- const versionMadeBy = getUint16(directoryView, offset + 4);
4979
+ const versionMadeBy = getUint16$1(directoryView, offset + 4);
4894
4980
  const msDosCompatible = versionMadeBy >> 8 == 0;
4895
4981
  const unixCompatible = versionMadeBy >> 8 == 3;
4896
4982
  const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
4897
- const commentLength = getUint16(directoryView, offset + 32);
4983
+ const commentLength = getUint16$1(directoryView, offset + 32);
4898
4984
  const endOffset = commentOffset + commentLength;
4899
4985
  const rawComment = directoryArray.subarray(commentOffset, endOffset);
4900
4986
  const filenameUTF8 = languageEncodingFlag;
4901
4987
  const commentUTF8 = languageEncodingFlag;
4902
- const externalFileAttributes = getUint32(directoryView, offset + 38);
4988
+ const externalFileAttributes = getUint32$1(directoryView, offset + 38);
4903
4989
  const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
4904
4990
  const msdosAttributes = {
4905
4991
  readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
@@ -4908,8 +4994,8 @@ class ZipReader {
4908
4994
  directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
4909
4995
  archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
4910
4996
  };
4911
- const offsetFileEntry = getUint32(directoryView, offset + 42);
4912
- const decode = getOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
4997
+ const offsetFileEntry = getUint32$1(directoryView, offset + 42);
4998
+ const decode = getFunctionOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
4913
4999
  const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
4914
5000
  const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
4915
5001
  let filename = decode(rawFilename, rawFilenameEncoding, TEXT_TYPE_FILENAME);
@@ -4933,6 +5019,7 @@ class ZipReader {
4933
5019
  }
4934
5020
  Object.assign(fileEntry, {
4935
5021
  index: indexFile,
5022
+ decryptedDirectory,
4936
5023
  versionMadeBy,
4937
5024
  msDosCompatible,
4938
5025
  zip64: false,
@@ -4940,8 +5027,8 @@ class ZipReader {
4940
5027
  uncompressedSize: 0,
4941
5028
  commentLength,
4942
5029
  offset: offsetFileEntry,
4943
- diskNumberStart: getUint16(directoryView, offset + 34),
4944
- internalFileAttributes: getUint16(directoryView, offset + 36),
5030
+ diskNumberStart: getUint16$1(directoryView, offset + 34),
5031
+ internalFileAttributes: getUint16$1(directoryView, offset + 36),
4945
5032
  externalFileAttributes,
4946
5033
  msdosAttributesRaw,
4947
5034
  msdosAttributes,
@@ -5009,12 +5096,11 @@ class ZipReader {
5009
5096
  yield entry;
5010
5097
  }
5011
5098
  let offsetAfterSignature = offset;
5012
- if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
5013
- const signatureDataLength = getUint16(directoryView, offset + 4);
5014
- if (offset + 6 + signatureDataLength <= directoryArray.length) {
5015
- zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
5016
- offsetAfterSignature = offset + 6 + signatureDataLength;
5017
- }
5099
+ const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5100
+ (decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
5101
+ if (digitalSignature) {
5102
+ zipReader.digitalSignature = digitalSignature;
5103
+ offsetAfterSignature = offset + 6 + digitalSignature.length;
5018
5104
  }
5019
5105
  if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
5020
5106
  throwAmbiguousArchive("trailing central directory data");
@@ -5022,13 +5108,17 @@ class ZipReader {
5022
5108
  if (duplicateFilename) {
5023
5109
  throwAmbiguousArchive("duplicate filename");
5024
5110
  }
5025
- if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > 0))) {
5026
- throwAmbiguousArchive("prepended data");
5027
- }
5028
5111
  const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
5029
5112
  const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
5113
+ const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
5114
+ startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
5115
+ if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
5116
+ throwAmbiguousArchive("prepended data");
5117
+ }
5030
5118
  if (extractPrependedData) {
5031
- zipReader.prependedData = startOffset > 0 ? await readUint8Array(reader, 0, startOffset) : EMPTY_UINT8_ARRAY;
5119
+ zipReader.prependedData = startOffset > splitZipSignatureLength ?
5120
+ await readUint8Array(reader, splitZipSignatureLength, startOffset - splitZipSignatureLength) :
5121
+ EMPTY_UINT8_ARRAY;
5032
5122
  }
5033
5123
  zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : EMPTY_UINT8_ARRAY;
5034
5124
  if (extractAppendedData) {
@@ -5095,16 +5185,16 @@ class ZipReaderStream {
5095
5185
 
5096
5186
  let ZipEntry$1 = class ZipEntry {
5097
5187
 
5098
- constructor(reader, config, options) {
5188
+ constructor(reader, options) {
5099
5189
  Object.assign(this, {
5100
5190
  reader,
5101
- config,
5102
5191
  options
5103
5192
  });
5104
5193
  }
5105
5194
 
5106
5195
  async getData(writer, fileEntry, readRanges, options = {}) {
5107
5196
  const zipEntry = this;
5197
+ const config = getConfiguration();
5108
5198
  const {
5109
5199
  reader,
5110
5200
  index,
@@ -5113,7 +5203,6 @@ let ZipEntry$1 = class ZipEntry {
5113
5203
  extraFieldAES,
5114
5204
  extraFieldZip64,
5115
5205
  compressionMethod,
5116
- config,
5117
5206
  bitFlag,
5118
5207
  rawBitFlag,
5119
5208
  crc32,
@@ -5131,6 +5220,7 @@ let ZipEntry$1 = class ZipEntry {
5131
5220
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
5132
5221
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
5133
5222
  const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
5223
+ checkPasswordOption(password, rawPassword);
5134
5224
  password = password && password.length && password;
5135
5225
  rawPassword = rawPassword && rawPassword.length && rawPassword;
5136
5226
  if (extraFieldAES) {
@@ -5138,7 +5228,7 @@ let ZipEntry$1 = class ZipEntry {
5138
5228
  throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
5139
5229
  }
5140
5230
  }
5141
- if (dataArray.length < HEADER_SIZE || getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
5231
+ if (dataArray.length < HEADER_SIZE || getUint32$1(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
5142
5232
  throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
5143
5233
  }
5144
5234
  readCommonHeader(localDirectory, dataView, 4);
@@ -5200,9 +5290,12 @@ let ZipEntry$1 = class ZipEntry {
5200
5290
  }
5201
5291
  }
5202
5292
  const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
5293
+ if (dataOffset + compressedSize > reader.size) {
5294
+ throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
5295
+ }
5203
5296
  const size = compressedSize;
5204
5297
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5205
- const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
5298
+ const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5206
5299
  const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5207
5300
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
5208
5301
  const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
@@ -5210,6 +5303,8 @@ let ZipEntry$1 = class ZipEntry {
5210
5303
  checkOverlappingEntry = true;
5211
5304
  }
5212
5305
  const { onstart, onprogress, onend } = options;
5306
+ const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
5307
+ const outputSize = passThrough ? compressedSize : uncompressedSize;
5213
5308
  const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
5214
5309
  let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
5215
5310
  if (deflate64) {
@@ -5230,9 +5325,9 @@ let ZipEntry$1 = class ZipEntry {
5230
5325
  checkCrc32,
5231
5326
  checkAuthenticationCode: getOptionValue$1(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
5232
5327
  passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((crc32 >>> 24) & MAX_8_BITS)),
5233
- outputSize: passThrough ? compressedSize : uncompressedSize,
5328
+ outputSize,
5234
5329
  crc32,
5235
- compressed: compressionMethod != 0 && !passThrough,
5330
+ compressed,
5236
5331
  encrypted,
5237
5332
  useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
5238
5333
  useCompressionStream,
@@ -5269,11 +5364,11 @@ let ZipEntry$1 = class ZipEntry {
5269
5364
  writer = new WritableStream();
5270
5365
  }
5271
5366
  writer = new GenericWriter(writer);
5272
- await initStream(writer, passThrough ? compressedSize : uncompressedSize);
5367
+ await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5273
5368
  ({ writable } = writer);
5274
- const { outputSize } = await runWorker({ readable, writable }, workerOptions);
5275
- writer.size += outputSize;
5276
- if (outputSize != (passThrough ? compressedSize : uncompressedSize)) {
5369
+ const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5370
+ writer.size += writtenSize;
5371
+ if (writtenSize != outputSize) {
5277
5372
  throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
5278
5373
  }
5279
5374
  }
@@ -5307,26 +5402,47 @@ let ZipEntry$1 = class ZipEntry {
5307
5402
  function detectEncryptedCentralDirectory(directoryView) {
5308
5403
  const maxOffset = Math.min(directoryView.byteLength, 1024) - 3;
5309
5404
  for (let offset = 0; offset < maxOffset; offset++) {
5310
- if (getUint32(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
5405
+ if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
5311
5406
  return true;
5312
5407
  }
5313
5408
  }
5314
5409
  return false;
5315
5410
  }
5316
5411
 
5412
+ function readDigitalSignature(signatureRecordArray) {
5413
+ if (signatureRecordArray.length >= 6) {
5414
+ const signatureRecordView = getDataView(signatureRecordArray);
5415
+ if (getUint32$1(signatureRecordView, 0) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
5416
+ const signatureDataLength = getUint16$1(signatureRecordView, 4);
5417
+ if (6 + signatureDataLength <= signatureRecordArray.length) {
5418
+ return signatureRecordArray.subarray(6, 6 + signatureDataLength);
5419
+ }
5420
+ }
5421
+ }
5422
+ }
5423
+
5424
+ function getEncryptedDirectoryDataLength(directoryEncryptionInfo, declaredDirectoryDataLength, directoryDataLength) {
5425
+ const encryptedDirectoryDataLength = directoryEncryptionInfo && directoryEncryptionInfo.compressedSize ?
5426
+ directoryEncryptionInfo.compressedSize :
5427
+ declaredDirectoryDataLength;
5428
+ return encryptedDirectoryDataLength > 0 && encryptedDirectoryDataLength <= directoryDataLength ?
5429
+ encryptedDirectoryDataLength :
5430
+ directoryDataLength;
5431
+ }
5432
+
5317
5433
  function getDirectoryEncryptionInfo(rawExtensibleData) {
5318
5434
  const directoryEncryptionInfo = { rawExtensibleData };
5319
5435
  if (rawExtensibleData.length >= 28) {
5320
5436
  const extensibleDataView = getDataView(rawExtensibleData);
5321
- const hashDataLength = getUint16(extensibleDataView, 26);
5437
+ const hashDataLength = getUint16$1(extensibleDataView, 26);
5322
5438
  Object.assign(directoryEncryptionInfo, {
5323
- compressionMethod: getUint16(extensibleDataView, 0),
5439
+ compressionMethod: getUint16$1(extensibleDataView, 0),
5324
5440
  compressedSize: Number(getBigUint64(extensibleDataView, 2)),
5325
5441
  uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
5326
- encryptionAlgorithm: getUint16(extensibleDataView, 18),
5327
- bitLength: getUint16(extensibleDataView, 20),
5328
- flags: getUint16(extensibleDataView, 22),
5329
- hashAlgorithm: getUint16(extensibleDataView, 24),
5442
+ encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
5443
+ bitLength: getUint16$1(extensibleDataView, 20),
5444
+ flags: getUint16$1(extensibleDataView, 22),
5445
+ hashAlgorithm: getUint16$1(extensibleDataView, 24),
5330
5446
  hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
5331
5447
  });
5332
5448
  }
@@ -5334,12 +5450,12 @@ function getDirectoryEncryptionInfo(rawExtensibleData) {
5334
5450
  }
5335
5451
 
5336
5452
  function readCommonHeader(directory, dataView, offset) {
5337
- const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
5453
+ const rawBitFlag = directory.rawBitFlag = getUint16$1(dataView, offset + 2);
5338
5454
  const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
5339
- const rawLastModDate = getUint32(dataView, offset + 6);
5455
+ const rawLastModDate = getUint32$1(dataView, offset + 6);
5340
5456
  Object.assign(directory, {
5341
5457
  encrypted,
5342
- version: getUint16(dataView, offset),
5458
+ version: getUint16$1(dataView, offset),
5343
5459
  bitFlag: {
5344
5460
  level: (rawBitFlag & BITFLAG_LEVEL) >> 1,
5345
5461
  dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR,
@@ -5347,8 +5463,8 @@ function readCommonHeader(directory, dataView, offset) {
5347
5463
  },
5348
5464
  rawLastModDate,
5349
5465
  lastModDate: getDate(rawLastModDate),
5350
- filenameLength: getUint16(dataView, offset + 22),
5351
- extraFieldLength: getUint16(dataView, offset + 24)
5466
+ filenameLength: getUint16$1(dataView, offset + 22),
5467
+ extraFieldLength: getUint16$1(dataView, offset + 24)
5352
5468
  });
5353
5469
  }
5354
5470
 
@@ -5359,8 +5475,8 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5359
5475
  let offsetExtraField = 0;
5360
5476
  try {
5361
5477
  while (offsetExtraField < rawExtraField.length) {
5362
- const type = getUint16(rawExtraFieldView, offsetExtraField);
5363
- const size = getUint16(rawExtraFieldView, offsetExtraField + 2);
5478
+ const type = getUint16$1(rawExtraFieldView, offsetExtraField);
5479
+ const size = getUint16$1(rawExtraFieldView, offsetExtraField + 2);
5364
5480
  extraField.set(type, {
5365
5481
  type,
5366
5482
  data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size)
@@ -5370,12 +5486,12 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5370
5486
  } catch {
5371
5487
  // ignored
5372
5488
  }
5373
- const compressionMethod = getUint16(dataView, offset + 4);
5489
+ const compressionMethod = getUint16$1(dataView, offset + 4);
5374
5490
  Object.assign(directory, {
5375
- signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
5376
- crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
5377
- compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
5378
- uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
5491
+ signature: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
5492
+ crc32: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
5493
+ compressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
5494
+ uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
5379
5495
  });
5380
5496
  const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
5381
5497
  if (extraFieldZip64) {
@@ -5464,11 +5580,11 @@ function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName,
5464
5580
  computedCrc32.append(fileEntry[rawPropertyName]);
5465
5581
  const computedCrc32View = getDataView(new Uint8Array(4));
5466
5582
  computedCrc32View.setUint32(0, computedCrc32.get(), true);
5467
- const nameCrc32 = getUint32(extraFieldView, 1);
5583
+ const nameCrc32 = getUint32$1(extraFieldView, 1);
5468
5584
  Object.assign(extraFieldUnicode, {
5469
5585
  version: getUint8(extraFieldView, 0),
5470
5586
  [propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
5471
- valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32(computedCrc32View, 0)
5587
+ valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
5472
5588
  });
5473
5589
  if (extraFieldUnicode.valid) {
5474
5590
  directory[propertyName] = extraFieldUnicode[propertyName];
@@ -5484,7 +5600,7 @@ function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
5484
5600
  vendorId: getUint8(extraFieldView, 2),
5485
5601
  strength,
5486
5602
  originalCompressionMethod: compressionMethod,
5487
- compressionMethod: getUint16(extraFieldView, 5)
5603
+ compressionMethod: getUint16$1(extraFieldView, 5)
5488
5604
  });
5489
5605
  directory.compressionMethod = extraFieldAES.compressionMethod;
5490
5606
  if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1$1) {
@@ -5498,8 +5614,8 @@ function readExtraFieldNTFS(extraFieldNTFS, directory) {
5498
5614
  let tag1Data;
5499
5615
  try {
5500
5616
  while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) {
5501
- const tagValue = getUint16(extraFieldView, offsetExtraField);
5502
- const attributeSize = getUint16(extraFieldView, offsetExtraField + 2);
5617
+ const tagValue = getUint16$1(extraFieldView, offsetExtraField);
5618
+ const attributeSize = getUint16$1(extraFieldView, offsetExtraField + 2);
5503
5619
  if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) {
5504
5620
  tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize);
5505
5621
  }
@@ -5532,12 +5648,12 @@ function readExtraFieldUnixDates(extraField, directory) {
5532
5648
  return;
5533
5649
  }
5534
5650
  const extraFieldView = getDataView(extraField.data);
5535
- const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
5536
- const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
5651
+ const lastAccessDate = new Date((getUint32$1(extraFieldView, 0) | 0) * 1000);
5652
+ const lastModDate = new Date((getUint32$1(extraFieldView, 4) | 0) * 1000);
5537
5653
  const extraFieldData = { lastAccessDate, lastModDate };
5538
5654
  if (extraField.data.length >= 12) {
5539
- extraFieldData.uid = getUint16(extraFieldView, 8);
5540
- extraFieldData.gid = getUint16(extraFieldView, 10);
5655
+ extraFieldData.uid = getUint16$1(extraFieldView, 8);
5656
+ extraFieldData.gid = getUint16$1(extraFieldView, 10);
5541
5657
  }
5542
5658
  Object.assign(extraField, extraFieldData);
5543
5659
  Object.assign(directory, extraFieldData);
@@ -5557,8 +5673,8 @@ function readExtraFieldUnix(extraField, directory, isInfoZip) {
5557
5673
  gid = unpackUnixId(extraField.data.subarray(offset, offset + gidSize));
5558
5674
  Object.assign(extraField, { version, uid, gid });
5559
5675
  } else if (extraField.data.length >= 4) {
5560
- uid = getUint16(view, 0);
5561
- gid = getUint16(view, 2);
5676
+ uid = getUint16$1(view, 0);
5677
+ gid = getUint16$1(view, 2);
5562
5678
  Object.assign(extraField, { uid, gid });
5563
5679
  }
5564
5680
  if (uid !== UNDEFINED_VALUE) {
@@ -5608,7 +5724,7 @@ function readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory,
5608
5724
  let offset = 1;
5609
5725
  timeProperties.forEach((propertyName, indexProperty) => {
5610
5726
  if (extraFieldExtendedTimestamp.data.length >= offset + 4) {
5611
- const time = getUint32(extraFieldView, offset);
5727
+ const time = getUint32$1(extraFieldView, offset);
5612
5728
  directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date((time | 0) * 1000);
5613
5729
  const rawPropertyName = timeRawProperties[indexProperty];
5614
5730
  extraFieldExtendedTimestamp[rawPropertyName] = time;
@@ -5642,7 +5758,7 @@ async function detectOverlappingEntry({
5642
5758
  const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
5643
5759
  const dataDescriptorView = getDataView(dataDescriptorArray);
5644
5760
  let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
5645
- getUint32(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5761
+ getUint32$1(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5646
5762
  if (signature) {
5647
5763
  const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
5648
5764
  const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
@@ -5676,15 +5792,15 @@ async function detectOverlappingEntry({
5676
5792
  }
5677
5793
 
5678
5794
  function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
5679
- const crc32 = getUint32(dataDescriptorView, offset);
5795
+ const crc32 = getUint32$1(dataDescriptorView, offset);
5680
5796
  let compressedSize;
5681
5797
  let uncompressedSize;
5682
5798
  if (extraFieldZip64) {
5683
5799
  compressedSize = getBigUint64(dataDescriptorView, offset + 4);
5684
5800
  uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
5685
5801
  } else {
5686
- compressedSize = getUint32(dataDescriptorView, offset + 4);
5687
- uncompressedSize = getUint32(dataDescriptorView, offset + 8);
5802
+ compressedSize = getUint32$1(dataDescriptorView, offset + 4);
5803
+ uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
5688
5804
  }
5689
5805
  return { crc32, compressedSize, uncompressedSize };
5690
5806
  }
@@ -5693,10 +5809,28 @@ function getDiskOffset$1(reader, diskNumber) {
5693
5809
  return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
5694
5810
  }
5695
5811
 
5812
+ async function startsWithSplitZipSignature$1(reader) {
5813
+ return await getFirstSignature(reader) == SPLIT_ZIP_FILE_SIGNATURE;
5814
+ }
5815
+
5816
+ async function startsWithSplitZipMarker(reader) {
5817
+ const signature = await getFirstSignature(reader);
5818
+ return signature == SPLIT_ZIP_FILE_SIGNATURE || signature == TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE;
5819
+ }
5820
+
5821
+ async function getFirstSignature(reader) {
5822
+ const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
5823
+ return getUint32$1(getDataView(signatureArray));
5824
+ }
5825
+
5696
5826
  function isStrictnessValue(value) {
5697
5827
  return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
5698
5828
  }
5699
5829
 
5830
+ function getDecodableOutputSize(outputSize, compressedSize, compressed) {
5831
+ return Math.min(outputSize, compressed ? compressedSize * MAX_DEFLATE_EXPANSION_RATIO : compressedSize);
5832
+ }
5833
+
5700
5834
  function getStrictness(options, inheritedOptions) {
5701
5835
  return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
5702
5836
  }
@@ -5759,7 +5893,7 @@ function isUnsafeFilename(filename, filenameValidation) {
5759
5893
 
5760
5894
  function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
5761
5895
  if (maxAppendedDataSize !== UNDEFINED_VALUE) {
5762
- const size = toNumber$1(maxAppendedDataSize);
5896
+ const size = toNumber(maxAppendedDataSize);
5763
5897
  if (typeof size != NUMBER_TYPE || Number.isNaN(size) || size < 0) {
5764
5898
  throw new Error(ERR_INVALID_MAX_APPENDED_DATA_SIZE);
5765
5899
  }
@@ -5782,7 +5916,7 @@ async function findEndOfCentralDirectory(reader, rejectAmbiguous, maxAppendedDat
5782
5916
  let plausibleEndOfDirectoryInfo;
5783
5917
  let endOfDirectoryReachingEndCount = 0;
5784
5918
  for await (const [anchoredView, anchoredOffset, anchoredArray, indexByte, offset] of scanEndOfCentralDirectory(reader, anchoredLength)) {
5785
- const commentLength = getUint16(anchoredView, indexByte + 20);
5919
+ const commentLength = getUint16$1(anchoredView, indexByte + 20);
5786
5920
  if (offset + END_OF_CENTRAL_DIR_LENGTH + commentLength == size) {
5787
5921
  const reachability = await getCentralDirectoryReachability(reader, anchoredView, anchoredOffset, indexByte, offset, size, remoteProbeBudget);
5788
5922
  if (reachability == CENTRAL_DIRECTORY_REACHABLE) {
@@ -5833,7 +5967,7 @@ async function* scanEndOfCentralDirectory(reader, scanLength) {
5833
5967
  const scanArray = await readUint8Array(reader, scanOffset, scanLength);
5834
5968
  const scanView = getDataView(scanArray);
5835
5969
  for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
5836
- if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
5970
+ if (getUint32$1(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
5837
5971
  yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
5838
5972
  }
5839
5973
  }
@@ -5844,9 +5978,9 @@ function getEndOfCentralDirectoryInfo(scanArray, indexByte, offset) {
5844
5978
  }
5845
5979
 
5846
5980
  async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
5847
- const filesLength = getUint16(view, indexByte + 10);
5848
- const directoryDataLength = getUint32(view, indexByte + 12);
5849
- const directoryDataOffset = getUint32(view, indexByte + 16);
5981
+ const filesLength = getUint16$1(view, indexByte + 10);
5982
+ const directoryDataLength = getUint32$1(view, indexByte + 12);
5983
+ const directoryDataOffset = getUint32$1(view, indexByte + 16);
5850
5984
  if (filesLength == MAX_16_BITS || directoryDataLength == MAX_32_BITS || directoryDataOffset == MAX_32_BITS) {
5851
5985
  const locatorSignature = await readSignature(reader, view, anchoredOffset, offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, size, remoteProbeBudget);
5852
5986
  return locatorSignature == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE ? CENTRAL_DIRECTORY_REACHABLE : CENTRAL_DIRECTORY_UNREACHABLE;
@@ -5854,7 +5988,7 @@ async function getCentralDirectoryReachability(reader, view, anchoredOffset, ind
5854
5988
  if (!filesLength && !directoryDataLength) {
5855
5989
  return CENTRAL_DIRECTORY_PLAUSIBLE;
5856
5990
  }
5857
- const directoryDiskNumber = getUint16(view, indexByte + 6);
5991
+ const directoryDiskNumber = getUint16$1(view, indexByte + 6);
5858
5992
  for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
5859
5993
  if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
5860
5994
  return CENTRAL_DIRECTORY_REACHABLE;
@@ -5868,19 +6002,21 @@ async function readSignature(reader, view, anchoredOffset, signatureOffset, size
5868
6002
  return UNDEFINED_VALUE;
5869
6003
  }
5870
6004
  if (signatureOffset >= anchoredOffset) {
5871
- return getUint32(view, signatureOffset - anchoredOffset);
6005
+ return getUint32$1(view, signatureOffset - anchoredOffset);
5872
6006
  }
5873
6007
  if (remoteProbeBudget.count > 0) {
5874
6008
  remoteProbeBudget.count--;
5875
6009
  const signatureArray = await readUint8Array(reader, signatureOffset, 4);
5876
- return getUint32(getDataView(signatureArray), 0);
6010
+ return getUint32$1(getDataView(signatureArray), 0);
5877
6011
  }
5878
6012
  return UNDEFINED_VALUE;
5879
6013
  }
5880
6014
 
5881
6015
  function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
5882
6016
  const { rawFilename } = zipEntry;
5883
- if (checkLocalFilename &&
6017
+ const maskedLocalDirectory = zipEntry.decryptedDirectory &&
6018
+ (localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
6019
+ if (checkLocalFilename && !maskedLocalDirectory &&
5884
6020
  (rawLocalFilename.length != rawFilename.length ||
5885
6021
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
5886
6022
  throwAmbiguousArchive("mismatched local file header (filename)");
@@ -5891,7 +6027,7 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
5891
6027
  if (localDirectory.compressionMethod != zipEntry.compressionMethod) {
5892
6028
  throwAmbiguousArchive("mismatched local file header (compression method)");
5893
6029
  }
5894
- if (!localDirectory.bitFlag.dataDescriptor &&
6030
+ if (!localDirectory.bitFlag.dataDescriptor && !maskedLocalDirectory &&
5895
6031
  (localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
5896
6032
  (localDirectory.crc32 != zipEntry.crc32 ||
5897
6033
  localDirectory.compressedSize != zipEntry.compressedSize ||
@@ -5910,10 +6046,11 @@ function getOptionValue$1(zipReader, options, name) {
5910
6046
  return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
5911
6047
  }
5912
6048
 
5913
- function toNumber$1(value) {
5914
- return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
6049
+ function getFunctionOptionValue$1(zipReader, options, name) {
6050
+ return checkFunctionOption(getOptionValue$1(zipReader, options, name));
5915
6051
  }
5916
6052
 
6053
+
5917
6054
  function getDate(timeRaw) {
5918
6055
  const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
5919
6056
  return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
@@ -5927,11 +6064,11 @@ function getUint8(view, offset) {
5927
6064
  return view.getUint8(offset);
5928
6065
  }
5929
6066
 
5930
- function getUint16(view, offset) {
6067
+ function getUint16$1(view, offset) {
5931
6068
  return view.getUint16(offset, true);
5932
6069
  }
5933
6070
 
5934
- function getUint32(view, offset) {
6071
+ function getUint32$1(view, offset) {
5935
6072
  return view.getUint32(offset, true);
5936
6073
  }
5937
6074
 
@@ -5946,6 +6083,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
5946
6083
  ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
5947
6084
  ERR_ENCRYPTED: ERR_ENCRYPTED,
5948
6085
  ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
6086
+ ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
5949
6087
  ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
5950
6088
  ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
5951
6089
  ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
@@ -6002,12 +6140,16 @@ const ERR_DUPLICATED_NAME = "File already exists";
6002
6140
  const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
6003
6141
  const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
6004
6142
  const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
6143
+ const ERR_INVALID_ENTRY_COMMENT_TYPE = "Invalid file entry comment (must be a string)";
6144
+ const ERR_INVALID_DATE = "Invalid date (must be a valid Date instance)";
6005
6145
  const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
6006
6146
  const ERR_INVALID_VERSION = "Version exceeds 65535";
6007
6147
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
6008
6148
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
6009
6149
  const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
6010
- const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
6150
+ const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
6151
+ const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
6152
+ const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
6011
6153
  const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
6012
6154
  const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
6013
6155
  const MIN_UNIX_TIME = -2147483648;
@@ -6016,6 +6158,7 @@ const MIN_NTFS_TIME = BigInt(0);
6016
6158
  const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
6017
6159
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
6018
6160
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
6161
+ const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
6019
6162
  const ERR_UNDETERMINED_SIZE = "Undetermined size";
6020
6163
  const ERR_UNDEFINED_READER = "Undefined reader";
6021
6164
  const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
@@ -6027,7 +6170,6 @@ const ERR_INVALID_UNIX_ID_SIZE = "uid/gid must be 0..65535 for unixExtraFieldTyp
6027
6170
  const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
6028
6171
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
6029
6172
  const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
6030
- const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
6031
6173
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6032
6174
 
6033
6175
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
@@ -6052,8 +6194,7 @@ class ZipWriter {
6052
6194
  writer,
6053
6195
  addSplitZipSignature,
6054
6196
  options,
6055
- config: getConfiguration(),
6056
- files: new Map(),
6197
+ fileEntries: new Map(),
6057
6198
  filenames: new Set(),
6058
6199
  offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
6059
6200
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
@@ -6074,14 +6215,23 @@ class ZipWriter {
6074
6215
  await initStream(reader);
6075
6216
  }
6076
6217
  const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
6077
- const zipReader$1 = new ZipReader(reader.readable);
6218
+ const zipReader$1 = new ZipReader(reader);
6078
6219
  const entries = await zipReader$1.getEntries();
6079
6220
  await zipReader$1.close();
6080
6221
  await initStream(this.writer);
6081
- await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
6082
- this.writer.size = this.offset = reader.size;
6222
+ const { directoryOffset } = zipReader$1;
6223
+ let splitZipSignatureLength = 0;
6224
+ if (this.addSplitZipSignature) {
6225
+ delete this.addSplitZipSignature;
6226
+ if (!await startsWithSplitZipSignature(reader)) {
6227
+ await writeData(this.writer, getSplitZipSignatureArray());
6228
+ splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6229
+ this.offset += splitZipSignatureLength;
6230
+ }
6231
+ }
6232
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
6083
6233
  this.filenames = new Set(entries.map(entry => entry.filename));
6084
- this.files = new Map(entries.map(entry => {
6234
+ this.fileEntries = new Map(entries.map(entry => {
6085
6235
  const {
6086
6236
  version,
6087
6237
  rawLastModDate,
@@ -6136,11 +6286,12 @@ class ZipWriter {
6136
6286
  if (crc32 !== UNDEFINED_VALUE) {
6137
6287
  setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
6138
6288
  }
6289
+ const { offset, diskNumberStart } = entryPositions.get(entry);
6139
6290
  Object.assign(entry, {
6140
6291
  zip64UncompressedSize,
6141
6292
  zip64CompressedSize,
6142
- zip64Offset: zip64 && entry.offset >= MAX_32_BITS,
6143
- diskNumberStart: 0,
6293
+ offset,
6294
+ diskNumberStart,
6144
6295
  zip64DiskNumberStart: false,
6145
6296
  rawExtraFieldZip64,
6146
6297
  rawExtraFieldAES,
@@ -6160,11 +6311,8 @@ class ZipWriter {
6160
6311
  async add(name = "", reader, options = {}) {
6161
6312
  const zipWriter = this;
6162
6313
  options = Object.assign({}, options);
6163
- const {
6164
- pendingAddFileCalls,
6165
- config
6166
- } = zipWriter;
6167
- if (workers < config.maxWorkers) {
6314
+ const { pendingAddFileCalls } = zipWriter;
6315
+ if (workers < getConfiguration().maxWorkers) {
6168
6316
  workers++;
6169
6317
  } else {
6170
6318
  await new Promise(resolve => pendingEntries.push(resolve));
@@ -6201,16 +6349,16 @@ class ZipWriter {
6201
6349
  }
6202
6350
 
6203
6351
  remove(entry) {
6204
- const { filenames, files } = this;
6352
+ const { filenames, fileEntries } = this;
6205
6353
  // deno-lint-ignore valid-typeof
6206
6354
  if (typeof entry == STRING_TYPE) {
6207
- entry = files.get(entry);
6355
+ entry = fileEntries.get(entry);
6208
6356
  }
6209
6357
  if (entry && entry.filename !== UNDEFINED_VALUE) {
6210
6358
  const { filename } = entry;
6211
- if (filenames.has(filename) && files.has(filename)) {
6359
+ if (filenames.has(filename) && fileEntries.has(filename)) {
6212
6360
  filenames.delete(filename);
6213
- files.delete(filename);
6361
+ fileEntries.delete(filename);
6214
6362
  return true;
6215
6363
  }
6216
6364
  }
@@ -6307,12 +6455,12 @@ async function addFile(zipWriter, name, reader, options) {
6307
6455
  const metadataInfo = resolveMetadata(zipWriter, name, options);
6308
6456
  const { comment } = metadataInfo;
6309
6457
  const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
6310
- zipWriter.files.set(name, UNDEFINED_VALUE);
6458
+ zipWriter.fileEntries.set(name, UNDEFINED_VALUE);
6311
6459
  let fileEntry;
6312
6460
  try {
6313
6461
  const { resolvedOptions } = metadataInfo;
6314
6462
  if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
6315
- !resolvedOptions.passThrough && !(await supportsDeflate(zipWriter.config))) {
6463
+ !resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
6316
6464
  resolvedOptions.level = 0;
6317
6465
  }
6318
6466
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
@@ -6330,7 +6478,7 @@ async function addFile(zipWriter, name, reader, options) {
6330
6478
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
6331
6479
  fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
6332
6480
  } catch (error) {
6333
- zipWriter.files.delete(name);
6481
+ zipWriter.fileEntries.delete(name);
6334
6482
  throw error;
6335
6483
  }
6336
6484
  Object.assign(fileEntry, {
@@ -6374,9 +6522,9 @@ function resolveAttributes(zipWriter, name, options) {
6374
6522
  if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
6375
6523
  unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
6376
6524
  }
6377
- let msdosAttributesRaw = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
6525
+ let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
6378
6526
  let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
6379
- const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
6527
+ const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType || executable;
6380
6528
  const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
6381
6529
  if (hasUnixMetadata) {
6382
6530
  msDosCompatible = false;
@@ -6385,10 +6533,10 @@ function resolveAttributes(zipWriter, name, options) {
6385
6533
  msDosCompatible = true;
6386
6534
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
6387
6535
  }
6388
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6536
+ if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6389
6537
  throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
6390
6538
  }
6391
- if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
6539
+ if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
6392
6540
  throw new Error(ERR_INVALID_MSDOS_DATA);
6393
6541
  }
6394
6542
  if (versionMadeBy > MAX_16_BITS) {
@@ -6476,7 +6624,7 @@ function resolveAttributes(zipWriter, name, options) {
6476
6624
  }
6477
6625
 
6478
6626
  function resolveMetadata(zipWriter, name, options) {
6479
- const encode = getOptionValue(zipWriter, options, OPTION_ENCODE_TEXT, encodeText);
6627
+ const encode = getFunctionOptionValue(zipWriter, options, OPTION_ENCODE_TEXT) || encodeText;
6480
6628
  let rawFilename = encode(name, TEXT_TYPE_FILENAME);
6481
6629
  if (rawFilename === UNDEFINED_VALUE) {
6482
6630
  rawFilename = encodeText(name);
@@ -6485,6 +6633,10 @@ function resolveMetadata(zipWriter, name, options) {
6485
6633
  throw new Error(ERR_INVALID_ENTRY_NAME);
6486
6634
  }
6487
6635
  const comment = options[PROPERTY_NAME_COMMENT] || "";
6636
+ // deno-lint-ignore valid-typeof
6637
+ if (typeof comment != STRING_TYPE) {
6638
+ throw new Error(ERR_INVALID_ENTRY_COMMENT_TYPE);
6639
+ }
6488
6640
  let rawComment = encode(comment, TEXT_TYPE_COMMENT);
6489
6641
  if (rawComment === UNDEFINED_VALUE) {
6490
6642
  rawComment = encodeText(comment);
@@ -6496,16 +6648,14 @@ function resolveMetadata(zipWriter, name, options) {
6496
6648
  if (version > MAX_16_BITS) {
6497
6649
  throw new Error(ERR_INVALID_VERSION);
6498
6650
  }
6499
- const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
6500
- const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6501
- const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6651
+ const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
6652
+ const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6653
+ const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6502
6654
  const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
6503
6655
  const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
6504
6656
  const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6505
6657
  const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6506
- if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
6507
- throw new Error(ERR_INVALID_PASSWORD_TYPE);
6508
- }
6658
+ checkPasswordOption(password, rawPassword);
6509
6659
  const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
6510
6660
  const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
6511
6661
  const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
@@ -6514,9 +6664,9 @@ function resolveMetadata(zipWriter, name, options) {
6514
6664
  const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
6515
6665
  const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
6516
6666
  const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
6517
- const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
6667
+ const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
6518
6668
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
6519
- const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
6669
+ const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
6520
6670
  const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
6521
6671
  const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
6522
6672
  const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
@@ -6536,6 +6686,9 @@ function resolveMetadata(zipWriter, name, options) {
6536
6686
  level = 0;
6537
6687
  }
6538
6688
  }
6689
+ if (passThrough) {
6690
+ level = UNDEFINED_VALUE;
6691
+ }
6539
6692
  let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
6540
6693
  let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
6541
6694
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
@@ -6596,18 +6749,26 @@ function serializeExtraField(extraField) {
6596
6749
  if (!extraField) {
6597
6750
  return EMPTY_UINT8_ARRAY;
6598
6751
  }
6752
+ if (!(extraField instanceof Map)) {
6753
+ throw new Error(ERR_INVALID_EXTRAFIELD);
6754
+ }
6599
6755
  let extraFieldSize = 0;
6600
6756
  let offset = 0;
6601
- extraField.forEach(data => extraFieldSize += 4 + getLength(data));
6602
- const rawExtraField = new Uint8Array(extraFieldSize);
6603
- const rawExtraFieldView = getDataView(rawExtraField);
6604
6757
  extraField.forEach((data, type) => {
6605
- if (type > MAX_16_BITS) {
6758
+ if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
6606
6759
  throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
6607
6760
  }
6761
+ if (!(data instanceof Uint8Array)) {
6762
+ throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
6763
+ }
6608
6764
  if (getLength(data) > MAX_16_BITS) {
6609
6765
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
6610
6766
  }
6767
+ extraFieldSize += 4 + getLength(data);
6768
+ });
6769
+ const rawExtraField = new Uint8Array(extraFieldSize);
6770
+ const rawExtraFieldView = getDataView(rawExtraField);
6771
+ extraField.forEach((data, type) => {
6611
6772
  setUint16(rawExtraFieldView, offset, type);
6612
6773
  setUint16(rawExtraFieldView, offset + 2, getLength(data));
6613
6774
  arraySet(rawExtraField, data, offset + 4);
@@ -6639,6 +6800,9 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
6639
6800
  if (uncompressedSize === UNDEFINED_VALUE) {
6640
6801
  throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
6641
6802
  }
6803
+ if (compressionMethod === UNDEFINED_VALUE) {
6804
+ throw new Error(ERR_UNDEFINED_COMPRESSION_METHOD);
6805
+ }
6642
6806
  }
6643
6807
  const zip64Enabled = zip64 === true;
6644
6808
  const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
@@ -6694,8 +6858,8 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
6694
6858
  }
6695
6859
 
6696
6860
  async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
6697
- const zipWriter = { options: writerOptions, config: getConfiguration() };
6698
- if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
6861
+ const zipWriter = { options: writerOptions };
6862
+ if (checkFunctionOption(writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY])) {
6699
6863
  throw new Error(ERR_UNDETERMINED_SIZE);
6700
6864
  }
6701
6865
  if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
@@ -6721,7 +6885,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6721
6885
  ({ name } = attributesInfo);
6722
6886
  const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
6723
6887
  if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
6724
- !metadata.passThrough && !(await supportsDeflate(zipWriter.config))) {
6888
+ !metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
6725
6889
  metadata.level = 0;
6726
6890
  }
6727
6891
  const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
@@ -6770,7 +6934,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6770
6934
 
6771
6935
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6772
6936
  const {
6773
- files,
6937
+ fileEntries,
6774
6938
  writer
6775
6939
  } = zipWriter;
6776
6940
  const {
@@ -6792,12 +6956,12 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6792
6956
  let writerSizeBeforeEntry;
6793
6957
  let flushedBufferedSize = 0;
6794
6958
  let fileWriter;
6795
- files.set(name, fileEntry);
6959
+ fileEntries.set(name, fileEntry);
6796
6960
  zipWriter.lastFileEntry = fileEntry;
6797
6961
  try {
6798
6962
  let lockPreviousFileEntry;
6799
6963
  if (keepOrder) {
6800
- lockPreviousFileEntry = previousFileEntry && previousFileEntry.lock;
6964
+ lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
6801
6965
  requestLockCurrentFileEntry();
6802
6966
  }
6803
6967
  if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
@@ -6818,11 +6982,8 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6818
6982
  const diskOffset = getDiskOffset(writer);
6819
6983
  if (zipWriter.addSplitZipSignature) {
6820
6984
  delete zipWriter.addSplitZipSignature;
6821
- const signatureArray = new Uint8Array(4);
6822
- const signatureArrayView = getDataView(signatureArray);
6823
- setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
6824
- await writeData(writer, signatureArray);
6825
- zipWriter.offset += 4;
6985
+ await writeData(writer, getSplitZipSignatureArray());
6986
+ zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6826
6987
  }
6827
6988
  if (usdz && !bufferedWrite) {
6828
6989
  appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
@@ -6840,11 +7001,11 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6840
7001
  writerSizeBeforeEntry = writer.size;
6841
7002
  await writeData(fileWriter, localHeaderArray);
6842
7003
  }
6843
- fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, zipWriter.config, options);
7004
+ fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, getConfiguration(), options);
6844
7005
  if (!bufferedWrite) {
6845
7006
  writingEntryData = false;
6846
7007
  }
6847
- files.set(name, fileEntry);
7008
+ fileEntries.set(name, fileEntry);
6848
7009
  fileEntry.filename = name;
6849
7010
  if (bufferedWrite) {
6850
7011
  await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
@@ -6885,7 +7046,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6885
7046
  zipWriter.offset += flushedBufferedSize;
6886
7047
  }
6887
7048
  }
6888
- files.delete(name);
7049
+ fileEntries.delete(name);
6889
7050
  throw error;
6890
7051
  } finally {
6891
7052
  if (bufferedWrite) {
@@ -6907,7 +7068,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6907
7068
  }
6908
7069
 
6909
7070
  function requestLockCurrentFileEntry() {
6910
- fileEntry.lock = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
7071
+ fileEntry.lockFileEntry = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
6911
7072
  }
6912
7073
 
6913
7074
  async function requestLockWriter() {
@@ -6927,7 +7088,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6927
7088
  }
6928
7089
  }
6929
7090
 
6930
- async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryInfo, config, options) {
7091
+ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry }, entryInfo, config, options) {
6931
7092
  const {
6932
7093
  headerInfo,
6933
7094
  dataDescriptorInfo,
@@ -6995,7 +7156,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
6995
7156
  codecURI
6996
7157
  } = options;
6997
7158
  const fileEntry = {
6998
- lock,
7159
+ lockFileEntry,
6999
7160
  versionMadeBy,
7000
7161
  zip64,
7001
7162
  directory: Boolean(directory),
@@ -7037,7 +7198,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
7037
7198
  }
7038
7199
  const { writable } = writer;
7039
7200
  if (reader) {
7040
- const readable = toCompatibleReadable(reader.createReadable ? reader.createReadable() : reader.readable);
7201
+ const readable = toCompatibleReadable(createReadable(reader));
7041
7202
  const size = reader.size;
7042
7203
  const workerOptions = {
7043
7204
  options: {
@@ -7149,14 +7310,14 @@ function getHeaderInfo(options) {
7149
7310
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
7150
7311
  const length = 4 + 16;
7151
7312
  const extraFieldZip64 = createRecordWriter(length);
7152
- extraFieldZip64.uint16(EXTRAFIELD_TYPE_ZIP64);
7153
- extraFieldZip64.uint16(length - 4);
7313
+ extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
7314
+ extraFieldZip64.writeUint16(length - 4);
7154
7315
  rawLocalExtraFieldZip64 = extraFieldZip64.array;
7155
7316
  if (zip64ExtraFieldComplete) {
7156
- extraFieldZip64.uint64(uncompressedSize);
7317
+ extraFieldZip64.writeUint64(uncompressedSize);
7157
7318
  if (uncompressedFile) {
7158
7319
  const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7159
- extraFieldZip64.uint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
7320
+ extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
7160
7321
  }
7161
7322
  }
7162
7323
  } else {
@@ -7165,8 +7326,8 @@ function getHeaderInfo(options) {
7165
7326
  let rawExtraFieldAES;
7166
7327
  if (encrypted && !zipCrypto) {
7167
7328
  const extraFieldAES = createRecordWriter(getLength(EXTRAFIELD_DATA_AES) + 2);
7168
- extraFieldAES.uint16(EXTRAFIELD_TYPE_AES);
7169
- extraFieldAES.bytes(EXTRAFIELD_DATA_AES);
7329
+ extraFieldAES.writeUint16(EXTRAFIELD_TYPE_AES);
7330
+ extraFieldAES.writeBytes(EXTRAFIELD_DATA_AES);
7170
7331
  rawExtraFieldAES = extraFieldAES.array;
7171
7332
  rawExtraFieldAES[8] = encryptionStrength;
7172
7333
  } else {
@@ -7182,15 +7343,15 @@ function getHeaderInfo(options) {
7182
7343
  const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
7183
7344
  const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
7184
7345
  extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
7185
- extraFieldTimestamp.uint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7186
- extraFieldTimestamp.uint16(extraFieldTimestampLength - 4);
7187
- extraFieldTimestamp.uint8(extraFieldExtendedTimestampFlag);
7188
- extraFieldTimestamp.uint32(lastModTimeUnix);
7346
+ extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7347
+ extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
7348
+ extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
7349
+ extraFieldTimestamp.writeUint32(lastModTimeUnix);
7189
7350
  if (lastAccessDate) {
7190
- extraFieldTimestamp.uint32(clampUnixTime(getTimeUnix(lastAccessDate)));
7351
+ extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(lastAccessDate)));
7191
7352
  }
7192
7353
  if (creationDate) {
7193
- extraFieldTimestamp.uint32(clampUnixTime(getTimeUnix(creationDate)));
7354
+ extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(creationDate)));
7194
7355
  }
7195
7356
  rawExtraFieldExtendedTimestamp = extraFieldTimestamp.array;
7196
7357
  } else {
@@ -7203,14 +7364,14 @@ function getHeaderInfo(options) {
7203
7364
  try {
7204
7365
  const lastModTimeNTFS = getTimeNTFS(lastModDate);
7205
7366
  const extraFieldNTFS = createRecordWriter(36);
7206
- extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS);
7207
- extraFieldNTFS.uint16(32);
7367
+ extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS);
7368
+ extraFieldNTFS.writeUint16(32);
7208
7369
  extraFieldNTFS.skip(4);
7209
- extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS_TAG1);
7210
- extraFieldNTFS.uint16(24);
7211
- extraFieldNTFS.uint64(lastModTimeNTFS);
7212
- extraFieldNTFS.uint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
7213
- extraFieldNTFS.uint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
7370
+ extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS_TAG1);
7371
+ extraFieldNTFS.writeUint16(24);
7372
+ extraFieldNTFS.writeUint64(lastModTimeNTFS);
7373
+ extraFieldNTFS.writeUint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
7374
+ extraFieldNTFS.writeUint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
7214
7375
  rawExtraFieldNTFS = extraFieldNTFS.array;
7215
7376
  } catch {
7216
7377
  rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
@@ -7229,20 +7390,20 @@ function getHeaderInfo(options) {
7229
7390
  const gidBytes = packUnixId(gid);
7230
7391
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
7231
7392
  const extraFieldUnix = createRecordWriter(4 + payloadLength);
7232
- extraFieldUnix.uint16(EXTRAFIELD_TYPE_INFOZIP);
7233
- extraFieldUnix.uint16(payloadLength);
7234
- extraFieldUnix.uint8(1);
7235
- extraFieldUnix.uint8(uidBytes.length);
7236
- extraFieldUnix.bytes(uidBytes);
7237
- extraFieldUnix.uint8(gidBytes.length);
7238
- extraFieldUnix.bytes(gidBytes);
7393
+ extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
7394
+ extraFieldUnix.writeUint16(payloadLength);
7395
+ extraFieldUnix.writeUint8(1);
7396
+ extraFieldUnix.writeUint8(uidBytes.length);
7397
+ extraFieldUnix.writeBytes(uidBytes);
7398
+ extraFieldUnix.writeUint8(gidBytes.length);
7399
+ extraFieldUnix.writeBytes(gidBytes);
7239
7400
  rawExtraFieldUnix = extraFieldUnix.array;
7240
7401
  } else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
7241
7402
  const extraFieldUnix = createRecordWriter(8);
7242
- extraFieldUnix.uint16(EXTRAFIELD_TYPE_UNIX);
7243
- extraFieldUnix.uint16(4);
7244
- extraFieldUnix.uint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
7245
- extraFieldUnix.uint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
7403
+ extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
7404
+ extraFieldUnix.writeUint16(4);
7405
+ extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
7406
+ extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
7246
7407
  rawExtraFieldUnix = extraFieldUnix.array;
7247
7408
  } else {
7248
7409
  rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
@@ -7292,18 +7453,18 @@ function getHeaderInfo(options) {
7292
7453
  const localHeader = createRecordWriter(HEADER_SIZE + getLength(rawFilename) + extraFieldLength);
7293
7454
  const localHeaderArray = localHeader.array;
7294
7455
  const localHeaderView = getDataView(localHeaderArray);
7295
- localHeader.uint32(LOCAL_FILE_HEADER_SIGNATURE);
7296
- localHeader.bytes(headerArray);
7297
- localHeader.bytes(rawFilename);
7456
+ localHeader.writeUint32(LOCAL_FILE_HEADER_SIGNATURE);
7457
+ localHeader.writeBytes(headerArray);
7458
+ localHeader.writeBytes(rawFilename);
7298
7459
  if (writeLocalExtraFieldZip64) {
7299
- localHeader.bytes(rawLocalExtraFieldZip64);
7300
- }
7301
- localHeader.bytes(rawExtraFieldAES);
7302
- localHeader.bytes(rawExtraFieldExtendedTimestamp);
7303
- localHeader.bytes(rawExtraFieldNTFS);
7304
- localHeader.bytes(rawExtraFieldUnix);
7305
- localHeader.bytes(rawExtraField);
7306
- localHeader.bytes(rawLocalExtraField);
7460
+ localHeader.writeBytes(rawLocalExtraFieldZip64);
7461
+ }
7462
+ localHeader.writeBytes(rawExtraFieldAES);
7463
+ localHeader.writeBytes(rawExtraFieldExtendedTimestamp);
7464
+ localHeader.writeBytes(rawExtraFieldNTFS);
7465
+ localHeader.writeBytes(rawExtraFieldUnix);
7466
+ localHeader.writeBytes(rawExtraField);
7467
+ localHeader.writeBytes(rawLocalExtraField);
7307
7468
  if (dataDescriptor) {
7308
7469
  if (!zip64CompressedSize) {
7309
7470
  setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, 0);
@@ -7493,7 +7654,7 @@ function updateLocalHeader({
7493
7654
 
7494
7655
 
7495
7656
  async function closeFile(zipWriter, comment, options) {
7496
- const directoryDataLength = createDirectoryRecords(zipWriter.files);
7657
+ const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
7497
7658
  const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7498
7659
  const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
7499
7660
  await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
@@ -7523,19 +7684,19 @@ function createDirectoryRecords(files) {
7523
7684
  if (zip64Offset || zip64DiskNumberStart || zip64UncompressedSize || zip64CompressedSize) {
7524
7685
  const length = 4 + (zip64UncompressedSize ? 8 : 0) + (zip64CompressedSize ? 8 : 0) + (zip64Offset ? 8 : 0) + (zip64DiskNumberStart ? 4 : 0);
7525
7686
  const extraFieldZip64 = createRecordWriter(length);
7526
- extraFieldZip64.uint16(EXTRAFIELD_TYPE_ZIP64);
7527
- extraFieldZip64.uint16(length - 4);
7687
+ extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
7688
+ extraFieldZip64.writeUint16(length - 4);
7528
7689
  if (zip64UncompressedSize) {
7529
- extraFieldZip64.uint64(uncompressedSize);
7690
+ extraFieldZip64.writeUint64(uncompressedSize);
7530
7691
  }
7531
7692
  if (zip64CompressedSize) {
7532
- extraFieldZip64.uint64(compressedSize);
7693
+ extraFieldZip64.writeUint64(compressedSize);
7533
7694
  }
7534
7695
  if (zip64Offset) {
7535
- extraFieldZip64.uint64(fileEntry.offset);
7696
+ extraFieldZip64.writeUint64(fileEntry.offset);
7536
7697
  }
7537
7698
  if (zip64DiskNumberStart) {
7538
- extraFieldZip64.uint32(fileEntry.diskNumberStart);
7699
+ extraFieldZip64.writeUint32(fileEntry.diskNumberStart);
7539
7700
  }
7540
7701
  rawExtraFieldZip64 = extraFieldZip64.array;
7541
7702
  } else {
@@ -7548,10 +7709,10 @@ function createDirectoryRecords(files) {
7548
7709
  const lastModTimeUnix = getTimeUnix(lastModDate);
7549
7710
  if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
7550
7711
  const extraFieldTimestamp = createRecordWriter(9);
7551
- extraFieldTimestamp.uint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7552
- extraFieldTimestamp.uint16(5);
7553
- extraFieldTimestamp.uint8(extraFieldExtendedTimestampFlag);
7554
- extraFieldTimestamp.uint32(lastModTimeUnix);
7712
+ extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7713
+ extraFieldTimestamp.writeUint16(5);
7714
+ extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
7715
+ extraFieldTimestamp.writeUint32(lastModTimeUnix);
7555
7716
  rawExtraFieldTimestamp = extraFieldTimestamp.array;
7556
7717
  } else {
7557
7718
  rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
@@ -7573,14 +7734,14 @@ function createDirectoryRecords(files) {
7573
7734
  }
7574
7735
 
7575
7736
  async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
7576
- const { files, writer } = zipWriter;
7737
+ const { fileEntries, writer } = zipWriter;
7577
7738
  const directoryArray = new Uint8Array(directoryDataLength);
7578
7739
  await initStream(writer);
7579
7740
  let offset = 0;
7580
7741
  let directoryDiskOffset = 0;
7581
7742
  let directoryStartDiskNumber = getDiskNumber(writer);
7582
7743
  let directoryStartDiskOffset = getDiskOffset(writer);
7583
- for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
7744
+ for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
7584
7745
  const {
7585
7746
  offset: fileEntryOffset,
7586
7747
  rawFilename,
@@ -7625,28 +7786,28 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
7625
7786
  setUint16(headerView, HEADER_OFFSET_VERSION, VERSION_ZIP64);
7626
7787
  }
7627
7788
  const directoryRecord = createRecordWriter(directoryRecordLength);
7628
- directoryRecord.uint32(CENTRAL_FILE_HEADER_SIGNATURE);
7629
- directoryRecord.uint16(versionMadeBy);
7630
- directoryRecord.bytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
7631
- directoryRecord.uint16(extraFieldLength);
7632
- directoryRecord.uint16(getLength(rawComment));
7633
- directoryRecord.uint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
7634
- directoryRecord.uint16(internalFileAttributes);
7635
- directoryRecord.uint32(externalFileAttributes);
7636
- directoryRecord.uint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
7637
- directoryRecord.bytes(rawFilename);
7638
- directoryRecord.bytes(rawExtraFieldZip64);
7639
- directoryRecord.bytes(rawExtraFieldAES);
7640
- directoryRecord.bytes(rawExtraFieldExtendedTimestamp);
7641
- directoryRecord.bytes(rawExtraFieldNTFS);
7642
- directoryRecord.bytes(rawExtraFieldUnix);
7643
- directoryRecord.bytes(rawExtraField);
7644
- directoryRecord.bytes(rawComment);
7789
+ directoryRecord.writeUint32(CENTRAL_FILE_HEADER_SIGNATURE);
7790
+ directoryRecord.writeUint16(versionMadeBy);
7791
+ directoryRecord.writeBytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
7792
+ directoryRecord.writeUint16(extraFieldLength);
7793
+ directoryRecord.writeUint16(getLength(rawComment));
7794
+ directoryRecord.writeUint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
7795
+ directoryRecord.writeUint16(internalFileAttributes);
7796
+ directoryRecord.writeUint32(externalFileAttributes);
7797
+ directoryRecord.writeUint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
7798
+ directoryRecord.writeBytes(rawFilename);
7799
+ directoryRecord.writeBytes(rawExtraFieldZip64);
7800
+ directoryRecord.writeBytes(rawExtraFieldAES);
7801
+ directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
7802
+ directoryRecord.writeBytes(rawExtraFieldNTFS);
7803
+ directoryRecord.writeBytes(rawExtraFieldUnix);
7804
+ directoryRecord.writeBytes(rawExtraField);
7805
+ directoryRecord.writeBytes(rawComment);
7645
7806
  arraySet(directoryArray, directoryRecord.array, offset);
7646
7807
  offset += directoryRecordLength;
7647
7808
  if (options.onprogress) {
7648
7809
  try {
7649
- await options.onprogress(indexFileEntry + 1, files.size, new Entry(fileEntry));
7810
+ await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
7650
7811
  } catch {
7651
7812
  // ignored
7652
7813
  }
@@ -7660,7 +7821,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
7660
7821
  }
7661
7822
 
7662
7823
  async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7663
- const signCentralDirectory = getOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
7824
+ const signCentralDirectory = getFunctionOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
7664
7825
  if (signCentralDirectory) {
7665
7826
  const signatureData = await signCentralDirectory(directoryArray);
7666
7827
  const signatureDataLength = getLength(signatureData);
@@ -7668,9 +7829,9 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7668
7829
  throw new Error(ERR_INVALID_SIGNATURE_DATA);
7669
7830
  }
7670
7831
  const signatureRecord = createRecordWriter(6 + signatureDataLength);
7671
- signatureRecord.uint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7672
- signatureRecord.uint16(signatureDataLength);
7673
- signatureRecord.bytes(signatureData);
7832
+ signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7833
+ signatureRecord.writeUint16(signatureDataLength);
7834
+ signatureRecord.writeBytes(signatureData);
7674
7835
  await writeData(zipWriter.writer, signatureRecord.array);
7675
7836
  return 6 + signatureDataLength;
7676
7837
  }
@@ -7681,7 +7842,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7681
7842
  const { writer } = zipWriter;
7682
7843
  const { directoryStart, signatureLength } = cdInfo;
7683
7844
  let { directoryDataLength } = cdInfo;
7684
- let filesLength = zipWriter.files.size;
7845
+ let fileEntriesLength = zipWriter.fileEntries.size;
7685
7846
  let diskNumber = directoryStart.diskNumber;
7686
7847
  let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
7687
7848
  let lastDiskNumber = getDiskNumber(writer);
@@ -7689,7 +7850,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7689
7850
  lastDiskNumber++;
7690
7851
  }
7691
7852
  let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
7692
- if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || filesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
7853
+ if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
7693
7854
  if (zip64 === false) {
7694
7855
  throw new Error(ERR_UNSUPPORTED_FORMAT);
7695
7856
  } else {
@@ -7706,37 +7867,37 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7706
7867
  }
7707
7868
  lastDiskNumber = getDiskNumber(writer);
7708
7869
  if (zip64) {
7709
- endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
7710
- endOfdirectoryRecord.uint64(44);
7711
- endOfdirectoryRecord.uint16(45);
7712
- endOfdirectoryRecord.uint16(45);
7713
- endOfdirectoryRecord.uint32(lastDiskNumber);
7714
- endOfdirectoryRecord.uint32(diskNumber);
7715
- endOfdirectoryRecord.uint64(filesLength);
7716
- endOfdirectoryRecord.uint64(filesLength);
7717
- endOfdirectoryRecord.uint64(directoryDataLength);
7718
- endOfdirectoryRecord.uint64(directoryOffset);
7719
- endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
7720
- endOfdirectoryRecord.uint32(lastDiskNumber);
7721
- endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
7722
- endOfdirectoryRecord.uint32(lastDiskNumber + 1);
7870
+ endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
7871
+ endOfdirectoryRecord.writeUint64(44);
7872
+ endOfdirectoryRecord.writeUint16(45);
7873
+ endOfdirectoryRecord.writeUint16(45);
7874
+ endOfdirectoryRecord.writeUint32(lastDiskNumber);
7875
+ endOfdirectoryRecord.writeUint32(diskNumber);
7876
+ endOfdirectoryRecord.writeUint64(fileEntriesLength);
7877
+ endOfdirectoryRecord.writeUint64(fileEntriesLength);
7878
+ endOfdirectoryRecord.writeUint64(directoryDataLength);
7879
+ endOfdirectoryRecord.writeUint64(directoryOffset);
7880
+ endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
7881
+ endOfdirectoryRecord.writeUint32(lastDiskNumber);
7882
+ endOfdirectoryRecord.writeUint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
7883
+ endOfdirectoryRecord.writeUint32(lastDiskNumber + 1);
7723
7884
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
7724
7885
  if (supportZip64SplitFile) {
7725
7886
  lastDiskNumber = MAX_16_BITS;
7726
7887
  diskNumber = MAX_16_BITS;
7727
7888
  }
7728
- filesLength = MAX_16_BITS;
7889
+ fileEntriesLength = MAX_16_BITS;
7729
7890
  directoryOffset = MAX_32_BITS;
7730
7891
  directoryDataLength = MAX_32_BITS;
7731
7892
  }
7732
- endOfdirectoryRecord.uint32(END_OF_CENTRAL_DIR_SIGNATURE);
7733
- endOfdirectoryRecord.uint16(lastDiskNumber);
7734
- endOfdirectoryRecord.uint16(diskNumber);
7735
- endOfdirectoryRecord.uint16(filesLength);
7736
- endOfdirectoryRecord.uint16(filesLength);
7737
- endOfdirectoryRecord.uint32(directoryDataLength);
7738
- endOfdirectoryRecord.uint32(directoryOffset);
7739
- endOfdirectoryRecord.uint16(commentLength);
7893
+ endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
7894
+ endOfdirectoryRecord.writeUint16(lastDiskNumber);
7895
+ endOfdirectoryRecord.writeUint16(diskNumber);
7896
+ endOfdirectoryRecord.writeUint16(fileEntriesLength);
7897
+ endOfdirectoryRecord.writeUint16(fileEntriesLength);
7898
+ endOfdirectoryRecord.writeUint32(directoryDataLength);
7899
+ endOfdirectoryRecord.writeUint32(directoryOffset);
7900
+ endOfdirectoryRecord.writeUint16(commentLength);
7740
7901
  await writeData(writer, endOfdirectoryRecord.array);
7741
7902
  if (commentLength) {
7742
7903
  await writeData(writer, comment);
@@ -7749,11 +7910,11 @@ function createRecordWriter(length) {
7749
7910
  let offset = 0;
7750
7911
  return {
7751
7912
  array,
7752
- uint8: value => { setUint8(view, offset, value); offset += 1; },
7753
- uint16: value => { setUint16(view, offset, value); offset += 2; },
7754
- uint32: value => { setUint32(view, offset, value); offset += 4; },
7755
- uint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
7756
- bytes: value => { arraySet(array, value, offset); offset += getLength(value); },
7913
+ writeUint8: value => { setUint8(view, offset, value); offset += 1; },
7914
+ writeUint16: value => { setUint16(view, offset, value); offset += 2; },
7915
+ writeUint32: value => { setUint32(view, offset, value); offset += 4; },
7916
+ writeUint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
7917
+ writeBytes: value => { arraySet(array, value, offset); offset += getLength(value); },
7757
7918
  skip: count => offset += count
7758
7919
  };
7759
7920
  }
@@ -7777,6 +7938,71 @@ function getSegmentOffset(zipWriter, { diskNumber = 0, diskOffset = 0 }) {
7777
7938
  return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
7778
7939
  }
7779
7940
 
7941
+ async function startsWithSplitZipSignature(reader) {
7942
+ const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
7943
+ return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7944
+ }
7945
+
7946
+ async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7947
+ const { writer } = zipWriter;
7948
+ const entryPositions = new Map();
7949
+ if (writer.closeDisk) {
7950
+ const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
7951
+ getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
7952
+ let copiedLength = 0;
7953
+ for (const entry of sortedEntries) {
7954
+ const sourceOffset = getSourceOffset(reader, entry);
7955
+ await copyData(zipWriter, reader, copiedLength, sourceOffset - copiedLength);
7956
+ if (exceedsAvailableSize(writer, await getLocalHeaderLength(reader, sourceOffset))) {
7957
+ await writer.closeDisk();
7958
+ }
7959
+ entryPositions.set(entry, {
7960
+ offset: getSegmentOffset(zipWriter, writer),
7961
+ diskNumberStart: getDiskNumber(writer)
7962
+ });
7963
+ copiedLength = sourceOffset;
7964
+ }
7965
+ await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7966
+ } else {
7967
+ await copyData(zipWriter, reader, 0, directoryOffset);
7968
+ entries.forEach(entry => entryPositions.set(entry, {
7969
+ offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7970
+ diskNumberStart: 0
7971
+ }));
7972
+ }
7973
+ return entryPositions;
7974
+ }
7975
+
7976
+ async function copyData(zipWriter, reader, offset, size) {
7977
+ if (size > 0) {
7978
+ const { writer } = zipWriter;
7979
+ await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
7980
+ writer.size += size;
7981
+ zipWriter.offset += size;
7982
+ }
7983
+ }
7984
+
7985
+ async function getLocalHeaderLength(reader, offset) {
7986
+ const headerArray = await readUint8Array(reader, offset, HEADER_SIZE);
7987
+ if (getLength(headerArray) < HEADER_SIZE) {
7988
+ return HEADER_SIZE;
7989
+ }
7990
+ const headerView = getDataView(headerArray);
7991
+ return HEADER_SIZE +
7992
+ getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
7993
+ getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
7994
+ }
7995
+
7996
+ function getSourceOffset(reader, { offset, diskNumberStart }) {
7997
+ return offset + (reader.getDiskOffset ? reader.getDiskOffset(diskNumberStart) : 0);
7998
+ }
7999
+
8000
+ function getSplitZipSignatureArray() {
8001
+ const signatureArray = new Uint8Array(SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
8002
+ setUint32(getDataView(signatureArray), 0, SPLIT_ZIP_FILE_SIGNATURE);
8003
+ return signatureArray;
8004
+ }
8005
+
7780
8006
  async function writeData(writer, array) {
7781
8007
  const { writable } = writer;
7782
8008
  const streamWriter = writable.getWriter();
@@ -7828,6 +8054,21 @@ function getOptionValue(zipWriter, options, name, defaultValue) {
7828
8054
  return result === UNDEFINED_VALUE ? defaultValue : result;
7829
8055
  }
7830
8056
 
8057
+ function getDateOptionValue(zipWriter, options, name, defaultValue) {
8058
+ const date = getOptionValue(zipWriter, options, name, defaultValue);
8059
+ if (date === null) {
8060
+ return defaultValue;
8061
+ }
8062
+ if (date !== UNDEFINED_VALUE && (typeof date.getTime != FUNCTION_TYPE || Number.isNaN(date.getTime()))) {
8063
+ throw new Error(ERR_INVALID_DATE);
8064
+ }
8065
+ return date;
8066
+ }
8067
+
8068
+ function getFunctionOptionValue(zipWriter, options, name) {
8069
+ return checkFunctionOption(getOptionValue(zipWriter, options, name));
8070
+ }
8071
+
7831
8072
  function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
7832
8073
  const value = getAliasedValue(options, name, deprecatedName);
7833
8074
  const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
@@ -7842,9 +8083,6 @@ function getNumberOptionValue(zipWriter, options, name, defaultValue) {
7842
8083
  return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
7843
8084
  }
7844
8085
 
7845
- function toNumber(value) {
7846
- return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
7847
- }
7848
8086
 
7849
8087
  function getMaximumCompressedSize(uncompressedSize) {
7850
8088
  return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
@@ -7856,6 +8094,14 @@ function isCompressed(compressionMethod, level) {
7856
8094
  : compressionMethod !== COMPRESSION_METHOD_STORE;
7857
8095
  }
7858
8096
 
8097
+ function getUint16(view, offset) {
8098
+ return view.getUint16(offset, true);
8099
+ }
8100
+
8101
+ function getUint32(view, offset) {
8102
+ return view.getUint32(offset, true);
8103
+ }
8104
+
7859
8105
  function setUint8(view, offset, value) {
7860
8106
  view.setUint8(offset, value);
7861
8107
  }
@@ -7899,9 +8145,9 @@ function getHeaderArrayData({
7899
8145
  const headerRecord = createRecordWriter(HEADER_SIZE - 4);
7900
8146
  const headerArray = headerRecord.array;
7901
8147
  const headerView = getDataView(headerArray);
7902
- headerRecord.uint16(version);
7903
- headerRecord.uint16(bitFlag);
7904
- headerRecord.uint16(compressionMethod);
8148
+ headerRecord.writeUint16(version);
8149
+ headerRecord.writeUint16(bitFlag);
8150
+ headerRecord.writeUint16(compressionMethod);
7905
8151
  if (rawLastModDate === UNDEFINED_VALUE) {
7906
8152
  const dateArray = new Uint32Array(1);
7907
8153
  const dateView = getDataView(dateArray);
@@ -7909,20 +8155,20 @@ function getHeaderArrayData({
7909
8155
  setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
7910
8156
  rawLastModDate = dateArray[0];
7911
8157
  }
7912
- headerRecord.uint32(rawLastModDate);
8158
+ headerRecord.writeUint32(rawLastModDate);
7913
8159
  headerRecord.skip(4);
7914
8160
  if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
7915
- headerRecord.uint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
8161
+ headerRecord.writeUint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
7916
8162
  } else {
7917
8163
  headerRecord.skip(4);
7918
8164
  }
7919
8165
  if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
7920
- headerRecord.uint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
8166
+ headerRecord.writeUint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
7921
8167
  } else {
7922
8168
  headerRecord.skip(4);
7923
8169
  }
7924
- headerRecord.uint16(getLength(rawFilename));
7925
- headerRecord.uint16(extraFieldLength);
8170
+ headerRecord.writeUint16(getLength(rawFilename));
8171
+ headerRecord.writeUint16(extraFieldLength);
7926
8172
  return {
7927
8173
  headerArray,
7928
8174
  headerView,
@@ -8842,6 +9088,7 @@ configureExternalAssets();
8842
9088
  const ERR_ENTRY_EXISTS = "Entry filename already exists";
8843
9089
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
8844
9090
  const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
9091
+ const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
8845
9092
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
8846
9093
  const ERR_ABORTED = "The operation was aborted";
8847
9094
  const ABORT_ERROR_NAME = "AbortError";
@@ -8874,13 +9121,14 @@ class ZipEntry {
8874
9121
  fs,
8875
9122
  name,
8876
9123
  data: params.data,
8877
- options: params.options,
9124
+ options: params.options && Object.assign({}, params.options),
8878
9125
  id: fs.entryIdCounter++,
8879
9126
  parent,
8880
9127
  children: [],
8881
9128
  uncompressedSize: params.uncompressedSize || 0,
8882
9129
  undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
8883
- passThrough: params.passThrough
9130
+ passThrough: params.passThrough,
9131
+ defaultLastModDate: params.defaultLastModDate || new Date()
8884
9132
  });
8885
9133
  if (parent || !fs.root) {
8886
9134
  fs.entries[zipEntry.id] = zipEntry;
@@ -8890,12 +9138,6 @@ class ZipEntry {
8890
9138
  }
8891
9139
  }
8892
9140
 
8893
- moveTo(target) {
8894
- // deprecated
8895
- const zipEntry = this;
8896
- zipEntry.fs.move(zipEntry, target);
8897
- }
8898
-
8899
9141
  getFullname() {
8900
9142
  return this.getRelativeName();
8901
9143
  }
@@ -8927,6 +9169,11 @@ class ZipEntry {
8927
9169
  this.name = name;
8928
9170
  }
8929
9171
  }
9172
+
9173
+ setOptions(options) {
9174
+ const entryOptions = Object.assign({}, this.options, options);
9175
+ this.options = Object.fromEntries(Object.entries(entryOptions).filter(([, value]) => value !== UNDEFINED_VALUE));
9176
+ }
8930
9177
  }
8931
9178
 
8932
9179
  class ZipFileEntry extends ZipEntry {
@@ -8953,7 +9200,7 @@ class ZipFileEntry extends ZipEntry {
8953
9200
  const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
8954
9201
  const dataSize = zipEntry.uncompressedSize || reader.size;
8955
9202
  await Promise.all([initStream(reader), initStream(writer, dataSize)]);
8956
- const { signal } = options;
9203
+ const signal = checkSignalOption(options.signal);
8957
9204
  const readable = createProgressReadable(zipEntry, reader, options, signal);
8958
9205
  const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
8959
9206
  zipEntry.uncompressedSize = reader.size;
@@ -9171,10 +9418,6 @@ class ZipDirectoryEntry extends ZipEntry {
9171
9418
  });
9172
9419
  }
9173
9420
 
9174
- addData(name, params) {
9175
- return addChild(this, name, params);
9176
- }
9177
-
9178
9421
  importBlob(blob, options) {
9179
9422
  return this.importZip(new BlobReader(blob), options);
9180
9423
  }
@@ -9288,7 +9531,7 @@ class ZipDirectoryEntry extends ZipEntry {
9288
9531
  if (options.bufferedWrite === UNDEFINED_VALUE) {
9289
9532
  options.bufferedWrite = true;
9290
9533
  }
9291
- const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
9534
+ const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
9292
9535
  const zipWriter = new ZipWriter(writer, options);
9293
9536
  await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
9294
9537
  await zipWriter.close(options.globalComment);
@@ -9298,12 +9541,13 @@ class ZipDirectoryEntry extends ZipEntry {
9298
9541
  getExportedSize(options = {}) {
9299
9542
  const zipEntry = this;
9300
9543
  options = Object.assign({}, options);
9544
+ checkReaderOptions(options.readerOptions);
9301
9545
  if (options.bufferedWrite === UNDEFINED_VALUE) {
9302
9546
  options.bufferedWrite = true;
9303
9547
  }
9304
9548
  const writeOrderGuaranteed = !options.bufferedWrite ||
9305
9549
  (options.keepOrder !== false && zipEntry.children.every(child => !child.children.length));
9306
- return getEntriesSize(options, Array.from(zipEntry.getChildren({ recursive: true }), child => {
9550
+ return getEntriesSize(options, zipEntry.getChildren({ recursive: true }).filter(child => !isImplicitDirectory(child)).map(child => {
9307
9551
  const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
9308
9552
  return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
9309
9553
  }), writeOrderGuaranteed, options.globalComment);
@@ -9342,7 +9586,7 @@ class ZipDirectoryEntry extends ZipEntry {
9342
9586
  }
9343
9587
 
9344
9588
 
9345
- class FS {
9589
+ class ZipFS {
9346
9590
 
9347
9591
  constructor() {
9348
9592
  resetFS(this);
@@ -9458,10 +9702,6 @@ class FS {
9458
9702
  return this.root.addFile(file, options);
9459
9703
  }
9460
9704
 
9461
- addData(name, params) {
9462
- return this.root.addData(name, params);
9463
- }
9464
-
9465
9705
  importBlob(blob, options) {
9466
9706
  resetFS(this);
9467
9707
  return this.root.importBlob(blob, options);
@@ -9529,7 +9769,7 @@ class FS {
9529
9769
  }
9530
9770
  }
9531
9771
 
9532
- const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
9772
+ const fs = { FS: ZipFS, ZipDirectoryEntry, ZipFileEntry };
9533
9773
 
9534
9774
  function getTotalSize(entries, getEntrySize) {
9535
9775
  let size = 0;
@@ -9673,7 +9913,7 @@ function detach(entry) {
9673
9913
  }
9674
9914
 
9675
9915
  function forwardAbort(signal, abortController) {
9676
- if (!signal) {
9916
+ if (!checkSignalOption(signal)) {
9677
9917
  return () => { };
9678
9918
  }
9679
9919
  if (signal.aborted) {
@@ -9750,10 +9990,7 @@ function getChildEntryOptions(child, selectedEntry, options) {
9750
9990
  });
9751
9991
  }
9752
9992
  if (isPassThrough(child, options)) {
9753
- let level, encryptionStrength;
9754
- if (compressionMethod === 0) {
9755
- level = 0;
9756
- }
9993
+ let encryptionStrength;
9757
9994
  if (extraFieldAES) {
9758
9995
  encryptionStrength = extraFieldAES.strength;
9759
9996
  }
@@ -9763,13 +10000,12 @@ function getChildEntryOptions(child, selectedEntry, options) {
9763
10000
  zipCrypto,
9764
10001
  crc32,
9765
10002
  uncompressedSize,
9766
- level,
9767
10003
  encryptionStrength,
9768
10004
  compressionMethod
9769
10005
  };
9770
10006
  }
9771
10007
  }
9772
- const entryOptions = Object.assign({}, zipEntryMetadata, options, passThroughOptions, childOptions, { directory: child.directory });
10008
+ const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
9773
10009
  if (!child.directory && entryOptions.passThrough && entryOptions.uncompressedSize === UNDEFINED_VALUE) {
9774
10010
  throw new Error(ERR_INVALID_PASS_THROUGH);
9775
10011
  }
@@ -9784,11 +10020,22 @@ function getDeterminedSize(child, passThrough) {
9784
10020
  return child.undeterminedSize ? UNDEFINED_VALUE : getExtractedSize(child, passThrough);
9785
10021
  }
9786
10022
 
10023
+ function checkReaderOptions(readerOptions) {
10024
+ if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
10025
+ throw new Error(ERR_INVALID_READER_OPTIONS);
10026
+ }
10027
+ return readerOptions;
10028
+ }
10029
+
9787
10030
  function isPassThrough(child, options) {
9788
10031
  const { readerOptions } = options;
9789
10032
  return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
9790
10033
  }
9791
10034
 
10035
+ function isImplicitDirectory(child) {
10036
+ return child.directory && child.data === null;
10037
+ }
10038
+
9792
10039
  function getUserExtraField(extraField) {
9793
10040
  if (extraField) {
9794
10041
  const userExtraField = new Map();
@@ -9806,7 +10053,7 @@ function getUserExtraField(extraField) {
9806
10053
  async function exportZip(zipWriter, entry, totalSize, options, readers) {
9807
10054
  const { onstart, onprogress, onend, onentryprogress } = options;
9808
10055
  const selectedEntry = entry;
9809
- const totalEntries = getTotalSize(entry.children, () => 1);
10056
+ const totalEntries = getTotalSize(entry.children, child => isImplicitDirectory(child) ? 0 : 1);
9810
10057
  let writtenSize = 0;
9811
10058
  let writtenEntries = 0;
9812
10059
  if (onstart) {
@@ -9835,6 +10082,9 @@ async function exportZip(zipWriter, entry, totalSize, options, readers) {
9835
10082
  }
9836
10083
 
9837
10084
  async function addChild(child) {
10085
+ if (isImplicitDirectory(child)) {
10086
+ return;
10087
+ }
9838
10088
  const { name, entryOptions } = getChildEntryOptions(child, selectedEntry, options);
9839
10089
  let entryWrittenSize = 0;
9840
10090
  const entryMetadata = await zipWriter.add(name, readers.get(child), Object.assign(entryOptions, {
@@ -9868,7 +10118,7 @@ function addFileSystemHandle(zipEntry, handle, options) {
9868
10118
  if (handle.kind == "file") {
9869
10119
  const file = await handle.getFile();
9870
10120
  addedEntries.push(
9871
- parentEntry.addData(file.name, {
10121
+ addChild(parentEntry, file.name, {
9872
10122
  Reader: function () {
9873
10123
  const readable = file.stream();
9874
10124
  const size = file.size;
@@ -9902,10 +10152,11 @@ function addFileSystemHandle(zipEntry, handle, options) {
9902
10152
 
9903
10153
  async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
9904
10154
  const { onstart, onprogress, onend } = options;
10155
+ const readerOptions = checkReaderOptions(options.readerOptions);
9905
10156
  const abortController = new AbortController();
9906
10157
  const { signal } = abortController;
9907
10158
  const releaseSignal = forwardAbort(options.signal, abortController);
9908
- const getDataOptions = Object.assign({}, options, options.readerOptions, {
10159
+ const getDataOptions = Object.assign({}, options, readerOptions, {
9909
10160
  signal,
9910
10161
  onstart: UNDEFINED_VALUE,
9911
10162
  onprogress: UNDEFINED_VALUE,
@@ -10163,4 +10414,4 @@ function decodeMimeTypes(data) {
10163
10414
  return mimeTypes;
10164
10415
  }
10165
10416
 
10166
- export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_DUPLICATED_NAME, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_EXISTS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH, ERR_INVALID_SIGNATURE, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_READABLE_CONSUMED, ERR_RESERVED_COMPRESSION_METHOD, ERR_SPLIT_ZIP_FILE, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION$1 as ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, Writer, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, fs, getMimeType, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };
10417
+ export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_DUPLICATED_NAME, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_ENTRY_EXISTS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH, ERR_INVALID_READER_OPTIONS, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_READABLE_CONSUMED, ERR_RESERVED_COMPRESSION_METHOD, ERR_SPLIT_ZIP_FILE, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION$1 as ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, Writer, ZipDirectoryEntry, ZipEntry, ZipFS, ZipFileEntry, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, fs, getMimeType, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };