@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
@@ -45,6 +45,7 @@
45
45
 
46
46
  const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
47
47
  const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
48
+ const TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE = 0x30304b50;
48
49
  const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
49
50
  const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
50
51
  const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
@@ -61,6 +62,7 @@
61
62
  const DATA_DESCRIPTOR_RECORD_LENGTH = 12;
62
63
  const DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH = 20;
63
64
  const DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH = 4;
65
+ const SPLIT_ZIP_FILE_SIGNATURE_LENGTH = 4;
64
66
 
65
67
  const EXTRAFIELD_TYPE_ZIP64 = 0x0001;
66
68
  const EXTRAFIELD_TYPE_AES = 0x9901;
@@ -83,6 +85,7 @@
83
85
  const BITFLAG_DATA_DESCRIPTOR = 0b1000;
84
86
  const BITFLAG_STRONG_ENCRYPTION = 0b1000000;
85
87
  const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
88
+ const BITFLAG_MASKED_LOCAL_HEADERS = 0b10000000000000;
86
89
  const FILE_ATTR_MSDOS_DIR_MASK = 0b10000;
87
90
  const FILE_ATTR_MSDOS_READONLY_MASK = 0x01;
88
91
  const FILE_ATTR_MSDOS_HIDDEN_MASK = 0x02;
@@ -112,6 +115,8 @@
112
115
  const HEADER_OFFSET_SIGNATURE = 10;
113
116
  const HEADER_OFFSET_COMPRESSED_SIZE = 14;
114
117
  const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18;
118
+ const HEADER_OFFSET_FILENAME_LENGTH = 22;
119
+ const HEADER_OFFSET_EXTRAFIELD_LENGTH = 24;
115
120
  const LOCAL_HEADER_COMMON_OFFSET = 4;
116
121
 
117
122
  const MAX_DATE = new Date(2107, 11, 31, 23, 59, 58);
@@ -124,9 +129,116 @@
124
129
  const OBJECT_TYPE = "object";
125
130
  const STRING_TYPE = "string";
126
131
  const NUMBER_TYPE = "number";
132
+ const BOOLEAN_TYPE = "boolean";
127
133
 
128
134
  const EMPTY_UINT8_ARRAY = new Uint8Array();
129
135
 
136
+ /*
137
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
138
+
139
+ Redistribution and use in source and binary forms, with or without
140
+ modification, are permitted provided that the following conditions are met:
141
+
142
+ 1. Redistributions of source code must retain the above copyright notice,
143
+ this list of conditions and the following disclaimer.
144
+
145
+ 2. Redistributions in binary form must reproduce the above copyright
146
+ notice, this list of conditions and the following disclaimer in
147
+ the documentation and/or other materials provided with the distribution.
148
+
149
+ 3. The names of the authors may not be used to endorse or promote products
150
+ derived from this software without specific prior written permission.
151
+
152
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
153
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
154
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
155
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
156
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
157
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
158
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
159
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
160
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
161
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
162
+ */
163
+
164
+
165
+ const OPTION_FILENAME_ENCODING = "filenameEncoding";
166
+ const OPTION_COMMENT_ENCODING = "commentEncoding";
167
+ const OPTION_DECODE_TEXT = "decodeText";
168
+ const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
169
+ const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
170
+ const OPTION_PASSWORD = "password";
171
+ const OPTION_RAW_PASSWORD = "rawPassword";
172
+ const OPTION_PASS_THROUGH = "passThrough";
173
+ const OPTION_SIGNAL = "signal";
174
+ const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
175
+ const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
176
+ const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
177
+ const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
178
+ const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
179
+ const OPTION_CHECK_SIGNATURE = "checkSignature";
180
+ const OPTION_CHECK_CRC32 = "checkCrc32";
181
+ const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
182
+ const OPTION_USE_WEB_WORKERS = "useWebWorkers";
183
+ const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
184
+ const OPTION_TRANSFER_STREAMS = "transferStreams";
185
+ const OPTION_PREVENT_CLOSE = "preventClose";
186
+ const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
187
+ const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
188
+ const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
189
+ const OPTION_KEEP_ORDER = "keepOrder";
190
+ const OPTION_LEVEL = "level";
191
+ const OPTION_BUFFERED_WRITE = "bufferedWrite";
192
+ const OPTION_CREATE_TEMP_STREAM = "createTempStream";
193
+ const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
194
+ const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
195
+ const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
196
+ const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
197
+ const OPTION_ENCODE_TEXT = "encodeText";
198
+ const OPTION_OFFSET = "offset";
199
+ const OPTION_USDZ = "usdz";
200
+ const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
201
+ const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
202
+ const OPTION_STRICTNESS = "strictness";
203
+ const OPTION_FILENAME_VALIDATION = "filenameValidation";
204
+ const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
205
+ const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
206
+ const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
207
+ const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
208
+ const TEXT_TYPE_FILENAME = "filename";
209
+ const TEXT_TYPE_COMMENT = "comment";
210
+ const STRICTNESS_STRICT = "strict";
211
+ const STRICTNESS_BALANCED = "balanced";
212
+ const STRICTNESS_TOLERANT = "tolerant";
213
+
214
+ const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
215
+ const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
216
+ const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
217
+
218
+ function checkFunctionOption(value) {
219
+ if (value && typeof value != FUNCTION_TYPE) {
220
+ throw new Error(ERR_INVALID_FUNCTION_OPTION);
221
+ }
222
+ return value;
223
+ }
224
+
225
+ function checkSignalOption(signal) {
226
+ if (signal && (typeof signal.addEventListener != FUNCTION_TYPE || typeof signal.aborted != BOOLEAN_TYPE)) {
227
+ throw new Error(ERR_INVALID_SIGNAL);
228
+ }
229
+ return signal || UNDEFINED_VALUE;
230
+ }
231
+
232
+ function checkPasswordOption(password, rawPassword) {
233
+ if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
234
+ throw new Error(ERR_INVALID_PASSWORD_TYPE);
235
+ }
236
+ }
237
+
238
+ function toNumber(value) {
239
+ return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
240
+ }
241
+
130
242
  /*
131
243
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
132
244
 
@@ -156,7 +268,10 @@
156
268
  */
157
269
 
158
270
 
271
+ const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
159
272
  const MINIMUM_CHUNK_SIZE = 64;
273
+ const MINIMUM_PROPERTY_VALUE = 1;
274
+ const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
160
275
  let maxWorkers = 2;
161
276
  try {
162
277
  if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
@@ -168,7 +283,7 @@
168
283
  const DEFAULT_CONFIGURATION = {
169
284
  workerURI: "./core/web-worker-wasm.js",
170
285
  wasmURI: "./core/streams/zlib-wasm/zlib-streams.wasm",
171
- chunkSize: 64 * 1024,
286
+ chunkSize: DEFAULT_CHUNK_SIZE$1,
172
287
  maxWorkers,
173
288
  terminateWorkerTimeout: 5000,
174
289
  workerStarvationTimeout: 5000,
@@ -180,24 +295,38 @@
180
295
  DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
181
296
  };
182
297
 
183
- const CONFIGURABLE_PROPERTY_NAMES = [
298
+ const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
299
+
300
+ const STRING_PROPERTY_NAMES = [
184
301
  "baseURI",
185
302
  "wasmURI",
186
- "workerURI",
187
- "createWorker",
303
+ "workerURI"
304
+ ];
305
+ const BOOLEAN_PROPERTY_NAMES = [
306
+ "useCompressionStream",
307
+ "useWebWorkers",
308
+ "transferStreams"
309
+ ];
310
+ const NUMBER_PROPERTY_NAMES = [
188
311
  "chunkSize",
189
- "maxWorkers",
312
+ PROPERTY_NAME_MAX_WORKERS,
190
313
  "terminateWorkerTimeout",
191
314
  "workerStarvationTimeout",
192
- "workerStartupTimeout",
193
- "useCompressionStream",
194
- "useWebWorkers",
195
- "transferStreams",
315
+ "workerStartupTimeout"
316
+ ];
317
+ const FUNCTION_PROPERTY_NAMES = [
318
+ "createWorker",
196
319
  "CompressionStream",
197
320
  "DecompressionStream",
198
321
  "CompressionStreamFallback",
199
322
  "DecompressionStreamFallback"
200
323
  ];
324
+ const CONFIGURABLE_PROPERTY_NAMES = [
325
+ ...STRING_PROPERTY_NAMES,
326
+ ...BOOLEAN_PROPERTY_NAMES,
327
+ ...NUMBER_PROPERTY_NAMES,
328
+ ...FUNCTION_PROPERTY_NAMES
329
+ ];
201
330
 
202
331
  const config = { ...DEFAULT_CONFIGURATION };
203
332
 
@@ -206,20 +335,43 @@
206
335
  }
207
336
 
208
337
  function getChunkSize(config) {
209
- return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
338
+ return normalizeChunkSize(config.chunkSize);
339
+ }
340
+
341
+ function normalizeChunkSize(chunkSize) {
342
+ chunkSize = toNumber(chunkSize);
343
+ return Number.isInteger(chunkSize) && chunkSize >= MINIMUM_PROPERTY_VALUE ? Math.max(chunkSize, MINIMUM_CHUNK_SIZE) : DEFAULT_CHUNK_SIZE$1;
210
344
  }
211
345
 
212
346
  function configure(configuration) {
213
- configuration = normalizeConfiguration(configuration);
347
+ Object.assign(config, checkConfiguration(normalizeConfiguration(configuration)));
348
+ }
349
+
350
+ function checkConfiguration(configuration) {
351
+ const checkedConfiguration = {};
214
352
  for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
215
353
  const propertyValue = configuration[propertyName];
216
354
  if (propertyValue !== UNDEFINED_VALUE) {
217
- config[propertyName] = propertyValue;
355
+ checkedConfiguration[propertyName] = checkPropertyValue(propertyName, propertyValue);
218
356
  }
219
357
  }
358
+ return checkedConfiguration;
359
+ }
360
+
361
+ function checkPropertyValue(propertyName, propertyValue) {
362
+ if (NUMBER_PROPERTY_NAMES.includes(propertyName)) {
363
+ propertyValue = toNumber(propertyValue);
364
+ if (propertyName == PROPERTY_NAME_MAX_WORKERS && (!Number.isInteger(propertyValue) || propertyValue < MINIMUM_PROPERTY_VALUE)) {
365
+ throw new Error(ERR_INVALID_MAX_WORKERS);
366
+ }
367
+ } else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
368
+ checkFunctionOption(propertyValue);
369
+ }
370
+ return propertyValue;
220
371
  }
221
372
 
222
373
  function normalizeConfiguration(configuration) {
374
+ configuration = configuration || {};
223
375
  const { CompressionStreamZlib, DecompressionStreamZlib } = configuration;
224
376
  if (CompressionStreamZlib === UNDEFINED_VALUE && DecompressionStreamZlib === UNDEFINED_VALUE) {
225
377
  return configuration;
@@ -235,14 +387,9 @@
235
387
  }
236
388
 
237
389
  function setDefaultConfiguration(configuration) {
238
- configuration = normalizeConfiguration(configuration);
239
- for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
240
- const propertyValue = configuration[propertyName];
241
- if (propertyValue !== UNDEFINED_VALUE) {
242
- DEFAULT_CONFIGURATION[propertyName] = propertyValue;
243
- }
244
- }
245
- configure(configuration);
390
+ const checkedConfiguration = checkConfiguration(normalizeConfiguration(configuration));
391
+ Object.assign(DEFAULT_CONFIGURATION, checkedConfiguration);
392
+ Object.assign(config, checkedConfiguration);
246
393
  }
247
394
 
248
395
  function resetConfiguration() {
@@ -252,7 +399,7 @@
252
399
  Object.assign(config, DEFAULT_CONFIGURATION);
253
400
  }
254
401
 
255
- const r=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],t=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],f=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],n=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],c=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],e=new Uint8Array(288);e.fill(8,0,144),e.fill(9,144,256),e.fill(7,256,280),e.fill(8,280,288);const j$1=new Uint8Array(30).fill(5);function z$1(r){const t=new Uint16Array(16);for(const f of r)t[f]++;t[0]=0;const f=new Uint16Array(17);for(let r=1;15>=r;r++)f[r+1]=f[r]+t[r];const n=new Uint16Array(r.length);for(let t=0;t<r.length;t++)r[t]&&(n[f[r[t]]++]=t);return {j:t,symbols:n}}const W$1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",p$1=(s=()=>(W=>{let p=0,s=0,o=0,Y=new Uint8Array(1024),l=0,B=0;for(;!B;){B=u(1);const r=u(2);if(0==r)T();else if(1==r)w(z$1(e),z$1(j$1));else {if(2!=r)throw Error("invalid deflate block type");w(...K());}}return Y.subarray(0,l);function S(){if(p>=W.length)throw Error("unexpected end of deflate data");return W[p++]}function u(r){for(;r>o;)s|=S()<<o,o+=8;const t=s&(1<<r)-1;return s>>>=r,o-=r,t}function T(){s=0,o=0;const r=S()|S()<<8;p+=2,D(l+r);for(let t=0;r>t;t++)Y[l++]=S();}function w(c,e){let j=q(c);for(;256!=j;){if(256>j)D(l+1),Y[l++]=j;else {const c=j-257,z=r[c]+u(t[c]),W=q(e),p=f[W]+u(n[W]);D(l+z);const s=l-p;for(let r=0;z>r;r++)Y[l++]=Y[s+r];}j=q(c);}}function K(){const r=u(5)+257,t=u(5)+1,f=u(4)+4,n=new Uint8Array(19);for(let r=0;f>r;r++)n[c[r]]=u(3);const e=z$1(n),j=new Uint8Array(r+t);let W=0;for(;W<j.length;){const r=q(e);if(16>r)j[W++]=r;else if(16==r){const r=j[W-1];let t=u(2)+3;for(;t--;)j[W++]=r;}else W+=17==r?u(3)+3:u(7)+11;}return [z$1(j.subarray(0,r)),z$1(j.subarray(r))]}function q(r){const{j:t,symbols:f}=r;let n=0,c=0,e=0;for(let r=1;15>=r;r++){n|=u(1);const j=t[r];if(j>n-c)return f[e+(n-c)];e+=j,c=c+j<<1,n<<=1;}throw Error("invalid huffman code")}function D(r){if(Y.length<r){let t=2*Y.length;for(;r>t;)t*=2;const f=new Uint8Array(t);f.set(Y.subarray(0,l)),Y=f;}}})((r=>{const t=(r=(r+"").replace(/[^A-Za-z0-9+/=]/g,"")).length,f=[];for(let n=0;t>n;n+=4){const t=W$1.indexOf(r[n])<<18|W$1.indexOf(r[n+1])<<12|(63&W$1.indexOf(r[n+2]))<<6|63&W$1.indexOf(r[n+3]);f.push(t>>16&255),"="!==r[n+2]&&f.push(t>>8&255),"="!==r[n+3]&&f.push(255&t);}return new Uint8Array(f)})("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")),r=>r({workerURI:r=>{const t="text/javascript";let f=s();if("string"==typeof f&&(f=(new TextEncoder).encode(f)),r){const r=new Blob([f],{type:t});return URL.createObjectURL(r)}return "data:"+t+";base64,"+(r=>{let t="";const f=r.length;let n=0;for(;f>n+2;n+=3){const f=r[n]<<16|r[n+1]<<8|r[n+2];t+=W$1[f>>18&63]+W$1[f>>12&63]+W$1[f>>6&63]+W$1[63&f];}const c=f-n;if(1===c){const f=r[n]<<16;t+=W$1[f>>18&63]+W$1[f>>12&63]+"==";}else if(2===c){const f=r[n]<<16|r[n+1]<<8;t+=W$1[f>>18&63]+W$1[f>>12&63]+W$1[f>>6&63]+"=";}return t})(f)}}));var s;
402
+ const n=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],r=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],e=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],f=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],t=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],o=new Uint8Array(288);o.fill(8,0,144),o.fill(9,144,256),o.fill(7,256,280),o.fill(8,280,288);const u=new Uint8Array(30).fill(5);function a(n){const r=new Uint16Array(16);for(const e of n)r[e]++;r[0]=0;const e=new Uint16Array(17);for(let n=1;n<=15;n++)e[n+1]=e[n]+r[n];const f=new Uint16Array(n.length);for(let r=0;r<n.length;r++)n[r]&&(f[e[n[r]]++]=r);return {o:r,symbols:f}}const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",p$1=(l=()=>(s=>{let p=0,l=0,U=0,K=new Uint8Array(1024),x=0,w=0;for(;!w;){w=i(1);const n=i(2);if(0==n)c();else if(1==n)j(a(o),a(u));else {if(2!=n)throw Error("invalid deflate block type");j(...y());}}return K.subarray(0,x);function b(){if(p>=s.length)throw Error("unexpected end of deflate data");return s[p++]}function i(n){for(;U<n;)l|=b()<<U,U+=8;const r=l&(1<<n)-1;return l>>>=n,U-=n,r}function c(){l=0,U=0;const n=b()|b()<<8;p+=2,V(x+n);for(let r=0;r<n;r++)K[x++]=b();}function j(t,o){let u=C(t);for(;256!=u;){if(u<256)V(x+1),K[x++]=u;else {const t=u-257,a=n[t]+i(r[t]),s=C(o),p=e[s]+i(f[s]);V(x+a);const l=x-p;for(let n=0;n<a;n++)K[x++]=K[l+n];}u=C(t);}}function y(){const n=i(5)+257,r=i(5)+1,e=i(4)+4,f=new Uint8Array(19);for(let n=0;n<e;n++)f[t[n]]=i(3);const o=a(f),u=new Uint8Array(n+r);let s=0;for(;s<u.length;){const n=C(o);if(n<16)u[s++]=n;else if(16==n){const n=u[s-1];let r=i(2)+3;for(;r--;)u[s++]=n;}else s+=17==n?i(3)+3:i(7)+11;}return [a(u.subarray(0,n)),a(u.subarray(n))]}function C(n){const{o:r,symbols:e}=n;let f=0,t=0,o=0;for(let n=1;n<=15;n++){f|=i(1);const u=r[n];if(f-t<u)return e[o+(f-t)];o+=u,t=t+u<<1,f<<=1;}throw Error("invalid huffman code")}function V(n){if(K.length<n){let r=2*K.length;for(;r<n;)r*=2;const e=new Uint8Array(r);e.set(K.subarray(0,x)),K=e;}}})((n=>{const r=(n=(n+"").replace(/[^A-Za-z0-9+/=]/g,"")).length,e=[];for(let f=0;f<r;f+=4){const r=s.indexOf(n[f])<<18|s.indexOf(n[f+1])<<12|(63&s.indexOf(n[f+2]))<<6|63&s.indexOf(n[f+3]);e.push(r>>16&255),"="!==n[f+2]&&e.push(r>>8&255),"="!==n[f+3]&&e.push(255&r);}return new Uint8Array(e)})("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")),n=>n({workerURI:n=>{const r="text/javascript";let e=l();if("string"==typeof e&&(e=(new TextEncoder).encode(e)),n){const n=new Blob([e],{type:r});return URL.createObjectURL(n)}return "data:"+r+";base64,"+(n=>{let r="";const e=n.length;let f=0;for(;f+2<e;f+=3){const e=n[f]<<16|n[f+1]<<8|n[f+2];r+=s[e>>18&63]+s[e>>12&63]+s[e>>6&63]+s[63&e];}const t=e-f;if(1===t){const e=n[f]<<16;r+=s[e>>18&63]+s[e>>12&63]+"==";}else if(2===t){const e=n[f]<<16|n[f+1]<<8;r+=s[e>>18&63]+s[e>>12&63]+s[e>>6&63]+"=";}return r})(e)}}));var l;
256
403
 
