@zip.js/zip.js 2.8.48 → 2.8.50

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 (47) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +351 -205
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +357 -205
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +438 -216
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +213 -435
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +438 -216
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +447 -219
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +445 -217
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +359 -207
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +360 -208
  19. package/dist/zip-native.min.js +1 -1
  20. package/dist/zip-web-worker-native.js +1 -1
  21. package/dist/zip-web-worker.js +1 -1
  22. package/dist/zip.js +358 -206
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +446 -218
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +444 -216
  27. package/index.d.cts +124 -2
  28. package/index.d.ts +124 -2
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-pool.js +1 -1
  31. package/lib/core/codec-registry.js +2 -2
  32. package/lib/core/codec-worker-web.js +436 -0
  33. package/lib/core/codec-worker.js +23 -388
  34. package/lib/core/constants.js +5 -1
  35. package/lib/core/io.js +2 -1
  36. package/lib/core/options.js +8 -0
  37. package/lib/core/streams/zlib-js/zlib-streams.min.js +1 -1
  38. package/lib/core/web-worker-base.js +10 -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 +88 -12
  42. package/lib/core/zip-reader.js +90 -16
  43. package/lib/core/zip-writer.js +36 -13
  44. package/lib/zip-core-reader.js +6 -0
  45. package/lib/zip-core-writer.js +4 -0
  46. package/package.json +1 -1
  47. package/worker-message-property-names.js +1 -1
package/dist/zip-core.js CHANGED
@@ -4,7 +4,7 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.zip = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- const { Array, Object, String, Number, BigInt, Math, Date, Map, Set, Response, URL, Error, Uint8Array, Uint16Array, Uint32Array, DataView, Blob, Promise, TextEncoder, TextDecoder, document, crypto, btoa, TransformStream, ReadableStream, WritableStream, CompressionStream, DecompressionStream, navigator, Worker } = typeof globalThis !== 'undefined' ? globalThis : this || self;
7
+ const { Array, Object, String, Number, BigInt, Math, Date, Map, Set, Response, URL, Error, Uint8Array, Uint16Array, Uint32Array, DataView, Blob, Promise, TextEncoder, TextDecoder, document, crypto, btoa, TransformStream, ReadableStream, WritableStream, CompressionStream, DecompressionStream, navigator, Worker, Symbol, setTimeout, clearTimeout, structuredClone } = typeof globalThis !== 'undefined' ? globalThis : this || self;
8
8
 
9
9
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
10
10
  /*
@@ -117,6 +117,8 @@
117
117
  const UNDEFINED_TYPE = "undefined";
118
118
  const FUNCTION_TYPE = "function";
119
119
  const OBJECT_TYPE = "object";
120
+ const STRING_TYPE = "string";
121
+ const NUMBER_TYPE = "number";
120
122
 
121
123
  const EMPTY_UINT8_ARRAY = new Uint8Array();
122
124
 
@@ -246,7 +248,7 @@
246
248
  }
247
249
 
248
250
  /*
249
- Copyright (c) 2025 Gildas Lormeau. All rights reserved.
251
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
250
252
 
251
253
  Redistribution and use in source and binary forms, with or without
252
254
  modification, are permitted provided that the following conditions are met:
@@ -274,72 +276,19 @@
274
276
  */
275
277
 
276
278
 
277
- const ERR_INVALID_CODEC_DEFINITION = "Invalid codec definition";
278
- const ERR_RESERVED_COMPRESSION_METHOD = "Reserved compression method";
279
- const ERR_INVALID_CODEC_MODULE = "Invalid codec module";
280
-
281
- const STRING_TYPE = "string";
282
- const RESERVED_COMPRESSION_METHODS = [
283
- COMPRESSION_METHOD_STORE,
284
- COMPRESSION_METHOD_DEFLATE,
285
- COMPRESSION_METHOD_DEFLATE_64,
286
- COMPRESSION_METHOD_AES
287
- ];
288
-
289
- const registeredCodecs = new Map();
290
- const codecStreams = new Map();
291
-
292
- function registerCodec(codec = {}) {
293
- const { compressionMethod, format, codecURI, CompressionStream, DecompressionStream, versionNeeded } = codec;
294
- if (!Number.isInteger(compressionMethod) || compressionMethod < 0 || compressionMethod > MAX_16_BITS ||
295
- typeof format != STRING_TYPE || !format.length) {
296
- throw new Error(ERR_INVALID_CODEC_DEFINITION);
297
- }
298
- if (RESERVED_COMPRESSION_METHODS.includes(compressionMethod)) {
299
- throw new Error(ERR_RESERVED_COMPRESSION_METHOD);
300
- }
301
- const hasStreams = typeof CompressionStream == FUNCTION_TYPE || typeof DecompressionStream == FUNCTION_TYPE;
302
- if (!hasStreams && (typeof codecURI != STRING_TYPE || !codecURI.length)) {
303
- throw new Error(ERR_INVALID_CODEC_DEFINITION);
304
- }
305
- registeredCodecs.set(compressionMethod, { compressionMethod, format, codecURI, versionNeeded });
306
- if (hasStreams) {
307
- setCodecStreams(format, { CompressionStream, DecompressionStream });
308
- }
309
- }
310
-
311
- function unregisterCodec(compressionMethod) {
312
- const codec = registeredCodecs.get(compressionMethod);
313
- if (codec) {
314
- registeredCodecs.delete(compressionMethod);
315
- let formatUsed;
316
- registeredCodecs.forEach(otherCodec => formatUsed = formatUsed || otherCodec.format == codec.format);
317
- if (!formatUsed) {
318
- codecStreams.delete(codec.format);
319
- }
320
- }
321
- }
322
-
323
- function getRegisteredCodec(compressionMethod) {
324
- return registeredCodecs.get(compressionMethod);
325
- }
326
-
327
- function getCodecStreams(format) {
328
- return codecStreams.get(format);
279
+ function concat(first, second) {
280
+ const result = new Uint8Array(first.length + second.length);
281
+ result.set(first);
282
+ result.set(second, first.length);
283
+ return result;
329
284
  }
330
285
 
331
- function setCodecStreams(format, streams) {
332
- const { CompressionStream, DecompressionStream } = streams;
333
- if (typeof CompressionStream != FUNCTION_TYPE && typeof DecompressionStream != FUNCTION_TYPE) {
334
- throw new Error(ERR_INVALID_CODEC_MODULE);
335
- }
336
- codecStreams.set(format, { CompressionStream, DecompressionStream });
286
+ function toExactUint8Array(array) {
287
+ return array.byteOffset || array.byteLength != array.buffer.byteLength ? new Uint8Array(array) : array;
337
288
  }
338
289
 
339
- async function ensureCodecStreams(format, codecURI) {
340
- if (!codecStreams.has(format) && codecURI) {
341
- setCodecStreams(format, await import(/* webpackIgnore: true */ /* @vite-ignore */ codecURI));
342
- }
290
+ function getDataView(array) {
291
+ return new DataView(array.buffer, array.byteOffset, array.byteLength);
343
292
  }
344
293
 
345
294
  /*
@@ -524,50 +473,6 @@
524
473
  }
525
474
  }
526
475
 
527
- /*
528
- Copyright (c) 2026 Gildas Lormeau. All rights reserved.
529
-
530
- Redistribution and use in source and binary forms, with or without
531
- modification, are permitted provided that the following conditions are met:
532
-
533
- 1. Redistributions of source code must retain the above copyright notice,
534
- this list of conditions and the following disclaimer.
535
-
536
- 2. Redistributions in binary form must reproduce the above copyright
537
- notice, this list of conditions and the following disclaimer in
538
- the documentation and/or other materials provided with the distribution.
539
-
540
- 3. The names of the authors may not be used to endorse or promote products
541
- derived from this software without specific prior written permission.
542
-
543
- THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
544
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
545
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
546
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
547
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
548
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
549
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
550
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
551
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
552
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
553
- */
554
-
555
-
556
- function concat(first, second) {
557
- const result = new Uint8Array(first.length + second.length);
558
- result.set(first);
559
- result.set(second, first.length);
560
- return result;
561
- }
562
-
563
- function toExactUint8Array(array) {
564
- return array.byteOffset || array.byteLength != array.buffer.byteLength ? new Uint8Array(array) : array;
565
- }
566
-
567
- function getDataView(array) {
568
- return new DataView(array.buffer, array.byteOffset, array.byteLength);
569
- }
570
-
571
476
  // Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
572
477
 
573
478
  // deno-lint-ignore-file no-this-alias
@@ -1937,6 +1842,102 @@
1937
1842
  });
1938
1843
  }
1939
1844
 