257
404
  /*
258
405
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -1400,13 +1547,13 @@
1400
1547
  const {
1401
1548
  ctr,
1402
1549
  hmac,
1403
- pending,
1550
+ pendingInput,
1404
1551
  ready
1405
1552
  } = this;
1406
1553
  if (hmac && ctr) {
1407
1554
  await ready;
1408
- const chunkToDecrypt = subarray(pending, 0, pending.length - AUTHENTICATION_CODE_LENGTH);
1409
- const originalAuthenticationCode = subarray(pending, pending.length - AUTHENTICATION_CODE_LENGTH);
1555
+ const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
1556
+ const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
1410
1557
  let decryptedChunkArray = EMPTY_UINT8_ARRAY;
1411
1558
  if (chunkToDecrypt.length) {
1412
1559
  const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
@@ -1415,7 +1562,7 @@
1415
1562
  decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
1416
1563
  }
1417
1564
  const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
1418
- let invalidAuthenticationCode = pending.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
1565
+ let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
1419
1566
  for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
1420
1567
  invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
1421
1568
  }
@@ -1459,14 +1606,14 @@
1459
1606
  const {
1460
1607
  ctr,
1461
1608
  hmac,
1462
- pending,
1609
+ pendingInput,
1463
1610
  ready
1464
1611
  } = this;
1465
1612
  if (hmac && ctr) {
1466
1613
  await ready;
1467
1614
  let encryptedChunkArray = EMPTY_UINT8_ARRAY;
1468
- if (pending.length) {
1469
- const encryptedChunk = ctr.update(toBits(codecBytes, pending));
1615
+ if (pendingInput.length) {
1616
+ const encryptedChunk = ctr.update(toBits(codecBytes, pendingInput));
1470
1617
  hmac.update(encryptedChunk);
1471
1618
  encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
1472
1619
  }
@@ -1483,7 +1630,7 @@
1483
1630
  ready: new Promise(resolve => aesCrypto.resolveReady = resolve),
1484
1631
  password: encodePassword(password, rawPassword),
1485
1632
  strength: encryptionStrength - 1,
1486
- pending: EMPTY_UINT8_ARRAY
1633
+ pendingInput: EMPTY_UINT8_ARRAY
1487
1634
  });
1488
1635
  }
1489
1636
 
@@ -1491,10 +1638,10 @@
1491
1638
  const {
1492
1639
  ctr,
1493
1640
  hmac,
1494
- pending
1641
+ pendingInput
1495
1642
  } = aesCrypto;
1496
- if (pending.length) {
1497
- input = concat(pending, input);
1643
+ if (pendingInput.length) {
1644
+ input = concat(pendingInput, input);
1498
1645
  }
1499
1646
  const inputLength = input.length - paddingEnd;
1500
1647
  output = expand(output, paddingStart + (inputLength - (inputLength % BLOCK_LENGTH)));
@@ -1510,7 +1657,7 @@
1510
1657
  }
1511
1658
  output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
1512
1659
  }
1513
- aesCrypto.pending = subarray(input, offset);
1660
+ aesCrypto.pendingInput = subarray(input, offset);
1514
1661
  return output;
1515
1662
  }
1516
1663
 
@@ -3283,6 +3430,96 @@
3283
3430
  resetWebWorkerSupport();
3284
3431
  }
3285
3432
 
3433
+ /*
3434
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
3435
+
3436
+ Redistribution and use in source and binary forms, with or without
3437
+ modification, are permitted provided that the following conditions are met:
3438
+
3439
+ 1. Redistributions of source code must retain the above copyright notice,
3440
+ this list of conditions and the following disclaimer.
3441
+
3442
+ 2. Redistributions in binary form must reproduce the above copyright
3443
+ notice, this list of conditions and the following disclaimer in
3444
+ the documentation and/or other materials provided with the distribution.
3445
+
3446
+ 3. The names of the authors may not be used to endorse or promote products
3447
+ derived from this software without specific prior written permission.
3448
+
3449
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
3450
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
3451
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
3452
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
3453
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3454
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
3455
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3456
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3457
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
3458
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3459
+ */
3460
+
3461
+ /* global TextDecoder */
3462
+
3463
+ const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
3464
+ const VALID_CP437 = CP437.length == 256;
3465
+
3466
+ function decodeCP437(stringValue) {
3467
+ if (VALID_CP437) {
3468
+ let result = "";
3469
+ for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
3470
+ result += CP437[stringValue[indexCharacter]];
3471
+ }
3472
+ return result;
3473
+ } else {
3474
+ return new TextDecoder().decode(stringValue);
3475
+ }
3476
+ }
3477
+
3478
+ /*
3479
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
3480
+
3481
+ Redistribution and use in source and binary forms, with or without
3482
+ modification, are permitted provided that the following conditions are met:
3483
+
3484
+ 1. Redistributions of source code must retain the above copyright notice,
3485
+ this list of conditions and the following disclaimer.
3486
+
3487
+ 2. Redistributions in binary form must reproduce the above copyright
3488
+ notice, this list of conditions and the following disclaimer in
3489
+ the documentation and/or other materials provided with the distribution.
3490
+
3491
+ 3. The names of the authors may not be used to endorse or promote products
3492
+ derived from this software without specific prior written permission.
3493
+
3494
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
3495
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
3496
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
3497
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
3498
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3499
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
3500
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3501
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3502
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
3503
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3504
+ */
3505
+
3506
+
3507
+ function decodeText(value, encoding) {
3508
+ return decode(value, encoding, true);
3509
+ }
3510
+
3511
+ function decodeTextRemovingBOM(value, encoding) {
3512
+ return decode(value, encoding, false);
3513
+ }
3514
+
3515
+ function decode(value, encoding, ignoreBOM) {
3516
+ if (encoding && encoding.trim().toLowerCase() == "cp437") {
3517
+ return decodeCP437(value);
3518
+ } else {
3519
+ return new TextDecoder(encoding, { ignoreBOM }).decode(value);
3520
+ }
3521
+ }
3522
+
3286
3523
  /*
3287
3524
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
3288
3525
 
@@ -3355,6 +3592,7 @@
3355
3592
  createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
3356
3593
  const reader = this;
3357
3594
  let chunkOffset = 0;
3595
+ chunkSize = normalizeChunkSize(chunkSize);
3358
3596
  return new ReadableStream({
3359
3597
  async pull(controller) {
3360
3598
  const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
@@ -3362,7 +3600,7 @@
3362
3600
  if (data.length) {
3363
3601
  controller.enqueue(data);
3364
3602
  }
3365
- if ((chunkOffset + chunkSize >= size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
3603
+ if ((chunkOffset + chunkSize >= size) || (!data.length && dataSize)) {
3366
3604
  controller.close();
3367
3605
  } else {
3368
3606
  chunkOffset += chunkSize;
@@ -3442,31 +3680,31 @@
3442
3680
  Object.assign(this, {
3443
3681
  contentType,
3444
3682
  data: "data:" + (contentType || "") + ";base64,",
3445
- pending: []
3683
+ pendingCharacters: ""
3446
3684
  });
3447
3685
  }
3448
3686
 
3449
3687
  writeUint8Array(array) {
3450
3688
  const writer = this;
3451
3689
  let indexArray;
3452
- let dataString = writer.pending;
3453
- const delta = writer.pending.length;
3454
- writer.pending = "";
3690
+ let dataString = writer.pendingCharacters;
3691
+ const delta = writer.pendingCharacters.length;
3692
+ writer.pendingCharacters = "";
3455
3693
  for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
3456
3694
  dataString += String.fromCharCode(array[indexArray]);
3457
3695
  }
3458
3696
  for (; indexArray < array.length; indexArray++) {
3459
- writer.pending += String.fromCharCode(array[indexArray]);
3697
+ writer.pendingCharacters += String.fromCharCode(array[indexArray]);
3460
3698
  }
3461
3699
  if (dataString.length > 2) {
3462
3700
  writer.data += btoa(dataString);
3463
3701
  } else {
3464
- writer.pending = dataString + writer.pending;
3702
+ writer.pendingCharacters = dataString + writer.pendingCharacters;
3465
3703
  }
3466
3704
  }
3467
3705
 
3468
3706
  getData() {
3469
- return this.data + btoa(this.pending);
3707
+ return this.data + btoa(this.pendingCharacters);
3470
3708
  }
3471
3709
  }
3472
3710
 
@@ -3496,7 +3734,7 @@
3496
3734
  constructor(blob) {
3497
3735
  super();
3498
3736
  Object.assign(this, {
3499
- blob,
3737
+ sourceBlob: blob,
3500
3738
  size: blob.size
3501
3739
  });
3502
3740
  if (!blobSliceProbe) {
@@ -3506,13 +3744,13 @@
3506
3744
 
3507
3745
  createReadable(options) {
3508
3746
  const reader = this;
3509
- const { blob, size } = reader;
3747
+ const { sourceBlob, size } = reader;
3510
3748
  const { offset = 0, size: readSize = size - offset } = options || {};
3511
3749
  if (!offset && readSize >= size) {
3512
- return toCompatibleReadable(blob.stream());
3750
+ return toCompatibleReadable(sourceBlob.stream());
3513
3751
  }
3514
3752
  if (blobSliceReliable) {
3515
- return toCompatibleReadable(blob.slice(offset, offset + readSize).stream());
3753
+ return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
3516
3754
  }
3517
3755
  return super.createReadable(options);
3518
3756
  }
@@ -3521,7 +3759,7 @@
3521
3759
  const reader = this;
3522
3760
  const offsetEnd = offset + length;
3523
3761
  const readsWholeBlob = !offset && offsetEnd >= reader.size;
3524
- const blob = readsWholeBlob ? reader.blob : reader.blob.slice(offset, offsetEnd);
3762
+ const blob = readsWholeBlob ? reader.sourceBlob : reader.sourceBlob.slice(offset, offsetEnd);
3525
3763
  let arrayBuffer = await blob.arrayBuffer();
3526
3764
  const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
3527
3765
  if (sliceIgnoredByBuggyImplementation) {
@@ -3543,12 +3781,12 @@
3543
3781
  }
3544
3782
  });
3545
3783
  writer.contentType = contentType;
3546
- writer.blob = streamToBlob(transformStream.readable, contentType);
3547
- writer.blob.catch(() => { });
3784
+ writer.blobPromise = streamToBlob(transformStream.readable, contentType);
3785
+ writer.blobPromise.catch(() => { });
3548
3786
  }
3549
3787
 
3550
3788
  getData() {
3551
- return this.blob;
3789
+ return this.blobPromise;
3552
3790
  }
3553
3791
  }
3554
3792
 
@@ -3582,7 +3820,7 @@
3582
3820
  class TextWriter extends BlobWriter {
3583
3821
 
3584
3822
  constructor(encoding) {
3585
- super(encoding);
3823
+ super();
3586
3824
  Object.assign(this, {
3587
3825
  encoding,
3588
3826
  utf8: !encoding || encoding.toLowerCase() == "utf-8"
@@ -3598,14 +3836,7 @@
3598
3836
  if (blob.text && utf8) {
3599
3837
  return blob.text();
3600
3838
  } else {
3601
- const reader = new FileReader();
3602
- return new Promise((resolve, reject) => {
3603
- Object.assign(reader, {
3604
- onload: ({ target }) => resolve(target.result),
3605
- onerror: () => reject(reader.error)
3606
- });
3607
- reader.readAsText(blob, encoding);
3608
- });
3839
+ return decodeTextRemovingBOM(new Uint8Array(await blob.arrayBuffer()), encoding);
3609
3840
  }
3610
3841
  }
3611
3842
  }
@@ -4273,85 +4504,13 @@
4273
4504
  return reader.readUint8Array(offset, size);
4274
4505
  }
4275
4506
 
4276
- /*
4277
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
4278
-
4279
- Redistribution and use in source and binary forms, with or without
4280
- modification, are permitted provided that the following conditions are met:
4281
-
4282
- 1. Redistributions of source code must retain the above copyright notice,
4283
- this list of conditions and the following disclaimer.
4284
-
4285
- 2. Redistributions in binary form must reproduce the above copyright
4286
- notice, this list of conditions and the following disclaimer in
4287
- the documentation and/or other materials provided with the distribution.
4288
-
4289
- 3. The names of the authors may not be used to endorse or promote products
4290
- derived from this software without specific prior written permission.
4291
-
4292
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4293
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4294
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4295
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4296
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4297
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4298
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4299
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4300
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4301
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4302
- */
4303
-
4304
- /* global TextDecoder */
4305
-
4306
- const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
4307
- const VALID_CP437 = CP437.length == 256;
4308
-
4309
- function decodeCP437(stringValue) {
4310
- if (VALID_CP437) {
4311
- let result = "";
4312
- for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
4313
- result += CP437[stringValue[indexCharacter]];
4314
- }
4315
- return result;
4316
- } else {
4317
- return new TextDecoder().decode(stringValue);
4318
- }
4319
- }
4320
-
4321
- /*
4322
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
4323
-
4324
- Redistribution and use in source and binary forms, with or without
4325
- modification, are permitted provided that the following conditions are met:
4326
-
4327
- 1. Redistributions of source code must retain the above copyright notice,
4328
- this list of conditions and the following disclaimer.
4329
-
4330
- 2. Redistributions in binary form must reproduce the above copyright
4331
- notice, this list of conditions and the following disclaimer in
4332
- the documentation and/or other materials provided with the distribution.
4333
-
4334
- 3. The names of the authors may not be used to endorse or promote products
4335
- derived from this software without specific prior written permission.
4336
-
4337
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4338
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4339
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4340
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4341
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4342
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4343
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4344
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4345
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4346
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4347
- */
4348
-
4349
-
4350
- function decodeText(value, encoding) {
4351
- if (encoding && encoding.trim().toLowerCase() == "cp437") {
4352
- return decodeCP437(value);
4507
+ function createReadable(reader, options) {
4508
+ if (reader.createReadable) {
4509
+ return reader.createReadable(options);
4510
+ } else if (reader.readUint8Array) {
4511
+ return Reader.prototype.createReadable.call(reader, options);
4353
4512
  } else {
4354
- return new TextDecoder(encoding, { ignoreBOM: true }).decode(value);
4513
+ return reader.readable;
4355
4514
  }
4356
4515
  }
4357
4516
 
@@ -4511,83 +4670,6 @@
4511
4670
 
4512
4671
  }
4513
4672
 
4514
- /*
4515
- Copyright (c) 2022 Gildas Lormeau. All rights reserved.
4516
-
4517
- Redistribution and use in source and binary forms, with or without
4518
- modification, are permitted provided that the following conditions are met:
4519
-
4520
- 1. Redistributions of source code must retain the above copyright notice,
4521
- this list of conditions and the following disclaimer.
4522
-
4523
- 2. Redistributions in binary form must reproduce the above copyright
4524
- notice, this list of conditions and the following disclaimer in
4525
- the documentation and/or other materials provided with the distribution.
4526
-
4527
- 3. The names of the authors may not be used to endorse or promote products
4528
- derived from this software without specific prior written permission.
4529
-
4530
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
4531
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
4532
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
4533
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
4534
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4535
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
4536
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
4537
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4538
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
4539
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4540
- */
4541
-
4542
- const OPTION_FILENAME_ENCODING = "filenameEncoding";
4543
- const OPTION_COMMENT_ENCODING = "commentEncoding";
4544
- const OPTION_DECODE_TEXT = "decodeText";
4545
- const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
4546
- const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
4547
- const OPTION_PASSWORD = "password";
4548
- const OPTION_RAW_PASSWORD = "rawPassword";
4549
- const OPTION_PASS_THROUGH = "passThrough";
4550
- const OPTION_SIGNAL = "signal";
4551
- const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
4552
- const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
4553
- const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
4554
- const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
4555
- const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
4556
- const OPTION_CHECK_SIGNATURE = "checkSignature";
4557
- const OPTION_CHECK_CRC32 = "checkCrc32";
4558
- const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
4559
- const OPTION_USE_WEB_WORKERS = "useWebWorkers";
4560
- const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
4561
- const OPTION_TRANSFER_STREAMS = "transferStreams";
4562
- const OPTION_PREVENT_CLOSE = "preventClose";
4563
- const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
4564
- const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
4565
- const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
4566
- const OPTION_KEEP_ORDER = "keepOrder";
4567
- const OPTION_LEVEL = "level";
4568
- const OPTION_BUFFERED_WRITE = "bufferedWrite";
4569
- const OPTION_CREATE_TEMP_STREAM = "createTempStream";
4570
- const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
4571
- const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
4572
- const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
4573
- const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
4574
- const OPTION_ENCODE_TEXT = "encodeText";
4575
- const OPTION_OFFSET = "offset";
4576
- const OPTION_USDZ = "usdz";
4577
- const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
4578
- const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
4579
- const OPTION_STRICTNESS = "strictness";
4580
- const OPTION_FILENAME_VALIDATION = "filenameValidation";
4581
- const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
4582
- const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
4583
- const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
4584
- const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
4585
- const TEXT_TYPE_FILENAME = "filename";
4586
- const TEXT_TYPE_COMMENT = "comment";
4587
- const STRICTNESS_STRICT = "strict";
4588
- const STRICTNESS_BALANCED = "balanced";
4589
- const STRICTNESS_TOLERANT = "tolerant";
4590
-
4591
4673
  /*
4592
4674
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
4593
4675
 
@@ -4628,6 +4710,7 @@
4628
4710
  const ERR_UNSUPPORTED_COMPRESSION$1 = "Compression method not supported";
4629
4711
  const ERR_SPLIT_ZIP_FILE = "Split zip file";
4630
4712
  const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
4713
+ const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
4631
4714
  const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
4632
4715
  const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
4633
4716
  const ERR_UNSAFE_FILENAME = "Unsafe filename";
@@ -4648,7 +4731,7 @@
4648
4731
  ];
4649
4732
  const ZIP64_EXTRACTION = {
4650
4733
  [MAX_16_BITS]: {
4651
- getValue: getUint32,
4734
+ getValue: getUint32$1,
4652
4735
  bytes: 4
4653
4736
  },
4654
4737
  [MAX_32_BITS]: {
@@ -4657,6 +4740,7 @@
4657
4740
  }
4658
4741
  };
4659
4742
  const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
4743
+ const MAX_DEFLATE_EXPANSION_RATIO = 1032;
4660
4744
  const CENTRAL_DIRECTORY_UNREACHABLE = 0;
4661
4745
  const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
4662
4746
  const CENTRAL_DIRECTORY_REACHABLE = 2;
@@ -4667,7 +4751,6 @@
4667
4751
  Object.assign(this, {
4668
4752
  reader: new GenericReader(reader),
4669
4753
  options,
4670
- config: getConfiguration(),
4671
4754
  readRanges: new Map()
4672
4755
  });
4673
4756
  }
@@ -4675,7 +4758,6 @@
4675
4758
  async* getEntriesGenerator(options = {}) {
4676
4759
  const zipReader = this;
4677
4760
  let { reader } = zipReader;
4678
- const { config } = zipReader;
4679
4761
  await initStream(reader);
4680
4762
  if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
4681
4763
  reader = new BlobReader(await streamToBlob(reader.readable));
@@ -4692,9 +4774,7 @@
4692
4774
  const normalizeFilename = getOptionValue$1(zipReader, options, OPTION_NORMALIZE_FILENAME);
4693
4775
  const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
4694
4776
  if (!endOfDirectoryInfo) {
4695
- const signatureArray = await readUint8Array(reader, 0, 4);
4696
- const signatureView = getDataView(signatureArray);
4697
- if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
4777
+ if (await startsWithSplitZipSignature$1(reader)) {
4698
4778
  throw new Error(ERR_SPLIT_ZIP_FILE);
4699
4779
  } else {
4700
4780
  throw new Error(ERR_EOCDR_NOT_FOUND);
@@ -4704,22 +4784,23 @@
4704
4784
  throwAmbiguousArchive("multiple end of central directory records");
4705
4785
  }
4706
4786
  const endOfDirectoryView = getDataView(endOfDirectoryInfo);
4707
- let directoryDataLength = getUint32(endOfDirectoryView, 12);
4708
- let directoryDataOffset = getUint32(endOfDirectoryView, 16);
4787
+ let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
4788
+ let directoryDataOffset = getUint32$1(endOfDirectoryView, 16);
4709
4789
  const commentOffset = endOfDirectoryInfo.offset;
4710
- const commentLength = getUint16(endOfDirectoryView, 20);
4790
+ const commentLength = getUint16$1(endOfDirectoryView, 20);
4711
4791
  const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
4712
4792
  if (reader.size - appendedDataOffset > maxAppendedDataSize) {
4713
4793
  throwAmbiguousArchive("appended data");
4714
4794
  }
4715
- let lastDiskNumber = getUint16(endOfDirectoryView, 4);
4795
+ let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
4716
4796
  const expectedLastDiskNumber = reader.lastDiskNumber || 0;
4717
- let diskNumber = getUint16(endOfDirectoryView, 6);
4718
- let filesLength = getUint16(endOfDirectoryView, 10);
4797
+ let diskNumber = getUint16$1(endOfDirectoryView, 6);
4798
+ let filesLength = getUint16$1(endOfDirectoryView, 10);
4719
4799
  let prependedDataLength = 0;
4720
4800
  let startOffset;
4721
4801
  let zip64EndOfDirectory;
4722
4802
  let zip64EndOfDirectoryVersion2;
4803
+ let zip64EndOfDirectoryLength = ZIP64_END_OF_CENTRAL_DIR_LENGTH;
4723
4804
  let directoryEncryptionInfo;
4724
4805
  const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
4725
4806
  if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
@@ -4731,12 +4812,12 @@
4731
4812
  EMPTY_UINT8_ARRAY;
4732
4813
  const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
4733
4814
  if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
4734
- getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
4735
- directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
4815
+ getUint32$1(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
4816
+ directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
4736
4817
  let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4737
4818
  let endOfDirectoryView = getDataView(endOfDirectoryArray);
4738
4819
  const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
4739
- if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
4820
+ if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
4740
4821
  directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
4741
4822
  const originalDirectoryDataOffset = directoryDataOffset;
4742
4823
  directoryDataOffset = expectedDirectoryDataOffset;
@@ -4746,7 +4827,7 @@
4746
4827
  endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4747
4828
  endOfDirectoryView = getDataView(endOfDirectoryArray);
4748
4829
  }
4749
- if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
4830
+ if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
4750
4831
  throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
4751
4832
  }
4752
4833
  zip64EndOfDirectory = true;
@@ -4756,18 +4837,19 @@
4756
4837
  Number(getBigUint64(endOfDirectoryView, 4)) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
4757
4838
  reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4758
4839
  if (extensibleDataLength > 0) {
4840
+ zip64EndOfDirectoryLength += extensibleDataLength;
4759
4841
  const rawExtensibleData = await readUint8Array(reader, directoryDataOffset + ZIP64_END_OF_CENTRAL_DIR_LENGTH, extensibleDataLength);
4760
4842
  directoryEncryptionInfo = getDirectoryEncryptionInfo(rawExtensibleData);
4761
4843
  }
4762
4844
  }
4763
4845
  if (lastDiskNumber == MAX_16_BITS) {
4764
- lastDiskNumber = getUint32(endOfDirectoryView, 16);
4765
- } else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
4846
+ lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
4847
+ } else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
4766
4848
  throwAmbiguousArchive("mismatched zip64 end of central directory record");
4767
4849
  }
4768
4850
  if (diskNumber == MAX_16_BITS) {
4769
- diskNumber = getUint32(endOfDirectoryView, 20);
4770
- } else if (checkAmbiguity && diskNumber != getUint32(endOfDirectoryView, 20)) {
4851
+ diskNumber = getUint32$1(endOfDirectoryView, 20);
4852
+ } else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
4771
4853
  throwAmbiguousArchive("mismatched zip64 end of central directory record");
4772
4854
  }
4773
4855
  if (filesLength == MAX_16_BITS) {
@@ -4785,7 +4867,7 @@
4785
4867
  }
4786
4868
  let declaredDirectoryDataLength = directoryDataLength;
4787
4869
  const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
4788
- (zip64EndOfDirectory ? ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
4870
+ (zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
4789
4871
  if (directoryDataOffset >= reader.size) {
4790
4872
  prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
4791
4873
  directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
@@ -4805,11 +4887,13 @@
4805
4887
  }
4806
4888
  const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
4807
4889
  if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
4808
- const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
4890
+ const storedPointsAtDirectory = getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
4891
+ Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
4892
+ detectEncryptedCentralDirectory(directoryView);
4809
4893
  let reconcile = !storedPointsAtDirectory;
4810
4894
  if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
4811
4895
  const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
4812
- reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
4896
+ reconcile = getUint32$1(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
4813
4897
  }
4814
4898
  if (reconcile) {
4815
4899
  const originalDirectoryDataOffset = directoryDataOffset;
@@ -4833,12 +4917,14 @@
4833
4917
  }
4834
4918
  zipReader.directoryOffset = directoryDataOffset;
4835
4919
  zipReader.directoryLength = declaredDirectoryDataLength;
4836
- const decryptCentralDirectory = getOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4837
- let decryptedDirectory;
4920
+ const decryptCentralDirectory = getFunctionOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4921
+ let decryptedDirectory, dataAfterEncryptedDirectory;
4838
4922
  if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
4839
- getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4923
+ getUint32$1(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4840
4924
  (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4841
- directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
4925
+ const encryptedDirectoryDataLength = getEncryptedDirectoryDataLength(directoryEncryptionInfo, declaredDirectoryDataLength, directoryArray.length);
4926
+ dataAfterEncryptedDirectory = directoryArray.subarray(encryptedDirectoryDataLength);
4927
+ directoryArray = await decryptCentralDirectory(directoryArray.subarray(0, encryptedDirectoryDataLength), directoryEncryptionInfo);
4842
4928
  directoryView = getDataView(directoryArray);
4843
4929
  declaredDirectoryDataLength = directoryArray.length;
4844
4930
  decryptedDirectory = true;
@@ -4849,8 +4935,8 @@
4849
4935
  const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
4850
4936
  let duplicateFilename;
4851
4937
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4852
- const fileEntry = new ZipEntry$1(reader, config, zipReader.options);
4853
- if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4938
+ const fileEntry = new ZipEntry$1(reader, zipReader.options);
4939
+ if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4854
4940
  if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4855
4941
  throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
4856
4942
  }
@@ -4861,16 +4947,16 @@
4861
4947
  const filenameOffset = offset + CENTRAL_FILE_HEADER_LENGTH;
4862
4948
  const extraFieldOffset = filenameOffset + fileEntry.filenameLength;
4863
4949
  const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
4864
- const versionMadeBy = getUint16(directoryView, offset + 4);
4950
+ const versionMadeBy = getUint16$1(directoryView, offset + 4);
4865
4951
  const msDosCompatible = versionMadeBy >> 8 == 0;
4866
4952
  const unixCompatible = versionMadeBy >> 8 == 3;
4867
4953
  const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
4868
- const commentLength = getUint16(directoryView, offset + 32);
4954
+ const commentLength = getUint16$1(directoryView, offset + 32);
4869
4955
  const endOffset = commentOffset + commentLength;
4870
4956
  const rawComment = directoryArray.subarray(commentOffset, endOffset);
4871
4957
  const filenameUTF8 = languageEncodingFlag;
4872
4958
  const commentUTF8 = languageEncodingFlag;
4873
- const externalFileAttributes = getUint32(directoryView, offset + 38);
4959
+ const externalFileAttributes = getUint32$1(directoryView, offset + 38);
4874
4960
  const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
4875
4961
  const msdosAttributes = {
4876
4962
  readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
@@ -4879,8 +4965,8 @@
4879
4965
  directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
4880
4966
  archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
4881
4967
  };
4882
- const offsetFileEntry = getUint32(directoryView, offset + 42);
4883
- const decode = getOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
4968
+ const offsetFileEntry = getUint32$1(directoryView, offset + 42);
4969
+ const decode = getFunctionOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
4884
4970
  const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
4885
4971
  const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
4886
4972
  let filename = decode(rawFilename, rawFilenameEncoding, TEXT_TYPE_FILENAME);
@@ -4904,6 +4990,7 @@
4904
4990
  }
4905
4991
  Object.assign(fileEntry, {
4906
4992
  index: indexFile,
4993
+ decryptedDirectory,
4907
4994
  versionMadeBy,
4908
4995
  msDosCompatible,
4909
4996
  zip64: false,
@@ -4911,8 +4998,8 @@
4911
4998
  uncompressedSize: 0,
4912
4999
  commentLength,
4913
5000
  offset: offsetFileEntry,
4914
- diskNumberStart: getUint16(directoryView, offset + 34),
4915
- internalFileAttributes: getUint16(directoryView, offset + 36),
5001
+ diskNumberStart: getUint16$1(directoryView, offset + 34),
5002
+ internalFileAttributes: getUint16$1(directoryView, offset + 36),
4916
5003
  externalFileAttributes,
4917
5004
  msdosAttributesRaw,
4918
5005
  msdosAttributes,
@@ -4980,12 +5067,11 @@
4980
5067
  yield entry;
4981
5068
  }
4982
5069
  let offsetAfterSignature = offset;
4983
- if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
4984
- const signatureDataLength = getUint16(directoryView, offset + 4);
4985
- if (offset + 6 + signatureDataLength <= directoryArray.length) {
4986
- zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
4987
- offsetAfterSignature = offset + 6 + signatureDataLength;
4988
- }
5070
+ const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5071
+ (decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
5072
+ if (digitalSignature) {
5073
+ zipReader.digitalSignature = digitalSignature;
5074
+ offsetAfterSignature = offset + 6 + digitalSignature.length;
4989
5075
  }
4990
5076
  if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
4991
5077
  throwAmbiguousArchive("trailing central directory data");
@@ -4993,13 +5079,17 @@
4993
5079
  if (duplicateFilename) {
4994
5080
  throwAmbiguousArchive("duplicate filename");
4995
5081
  }
4996
- if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > 0))) {
4997
- throwAmbiguousArchive("prepended data");
4998
- }
4999
5082
  const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
5000
5083
  const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
5084
+ const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
5085
+ startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
5086
+ if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
5087
+ throwAmbiguousArchive("prepended data");
5088
+ }
5001
5089
  if (extractPrependedData) {
5002
- zipReader.prependedData = startOffset > 0 ? await readUint8Array(reader, 0, startOffset) : EMPTY_UINT8_ARRAY;
5090
+ zipReader.prependedData = startOffset > splitZipSignatureLength ?
5091
+ await readUint8Array(reader, splitZipSignatureLength, startOffset - splitZipSignatureLength) :
5092
+ EMPTY_UINT8_ARRAY;
5003
5093
  }
5004
5094
  zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : EMPTY_UINT8_ARRAY;
5005
5095
  if (extractAppendedData) {
@@ -5066,16 +5156,16 @@
5066
5156
 
5067
5157
  let ZipEntry$1 = class ZipEntry {
5068
5158
 
5069
- constructor(reader, config, options) {
5159
+ constructor(reader, options) {
5070
5160
  Object.assign(this, {
5071
5161
  reader,
5072
- config,
5073
5162
  options
5074
5163
  });
5075
5164
  }
5076
5165
 
5077
5166
  async getData(writer, fileEntry, readRanges, options = {}) {
5078
5167
  const zipEntry = this;
5168
+ const config = getConfiguration();
5079
5169
  const {
5080
5170
  reader,
5081
5171
  index,
@@ -5084,7 +5174,6 @@
5084
5174
  extraFieldAES,
5085
5175
  extraFieldZip64,
5086
5176
  compressionMethod,
5087
- config,
5088
5177
  bitFlag,
5089
5178
  rawBitFlag,
5090
5179
  crc32,
@@ -5102,6 +5191,7 @@
5102
5191
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
5103
5192
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
5104
5193
  const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
5194
+ checkPasswordOption(password, rawPassword);
5105
5195
  password = password && password.length && password;
5106
5196
  rawPassword = rawPassword && rawPassword.length && rawPassword;
5107
5197
  if (extraFieldAES) {
@@ -5109,7 +5199,7 @@
5109
5199
  throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
5110
5200
  }
5111
5201
  }
5112
- if (dataArray.length < HEADER_SIZE || getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
5202
+ if (dataArray.length < HEADER_SIZE || getUint32$1(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
5113
5203
  throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
5114
5204
  }
5115
5205
  readCommonHeader(localDirectory, dataView, 4);
@@ -5171,9 +5261,12 @@
5171
5261
  }
5172
5262
  }
5173
5263
  const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
5264
+ if (dataOffset + compressedSize > reader.size) {
5265
+ throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
5266
+ }
5174
5267
  const size = compressedSize;
5175
5268
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5176
- const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
5269
+ const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5177
5270
  const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5178
5271
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
5179
5272
  const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
@@ -5181,6 +5274,8 @@
5181
5274
  checkOverlappingEntry = true;
5182
5275
  }
5183
5276
  const { onstart, onprogress, onend } = options;
5277
+ const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
5278
+ const outputSize = passThrough ? compressedSize : uncompressedSize;
5184
5279
  const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
5185
5280
  let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
5186
5281
  if (deflate64) {
@@ -5201,9 +5296,9 @@
5201
5296
  checkCrc32,
5202
5297
  checkAuthenticationCode: getOptionValue$1(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
5203
5298
  passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((crc32 >>> 24) & MAX_8_BITS)),
5204
- outputSize: passThrough ? compressedSize : uncompressedSize,
5299
+ outputSize,
5205
5300
  crc32,
5206
- compressed: compressionMethod != 0 && !passThrough,
5301
+ compressed,
5207
5302
  encrypted,
5208
5303
  useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
5209
5304
  useCompressionStream,
@@ -5240,11 +5335,11 @@
5240
5335
  writer = new WritableStream();
5241
5336
  }
5242
5337
  writer = new GenericWriter(writer);
5243
- await initStream(writer, passThrough ? compressedSize : uncompressedSize);
5338
+ await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5244
5339
  ({ writable } = writer);
5245
- const { outputSize } = await runWorker({ readable, writable }, workerOptions);
5246
- writer.size += outputSize;
5247
- if (outputSize != (passThrough ? compressedSize : uncompressedSize)) {
5340
+ const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5341
+ writer.size += writtenSize;
5342
+ if (writtenSize != outputSize) {
5248
5343
  throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
5249
5344
  }
5250
5345
  }
@@ -5278,26 +5373,47 @@
5278
5373
  function detectEncryptedCentralDirectory(directoryView) {
5279
5374
  const maxOffset = Math.min(directoryView.byteLength, 1024) - 3;
5280
5375
  for (let offset = 0; offset < maxOffset; offset++) {
5281
- if (getUint32(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
5376
+ if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
5282
5377
  return true;
5283
5378
  }
5284
5379
  }
5285
5380
  return false;
5286
5381
  }
5287
5382
 
5383
+ function readDigitalSignature(signatureRecordArray) {
5384
+ if (signatureRecordArray.length >= 6) {
5385
+ const signatureRecordView = getDataView(signatureRecordArray);
5386
+ if (getUint32$1(signatureRecordView, 0) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
5387
+ const signatureDataLength = getUint16$1(signatureRecordView, 4);
5388
+ if (6 + signatureDataLength <= signatureRecordArray.length) {
5389
+ return signatureRecordArray.subarray(6, 6 + signatureDataLength);
5390
+ }
5391
+ }
5392
+ }
5393
+ }
5394
+
5395
+ function getEncryptedDirectoryDataLength(directoryEncryptionInfo, declaredDirectoryDataLength, directoryDataLength) {
5396
+ const encryptedDirectoryDataLength = directoryEncryptionInfo && directoryEncryptionInfo.compressedSize ?
5397
+ directoryEncryptionInfo.compressedSize :
5398
+ declaredDirectoryDataLength;
5399
+ return encryptedDirectoryDataLength > 0 && encryptedDirectoryDataLength <= directoryDataLength ?
5400
+ encryptedDirectoryDataLength :
5401
+ directoryDataLength;
5402
+ }
5403
+
5288
5404
  function getDirectoryEncryptionInfo(rawExtensibleData) {
5289
5405
  const directoryEncryptionInfo = { rawExtensibleData };
5290
5406
  if (rawExtensibleData.length >= 28) {
5291
5407
  const extensibleDataView = getDataView(rawExtensibleData);
5292
- const hashDataLength = getUint16(extensibleDataView, 26);
5408
+ const hashDataLength = getUint16$1(extensibleDataView, 26);
5293
5409
  Object.assign(directoryEncryptionInfo, {
5294
- compressionMethod: getUint16(extensibleDataView, 0),
5410
+ compressionMethod: getUint16$1(extensibleDataView, 0),
5295
5411
  compressedSize: Number(getBigUint64(extensibleDataView, 2)),
5296
5412
  uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
5297
- encryptionAlgorithm: getUint16(extensibleDataView, 18),
5298
- bitLength: getUint16(extensibleDataView, 20),
5299
- flags: getUint16(extensibleDataView, 22),
5300
- hashAlgorithm: getUint16(extensibleDataView, 24),
5413
+ encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
5414
+ bitLength: getUint16$1(extensibleDataView, 20),
5415
+ flags: getUint16$1(extensibleDataView, 22),
5416
+ hashAlgorithm: getUint16$1(extensibleDataView, 24),
5301
5417
  hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
5302
5418
  });
5303
5419
  }
@@ -5305,12 +5421,12 @@
5305
5421
  }
5306
5422
 
5307
5423
  function readCommonHeader(directory, dataView, offset) {
5308
- const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
5424
+ const rawBitFlag = directory.rawBitFlag = getUint16$1(dataView, offset + 2);
5309
5425
  const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
5310
- const rawLastModDate = getUint32(dataView, offset + 6);
5426
+ const rawLastModDate = getUint32$1(dataView, offset + 6);
5311
5427
  Object.assign(directory, {
5312
5428
  encrypted,
5313
- version: getUint16(dataView, offset),
5429
+ version: getUint16$1(dataView, offset),
5314
5430
  bitFlag: {
5315
5431
  level: (rawBitFlag & BITFLAG_LEVEL) >> 1,
5316
5432
  dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR,
@@ -5318,8 +5434,8 @@
5318
5434
  },
5319
5435
  rawLastModDate,
5320
5436
  lastModDate: getDate(rawLastModDate),
5321
- filenameLength: getUint16(dataView, offset + 22),
5322
- extraFieldLength: getUint16(dataView, offset + 24)
5437
+ filenameLength: getUint16$1(dataView, offset + 22),
5438
+ extraFieldLength: getUint16$1(dataView, offset + 24)
5323
5439
  });
5324
5440
  }
5325
5441
 
@@ -5330,8 +5446,8 @@
5330
5446
  let offsetExtraField = 0;
5331
5447
  try {
5332
5448
  while (offsetExtraField < rawExtraField.length) {
5333
- const type = getUint16(rawExtraFieldView, offsetExtraField);
5334
- const size = getUint16(rawExtraFieldView, offsetExtraField + 2);
5449
+ const type = getUint16$1(rawExtraFieldView, offsetExtraField);
5450
+ const size = getUint16$1(rawExtraFieldView, offsetExtraField + 2);
5335
5451
  extraField.set(type, {
5336
5452
  type,
5337
5453
  data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size)
@@ -5341,12 +5457,12 @@
5341
5457
  } catch {
5342
5458
  // ignored
5343
5459
  }
5344
- const compressionMethod = getUint16(dataView, offset + 4);
5460
+ const compressionMethod = getUint16$1(dataView, offset + 4);
5345
5461
  Object.assign(directory, {
5346
- signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
5347
- crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
5348
- compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
5349
- uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
5462
+ signature: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
5463
+ crc32: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
5464
+ compressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
5465
+ uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
5350
5466
  });
5351
5467
  const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
5352
5468
  if (extraFieldZip64) {
@@ -5435,11 +5551,11 @@
5435
5551
  computedCrc32.append(fileEntry[rawPropertyName]);
5436
5552
  const computedCrc32View = getDataView(new Uint8Array(4));
5437
5553
  computedCrc32View.setUint32(0, computedCrc32.get(), true);
5438
- const nameCrc32 = getUint32(extraFieldView, 1);
5554
+ const nameCrc32 = getUint32$1(extraFieldView, 1);
5439
5555
  Object.assign(extraFieldUnicode, {
5440
5556
  version: getUint8(extraFieldView, 0),
5441
5557
  [propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
5442
- valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32(computedCrc32View, 0)
5558
+ valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
5443
5559
  });
5444
5560
  if (extraFieldUnicode.valid) {
5445
5561
  directory[propertyName] = extraFieldUnicode[propertyName];
@@ -5455,7 +5571,7 @@
5455
5571
  vendorId: getUint8(extraFieldView, 2),
5456
5572
  strength,
5457
5573
  originalCompressionMethod: compressionMethod,
5458
- compressionMethod: getUint16(extraFieldView, 5)
5574
+ compressionMethod: getUint16$1(extraFieldView, 5)
5459
5575
  });
5460
5576
  directory.compressionMethod = extraFieldAES.compressionMethod;
5461
5577
  if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1$1) {
@@ -5469,8 +5585,8 @@
5469
5585
  let tag1Data;
5470
5586
  try {
5471
5587
  while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) {
5472
- const tagValue = getUint16(extraFieldView, offsetExtraField);
5473
- const attributeSize = getUint16(extraFieldView, offsetExtraField + 2);
5588
+ const tagValue = getUint16$1(extraFieldView, offsetExtraField);
5589
+ const attributeSize = getUint16$1(extraFieldView, offsetExtraField + 2);
5474
5590
  if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) {
5475
5591
  tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize);
5476
5592
  }
@@ -5503,12 +5619,12 @@
5503
5619
  return;
5504
5620
  }
5505
5621
  const extraFieldView = getDataView(extraField.data);
5506
- const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
5507
- const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
5622
+ const lastAccessDate = new Date((getUint32$1(extraFieldView, 0) | 0) * 1000);
5623
+ const lastModDate = new Date((getUint32$1(extraFieldView, 4) | 0) * 1000);
5508
5624
  const extraFieldData = { lastAccessDate, lastModDate };
5509
5625
  if (extraField.data.length >= 12) {
5510
- extraFieldData.uid = getUint16(extraFieldView, 8);
5511
- extraFieldData.gid = getUint16(extraFieldView, 10);
5626
+ extraFieldData.uid = getUint16$1(extraFieldView, 8);
5627
+ extraFieldData.gid = getUint16$1(extraFieldView, 10);
5512
5628
  }
5513
5629
  Object.assign(extraField, extraFieldData);
5514
5630
  Object.assign(directory, extraFieldData);
@@ -5528,8 +5644,8 @@
5528
5644
  gid = unpackUnixId(extraField.data.subarray(offset, offset + gidSize));
5529
5645
  Object.assign(extraField, { version, uid, gid });
5530
5646
  } else if (extraField.data.length >= 4) {
5531
- uid = getUint16(view, 0);
5532
- gid = getUint16(view, 2);
5647
+ uid = getUint16$1(view, 0);
5648
+ gid = getUint16$1(view, 2);
5533
5649
  Object.assign(extraField, { uid, gid });
5534
5650
  }
5535
5651
  if (uid !== UNDEFINED_VALUE) {
@@ -5579,7 +5695,7 @@
5579
5695
  let offset = 1;
5580
5696
  timeProperties.forEach((propertyName, indexProperty) => {
5581
5697
  if (extraFieldExtendedTimestamp.data.length >= offset + 4) {
5582
- const time = getUint32(extraFieldView, offset);
5698
+ const time = getUint32$1(extraFieldView, offset);
5583
5699
  directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date((time | 0) * 1000);
5584
5700
  const rawPropertyName = timeRawProperties[indexProperty];
5585
5701
  extraFieldExtendedTimestamp[rawPropertyName] = time;
@@ -5613,7 +5729,7 @@
5613
5729
  const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
5614
5730
  const dataDescriptorView = getDataView(dataDescriptorArray);
5615
5731
  let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
5616
- getUint32(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5732
+ getUint32$1(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5617
5733
  if (signature) {
5618
5734
  const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
5619
5735
  const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
@@ -5647,15 +5763,15 @@
5647
5763
  }
5648
5764
 
5649
5765
  function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
5650
- const crc32 = getUint32(dataDescriptorView, offset);
5766
+ const crc32 = getUint32$1(dataDescriptorView, offset);
5651
5767
  let compressedSize;
5652
5768
  let uncompressedSize;
5653
5769
  if (extraFieldZip64) {
5654
5770
  compressedSize = getBigUint64(dataDescriptorView, offset + 4);
5655
5771
  uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
5656
5772
  } else {
5657
- compressedSize = getUint32(dataDescriptorView, offset + 4);
5658
- uncompressedSize = getUint32(dataDescriptorView, offset + 8);
5773
+ compressedSize = getUint32$1(dataDescriptorView, offset + 4);
5774
+ uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
5659
5775
  }
5660
5776
  return { crc32, compressedSize, uncompressedSize };
5661
5777
  }
@@ -5664,10 +5780,28 @@
5664
5780
  return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
5665
5781
  }
5666
5782
 
5783
+ async function startsWithSplitZipSignature$1(reader) {
5784
+ return await getFirstSignature(reader) == SPLIT_ZIP_FILE_SIGNATURE;
5785
+ }
5786
+
5787
+ async function startsWithSplitZipMarker(reader) {
5788
+ const signature = await getFirstSignature(reader);
5789
+ return signature == SPLIT_ZIP_FILE_SIGNATURE || signature == TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE;
5790
+ }
5791
+
5792
+ async function getFirstSignature(reader) {
5793
+ const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
5794
+ return getUint32$1(getDataView(signatureArray));
5795
+ }
5796
+
5667
5797
  function isStrictnessValue(value) {
5668
5798
  return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
5669
5799
  }
5670
5800
 
5801
+ function getDecodableOutputSize(outputSize, compressedSize, compressed) {
5802
+ return Math.min(outputSize, compressed ? compressedSize * MAX_DEFLATE_EXPANSION_RATIO : compressedSize);
5803
+ }
5804
+
5671
5805
  function getStrictness(options, inheritedOptions) {
5672
5806
  return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
5673
5807
  }
@@ -5730,7 +5864,7 @@
5730
5864
 
5731
5865
  function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
5732
5866
  if (maxAppendedDataSize !== UNDEFINED_VALUE) {
5733
- const size = toNumber$1(maxAppendedDataSize);
5867
+ const size = toNumber(maxAppendedDataSize);
5734
5868
  if (typeof size != NUMBER_TYPE || Number.isNaN(size) || size < 0) {
5735
5869
  throw new Error(ERR_INVALID_MAX_APPENDED_DATA_SIZE);
5736
5870
  }
@@ -5753,7 +5887,7 @@
5753
5887
  let plausibleEndOfDirectoryInfo;
5754
5888
  let endOfDirectoryReachingEndCount = 0;
5755
5889
  for await (const [anchoredView, anchoredOffset, anchoredArray, indexByte, offset] of scanEndOfCentralDirectory(reader, anchoredLength)) {
5756
- const commentLength = getUint16(anchoredView, indexByte + 20);
5890
+ const commentLength = getUint16$1(anchoredView, indexByte + 20);
5757
5891
  if (offset + END_OF_CENTRAL_DIR_LENGTH + commentLength == size) {
5758
5892
  const reachability = await getCentralDirectoryReachability(reader, anchoredView, anchoredOffset, indexByte, offset, size, remoteProbeBudget);
5759
5893
  if (reachability == CENTRAL_DIRECTORY_REACHABLE) {
@@ -5804,7 +5938,7 @@
5804
5938
  const scanArray = await readUint8Array(reader, scanOffset, scanLength);
5805
5939
  const scanView = getDataView(scanArray);
5806
5940
  for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
5807
- if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
5941
+ if (getUint32$1(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
5808
5942
  yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
5809
5943
  }
5810
5944
  }
@@ -5815,9 +5949,9 @@
5815
5949
  }
5816
5950
 
5817
5951
  async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
5818
- const filesLength = getUint16(view, indexByte + 10);
5819
- const directoryDataLength = getUint32(view, indexByte + 12);
5820
- const directoryDataOffset = getUint32(view, indexByte + 16);
5952
+ const filesLength = getUint16$1(view, indexByte + 10);
5953
+ const directoryDataLength = getUint32$1(view, indexByte + 12);
5954
+ const directoryDataOffset = getUint32$1(view, indexByte + 16);
5821
5955
  if (filesLength == MAX_16_BITS || directoryDataLength == MAX_32_BITS || directoryDataOffset == MAX_32_BITS) {
5822
5956
  const locatorSignature = await readSignature(reader, view, anchoredOffset, offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, size, remoteProbeBudget);
5823
5957
  return locatorSignature == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE ? CENTRAL_DIRECTORY_REACHABLE : CENTRAL_DIRECTORY_UNREACHABLE;
@@ -5825,7 +5959,7 @@
5825
5959
  if (!filesLength && !directoryDataLength) {
5826
5960
  return CENTRAL_DIRECTORY_PLAUSIBLE;
5827
5961
  }
5828
- const directoryDiskNumber = getUint16(view, indexByte + 6);
5962
+ const directoryDiskNumber = getUint16$1(view, indexByte + 6);
5829
5963
  for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
5830
5964
  if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
5831
5965
  return CENTRAL_DIRECTORY_REACHABLE;
@@ -5839,19 +5973,21 @@
5839
5973
  return UNDEFINED_VALUE;
5840
5974
  }
5841
5975
  if (signatureOffset >= anchoredOffset) {
5842
- return getUint32(view, signatureOffset - anchoredOffset);
5976
+ return getUint32$1(view, signatureOffset - anchoredOffset);
5843
5977
  }
5844
5978
  if (remoteProbeBudget.count > 0) {
5845
5979
  remoteProbeBudget.count--;
5846
5980
  const signatureArray = await readUint8Array(reader, signatureOffset, 4);
5847
- return getUint32(getDataView(signatureArray), 0);
5981
+ return getUint32$1(getDataView(signatureArray), 0);
5848
5982
  }
5849
5983
  return UNDEFINED_VALUE;
5850
5984
  }
5851
5985
 
5852
5986
  function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
5853
5987
  const { rawFilename } = zipEntry;
5854
- if (checkLocalFilename &&
5988
+ const maskedLocalDirectory = zipEntry.decryptedDirectory &&
5989
+ (localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
5990
+ if (checkLocalFilename && !maskedLocalDirectory &&
5855
5991
  (rawLocalFilename.length != rawFilename.length ||
5856
5992
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
5857
5993
  throwAmbiguousArchive("mismatched local file header (filename)");
@@ -5862,7 +5998,7 @@
5862
5998
  if (localDirectory.compressionMethod != zipEntry.compressionMethod) {
5863
5999
  throwAmbiguousArchive("mismatched local file header (compression method)");
5864
6000
  }
5865
- if (!localDirectory.bitFlag.dataDescriptor &&
6001
+ if (!localDirectory.bitFlag.dataDescriptor && !maskedLocalDirectory &&
5866
6002
  (localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
5867
6003
  (localDirectory.crc32 != zipEntry.crc32 ||
5868
6004
  localDirectory.compressedSize != zipEntry.compressedSize ||
@@ -5881,10 +6017,11 @@
5881
6017
  return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
5882
6018
  }
5883
6019
 
5884
- function toNumber$1(value) {
5885
- return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
6020
+ function getFunctionOptionValue$1(zipReader, options, name) {
6021
+ return checkFunctionOption(getOptionValue$1(zipReader, options, name));
5886
6022
  }
5887
6023
 
6024
+
5888
6025
  function getDate(timeRaw) {
5889
6026
  const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
5890
6027
  return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
@@ -5898,11 +6035,11 @@
5898
6035
  return view.getUint8(offset);
5899
6036
  }
5900
6037
 
5901
- function getUint16(view, offset) {
6038
+ function getUint16$1(view, offset) {
5902
6039
  return view.getUint16(offset, true);
5903
6040
  }
5904
6041
 
5905
- function getUint32(view, offset) {
6042
+ function getUint32$1(view, offset) {
5906
6043
  return view.getUint32(offset, true);
5907
6044
  }
5908
6045
 
@@ -5917,6 +6054,7 @@
5917
6054
  ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
5918
6055
  ERR_ENCRYPTED: ERR_ENCRYPTED,
5919
6056
  ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
6057
+ ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
5920
6058
  ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
5921
6059
  ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
5922
6060
  ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
@@ -5973,12 +6111,16 @@
5973
6111
  const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
5974
6112
  const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
5975
6113
  const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
6114
+ const ERR_INVALID_ENTRY_COMMENT_TYPE = "Invalid file entry comment (must be a string)";
6115
+ const ERR_INVALID_DATE = "Invalid date (must be a valid Date instance)";
5976
6116
  const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
5977
6117
  const ERR_INVALID_VERSION = "Version exceeds 65535";
5978
6118
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
5979
6119
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
5980
6120
  const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
5981
- const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
6121
+ const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
6122
+ const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
6123
+ const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
5982
6124
  const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
5983
6125
  const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
5984
6126
  const MIN_UNIX_TIME = -2147483648;
@@ -5987,6 +6129,7 @@
5987
6129
  const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
5988
6130
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
5989
6131
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
6132
+ const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
5990
6133
  const ERR_UNDETERMINED_SIZE = "Undetermined size";
5991
6134
  const ERR_UNDEFINED_READER = "Undefined reader";
5992
6135
  const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
@@ -5998,7 +6141,6 @@
5998
6141
  const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
5999
6142
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
6000
6143
  const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
6001
- const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
6002
6144
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6003
6145
 
6004
6146
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
@@ -6023,8 +6165,7 @@
6023
6165
  writer,
6024
6166
  addSplitZipSignature,
6025
6167
  options,
6026
- config: getConfiguration(),
6027
- files: new Map(),
6168
+ fileEntries: new Map(),
6028
6169
  filenames: new Set(),
6029
6170
  offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
6030
6171
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
@@ -6045,14 +6186,23 @@
6045
6186
  await initStream(reader);
6046
6187
  }
6047
6188
  const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
6048
- const zipReader$1 = new ZipReader(reader.readable);
6189
+ const zipReader$1 = new ZipReader(reader);
6049
6190
  const entries = await zipReader$1.getEntries();
6050
6191
  await zipReader$1.close();
6051
6192
  await initStream(this.writer);
6052
- await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
6053
- this.writer.size = this.offset = reader.size;
6193
+ const { directoryOffset } = zipReader$1;
6194
+ let splitZipSignatureLength = 0;
6195
+ if (this.addSplitZipSignature) {
6196
+ delete this.addSplitZipSignature;
6197
+ if (!await startsWithSplitZipSignature(reader)) {
6198
+ await writeData(this.writer, getSplitZipSignatureArray());
6199
+ splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6200
+ this.offset += splitZipSignatureLength;
6201
+ }
6202
+ }
6203
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
6054
6204
  this.filenames = new Set(entries.map(entry => entry.filename));
6055
- this.files = new Map(entries.map(entry => {
6205
+ this.fileEntries = new Map(entries.map(entry => {
6056
6206
  const {
6057
6207
  version,
6058
6208
  rawLastModDate,
@@ -6107,11 +6257,12 @@
6107
6257
  if (crc32 !== UNDEFINED_VALUE) {
6108
6258
  setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
6109
6259
  }
6260
+ const { offset, diskNumberStart } = entryPositions.get(entry);
6110
6261
  Object.assign(entry, {
6111
6262
  zip64UncompressedSize,
6112
6263
  zip64CompressedSize,
6113
- zip64Offset: zip64 && entry.offset >= MAX_32_BITS,
6114
- diskNumberStart: 0,
6264
+ offset,
6265
+ diskNumberStart,
6115
6266
  zip64DiskNumberStart: false,
6116
6267
  rawExtraFieldZip64,
6117
6268
  rawExtraFieldAES,
@@ -6131,11 +6282,8 @@
6131
6282
  async add(name = "", reader, options = {}) {
6132
6283
  const zipWriter = this;
6133
6284
  options = Object.assign({}, options);
6134
- const {
6135
- pendingAddFileCalls,
6136
- config
6137
- } = zipWriter;
6138
- if (workers < config.maxWorkers) {
6285
+ const { pendingAddFileCalls } = zipWriter;
6286
+ if (workers < getConfiguration().maxWorkers) {
6139
6287
  workers++;
6140
6288
  } else {
6141
6289
  await new Promise(resolve => pendingEntries.push(resolve));
@@ -6172,16 +6320,16 @@
6172
6320
  }
6173
6321
 
6174
6322
  remove(entry) {
6175
- const { filenames, files } = this;
6323
+ const { filenames, fileEntries } = this;
6176
6324
  // deno-lint-ignore valid-typeof
6177
6325
  if (typeof entry == STRING_TYPE) {
6178
- entry = files.get(entry);
6326
+ entry = fileEntries.get(entry);
6179
6327
  }
6180
6328
  if (entry && entry.filename !== UNDEFINED_VALUE) {
6181
6329
  const { filename } = entry;
6182
- if (filenames.has(filename) && files.has(filename)) {
6330
+ if (filenames.has(filename) && fileEntries.has(filename)) {
6183
6331
  filenames.delete(filename);
6184
- files.delete(filename);
6332
+ fileEntries.delete(filename);
6185
6333
  return true;
6186
6334
  }
6187
6335
  }
@@ -6278,12 +6426,12 @@
6278
6426
  const metadataInfo = resolveMetadata(zipWriter, name, options);
6279
6427
  const { comment } = metadataInfo;
6280
6428
  const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
6281
- zipWriter.files.set(name, UNDEFINED_VALUE);
6429
+ zipWriter.fileEntries.set(name, UNDEFINED_VALUE);
6282
6430
  let fileEntry;
6283
6431
  try {
6284
6432
  const { resolvedOptions } = metadataInfo;
6285
6433
  if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
6286
- !resolvedOptions.passThrough && !(await supportsDeflate(zipWriter.config))) {
6434
+ !resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
6287
6435
  resolvedOptions.level = 0;
6288
6436
  }
6289
6437
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
@@ -6301,7 +6449,7 @@
6301
6449
  const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
6302
6450
  fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
6303
6451
  } catch (error) {
6304
- zipWriter.files.delete(name);
6452
+ zipWriter.fileEntries.delete(name);
6305
6453
  throw error;
6306
6454
  }
6307
6455
  Object.assign(fileEntry, {
@@ -6345,9 +6493,9 @@
6345
6493
  if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
6346
6494
  unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
6347
6495
  }
6348
- let msdosAttributesRaw = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
6496
+ let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
6349
6497
  let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
6350
- const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
6498
+ const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType || executable;
6351
6499
  const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
6352
6500
  if (hasUnixMetadata) {
6353
6501
  msDosCompatible = false;
@@ -6356,10 +6504,10 @@
6356
6504
  msDosCompatible = true;
6357
6505
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
6358
6506
  }
6359
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6507
+ if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6360
6508
  throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
6361
6509
  }
6362
- if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
6510
+ if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
6363
6511
  throw new Error(ERR_INVALID_MSDOS_DATA);
6364
6512
  }
6365
6513
  if (versionMadeBy > MAX_16_BITS) {
@@ -6447,7 +6595,7 @@
6447
6595
  }
6448
6596
 
6449
6597
  function resolveMetadata(zipWriter, name, options) {
6450
- const encode = getOptionValue(zipWriter, options, OPTION_ENCODE_TEXT, encodeText);
6598
+ const encode = getFunctionOptionValue(zipWriter, options, OPTION_ENCODE_TEXT) || encodeText;
6451
6599
  let rawFilename = encode(name, TEXT_TYPE_FILENAME);
6452
6600
  if (rawFilename === UNDEFINED_VALUE) {
6453
6601
  rawFilename = encodeText(name);
@@ -6456,6 +6604,10 @@
6456
6604
  throw new Error(ERR_INVALID_ENTRY_NAME);
6457
6605
  }
6458
6606
  const comment = options[PROPERTY_NAME_COMMENT] || "";
6607
+ // deno-lint-ignore valid-typeof
6608
+ if (typeof comment != STRING_TYPE) {
6609
+ throw new Error(ERR_INVALID_ENTRY_COMMENT_TYPE);
6610
+ }
6459
6611
  let rawComment = encode(comment, TEXT_TYPE_COMMENT);
6460
6612
  if (rawComment === UNDEFINED_VALUE) {
6461
6613
  rawComment = encodeText(comment);
@@ -6467,16 +6619,14 @@
6467
6619
  if (version > MAX_16_BITS) {
6468
6620
  throw new Error(ERR_INVALID_VERSION);
6469
6621
  }
6470
- const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
6471
- const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6472
- const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6622
+ const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
6623
+ const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6624
+ const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6473
6625
  const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
6474
6626
  const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
6475
6627
  const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6476
6628
  const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6477
- if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
6478
- throw new Error(ERR_INVALID_PASSWORD_TYPE);
6479
- }
6629
+ checkPasswordOption(password, rawPassword);
6480
6630
  const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
6481
6631
  const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
6482
6632
  const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
@@ -6485,9 +6635,9 @@
6485
6635
  const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
6486
6636
  const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
6487
6637
  const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
6488
- const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
6638
+ const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
6489
6639
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
6490
- const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
6640
+ const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
6491
6641
  const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
6492
6642
  const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
6493
6643
  const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
@@ -6507,6 +6657,9 @@
6507
6657
  level = 0;
6508
6658
  }
6509
6659
  }
6660
+ if (passThrough) {
6661
+ level = UNDEFINED_VALUE;
6662
+ }
6510
6663
  let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
6511
6664
  let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
6512
6665
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
@@ -6567,18 +6720,26 @@
6567
6720
  if (!extraField) {
6568
6721
  return EMPTY_UINT8_ARRAY;
6569
6722
  }
6723
+ if (!(extraField instanceof Map)) {
6724
+ throw new Error(ERR_INVALID_EXTRAFIELD);
6725
+ }
6570
6726
  let extraFieldSize = 0;
6571
6727
  let offset = 0;
6572
- extraField.forEach(data => extraFieldSize += 4 + getLength(data));
6573
- const rawExtraField = new Uint8Array(extraFieldSize);
6574
- const rawExtraFieldView = getDataView(rawExtraField);
6575
6728
  extraField.forEach((data, type) => {
6576
- if (type > MAX_16_BITS) {
6729
+ if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
6577
6730
  throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
6578
6731
  }
6732
+ if (!(data instanceof Uint8Array)) {
6733
+ throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
6734
+ }
6579
6735
  if (getLength(data) > MAX_16_BITS) {
6580
6736
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
6581
6737
  }
6738
+ extraFieldSize += 4 + getLength(data);
6739
+ });
6740
+ const rawExtraField = new Uint8Array(extraFieldSize);
6741
+ const rawExtraFieldView = getDataView(rawExtraField);
6742
+ extraField.forEach((data, type) => {
6582
6743
  setUint16(rawExtraFieldView, offset, type);
6583
6744
  setUint16(rawExtraFieldView, offset + 2, getLength(data));
6584
6745
  arraySet(rawExtraField, data, offset + 4);
@@ -6610,6 +6771,9 @@
6610
6771
  if (uncompressedSize === UNDEFINED_VALUE) {
6611
6772
  throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
6612
6773
  }
6774
+ if (compressionMethod === UNDEFINED_VALUE) {
6775
+ throw new Error(ERR_UNDEFINED_COMPRESSION_METHOD);
6776
+ }
6613
6777
  }
6614
6778
  const zip64Enabled = zip64 === true;
6615
6779
  const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
@@ -6665,8 +6829,8 @@
6665
6829
  }
6666
6830
 
6667
6831
  async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
6668
- const zipWriter = { options: writerOptions, config: getConfiguration() };
6669
- if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
6832
+ const zipWriter = { options: writerOptions };
6833
+ if (checkFunctionOption(writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY])) {
6670
6834
  throw new Error(ERR_UNDETERMINED_SIZE);
6671
6835
  }
6672
6836
  if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
@@ -6692,7 +6856,7 @@
6692
6856
  ({ name } = attributesInfo);
6693
6857
  const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
6694
6858
  if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
6695
- !metadata.passThrough && !(await supportsDeflate(zipWriter.config))) {
6859
+ !metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
6696
6860
  metadata.level = 0;
6697
6861
  }
6698
6862
  const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
@@ -6741,7 +6905,7 @@
6741
6905
 
6742
6906
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6743
6907
  const {
6744
- files,
6908
+ fileEntries,
6745
6909
  writer
6746
6910
  } = zipWriter;
6747
6911
  const {
@@ -6763,12 +6927,12 @@
6763
6927
  let writerSizeBeforeEntry;
6764
6928
  let flushedBufferedSize = 0;
6765
6929
  let fileWriter;
6766
- files.set(name, fileEntry);
6930
+ fileEntries.set(name, fileEntry);
6767
6931
  zipWriter.lastFileEntry = fileEntry;
6768
6932
  try {
6769
6933
  let lockPreviousFileEntry;
6770
6934
  if (keepOrder) {
6771
- lockPreviousFileEntry = previousFileEntry && previousFileEntry.lock;
6935
+ lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
6772
6936
  requestLockCurrentFileEntry();
6773
6937
  }
6774
6938
  if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
@@ -6789,11 +6953,8 @@
6789
6953
  const diskOffset = getDiskOffset(writer);
6790
6954
  if (zipWriter.addSplitZipSignature) {
6791
6955
  delete zipWriter.addSplitZipSignature;
6792
- const signatureArray = new Uint8Array(4);
6793
- const signatureArrayView = getDataView(signatureArray);
6794
- setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
6795
- await writeData(writer, signatureArray);
6796
- zipWriter.offset += 4;
6956
+ await writeData(writer, getSplitZipSignatureArray());
6957
+ zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6797
6958
  }
6798
6959
  if (usdz && !bufferedWrite) {
6799
6960
  appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
@@ -6811,11 +6972,11 @@
6811
6972
  writerSizeBeforeEntry = writer.size;
6812
6973
  await writeData(fileWriter, localHeaderArray);
6813
6974
  }
6814
- fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, zipWriter.config, options);
6975
+ fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, getConfiguration(), options);
6815
6976
  if (!bufferedWrite) {
6816
6977
  writingEntryData = false;
6817
6978
  }
6818
- files.set(name, fileEntry);
6979
+ fileEntries.set(name, fileEntry);
6819
6980
  fileEntry.filename = name;
6820
6981
  if (bufferedWrite) {
6821
6982
  await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
@@ -6856,7 +7017,7 @@
6856
7017
  zipWriter.offset += flushedBufferedSize;
6857
7018
  }
6858
7019
  }
6859
- files.delete(name);
7020
+ fileEntries.delete(name);
6860
7021
  throw error;
6861
7022
  } finally {
6862
7023
  if (bufferedWrite) {
@@ -6878,7 +7039,7 @@
6878
7039
  }
6879
7040
 
6880
7041
  function requestLockCurrentFileEntry() {
6881
- fileEntry.lock = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
7042
+ fileEntry.lockFileEntry = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
6882
7043
  }
6883
7044
 
6884
7045
  async function requestLockWriter() {
@@ -6898,7 +7059,7 @@
6898
7059
  }
6899
7060
  }
6900
7061
 
6901
- async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryInfo, config, options) {
7062
+ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry }, entryInfo, config, options) {
6902
7063
  const {
6903
7064
  headerInfo,
6904
7065
  dataDescriptorInfo,
@@ -6966,7 +7127,7 @@
6966
7127
  codecURI
6967
7128
  } = options;
6968
7129
  const fileEntry = {
6969
- lock,
7130
+ lockFileEntry,
6970
7131
  versionMadeBy,
6971
7132
  zip64,
6972
7133
  directory: Boolean(directory),
@@ -7008,7 +7169,7 @@
7008
7169
  }
7009
7170
  const { writable } = writer;
7010
7171
  if (reader) {
7011
- const readable = toCompatibleReadable(reader.createReadable ? reader.createReadable() : reader.readable);
7172
+ const readable = toCompatibleReadable(createReadable(reader));
7012
7173
  const size = reader.size;
7013
7174
  const workerOptions = {
7014
7175
  options: {
@@ -7120,14 +7281,14 @@
7120
7281
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
7121
7282
  const length = 4 + 16;
7122
7283
  const extraFieldZip64 = createRecordWriter(length);
7123
- extraFieldZip64.uint16(EXTRAFIELD_TYPE_ZIP64);
7124
- extraFieldZip64.uint16(length - 4);
7284
+ extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
7285
+ extraFieldZip64.writeUint16(length - 4);
7125
7286
  rawLocalExtraFieldZip64 = extraFieldZip64.array;
7126
7287
  if (zip64ExtraFieldComplete) {
7127
- extraFieldZip64.uint64(uncompressedSize);
7288
+ extraFieldZip64.writeUint64(uncompressedSize);
7128
7289
  if (uncompressedFile) {
7129
7290
  const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
7130
- extraFieldZip64.uint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
7291
+ extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
7131
7292
  }
7132
7293
  }
7133
7294
  } else {
@@ -7136,8 +7297,8 @@
7136
7297
  let rawExtraFieldAES;
7137
7298
  if (encrypted && !zipCrypto) {
7138
7299
  const extraFieldAES = createRecordWriter(getLength(EXTRAFIELD_DATA_AES) + 2);
7139
- extraFieldAES.uint16(EXTRAFIELD_TYPE_AES);
7140
- extraFieldAES.bytes(EXTRAFIELD_DATA_AES);
7300
+ extraFieldAES.writeUint16(EXTRAFIELD_TYPE_AES);
7301
+ extraFieldAES.writeBytes(EXTRAFIELD_DATA_AES);
7141
7302
  rawExtraFieldAES = extraFieldAES.array;
7142
7303
  rawExtraFieldAES[8] = encryptionStrength;
7143
7304
  } else {
@@ -7153,15 +7314,15 @@
7153
7314
  const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
7154
7315
  const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
7155
7316
  extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
7156
- extraFieldTimestamp.uint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7157
- extraFieldTimestamp.uint16(extraFieldTimestampLength - 4);
7158
- extraFieldTimestamp.uint8(extraFieldExtendedTimestampFlag);
7159
- extraFieldTimestamp.uint32(lastModTimeUnix);
7317
+ extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7318
+ extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
7319
+ extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
7320
+ extraFieldTimestamp.writeUint32(lastModTimeUnix);
7160
7321
  if (lastAccessDate) {
7161
- extraFieldTimestamp.uint32(clampUnixTime(getTimeUnix(lastAccessDate)));
7322
+ extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(lastAccessDate)));
7162
7323
  }
7163
7324
  if (creationDate) {
7164
- extraFieldTimestamp.uint32(clampUnixTime(getTimeUnix(creationDate)));
7325
+ extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(creationDate)));
7165
7326
  }
7166
7327
  rawExtraFieldExtendedTimestamp = extraFieldTimestamp.array;
7167
7328
  } else {
@@ -7174,14 +7335,14 @@
7174
7335
  try {
7175
7336
  const lastModTimeNTFS = getTimeNTFS(lastModDate);
7176
7337
  const extraFieldNTFS = createRecordWriter(36);
7177
- extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS);
7178
- extraFieldNTFS.uint16(32);
7338
+ extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS);
7339
+ extraFieldNTFS.writeUint16(32);
7179
7340
  extraFieldNTFS.skip(4);
7180
- extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS_TAG1);
7181
- extraFieldNTFS.uint16(24);
7182
- extraFieldNTFS.uint64(lastModTimeNTFS);
7183
- extraFieldNTFS.uint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
7184
- extraFieldNTFS.uint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
7341
+ extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS_TAG1);
7342
+ extraFieldNTFS.writeUint16(24);
7343
+ extraFieldNTFS.writeUint64(lastModTimeNTFS);
7344
+ extraFieldNTFS.writeUint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
7345
+ extraFieldNTFS.writeUint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
7185
7346
  rawExtraFieldNTFS = extraFieldNTFS.array;
7186
7347
  } catch {
7187
7348
  rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
@@ -7200,20 +7361,20 @@
7200
7361
  const gidBytes = packUnixId(gid);
7201
7362
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
7202
7363
  const extraFieldUnix = createRecordWriter(4 + payloadLength);
7203
- extraFieldUnix.uint16(EXTRAFIELD_TYPE_INFOZIP);
7204
- extraFieldUnix.uint16(payloadLength);
7205
- extraFieldUnix.uint8(1);
7206
- extraFieldUnix.uint8(uidBytes.length);
7207
- extraFieldUnix.bytes(uidBytes);
7208
- extraFieldUnix.uint8(gidBytes.length);
7209
- extraFieldUnix.bytes(gidBytes);
7364
+ extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
7365
+ extraFieldUnix.writeUint16(payloadLength);
7366
+ extraFieldUnix.writeUint8(1);
7367
+ extraFieldUnix.writeUint8(uidBytes.length);
7368
+ extraFieldUnix.writeBytes(uidBytes);
7369
+ extraFieldUnix.writeUint8(gidBytes.length);
7370
+ extraFieldUnix.writeBytes(gidBytes);
7210
7371
  rawExtraFieldUnix = extraFieldUnix.array;
7211
7372
  } else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
7212
7373
  const extraFieldUnix = createRecordWriter(8);
7213
- extraFieldUnix.uint16(EXTRAFIELD_TYPE_UNIX);
7214
- extraFieldUnix.uint16(4);
7215
- extraFieldUnix.uint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
7216
- extraFieldUnix.uint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
7374
+ extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
7375
+ extraFieldUnix.writeUint16(4);
7376
+ extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
7377
+ extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
7217
7378
  rawExtraFieldUnix = extraFieldUnix.array;
7218
7379
  } else {
7219
7380
  rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
@@ -7263,18 +7424,18 @@
7263
7424
  const localHeader = createRecordWriter(HEADER_SIZE + getLength(rawFilename) + extraFieldLength);
7264
7425
  const localHeaderArray = localHeader.array;
7265
7426
  const localHeaderView = getDataView(localHeaderArray);
7266
- localHeader.uint32(LOCAL_FILE_HEADER_SIGNATURE);
7267
- localHeader.bytes(headerArray);
7268
- localHeader.bytes(rawFilename);
7427
+ localHeader.writeUint32(LOCAL_FILE_HEADER_SIGNATURE);
7428
+ localHeader.writeBytes(headerArray);
7429
+ localHeader.writeBytes(rawFilename);
7269
7430
  if (writeLocalExtraFieldZip64) {
7270
- localHeader.bytes(rawLocalExtraFieldZip64);
7271
- }
7272
- localHeader.bytes(rawExtraFieldAES);
7273
- localHeader.bytes(rawExtraFieldExtendedTimestamp);
7274
- localHeader.bytes(rawExtraFieldNTFS);
7275
- localHeader.bytes(rawExtraFieldUnix);
7276
- localHeader.bytes(rawExtraField);
7277
- localHeader.bytes(rawLocalExtraField);
7431
+ localHeader.writeBytes(rawLocalExtraFieldZip64);
7432
+ }
7433
+ localHeader.writeBytes(rawExtraFieldAES);
7434
+ localHeader.writeBytes(rawExtraFieldExtendedTimestamp);
7435
+ localHeader.writeBytes(rawExtraFieldNTFS);
7436
+ localHeader.writeBytes(rawExtraFieldUnix);
7437
+ localHeader.writeBytes(rawExtraField);
7438
+ localHeader.writeBytes(rawLocalExtraField);
7278
7439
  if (dataDescriptor) {
7279
7440
  if (!zip64CompressedSize) {
7280
7441
  setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, 0);
@@ -7464,7 +7625,7 @@
7464
7625
 
7465
7626
 
7466
7627
  async function closeFile(zipWriter, comment, options) {
7467
- const directoryDataLength = createDirectoryRecords(zipWriter.files);
7628
+ const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
7468
7629
  const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7469
7630
  const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
7470
7631
  await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
@@ -7494,19 +7655,19 @@
7494
7655
  if (zip64Offset || zip64DiskNumberStart || zip64UncompressedSize || zip64CompressedSize) {
7495
7656
  const length = 4 + (zip64UncompressedSize ? 8 : 0) + (zip64CompressedSize ? 8 : 0) + (zip64Offset ? 8 : 0) + (zip64DiskNumberStart ? 4 : 0);
7496
7657
  const extraFieldZip64 = createRecordWriter(length);
7497
- extraFieldZip64.uint16(EXTRAFIELD_TYPE_ZIP64);
7498
- extraFieldZip64.uint16(length - 4);
7658
+ extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
7659
+ extraFieldZip64.writeUint16(length - 4);
7499
7660
  if (zip64UncompressedSize) {
7500
- extraFieldZip64.uint64(uncompressedSize);
7661
+ extraFieldZip64.writeUint64(uncompressedSize);
7501
7662
  }
7502
7663
  if (zip64CompressedSize) {
7503
- extraFieldZip64.uint64(compressedSize);
7664
+ extraFieldZip64.writeUint64(compressedSize);
7504
7665
  }
7505
7666
  if (zip64Offset) {
7506
- extraFieldZip64.uint64(fileEntry.offset);
7667
+ extraFieldZip64.writeUint64(fileEntry.offset);
7507
7668
  }
7508
7669
  if (zip64DiskNumberStart) {
7509
- extraFieldZip64.uint32(fileEntry.diskNumberStart);
7670
+ extraFieldZip64.writeUint32(fileEntry.diskNumberStart);
7510
7671
  }
7511
7672
  rawExtraFieldZip64 = extraFieldZip64.array;
7512
7673
  } else {
@@ -7519,10 +7680,10 @@
7519
7680
  const lastModTimeUnix = getTimeUnix(lastModDate);
7520
7681
  if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
7521
7682
  const extraFieldTimestamp = createRecordWriter(9);
7522
- extraFieldTimestamp.uint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7523
- extraFieldTimestamp.uint16(5);
7524
- extraFieldTimestamp.uint8(extraFieldExtendedTimestampFlag);
7525
- extraFieldTimestamp.uint32(lastModTimeUnix);
7683
+ extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
7684
+ extraFieldTimestamp.writeUint16(5);
7685
+ extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
7686
+ extraFieldTimestamp.writeUint32(lastModTimeUnix);
7526
7687
  rawExtraFieldTimestamp = extraFieldTimestamp.array;
7527
7688
  } else {
7528
7689
  rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
@@ -7544,14 +7705,14 @@
7544
7705
  }
7545
7706
 
7546
7707
  async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
7547
- const { files, writer } = zipWriter;
7708
+ const { fileEntries, writer } = zipWriter;
7548
7709
  const directoryArray = new Uint8Array(directoryDataLength);
7549
7710
  await initStream(writer);
7550
7711
  let offset = 0;
7551
7712
  let directoryDiskOffset = 0;
7552
7713
  let directoryStartDiskNumber = getDiskNumber(writer);
7553
7714
  let directoryStartDiskOffset = getDiskOffset(writer);
7554
- for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
7715
+ for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
7555
7716
  const {
7556
7717
  offset: fileEntryOffset,
7557
7718
  rawFilename,
@@ -7596,28 +7757,28 @@
7596
7757
  setUint16(headerView, HEADER_OFFSET_VERSION, VERSION_ZIP64);
7597
7758
  }
7598
7759
  const directoryRecord = createRecordWriter(directoryRecordLength);
7599
- directoryRecord.uint32(CENTRAL_FILE_HEADER_SIGNATURE);
7600
- directoryRecord.uint16(versionMadeBy);
7601
- directoryRecord.bytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
7602
- directoryRecord.uint16(extraFieldLength);
7603
- directoryRecord.uint16(getLength(rawComment));
7604
- directoryRecord.uint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
7605
- directoryRecord.uint16(internalFileAttributes);
7606
- directoryRecord.uint32(externalFileAttributes);
7607
- directoryRecord.uint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
7608
- directoryRecord.bytes(rawFilename);
7609
- directoryRecord.bytes(rawExtraFieldZip64);
7610
- directoryRecord.bytes(rawExtraFieldAES);
7611
- directoryRecord.bytes(rawExtraFieldExtendedTimestamp);
7612
- directoryRecord.bytes(rawExtraFieldNTFS);
7613
- directoryRecord.bytes(rawExtraFieldUnix);
7614
- directoryRecord.bytes(rawExtraField);
7615
- directoryRecord.bytes(rawComment);
7760
+ directoryRecord.writeUint32(CENTRAL_FILE_HEADER_SIGNATURE);
7761
+ directoryRecord.writeUint16(versionMadeBy);
7762
+ directoryRecord.writeBytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
7763
+ directoryRecord.writeUint16(extraFieldLength);
7764
+ directoryRecord.writeUint16(getLength(rawComment));
7765
+ directoryRecord.writeUint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
7766
+ directoryRecord.writeUint16(internalFileAttributes);
7767
+ directoryRecord.writeUint32(externalFileAttributes);
7768
+ directoryRecord.writeUint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
7769
+ directoryRecord.writeBytes(rawFilename);
7770
+ directoryRecord.writeBytes(rawExtraFieldZip64);
7771
+ directoryRecord.writeBytes(rawExtraFieldAES);
7772
+ directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
7773
+ directoryRecord.writeBytes(rawExtraFieldNTFS);
7774
+ directoryRecord.writeBytes(rawExtraFieldUnix);
7775
+ directoryRecord.writeBytes(rawExtraField);
7776
+ directoryRecord.writeBytes(rawComment);
7616
7777
  arraySet(directoryArray, directoryRecord.array, offset);
7617
7778
  offset += directoryRecordLength;
7618
7779
  if (options.onprogress) {
7619
7780
  try {
7620
- await options.onprogress(indexFileEntry + 1, files.size, new Entry(fileEntry));
7781
+ await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
7621
7782
  } catch {
7622
7783
  // ignored
7623
7784
  }
@@ -7631,7 +7792,7 @@
7631
7792
  }
7632
7793
 
7633
7794
  async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7634
- const signCentralDirectory = getOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
7795
+ const signCentralDirectory = getFunctionOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
7635
7796
  if (signCentralDirectory) {
7636
7797
  const signatureData = await signCentralDirectory(directoryArray);
7637
7798
  const signatureDataLength = getLength(signatureData);
@@ -7639,9 +7800,9 @@
7639
7800
  throw new Error(ERR_INVALID_SIGNATURE_DATA);
7640
7801
  }
7641
7802
  const signatureRecord = createRecordWriter(6 + signatureDataLength);
7642
- signatureRecord.uint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7643
- signatureRecord.uint16(signatureDataLength);
7644
- signatureRecord.bytes(signatureData);
7803
+ signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7804
+ signatureRecord.writeUint16(signatureDataLength);
7805
+ signatureRecord.writeBytes(signatureData);
7645
7806
  await writeData(zipWriter.writer, signatureRecord.array);
7646
7807
  return 6 + signatureDataLength;
7647
7808
  }
@@ -7652,7 +7813,7 @@
7652
7813
  const { writer } = zipWriter;
7653
7814
  const { directoryStart, signatureLength } = cdInfo;
7654
7815
  let { directoryDataLength } = cdInfo;
7655
- let filesLength = zipWriter.files.size;
7816
+ let fileEntriesLength = zipWriter.fileEntries.size;
7656
7817
  let diskNumber = directoryStart.diskNumber;
7657
7818
  let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
7658
7819
  let lastDiskNumber = getDiskNumber(writer);
@@ -7660,7 +7821,7 @@
7660
7821
  lastDiskNumber++;
7661
7822
  }
7662
7823
  let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
7663
- if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || filesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
7824
+ if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
7664
7825
  if (zip64 === false) {
7665
7826
  throw new Error(ERR_UNSUPPORTED_FORMAT);
7666
7827
  } else {
@@ -7677,37 +7838,37 @@
7677
7838
  }
7678
7839
  lastDiskNumber = getDiskNumber(writer);
7679
7840
  if (zip64) {
7680
- endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
7681
- endOfdirectoryRecord.uint64(44);
7682
- endOfdirectoryRecord.uint16(45);
7683
- endOfdirectoryRecord.uint16(45);
7684
- endOfdirectoryRecord.uint32(lastDiskNumber);
7685
- endOfdirectoryRecord.uint32(diskNumber);
7686
- endOfdirectoryRecord.uint64(filesLength);
7687
- endOfdirectoryRecord.uint64(filesLength);
7688
- endOfdirectoryRecord.uint64(directoryDataLength);
7689
- endOfdirectoryRecord.uint64(directoryOffset);
7690
- endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
7691
- endOfdirectoryRecord.uint32(lastDiskNumber);
7692
- endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
7693
- endOfdirectoryRecord.uint32(lastDiskNumber + 1);
7841
+ endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
7842
+ endOfdirectoryRecord.writeUint64(44);
7843
+ endOfdirectoryRecord.writeUint16(45);
7844
+ endOfdirectoryRecord.writeUint16(45);
7845
+ endOfdirectoryRecord.writeUint32(lastDiskNumber);
7846
+ endOfdirectoryRecord.writeUint32(diskNumber);
7847
+ endOfdirectoryRecord.writeUint64(fileEntriesLength);
7848
+ endOfdirectoryRecord.writeUint64(fileEntriesLength);
7849
+ endOfdirectoryRecord.writeUint64(directoryDataLength);
7850
+ endOfdirectoryRecord.writeUint64(directoryOffset);
7851
+ endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
7852
+ endOfdirectoryRecord.writeUint32(lastDiskNumber);
7853
+ endOfdirectoryRecord.writeUint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
7854
+ endOfdirectoryRecord.writeUint32(lastDiskNumber + 1);
7694
7855
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
7695
7856
  if (supportZip64SplitFile) {
7696
7857
  lastDiskNumber = MAX_16_BITS;
7697
7858
  diskNumber = MAX_16_BITS;
7698
7859
  }
7699
- filesLength = MAX_16_BITS;
7860
+ fileEntriesLength = MAX_16_BITS;
7700
7861
  directoryOffset = MAX_32_BITS;
7701
7862
  directoryDataLength = MAX_32_BITS;
7702
7863
  }
7703
- endOfdirectoryRecord.uint32(END_OF_CENTRAL_DIR_SIGNATURE);
7704
- endOfdirectoryRecord.uint16(lastDiskNumber);
7705
- endOfdirectoryRecord.uint16(diskNumber);
7706
- endOfdirectoryRecord.uint16(filesLength);
7707
- endOfdirectoryRecord.uint16(filesLength);
7708
- endOfdirectoryRecord.uint32(directoryDataLength);
7709
- endOfdirectoryRecord.uint32(directoryOffset);
7710
- endOfdirectoryRecord.uint16(commentLength);
7864
+ endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
7865
+ endOfdirectoryRecord.writeUint16(lastDiskNumber);
7866
+ endOfdirectoryRecord.writeUint16(diskNumber);
7867
+ endOfdirectoryRecord.writeUint16(fileEntriesLength);
7868
+ endOfdirectoryRecord.writeUint16(fileEntriesLength);
7869
+ endOfdirectoryRecord.writeUint32(directoryDataLength);
7870
+ endOfdirectoryRecord.writeUint32(directoryOffset);
7871
+ endOfdirectoryRecord.writeUint16(commentLength);
7711
7872
  await writeData(writer, endOfdirectoryRecord.array);
7712
7873
  if (commentLength) {
7713
7874
  await writeData(writer, comment);
@@ -7720,11 +7881,11 @@
7720
7881
  let offset = 0;
7721
7882
  return {
7722
7883
  array,
7723
- uint8: value => { setUint8(view, offset, value); offset += 1; },
7724
- uint16: value => { setUint16(view, offset, value); offset += 2; },
7725
- uint32: value => { setUint32(view, offset, value); offset += 4; },
7726
- uint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
7727
- bytes: value => { arraySet(array, value, offset); offset += getLength(value); },
7884
+ writeUint8: value => { setUint8(view, offset, value); offset += 1; },
7885
+ writeUint16: value => { setUint16(view, offset, value); offset += 2; },
7886
+ writeUint32: value => { setUint32(view, offset, value); offset += 4; },
7887
+ writeUint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
7888
+ writeBytes: value => { arraySet(array, value, offset); offset += getLength(value); },
7728
7889
  skip: count => offset += count
7729
7890
  };
7730
7891
  }
@@ -7748,6 +7909,71 @@
7748
7909
  return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
7749
7910
  }
7750
7911
 
7912
+ async function startsWithSplitZipSignature(reader) {
7913
+ const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
7914
+ return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7915
+ }
7916
+
7917
+ async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7918
+ const { writer } = zipWriter;
7919
+ const entryPositions = new Map();
7920
+ if (writer.closeDisk) {
7921
+ const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
7922
+ getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
7923
+ let copiedLength = 0;
7924
+ for (const entry of sortedEntries) {
7925
+ const sourceOffset = getSourceOffset(reader, entry);
7926
+ await copyData(zipWriter, reader, copiedLength, sourceOffset - copiedLength);
7927
+ if (exceedsAvailableSize(writer, await getLocalHeaderLength(reader, sourceOffset))) {
7928
+ await writer.closeDisk();
7929
+ }
7930
+ entryPositions.set(entry, {
7931
+ offset: getSegmentOffset(zipWriter, writer),
7932
+ diskNumberStart: getDiskNumber(writer)
7933
+ });
7934
+ copiedLength = sourceOffset;
7935
+ }
7936
+ await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7937
+ } else {
7938
+ await copyData(zipWriter, reader, 0, directoryOffset);
7939
+ entries.forEach(entry => entryPositions.set(entry, {
7940
+ offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7941
+ diskNumberStart: 0
7942
+ }));
7943
+ }
7944
+ return entryPositions;
7945
+ }
7946
+
7947
+ async function copyData(zipWriter, reader, offset, size) {
7948
+ if (size > 0) {
7949
+ const { writer } = zipWriter;
7950
+ await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
7951
+ writer.size += size;
7952
+ zipWriter.offset += size;
7953
+ }
7954
+ }
7955
+
7956
+ async function getLocalHeaderLength(reader, offset) {
7957
+ const headerArray = await readUint8Array(reader, offset, HEADER_SIZE);
7958
+ if (getLength(headerArray) < HEADER_SIZE) {
7959
+ return HEADER_SIZE;
7960
+ }
7961
+ const headerView = getDataView(headerArray);
7962
+ return HEADER_SIZE +
7963
+ getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
7964
+ getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
7965
+ }
7966
+
7967
+ function getSourceOffset(reader, { offset, diskNumberStart }) {
7968
+ return offset + (reader.getDiskOffset ? reader.getDiskOffset(diskNumberStart) : 0);
7969
+ }
7970
+
7971
+ function getSplitZipSignatureArray() {
7972
+ const signatureArray = new Uint8Array(SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
7973
+ setUint32(getDataView(signatureArray), 0, SPLIT_ZIP_FILE_SIGNATURE);
7974
+ return signatureArray;
7975
+ }
7976
+
7751
7977
  async function writeData(writer, array) {
7752
7978
  const { writable } = writer;
7753
7979
  const streamWriter = writable.getWriter();
@@ -7799,6 +8025,21 @@
7799
8025
  return result === UNDEFINED_VALUE ? defaultValue : result;
7800
8026
  }
7801
8027
 
8028
+ function getDateOptionValue(zipWriter, options, name, defaultValue) {
8029
+ const date = getOptionValue(zipWriter, options, name, defaultValue);
8030
+ if (date === null) {
8031
+ return defaultValue;
8032
+ }
8033
+ if (date !== UNDEFINED_VALUE && (typeof date.getTime != FUNCTION_TYPE || Number.isNaN(date.getTime()))) {
8034
+ throw new Error(ERR_INVALID_DATE);
8035
+ }
8036
+ return date;
8037
+ }
8038
+
8039
+ function getFunctionOptionValue(zipWriter, options, name) {
8040
+ return checkFunctionOption(getOptionValue(zipWriter, options, name));
8041
+ }
8042
+
7802
8043
  function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
7803
8044
  const value = getAliasedValue(options, name, deprecatedName);
7804
8045
  const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
@@ -7813,9 +8054,6 @@
7813
8054
  return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
7814
8055
  }
7815
8056
 
7816
- function toNumber(value) {
7817
- return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
7818
- }
7819
8057
 
7820
8058
  function getMaximumCompressedSize(uncompressedSize) {
7821
8059
  return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
@@ -7827,6 +8065,14 @@
7827
8065
  : compressionMethod !== COMPRESSION_METHOD_STORE;
7828
8066
  }
7829
8067
 
8068
+ function getUint16(view, offset) {
8069
+ return view.getUint16(offset, true);
8070
+ }
8071
+
8072
+ function getUint32(view, offset) {
8073
+ return view.getUint32(offset, true);
8074
+ }
8075
+
7830
8076
  function setUint8(view, offset, value) {
7831
8077
  view.setUint8(offset, value);
7832
8078
  }
@@ -7870,9 +8116,9 @@
7870
8116
  const headerRecord = createRecordWriter(HEADER_SIZE - 4);
7871
8117
  const headerArray = headerRecord.array;
7872
8118
  const headerView = getDataView(headerArray);
7873
- headerRecord.uint16(version);
7874
- headerRecord.uint16(bitFlag);
7875
- headerRecord.uint16(compressionMethod);
8119
+ headerRecord.writeUint16(version);
8120
+ headerRecord.writeUint16(bitFlag);
8121
+ headerRecord.writeUint16(compressionMethod);
7876
8122
  if (rawLastModDate === UNDEFINED_VALUE) {
7877
8123
  const dateArray = new Uint32Array(1);
7878
8124
  const dateView = getDataView(dateArray);
@@ -7880,20 +8126,20 @@
7880
8126
  setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
7881
8127
  rawLastModDate = dateArray[0];
7882
8128
  }
7883
- headerRecord.uint32(rawLastModDate);
8129
+ headerRecord.writeUint32(rawLastModDate);
7884
8130
  headerRecord.skip(4);
7885
8131
  if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
7886
- headerRecord.uint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
8132
+ headerRecord.writeUint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
7887
8133
  } else {
7888
8134
  headerRecord.skip(4);
7889
8135
  }
7890
8136
  if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
7891
- headerRecord.uint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
8137
+ headerRecord.writeUint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
7892
8138
  } else {
7893
8139
  headerRecord.skip(4);
7894
8140
  }
7895
- headerRecord.uint16(getLength(rawFilename));
7896
- headerRecord.uint16(extraFieldLength);
8141
+ headerRecord.writeUint16(getLength(rawFilename));
8142
+ headerRecord.writeUint16(extraFieldLength);
7897
8143
  return {
7898
8144
  headerArray,
7899
8145
  headerView,
@@ -8476,6 +8722,7 @@
8476
8722
  const ERR_ENTRY_EXISTS = "Entry filename already exists";
8477
8723
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
8478
8724
  const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
8725
+ const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
8479
8726
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
8480
8727
  const ERR_ABORTED = "The operation was aborted";
8481
8728
  const ABORT_ERROR_NAME = "AbortError";
@@ -8508,13 +8755,14 @@
8508
8755
  fs,
8509
8756
  name,
8510
8757
  data: params.data,
8511
- options: params.options,
8758
+ options: params.options && Object.assign({}, params.options),
8512
8759
  id: fs.entryIdCounter++,
8513
8760
  parent,
8514
8761
  children: [],
8515
8762
  uncompressedSize: params.uncompressedSize || 0,
8516
8763
  undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
8517
- passThrough: params.passThrough
8764
+ passThrough: params.passThrough,
8765
+ defaultLastModDate: params.defaultLastModDate || new Date()
8518
8766
  });
8519
8767
  if (parent || !fs.root) {
8520
8768
  fs.entries[zipEntry.id] = zipEntry;
@@ -8524,12 +8772,6 @@
8524
8772
  }
8525
8773
  }
8526
8774
 
8527
- moveTo(target) {
8528
- // deprecated
8529
- const zipEntry = this;
8530
- zipEntry.fs.move(zipEntry, target);
8531
- }
8532
-
8533
8775
  getFullname() {
8534
8776
  return this.getRelativeName();
8535
8777
  }
@@ -8561,6 +8803,11 @@
8561
8803
  this.name = name;
8562
8804
  }
8563
8805
  }
8806
+
8807
+ setOptions(options) {
8808
+ const entryOptions = Object.assign({}, this.options, options);
8809
+ this.options = Object.fromEntries(Object.entries(entryOptions).filter(([, value]) => value !== UNDEFINED_VALUE));
8810
+ }
8564
8811
  }
8565
8812
 
8566
8813
  class ZipFileEntry extends ZipEntry {
@@ -8587,7 +8834,7 @@
8587
8834
  const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
8588
8835
  const dataSize = zipEntry.uncompressedSize || reader.size;
8589
8836
  await Promise.all([initStream(reader), initStream(writer, dataSize)]);
8590
- const { signal } = options;
8837
+ const signal = checkSignalOption(options.signal);
8591
8838
  const readable = createProgressReadable(zipEntry, reader, options, signal);
8592
8839
  const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
8593
8840
  zipEntry.uncompressedSize = reader.size;
@@ -8805,10 +9052,6 @@
8805
9052
  });
8806
9053
  }
8807
9054
 
8808
- addData(name, params) {
8809
- return addChild(this, name, params);
8810
- }
8811
-
8812
9055
  importBlob(blob, options) {
8813
9056
  return this.importZip(new BlobReader(blob), options);
8814
9057
  }
@@ -8922,7 +9165,7 @@
8922
9165
  if (options.bufferedWrite === UNDEFINED_VALUE) {
8923
9166
  options.bufferedWrite = true;
8924
9167
  }
8925
- const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
9168
+ const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
8926
9169
  const zipWriter = new ZipWriter(writer, options);
8927
9170
  await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
8928
9171
  await zipWriter.close(options.globalComment);
@@ -8932,12 +9175,13 @@
8932
9175
  getExportedSize(options = {}) {
8933
9176
  const zipEntry = this;
8934
9177
  options = Object.assign({}, options);
9178
+ checkReaderOptions(options.readerOptions);
8935
9179
  if (options.bufferedWrite === UNDEFINED_VALUE) {
8936
9180
  options.bufferedWrite = true;
8937
9181
  }
8938
9182
  const writeOrderGuaranteed = !options.bufferedWrite ||
8939
9183
  (options.keepOrder !== false && zipEntry.children.every(child => !child.children.length));
8940
- return getEntriesSize(options, Array.from(zipEntry.getChildren({ recursive: true }), child => {
9184
+ return getEntriesSize(options, zipEntry.getChildren({ recursive: true }).filter(child => !isImplicitDirectory(child)).map(child => {
8941
9185
  const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
8942
9186
  return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
8943
9187
  }), writeOrderGuaranteed, options.globalComment);
@@ -8976,7 +9220,7 @@
8976
9220
  }
8977
9221
 
8978
9222
 
8979
- class FS {
9223
+ class ZipFS {
8980
9224
 
8981
9225
  constructor() {
8982
9226
  resetFS(this);
@@ -9092,10 +9336,6 @@
9092
9336
  return this.root.addFile(file, options);
9093
9337
  }
9094
9338
 
9095
- addData(name, params) {
9096
- return this.root.addData(name, params);
9097
- }
9098
-
9099
9339
  importBlob(blob, options) {
9100
9340
  resetFS(this);
9101
9341
  return this.root.importBlob(blob, options);
@@ -9163,7 +9403,7 @@
9163
9403
  }
9164
9404
  }
9165
9405
 
9166
- const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
9406
+ const fs = { FS: ZipFS, ZipDirectoryEntry, ZipFileEntry };
9167
9407
 
9168
9408
  function getTotalSize(entries, getEntrySize) {
9169
9409
  let size = 0;
@@ -9307,7 +9547,7 @@
9307
9547
  }
9308
9548
 
9309
9549
  function forwardAbort(signal, abortController) {
9310
- if (!signal) {
9550
+ if (!checkSignalOption(signal)) {
9311
9551
  return () => { };
9312
9552
  }
9313
9553
  if (signal.aborted) {
@@ -9384,10 +9624,7 @@
9384
9624
  });
9385
9625
  }
9386
9626
  if (isPassThrough(child, options)) {
9387
- let level, encryptionStrength;
9388
- if (compressionMethod === 0) {
9389
- level = 0;
9390
- }
9627
+ let encryptionStrength;
9391
9628
  if (extraFieldAES) {
9392
9629
  encryptionStrength = extraFieldAES.strength;
9393
9630
  }
@@ -9397,13 +9634,12 @@
9397
9634
  zipCrypto,
9398
9635
  crc32,
9399
9636
  uncompressedSize,
9400
- level,
9401
9637
  encryptionStrength,
9402
9638
  compressionMethod
9403
9639
  };
9404
9640
  }
9405
9641
  }
9406
- const entryOptions = Object.assign({}, zipEntryMetadata, options, passThroughOptions, childOptions, { directory: child.directory });
9642
+ const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
9407
9643
  if (!child.directory && entryOptions.passThrough && entryOptions.uncompressedSize === UNDEFINED_VALUE) {
9408
9644
  throw new Error(ERR_INVALID_PASS_THROUGH);
9409
9645
  }
@@ -9418,11 +9654,22 @@
9418
9654
  return child.undeterminedSize ? UNDEFINED_VALUE : getExtractedSize(child, passThrough);
9419
9655
  }
9420
9656
 
9657
+ function checkReaderOptions(readerOptions) {
9658
+ if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
9659
+ throw new Error(ERR_INVALID_READER_OPTIONS);
9660
+ }
9661
+ return readerOptions;
9662
+ }
9663
+
9421
9664
  function isPassThrough(child, options) {
9422
9665
  const { readerOptions } = options;
9423
9666
  return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
9424
9667
  }
9425
9668
 
9669
+ function isImplicitDirectory(child) {
9670
+ return child.directory && child.data === null;
9671
+ }
9672
+
9426
9673
  function getUserExtraField(extraField) {
9427
9674
  if (extraField) {
9428
9675
  const userExtraField = new Map();
@@ -9440,7 +9687,7 @@
9440
9687
  async function exportZip(zipWriter, entry, totalSize, options, readers) {
9441
9688
  const { onstart, onprogress, onend, onentryprogress } = options;
9442
9689
  const selectedEntry = entry;
9443
- const totalEntries = getTotalSize(entry.children, () => 1);
9690
+ const totalEntries = getTotalSize(entry.children, child => isImplicitDirectory(child) ? 0 : 1);
9444
9691
  let writtenSize = 0;
9445
9692
  let writtenEntries = 0;
9446
9693
  if (onstart) {
@@ -9469,6 +9716,9 @@
9469
9716
  }
9470
9717
 
9471
9718
  async function addChild(child) {
9719
+ if (isImplicitDirectory(child)) {
9720
+ return;
9721
+ }
9472
9722
  const { name, entryOptions } = getChildEntryOptions(child, selectedEntry, options);
9473
9723
  let entryWrittenSize = 0;
9474
9724
  const entryMetadata = await zipWriter.add(name, readers.get(child), Object.assign(entryOptions, {
@@ -9502,7 +9752,7 @@
9502
9752
  if (handle.kind == "file") {
9503
9753
  const file = await handle.getFile();
9504
9754
  addedEntries.push(
9505
- parentEntry.addData(file.name, {
9755
+ addChild(parentEntry, file.name, {
9506
9756
  Reader: function () {
9507
9757
  const readable = file.stream();
9508
9758
  const size = file.size;
@@ -9536,10 +9786,11 @@
9536
9786
 
9537
9787
  async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
9538
9788
  const { onstart, onprogress, onend } = options;
9789
+ const readerOptions = checkReaderOptions(options.readerOptions);
9539
9790
  const abortController = new AbortController();
9540
9791
  const { signal } = abortController;
9541
9792
  const releaseSignal = forwardAbort(options.signal, abortController);
9542
- const getDataOptions = Object.assign({}, options, options.readerOptions, {
9793
+ const getDataOptions = Object.assign({}, options, readerOptions, {
9543
9794
  signal,
9544
9795
  onstart: UNDEFINED_VALUE,
9545
9796
  onprogress: UNDEFINED_VALUE,
@@ -9839,6 +10090,7 @@
9839
10090
  exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
9840
10091
  exports.ERR_ENCRYPTED = ERR_ENCRYPTED;
9841
10092
  exports.ERR_ENCRYPTED_CENTRAL_DIRECTORY = ERR_ENCRYPTED_CENTRAL_DIRECTORY;
10093
+ exports.ERR_ENTRY_DATA_OUT_OF_BOUNDS = ERR_ENTRY_DATA_OUT_OF_BOUNDS;
9842
10094
  exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
9843
10095
  exports.ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND;
9844
10096
  exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
@@ -9852,20 +10104,28 @@
9852
10104
  exports.ERR_INVALID_COMMENT_TYPE = ERR_INVALID_COMMENT_TYPE;
9853
10105
  exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
9854
10106
  exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
10107
+ exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
9855
10108
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
9856
10109
  exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
10110
+ exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
9857
10111
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
10112
+ exports.ERR_INVALID_EXTRAFIELD = ERR_INVALID_EXTRAFIELD;
9858
10113
  exports.ERR_INVALID_EXTRAFIELD_DATA = ERR_INVALID_EXTRAFIELD_DATA;
10114
+ exports.ERR_INVALID_EXTRAFIELD_DATA_TYPE = ERR_INVALID_EXTRAFIELD_DATA_TYPE;
9859
10115
  exports.ERR_INVALID_EXTRAFIELD_TYPE = ERR_INVALID_EXTRAFIELD_TYPE;
9860
10116
  exports.ERR_INVALID_FILENAME_VALIDATION = ERR_INVALID_FILENAME_VALIDATION;
10117
+ exports.ERR_INVALID_FUNCTION_OPTION = ERR_INVALID_FUNCTION_OPTION;
9861
10118
  exports.ERR_INVALID_GID = ERR_INVALID_GID;
9862
10119
  exports.ERR_INVALID_LEVEL = ERR_INVALID_LEVEL;
9863
10120
  exports.ERR_INVALID_MAX_APPENDED_DATA_SIZE = ERR_INVALID_MAX_APPENDED_DATA_SIZE;
10121
+ exports.ERR_INVALID_MAX_WORKERS = ERR_INVALID_MAX_WORKERS;
9864
10122
  exports.ERR_INVALID_MSDOS_ATTRIBUTES = ERR_INVALID_MSDOS_ATTRIBUTES;
9865
10123
  exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
9866
10124
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
9867
10125
  exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
9868
10126
  exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
10127
+ exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
10128
+ exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
9869
10129
  exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
9870
10130
  exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
9871
10131
  exports.ERR_INVALID_STRICTNESS = ERR_INVALID_STRICTNESS;
@@ -9881,6 +10141,7 @@
9881
10141
  exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
9882
10142
  exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
9883
10143
  exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
10144
+ exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
9884
10145
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
9885
10146
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
9886
10147
  exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
@@ -9905,6 +10166,10 @@
9905
10166
  exports.Uint8ArrayReader = Uint8ArrayReader;
9906
10167
  exports.Uint8ArrayWriter = Uint8ArrayWriter;
9907
10168
  exports.Writer = Writer;
10169
+ exports.ZipDirectoryEntry = ZipDirectoryEntry;
10170
+ exports.ZipEntry = ZipEntry;
10171
+ exports.ZipFS = ZipFS;
10172
+ exports.ZipFileEntry = ZipFileEntry;
9908
10173
  exports.ZipReader = ZipReader;
9909
10174
  exports.ZipReaderStream = ZipReaderStream;
9910
10175
  exports.ZipWriter = ZipWriter;