1845
+ /*
1846
+ Copyright (c) 2025 Gildas Lormeau. All rights reserved.
1847
+
1848
+ Redistribution and use in source and binary forms, with or without
1849
+ modification, are permitted provided that the following conditions are met:
1850
+
1851
+ 1. Redistributions of source code must retain the above copyright notice,
1852
+ this list of conditions and the following disclaimer.
1853
+
1854
+ 2. Redistributions in binary form must reproduce the above copyright
1855
+ notice, this list of conditions and the following disclaimer in
1856
+ the documentation and/or other materials provided with the distribution.
1857
+
1858
+ 3. The names of the authors may not be used to endorse or promote products
1859
+ derived from this software without specific prior written permission.
1860
+
1861
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
1862
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1863
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
1864
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
1865
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1866
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
1867
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1868
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1869
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
1870
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1871
+ */
1872
+
1873
+
1874
+ const ERR_INVALID_CODEC_DEFINITION = "Invalid codec definition";
1875
+ const ERR_RESERVED_COMPRESSION_METHOD = "Reserved compression method";
1876
+ const ERR_INVALID_CODEC_MODULE = "Invalid codec module";
1877
+
1878
+ const RESERVED_COMPRESSION_METHODS = [
1879
+ COMPRESSION_METHOD_STORE,
1880
+ COMPRESSION_METHOD_DEFLATE,
1881
+ COMPRESSION_METHOD_DEFLATE_64,
1882
+ COMPRESSION_METHOD_AES
1883
+ ];
1884
+
1885
+ const registeredCodecs = new Map();
1886
+ const codecStreams = new Map();
1887
+
1888
+ function registerCodec(codec = {}) {
1889
+ const { compressionMethod, format, codecURI, CompressionStream, DecompressionStream, versionNeeded } = codec;
1890
+ if (!Number.isInteger(compressionMethod) || compressionMethod < 0 || compressionMethod > MAX_16_BITS ||
1891
+ typeof format != STRING_TYPE || !format.length) {
1892
+ throw new Error(ERR_INVALID_CODEC_DEFINITION);
1893
+ }
1894
+ if (RESERVED_COMPRESSION_METHODS.includes(compressionMethod)) {
1895
+ throw new Error(ERR_RESERVED_COMPRESSION_METHOD);
1896
+ }
1897
+ const hasStreams = typeof CompressionStream == FUNCTION_TYPE || typeof DecompressionStream == FUNCTION_TYPE;
1898
+ if (!hasStreams && (typeof codecURI != STRING_TYPE || !codecURI.length)) {
1899
+ throw new Error(ERR_INVALID_CODEC_DEFINITION);
1900
+ }
1901
+ registeredCodecs.set(compressionMethod, { compressionMethod, format, codecURI, versionNeeded });
1902
+ if (hasStreams) {
1903
+ setCodecStreams(format, { CompressionStream, DecompressionStream });
1904
+ }
1905
+ }
1906
+
1907
+ function unregisterCodec(compressionMethod) {
1908
+ const codec = registeredCodecs.get(compressionMethod);
1909
+ if (codec) {
1910
+ registeredCodecs.delete(compressionMethod);
1911
+ let formatUsed;
1912
+ registeredCodecs.forEach(otherCodec => formatUsed = formatUsed || otherCodec.format == codec.format);
1913
+ if (!formatUsed) {
1914
+ codecStreams.delete(codec.format);
1915
+ }
1916
+ }
1917
+ }
1918
+
1919
+ function getRegisteredCodec(compressionMethod) {
1920
+ return registeredCodecs.get(compressionMethod);
1921
+ }
1922
+
1923
+ function getCodecStreams(format) {
1924
+ return codecStreams.get(format);
1925
+ }
1926
+
1927
+ function setCodecStreams(format, streams) {
1928
+ const { CompressionStream, DecompressionStream } = streams;
1929
+ if (typeof CompressionStream != FUNCTION_TYPE && typeof DecompressionStream != FUNCTION_TYPE) {
1930
+ throw new Error(ERR_INVALID_CODEC_MODULE);
1931
+ }
1932
+ codecStreams.set(format, { CompressionStream, DecompressionStream });
1933
+ }
1934
+
1935
+ async function ensureCodecStreams(format, codecURI) {
1936
+ if (!codecStreams.has(format) && codecURI) {
1937
+ setCodecStreams(format, await import(/* webpackIgnore: true */ /* @vite-ignore */ codecURI));
1938
+ }
1939
+ }
1940
+
1940
1941
  /*
1941
1942
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
1942
1943
 
@@ -2490,8 +2491,8 @@
2490
2491
  1. Redistributions of source code must retain the above copyright notice,
2491
2492
  this list of conditions and the following disclaimer.
2492
2493
 
2493
- 2. Redistributions in binary form must reproduce the above copyright
2494
- notice, this list of conditions and the following disclaimer in
2494
+ 2. Redistributions in binary form must reproduce the above copyright
2495
+ notice, this list of conditions and the following disclaimer in
2495
2496
  the documentation and/or other materials provided with the distribution.
2496
2497
 
2497
2498
  3. The names of the authors may not be used to endorse or promote products
@@ -2510,20 +2511,15 @@
2510
2511
  */
2511
2512
 
2512
2513
 
2513
- const MODULE_WORKER_OPTIONS = { type: "module" };
2514
- const ERROR_EVENT_TYPE = "error";
2515
- const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
2516
2514
  const ERR_WORKER_STARTUP_TIMEOUT = "Worker startup timeout";
2517
2515
 
2518
- let webWorkerSupported, webWorkerSource, webWorkerURI, webWorkerOptions, createWorkerFailed;
2519
- let transferStreamsSupported = true;
2520
- try {
2521
- transferStreamsSupported = typeof structuredClone == FUNCTION_TYPE && structuredClone(new DOMException("", "AbortError")).code !== UNDEFINED_VALUE;
2522
- } catch {
2523
- // ignored
2524
- }
2516
+ let webWorkerSupported, createWorkerFailed, webWorkerBackend;
2525
2517
  let initModule = () => { };
2526
2518
 
2519
+ function setWebWorkerBackend(backend) {
2520
+ webWorkerBackend = backend;
2521
+ }
2522
+
2527
2523
  async function supportsDeflate(config) {
2528
2524
  const { CompressionStream: NativeStream, CompressionStreamFallback: FallbackStream } = config;
2529
2525
  if (FallbackStream && !FallbackStream.requiresModule) {
@@ -2548,6 +2544,14 @@
2548
2544
  createWorkerFailed = false;
2549
2545
  }
2550
2546
 
2547
+ function disableWebWorker(workerData) {
2548
+ if (workerData.createWorker) {
2549
+ createWorkerFailed = true;
2550
+ } else {
2551
+ webWorkerSupported = false;
2552
+ }
2553
+ }
2554
+
2551
2555
  class CodecWorker {
2552
2556
 
2553
2557
  constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI, createWorker }, onTaskFinished) {
@@ -2600,7 +2604,7 @@
2600
2604
  // deno-lint-ignore valid-typeof
2601
2605
  webWorkerSupported = typeof Worker != UNDEFINED_TYPE;
2602
2606
  }
2603
- return (useWebWorkers && ((webWorkerSupported && workerURI) || createWorker) ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
2607
+ return (useWebWorkers && webWorkerBackend && ((webWorkerSupported && workerURI) || createWorker) ? webWorkerBackend : createWorkerInterface)(workerData, config);
2604
2608
  }
2605
2609
  }
2606
2610
 
@@ -2644,58 +2648,6 @@
2644
2648
  };
2645
2649
  }
2646
2650
 
2647
- function createWebWorkerInterface(workerData, config) {
2648
- const { baseURI, chunkSize, workerStartupTimeout } = config;
2649
- let { wasmURI } = config;
2650
-
2651
- if (!workerData.interface) {
2652
- // deno-lint-ignore valid-typeof
2653
- if (typeof wasmURI == FUNCTION_TYPE) {
2654
- wasmURI = wasmURI();
2655
- }
2656
- let worker;
2657
- try {
2658
- worker = getWebWorker(workerData.workerURI, baseURI, workerData);
2659
- } catch {
2660
- if (workerData.createWorker) {
2661
- createWorkerFailed = true;
2662
- } else {
2663
- webWorkerSupported = false;
2664
- }
2665
- return createWorkerInterface(workerData, config);
2666
- }
2667
- Object.assign(workerData, {
2668
- worker,
2669
- workerAlive: false,
2670
- terminated: false,
2671
- interface: {
2672
- run: async () => {
2673
- try {
2674
- return await runWebWorker(workerData, { chunkSize, wasmURI, baseURI, workerStartupTimeout });
2675
- } catch (error) {
2676
- if (error && error.workerStartupFailed) {
2677
- if (workerData.createWorker) {
2678
- createWorkerFailed = true;
2679
- } else {
2680
- webWorkerSupported = false;
2681
- }
2682
- const { reader } = workerData;
2683
- if (reader) {
2684
- reader.releaseLock();
2685
- }
2686
- workerData.reader = null;
2687
- workerData.writer = null;
2688
- return runWorker$1(workerData, config);
2689
- }
2690
- throw error;
2691
- }
2692
- }
2693
- }
2694
- });
2695
- }
2696
- return workerData.interface;
2697
- }
2698
-
2699
2651
  async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
2700
2652
  let codecStream;
2701
2653
  try {
@@ -2744,6 +2696,95 @@
2744
2696
  }
2745
2697
  }
2746
2698
 
2699
+ /*
2700
+ Copyright (c) 2025 Gildas Lormeau. All rights reserved.
2701
+
2702
+ Redistribution and use in source and binary forms, with or without
2703
+ modification, are permitted provided that the following conditions are met:
2704
+
2705
+ 1. Redistributions of source code must retain the above copyright notice,
2706
+ this list of conditions and the following disclaimer.
2707
+
2708
+ 2. Redistributions in binary form must reproduce the above copyright
2709
+ notice, this list of conditions and the following disclaimer in
2710
+ the documentation and/or other materials provided with the distribution.
2711
+
2712
+ 3. The names of the authors may not be used to endorse or promote products
2713
+ derived from this software without specific prior written permission.
2714
+
2715
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
2716
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
2717
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
2718
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
2719
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2720
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
2721
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2722
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2723
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
2724
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2725
+ */
2726
+
2727
+
2728
+ const MODULE_WORKER_OPTIONS = { type: "module" };
2729
+ const ERROR_EVENT_TYPE = "error";
2730
+ const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
2731
+
2732
+ let webWorkerSource, webWorkerURI, webWorkerOptions;
2733
+ let transferStreamsSupported = true;
2734
+ try {
2735
+ transferStreamsSupported = typeof structuredClone == FUNCTION_TYPE && structuredClone(new DOMException("", "AbortError")).code !== UNDEFINED_VALUE;
2736
+ } catch {
2737
+ // ignored
2738
+ }
2739
+
2740
+ setWebWorkerBackend(createWebWorkerInterface);
2741
+
2742
+ function createWebWorkerInterface(workerData, config) {
2743
+ const { baseURI, chunkSize, workerStartupTimeout } = config;
2744
+ let { wasmURI } = config;
2745
+
2746
+ if (!workerData.interface) {
2747
+ // deno-lint-ignore valid-typeof
2748
+ if (typeof wasmURI == FUNCTION_TYPE) {
2749
+ wasmURI = wasmURI();
2750
+ }
2751
+ let worker;
2752
+ try {
2753
+ worker = getWebWorker(workerData.workerURI, baseURI, workerData);
2754
+ } catch {
2755
+ disableWebWorker(workerData);
2756
+ return createWorkerInterface(workerData, config);
2757
+ }
2758
+ Object.assign(workerData, {
2759
+ worker,
2760
+ workerAlive: false,
2761
+ terminated: false,
2762
+ interface: {
2763
+ run: async () => {
2764
+ try {
2765
+ return await runWebWorker(workerData, { chunkSize, wasmURI, baseURI, workerStartupTimeout });
2766
+ } catch (error) {
2767
+ if (error && error.workerStartupFailed) {
2768
+ disableWebWorker(workerData);
2769
+ releaseWorkerStreams(workerData);
2770
+ return runWorker$1(workerData, config);
2771
+ }
2772
+ if (error && error.codecImportFailed) {
2773
+ if (workerData.reader) {
2774
+ releaseWorkerStreams(workerData);
2775
+ return runWorker$1(workerData, config);
2776
+ }
2777
+ workerData.onTaskFinished();
2778
+ }
2779
+ throw error;
2780
+ }
2781
+ }
2782
+ }
2783
+ });
2784
+ }
2785
+ return workerData.interface;
2786
+ }
2787
+
2747
2788
  async function runWebWorker(workerData, config) {
2748
2789
  let resolveResult, rejectResult;
2749
2790
  const result = new Promise((resolve, reject) => {
@@ -2823,6 +2864,15 @@
2823
2864
  return { writable, closed, abortPipe: () => abortController.abort() };
2824
2865
  }
2825
2866
 
2867
+ function releaseWorkerStreams(workerData) {
2868
+ const { reader } = workerData;
2869
+ if (reader) {
2870
+ reader.releaseLock();
2871
+ }
2872
+ workerData.reader = null;
2873
+ workerData.writer = null;
2874
+ }
2875
+
2826
2876
  function terminateWorker$1(workerData) {
2827
2877
  const { worker } = workerData;
2828
2878
  if (worker) {
@@ -2890,7 +2940,7 @@
2890
2940
  try {
2891
2941
  worker = new Worker(resolvedURI, resolvedOptions);
2892
2942
  } catch (error) {
2893
- if (!isModuleType) {
2943
+ if (isModuleType) {
2894
2944
  return getWebWorker(url, baseURI, workerData, false, useBlobURI);
2895
2945
  } else {
2896
2946
  throw error;
@@ -3008,12 +3058,15 @@
3008
3058
  const stale = () => workerData.generation != generation;
3009
3059
  try {
3010
3060
  if (error) {
3011
- const { message, stack, code, name, outputSize, cause } = error;
3061
+ const { message, stack, code, name, outputSize, cause, codecImportFailed } = error;
3012
3062
  const responseError = new Error(message);
3013
3063
  Object.assign(responseError, { stack, code, name, outputSize });
3014
3064
  if (cause) {
3015
3065
  responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3016
3066
  }
3067
+ if (codecImportFailed) {
3068
+ responseError.codecImportFailed = true;
3069
+ }
3017
3070
  close(responseError);
3018
3071
  } else {
3019
3072
  if (type == MESSAGE_PULL) {
@@ -3052,7 +3105,9 @@
3052
3105
  if (writer) {
3053
3106
  writer.releaseLock();
3054
3107
  }
3055
- onTaskFinished();
3108
+ if (!(error && error.codecImportFailed)) {
3109
+ onTaskFinished();
3110
+ }
3056
3111
  }
3057
3112
  }
3058
3113
 
@@ -3102,7 +3157,7 @@
3102
3157
  }
3103
3158
  await ensureCodecStreams(format, options.codecURI);
3104
3159
  }
3105
- workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
3160
+ workerOptions.transferStreams = !format && (transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams));
3106
3161
  const streamCopy = !compressed && !checkCrc32 && !computeCrc32 && !encrypted;
3107
3162
  const workerSupported = format === UNDEFINED_VALUE || Boolean(options.codecURI);
3108
3163
  workerOptions.useWebWorkers = !streamCopy && workerSupported && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
@@ -3606,7 +3661,7 @@
3606
3661
  forceRangeRequests,
3607
3662
  combineSizeEocd
3608
3663
  } = httpReader;
3609
- if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == "undefined" || preventHeadRequest)) {
3664
+ if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
3610
3665
  const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -END_OF_CENTRAL_DIR_LENGTH : undefined));
3611
3666
  const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
3612
3667
  if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
@@ -4459,9 +4514,13 @@
4459
4514
  const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
4460
4515
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
4461
4516
  const OPTION_STRICTNESS = "strictness";
4517
+ const OPTION_FILENAME_VALIDATION = "filenameValidation";
4518
+ const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
4462
4519
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
4463
4520
  const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
4464
4521
  const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
4522
+ const TEXT_TYPE_FILENAME = "filename";
4523
+ const TEXT_TYPE_COMMENT = "comment";
4465
4524
  const STRICTNESS_STRICT = "strict";
4466
4525
  const STRICTNESS_BALANCED = "balanced";
4467
4526
  const STRICTNESS_TOLERANT = "tolerant";
@@ -4508,6 +4567,11 @@
4508
4567
  const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
4509
4568
  const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
4510
4569
  const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
4570
+ const ERR_UNSAFE_FILENAME = "Unsafe filename";
4571
+ const ERR_INVALID_STRICTNESS = "Invalid strictness (must be 'strict', 'balanced' or 'tolerant')";
4572
+ const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
4573
+ const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
4574
+ const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
4511
4575
  const CHARSET_UTF8 = "utf-8";
4512
4576
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
4513
4577
  const CHARSET_CP437 = "cp437";
@@ -4529,6 +4593,10 @@
4529
4593
  bytes: 8
4530
4594
  }
4531
4595
  };
4596
+ const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
4597
+ const CENTRAL_DIRECTORY_UNREACHABLE = 0;
4598
+ const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
4599
+ const CENTRAL_DIRECTORY_REACHABLE = 2;
4532
4600
 
4533
4601
  class ZipReader {
4534
4602
 
@@ -4557,6 +4625,8 @@
4557
4625
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4558
4626
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
4559
4627
  const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
4628
+ const filenameValidation = getFilenameValidation(getOptionValue$1(zipReader, options, OPTION_FILENAME_VALIDATION), strictness);
4629
+ const normalizeFilename = getOptionValue$1(zipReader, options, OPTION_NORMALIZE_FILENAME);
4560
4630
  const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
4561
4631
  if (!endOfDirectoryInfo) {
4562
4632
  const signatureArray = await readUint8Array(reader, 0, 4);
@@ -4750,11 +4820,22 @@
4750
4820
  const decode = getOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
4751
4821
  const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
4752
4822
  const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
4753
- let filename = decode(rawFilename, rawFilenameEncoding);
4823
+ let filename = decode(rawFilename, rawFilenameEncoding, TEXT_TYPE_FILENAME);
4754
4824
  if (filename === UNDEFINED_VALUE) {
4755
4825
  filename = decodeText(rawFilename, rawFilenameEncoding);
4756
4826
  }
4757
- let comment = decode(rawComment, rawCommentEncoding);
4827
+ if (normalizeFilename) {
4828
+ const normalizedFilename = normalizeFilename(filename);
4829
+ if (normalizedFilename !== UNDEFINED_VALUE) {
4830
+ filename = normalizedFilename;
4831
+ }
4832
+ }
4833
+ if (isUnsafeFilename(filename, filenameValidation)) {
4834
+ const error = new Error(ERR_UNSAFE_FILENAME);
4835
+ error.filename = filename;
4836
+ throw error;
4837
+ }
4838
+ let comment = decode(rawComment, rawCommentEncoding, TEXT_TYPE_COMMENT);
4758
4839
  if (comment === UNDEFINED_VALUE) {
4759
4840
  comment = decodeText(rawComment, rawCommentEncoding);
4760
4841
  }
@@ -4815,10 +4896,10 @@
4815
4896
  entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader.readRanges, options);
4816
4897
  entry.arrayBuffer = async options => {
4817
4898
  const writer = new TransformStream();
4818
- const [arrayBuffer] = await Promise.all([
4819
- streamToBlob(writer.readable).then(blob => blob.arrayBuffer()),
4820
- fileEntry.getData(writer, entry, zipReader.readRanges, options)]);
4821
- return arrayBuffer;
4899
+ const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
4900
+ arrayBufferPromise.catch(() => { });
4901
+ await fileEntry.getData(writer, entry, zipReader.readRanges, options);
4902
+ return arrayBufferPromise;
4822
4903
  };
4823
4904
  offset = endOffset;
4824
4905
  const { onprogress } = options;
@@ -5069,7 +5150,7 @@
5069
5150
  readRanges
5070
5151
  });
5071
5152
  }
5072
- let writable;
5153
+ let writable, abortError;
5073
5154
  try {
5074
5155
  if (!checkOverlappingEntryOnly) {
5075
5156
  if (checkPasswordOnly) {
@@ -5089,12 +5170,22 @@
5089
5170
  writer.size += error.outputSize;
5090
5171
  }
5091
5172
  if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) {
5173
+ abortError = error;
5092
5174
  throw error;
5093
5175
  }
5094
5176
  } finally {
5095
5177
  const preventClose = getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
5096
5178
  if (!preventClose && writable && !writable.locked) {
5097
- await writable.getWriter().close();
5179
+ const writableWriter = writable.getWriter();
5180
+ if (abortError) {
5181
+ try {
5182
+ await writableWriter.abort(abortError);
5183
+ } catch {
5184
+ // the error being propagated is more relevant; ignored
5185
+ }
5186
+ } else {
5187
+ await writableWriter.close();
5188
+ }
5098
5189
  }
5099
5190
  }
5100
5191
  return checkPasswordOnly || checkOverlappingEntryOnly ? UNDEFINED_VALUE : writer.getData ? writer.getData() : writable;
@@ -5474,16 +5565,51 @@
5474
5565
  return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
5475
5566
  }
5476
5567
 
5568
+ function isStrictnessValue(value) {
5569
+ return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
5570
+ }
5571
+
5477
5572
  function getStrictness(strictness, checkAmbiguity) {
5478
5573
  if (strictness === UNDEFINED_VALUE) {
5479
5574
  return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
5480
5575
  }
5576
+ if (!isStrictnessValue(strictness)) {
5577
+ throw new Error(ERR_INVALID_STRICTNESS);
5578
+ }
5481
5579
  return strictness;
5482
5580
  }
5483
5581
 
5582
+ function getFilenameValidation(filenameValidation, strictness) {
5583
+ if (filenameValidation === UNDEFINED_VALUE) {
5584
+ return strictness;
5585
+ }
5586
+ if (!isStrictnessValue(filenameValidation)) {
5587
+ throw new Error(ERR_INVALID_FILENAME_VALIDATION);
5588
+ }
5589
+ return filenameValidation;
5590
+ }
5591
+
5592
+ function isUnsafeFilename(filename, filenameValidation) {
5593
+ if (filenameValidation == STRICTNESS_TOLERANT) {
5594
+ return false;
5595
+ }
5596
+ const pathParts = filename.split("/");
5597
+ if (pathParts.length > 1 && pathParts[pathParts.length - 1] === "") {
5598
+ pathParts.pop();
5599
+ }
5600
+ if (pathParts.includes("..") || filename.startsWith("/") || filename.startsWith("\\\\") || DRIVE_LETTER_REGEXP.test(filename)) {
5601
+ return true;
5602
+ }
5603
+ return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes(""));
5604
+ }
5605
+
5484
5606
  function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
5485
5607
  if (maxAppendedDataSize !== UNDEFINED_VALUE) {
5486
- return maxAppendedDataSize;
5608
+ const size = toNumber$1(maxAppendedDataSize);
5609
+ if (typeof size != NUMBER_TYPE || Number.isNaN(size) || size < 0) {
5610
+ throw new Error(ERR_INVALID_MAX_APPENDED_DATA_SIZE);
5611
+ }
5612
+ return size;
5487
5613
  }
5488
5614
  if (strictness == STRICTNESS_STRICT) {
5489
5615
  return 0;
@@ -5494,12 +5620,6 @@
5494
5620
  return MAX_16_BITS;
5495
5621
  }
5496
5622
 
5497
- const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
5498
-
5499
- const CENTRAL_DIRECTORY_UNREACHABLE = 0;
5500
- const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
5501
- const CENTRAL_DIRECTORY_REACHABLE = 2;
5502
-
5503
5623
  async function findEndOfCentralDirectory(reader, rejectAmbiguous, maxAppendedDataSize) {
5504
5624
  const { size } = reader;
5505
5625
  const anchoredLength = Math.min(size, END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS);
@@ -5635,6 +5755,10 @@
5635
5755
  return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
5636
5756
  }
5637
5757
 
5758
+ function toNumber$1(value) {
5759
+ return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
5760
+ }
5761
+
5638
5762
  function getDate(timeRaw) {
5639
5763
  const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
5640
5764
  return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
@@ -5673,12 +5797,16 @@
5673
5797
  ERR_INVALID_AUTHENTICATION_CODE: ERR_INVALID_AUTHENTICATION_CODE,
5674
5798
  ERR_INVALID_COMPRESSED_DATA: ERR_INVALID_COMPRESSED_DATA,
5675
5799
  ERR_INVALID_CRC32: ERR_INVALID_CRC32,
5800
+ ERR_INVALID_FILENAME_VALIDATION: ERR_INVALID_FILENAME_VALIDATION,
5801
+ ERR_INVALID_MAX_APPENDED_DATA_SIZE: ERR_INVALID_MAX_APPENDED_DATA_SIZE,
5676
5802
  ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
5677
5803
  ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
5804
+ ERR_INVALID_STRICTNESS: ERR_INVALID_STRICTNESS,
5678
5805
  ERR_INVALID_UNCOMPRESSED_SIZE: ERR_INVALID_UNCOMPRESSED_SIZE,
5679
5806
  ERR_LOCAL_FILE_HEADER_NOT_FOUND: ERR_LOCAL_FILE_HEADER_NOT_FOUND,
5680
5807
  ERR_OVERLAPPING_ENTRY: ERR_OVERLAPPING_ENTRY,
5681
5808
  ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
5809
+ ERR_UNSAFE_FILENAME: ERR_UNSAFE_FILENAME,
5682
5810
  ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
5683
5811
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
5684
5812
  ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
@@ -5740,6 +5868,8 @@
5740
5868
  const ERR_INVALID_UNIX_ID_SIZE = "uid/gid must be 0..65535 for unixExtraFieldType 'unix' (use 'infozip' for larger ids)";
5741
5869
  const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
5742
5870
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
5871
+ const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
5872
+ const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
5743
5873
  const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
5744
5874
 
5745
5875
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
@@ -5747,6 +5877,7 @@
5747
5877
  const VENDOR_VERSION_AE_1 = 1;
5748
5878
  const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
5749
5879
  const UNIX_EXTRA_FIELD_TYPE = "unix";
5880
+ const MAX_LEVEL = 9;
5750
5881
 
5751
5882
  let workers = 0;
5752
5883
  const pendingEntries = [];
@@ -5909,7 +6040,8 @@
5909
6040
 
5910
6041
  remove(entry) {
5911
6042
  const { filenames, files } = this;
5912
- if (typeof entry == "string") {
6043
+ // deno-lint-ignore valid-typeof
6044
+ if (typeof entry == STRING_TYPE) {
5913
6045
  entry = files.get(entry);
5914
6046
  }
5915
6047
  if (entry && entry.filename !== UNDEFINED_VALUE) {
@@ -6047,20 +6179,20 @@
6047
6179
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6048
6180
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
6049
6181
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
6050
- const uid = getOptionValue(zipWriter, options, PROPERTY_NAME_UID);
6051
- const gid = getOptionValue(zipWriter, options, PROPERTY_NAME_GID);
6052
- let unixMode = getOptionValue(zipWriter, options, PROPERTY_NAME_UNIX_MODE);
6182
+ const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
6183
+ const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
6184
+ let unixMode = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UNIX_MODE);
6053
6185
  let unixExtraFieldType = getOptionValue(zipWriter, options, OPTION_UNIX_EXTRA_FIELD_TYPE);
6054
6186
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
6055
6187
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
6056
6188
  let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
6057
- if (uid !== UNDEFINED_VALUE && (uid < 0 || uid > MAX_32_BITS)) {
6189
+ if (uid !== UNDEFINED_VALUE && (!Number.isInteger(uid) || uid < 0 || uid > MAX_32_BITS)) {
6058
6190
  throw new Error(ERR_INVALID_UID);
6059
6191
  }
6060
- if (gid !== UNDEFINED_VALUE && (gid < 0 || gid > MAX_32_BITS)) {
6192
+ if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
6061
6193
  throw new Error(ERR_INVALID_GID);
6062
6194
  }
6063
- if (unixMode !== UNDEFINED_VALUE && (unixMode < 0 || unixMode > MAX_16_BITS)) {
6195
+ if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
6064
6196
  throw new Error(ERR_INVALID_UNIX_MODE);
6065
6197
  }
6066
6198
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
@@ -6172,7 +6304,7 @@
6172
6304
 
6173
6305
  function resolveMetadata(zipWriter, name, options) {
6174
6306
  const encode = getOptionValue(zipWriter, options, OPTION_ENCODE_TEXT, encodeText);
6175
- let rawFilename = encode(name);
6307
+ let rawFilename = encode(name, TEXT_TYPE_FILENAME);
6176
6308
  if (rawFilename === UNDEFINED_VALUE) {
6177
6309
  rawFilename = encodeText(name);
6178
6310
  }
@@ -6180,7 +6312,7 @@
6180
6312
  throw new Error(ERR_INVALID_ENTRY_NAME);
6181
6313
  }
6182
6314
  const comment = options[PROPERTY_NAME_COMMENT] || "";
6183
- let rawComment = encode(comment);
6315
+ let rawComment = encode(comment, TEXT_TYPE_COMMENT);
6184
6316
  if (rawComment === UNDEFINED_VALUE) {
6185
6317
  rawComment = encodeText(comment);
6186
6318
  }
@@ -6200,8 +6332,11 @@
6200
6332
  if (!passThrough) {
6201
6333
  password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
6202
6334
  rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
6335
+ if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
6336
+ throw new Error(ERR_INVALID_PASSWORD_TYPE);
6337
+ }
6203
6338
  }
6204
- const encryptionStrength = getOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
6339
+ const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
6205
6340
  const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
6206
6341
  const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
6207
6342
  const ntfsTimestamp = getOptionValue(zipWriter, options, OPTION_NTFS_TIMESTAMP);
@@ -6219,7 +6354,10 @@
6219
6354
  compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
6220
6355
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6221
6356
  }
6222
- let level = getOptionValue(zipWriter, options, OPTION_LEVEL);
6357
+ let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
6358
+ if (level !== UNDEFINED_VALUE && (!Number.isInteger(level) || level < 0 || level > MAX_LEVEL)) {
6359
+ throw new Error(ERR_INVALID_LEVEL);
6360
+ }
6223
6361
  if (zipWriter.options[OPTION_USDZ]) {
6224
6362
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
6225
6363
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -6240,7 +6378,7 @@
6240
6378
  useCompressionStream = false;
6241
6379
  }
6242
6380
  const zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
6243
- if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(encryptionStrength >= 1 && encryptionStrength <= 3)) {
6381
+ if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(Number.isInteger(encryptionStrength) && encryptionStrength >= 1 && encryptionStrength <= 3)) {
6244
6382
  throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
6245
6383
  }
6246
6384
  const rawExtraField = serializeExtraField(options[PROPERTY_NAME_EXTRA_FIELD]);
@@ -7434,6 +7572,14 @@
7434
7572
  return result === UNDEFINED_VALUE ? defaultValue : result;
7435
7573
  }
7436
7574
 
7575
+ function getNumberOptionValue(zipWriter, options, name, defaultValue) {
7576
+ return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
7577
+ }
7578
+
7579
+ function toNumber(value) {
7580
+ return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
7581
+ }
7582
+
7437
7583
  function getMaximumCompressedSize(uncompressedSize) {
7438
7584
  return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
7439
7585
  }
@@ -8043,12 +8189,17 @@
8043
8189
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
8044
8190
  exports.ERR_INVALID_EXTRAFIELD_DATA = ERR_INVALID_EXTRAFIELD_DATA;
8045
8191
  exports.ERR_INVALID_EXTRAFIELD_TYPE = ERR_INVALID_EXTRAFIELD_TYPE;
8192
+ exports.ERR_INVALID_FILENAME_VALIDATION = ERR_INVALID_FILENAME_VALIDATION;
8046
8193
  exports.ERR_INVALID_GID = ERR_INVALID_GID;
8194
+ exports.ERR_INVALID_LEVEL = ERR_INVALID_LEVEL;
8195
+ exports.ERR_INVALID_MAX_APPENDED_DATA_SIZE = ERR_INVALID_MAX_APPENDED_DATA_SIZE;
8047
8196
  exports.ERR_INVALID_MSDOS_ATTRIBUTES = ERR_INVALID_MSDOS_ATTRIBUTES;
8048
8197
  exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
8049
8198
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
8199
+ exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
8050
8200
  exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
8051
8201
  exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
8202
+ exports.ERR_INVALID_STRICTNESS = ERR_INVALID_STRICTNESS;
8052
8203
  exports.ERR_INVALID_UID = ERR_INVALID_UID;
8053
8204
  exports.ERR_INVALID_UNCOMPRESSED_SIZE = ERR_INVALID_UNCOMPRESSED_SIZE;
8054
8205
  exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
@@ -8062,6 +8213,7 @@
8062
8213
  exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
8063
8214
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
8064
8215
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
8216
+ exports.ERR_UNSAFE_FILENAME = ERR_UNSAFE_FILENAME;
8065
8217
  exports.ERR_UNSUPPORTED_COMPRESSION = ERR_UNSUPPORTED_COMPRESSION$1;
8066
8218
  exports.ERR_UNSUPPORTED_CONTEXT = ERR_UNSUPPORTED_CONTEXT;
8067
8219
  exports.ERR_UNSUPPORTED_CRYPTO_API = ERR_UNSUPPORTED_CRYPTO_API;