@zip.js/zip.js 2.16.1 → 2.17.0

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 (45) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +169 -119
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +138 -106
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +181 -121
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +150 -108
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +181 -121
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +153 -111
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +182 -121
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +140 -108
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +141 -109
  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 +170 -119
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +153 -111
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +182 -121
  27. package/index.d.cts +58 -20
  28. package/index.d.ts +58 -20
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-pool.js +2 -0
  31. package/lib/core/codec-worker-web.js +11 -3
  32. package/lib/core/codec-worker.js +2 -1
  33. package/lib/core/streams/codec-stream.js +2 -0
  34. package/lib/core/streams/zip-entry-stream.js +123 -102
  35. package/lib/core/streams/zlib-js/zlib-streams.min.js +1 -1
  36. package/lib/core/streams/zlib-wasm/zlib-streams.js +31 -12
  37. package/lib/core/version.js +1 -1
  38. package/lib/core/web-worker-base.js +1 -1
  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 +16 -3
  42. package/lib/core/zip-reader.js +3 -0
  43. package/lib/core/zip-writer.js +1 -0
  44. package/lib/zip-core-reader.js +1 -0
  45. package/package.json +1 -1
@@ -1931,7 +1931,9 @@ async function ensureCodecStreams(format, codecURI) {
1931
1931
 
1932
1932
  const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
1933
1933
  const ERR_INVALID_COMPRESSED_DATA = "Invalid compressed data";
1934
+ const ERR_CODEC_OUT_OF_MEMORY = "Codec out of memory";
1934
1935
  const ERR_INVALID_CRC32 = "Invalid CRC32";
1936
+ const Z_MEM_ERROR_CODE$1 = "Z_MEM_ERROR";
1935
1937
  const FORMAT_DEFLATE_RAW$1 = "deflate-raw";
1936
1938
  const FORMAT_DEFLATE64_RAW$1 = "deflate64-raw";
1937
1939
  const FORMAT_GZIP$1 = "gzip";
@@ -1966,13 +1968,13 @@ class DeflateStream extends TransformStream {
1966
1968
  readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamFallback);
1967
1969
  } catch (error) {
1968
1970
  if (!useCompressionStream && CompressionStreamFallback) {
1969
- throw error;
1971
+ throw mapMemoryError(error);
1970
1972
  }
1971
1973
  let gzipStream;
1972
1974
  try {
1973
1975
  gzipStream = new CompressionStream(FORMAT_GZIP$1);
1974
1976
  } catch {
1975
- throw error;
1977
+ throw mapMemoryError(error);
1976
1978
  }
1977
1979
  readable = pipeThroughBackpressured(readable, gzipStream);
1978
1980
  readable = pipeThrough(readable, new GzipToRawDeflateStream());
@@ -2036,50 +2038,30 @@ class GzipToRawDeflateStream extends TransformStream {
2036
2038
  }
2037
2039
  }
2038
2040
 
2039
- function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32) {
2041
+ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32, sourceErrors) {
2040
2042
  const writer = gzipStream.writable.getWriter();
2041
2043
  const reader = gzipStream.readable.getReader();
2042
2044
  const outputCrc32 = crc32 === UNDEFINED_VALUE ? new Crc32() : UNDEFINED_VALUE;
2043
2045
  let outputLength = 0;
2044
- let inputDone = false;
2045
2046
  let trailerWritten = false;
2046
- let idleCheckArmed = false;
2047
- let readCount = 0;
2048
- let readPending = false;
2049
- let resolveTrailerReady, rejectTrailerReady;
2050
- const trailerReady = new Promise((resolve, reject) => {
2051
- resolveTrailerReady = resolve;
2052
- rejectTrailerReady = reject;
2053
- });
2054
- trailerReady.catch(() => { });
2055
- pump();
2056
- return new ReadableStream({
2057
- async pull(controller) {
2058
- try {
2059
- const { value, done } = await read();
2060
- if (done) {
2061
- controller.close();
2062
- } else {
2063
- outputLength += value.length;
2064
- if (outputLength > outputSize) {
2065
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
2066
- }
2067
- if (outputCrc32) {
2068
- outputCrc32.append(value);
2069
- }
2070
- controller.enqueue(value);
2071
- }
2072
- } catch (error) {
2073
- rejectTrailerReady(error);
2074
- await cancel(reader, error);
2075
- throw trailerWritten ? getTrailerError(error) : error;
2076
- }
2047
+ let settled = false;
2048
+ let resolvePull, controller;
2049
+ const output = new ReadableStream({
2050
+ start(streamController) {
2051
+ controller = streamController;
2052
+ },
2053
+ pull() {
2054
+ resumePump();
2077
2055
  },
2078
2056
  cancel(reason) {
2079
- rejectTrailerReady(reason);
2057
+ settled = true;
2058
+ resumePump();
2080
2059
  return reader.cancel(reason);
2081
2060
  }
2082
2061
  });
2062
+ pump();
2063
+ drain();
2064
+ return output;
2083
2065
 
2084
2066
  async function pump() {
2085
2067
  const inputReader = readable.getReader();
@@ -2088,19 +2070,16 @@ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, cr
2088
2070
  header.set(GZIP_HEADER_BYTES);
2089
2071
  await writer.write(header);
2090
2072
  for (; ;) {
2073
+ await outputCapacity();
2091
2074
  await writer.ready;
2092
- const { value, done } = await inputReader.read();
2075
+ const { value, done } = await readSource(inputReader, sourceErrors);
2093
2076
  if (done) {
2094
2077
  break;
2095
2078
  }
2096
2079
  await writer.write(value);
2097
2080
  }
2098
- inputDone = true;
2099
2081
  if (outputCrc32) {
2100
- if (readPending) {
2101
- armIdleCheck();
2102
- }
2103
- await trailerReady;
2082
+ await writer.write(new Uint8Array(0));
2104
2083
  }
2105
2084
  const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
2106
2085
  const dataView = getDataView(trailer);
@@ -2115,54 +2094,68 @@ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, cr
2115
2094
  }
2116
2095
  }
2117
2096
 
2118
- function read() {
2119
- readCount++;
2120
- readPending = true;
2121
- const result = reader.read();
2122
- result.then(onReadSettled, onReadSettled);
2123
- if (inputDone && outputCrc32) {
2124
- armIdleCheck();
2097
+ async function drain() {
2098
+ try {
2099
+ for (; ;) {
2100
+ const { value, done } = await read();
2101
+ if (done) {
2102
+ break;
2103
+ }
2104
+ outputLength += value.length;
2105
+ if (outputLength > outputSize) {
2106
+ throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
2107
+ }
2108
+ if (outputCrc32) {
2109
+ outputCrc32.append(value);
2110
+ }
2111
+ controller.enqueue(value);
2112
+ }
2113
+ if (!settled) {
2114
+ settled = true;
2115
+ controller.close();
2116
+ }
2117
+ } catch (error) {
2118
+ fail(error);
2119
+ await cancel(reader, error);
2125
2120
  }
2126
- return result;
2127
2121
  }
2128
2122
 
2129
- function onReadSettled() {
2130
- readPending = false;
2131
- }
2132
-
2133
- async function armIdleCheck() {
2134
- if (!idleCheckArmed) {
2135
- idleCheckArmed = true;
2136
- const count = readCount;
2137
- await nextTask();
2138
- idleCheckArmed = false;
2139
- if (readPending) {
2140
- if (readCount == count) {
2141
- resolveTrailerReady();
2142
- } else {
2143
- armIdleCheck();
2123
+ function read() {
2124
+ return reader.read().catch(error => {
2125
+ if (trailerWritten) {
2126
+ if (!outputCrc32) {
2127
+ throw mapError(error, ERR_INVALID_CRC32);
2128
+ }
2129
+ if (outputLength != outputSize) {
2130
+ throw mapError(error, ERR_INVALID_UNCOMPRESSED_SIZE);
2144
2131
  }
2132
+ return { done: true };
2145
2133
  }
2146
- }
2134
+ throw mapCodecError(error, sourceErrors);
2135
+ });
2147
2136
  }
2148
2137
 
2149
- function getTrailerError(error) {
2150
- const trailerError = new Error(outputLength == outputSize ? ERR_INVALID_CRC32 : ERR_INVALID_UNCOMPRESSED_SIZE);
2151
- trailerError.cause = error;
2152
- return trailerError;
2138
+ function outputCapacity() {
2139
+ if (!settled && controller.desiredSize <= 0) {
2140
+ return new Promise(resolve => resolvePull = resolve);
2141
+ }
2153
2142
  }
2154
- }
2155
2143
 
2156
- function nextTask() {
2157
- return new Promise(resolve => {
2158
- const { port1, port2 } = new MessageChannel();
2159
- port2.onmessage = () => {
2160
- port1.close();
2161
- port2.close();
2144
+ function resumePump() {
2145
+ if (resolvePull) {
2146
+ const resolve = resolvePull;
2147
+ resolvePull = UNDEFINED_VALUE;
2162
2148
  resolve();
2163
- };
2164
- port1.postMessage(UNDEFINED_VALUE);
2165
- });
2149
+ }
2150
+ }
2151
+
2152
+ function fail(error) {
2153
+ if (!settled) {
2154
+ settled = true;
2155
+ controller.error(error);
2156
+ resumePump();
2157
+ }
2158
+ }
2166
2159
  }
2167
2160
 
2168
2161
  class InflateStream extends TransformStream {
@@ -2181,11 +2174,12 @@ class InflateStream extends TransformStream {
2181
2174
  }
2182
2175
  }
2183
2176
  if (compressed) {
2177
+ const sourceErrors = new Set();
2184
2178
  const codecStreams = format && getCodecStreams(format);
2179
+ let gzipStream;
2185
2180
  if (codecStreams) {
2186
- readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }));
2181
+ readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }), sourceErrors);
2187
2182
  } else {
2188
- let gzipStream;
2189
2183
  const GzipDecompressionStream = getGzipCodecStream(useCompressionStream, DecompressionStream, DecompressionStreamFallback);
2190
2184
  if (checkCrc32 && !deflate64 && crc32 !== UNDEFINED_VALUE && outputSize !== UNDEFINED_VALUE && GzipDecompressionStream) {
2191
2185
  try {
@@ -2196,24 +2190,25 @@ class InflateStream extends TransformStream {
2196
2190
  }
2197
2191
  if (!gzipStream) {
2198
2192
  try {
2199
- readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback);
2193
+ readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback, sourceErrors);
2200
2194
  } catch (error) {
2201
2195
  if (deflate64 || outputSize === UNDEFINED_VALUE || (!useCompressionStream && DecompressionStreamFallback)) {
2202
- throw error;
2196
+ throw mapMemoryError(error);
2203
2197
  }
2204
2198
  try {
2205
2199
  gzipStream = new DecompressionStream(FORMAT_GZIP$1);
2206
2200
  } catch {
2207
- throw error;
2201
+ throw mapMemoryError(error);
2208
2202
  }
2209
2203
  }
2210
2204
  }
2211
- if (gzipStream) {
2212
- gzipCrc32 = true;
2213
- readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32);
2214
- }
2215
2205
  }
2216
- readable = mapInflateStreamError(readable);
2206
+ if (gzipStream) {
2207
+ gzipCrc32 = true;
2208
+ readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32, sourceErrors);
2209
+ } else {
2210
+ readable = mapInflateStreamError(readable, sourceErrors);
2211
+ }
2217
2212
  }
2218
2213
  if (checkCrc32 && !gzipCrc32) {
2219
2214
  crc32Stream = new Crc32Stream();
@@ -2286,7 +2281,7 @@ function getGzipCodecStream(useCompressionStream, CodecStreamNative, CodecStream
2286
2281
  }
2287
2282
  }
2288
2283
 
2289
- function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
2284
+ function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback, sourceErrors) {
2290
2285
  const Stream = useCompressionStream && CompressionStreamNative ?
2291
2286
  CompressionStreamNative :
2292
2287
  CompressionStreamFallback || CompressionStreamNative;
@@ -2301,14 +2296,14 @@ function pipeThroughCompressionStream(readable, useCompressionStream, options, C
2301
2296
  throw error;
2302
2297
  }
2303
2298
  }
2304
- return pipeThroughBackpressured(readable, codecStream);
2299
+ return pipeThroughBackpressured(readable, codecStream, sourceErrors);
2305
2300
  }
2306
2301
 
2307
2302
  function pipeThrough(readable, transformStream) {
2308
2303
  return toCompatibleReadable(readable).pipeThrough(transformStream);
2309
2304
  }
2310
2305
 
2311
- function pipeThroughBackpressured(readable, transformStream) {
2306
+ function pipeThroughBackpressured(readable, transformStream, sourceErrors) {
2312
2307
  const writer = transformStream.writable.getWriter();
2313
2308
  const reader = readable.getReader();
2314
2309
  pump();
@@ -2318,7 +2313,7 @@ function pipeThroughBackpressured(readable, transformStream) {
2318
2313
  try {
2319
2314
  for (; ;) {
2320
2315
  await writer.ready;
2321
- const result = await reader.read();
2316
+ const result = await readSource(reader, sourceErrors);
2322
2317
  if (result.done) {
2323
2318
  await writer.close();
2324
2319
  break;
@@ -2348,7 +2343,36 @@ async function cancel(reader, error) {
2348
2343
  }
2349
2344
  }
2350
2345
 
2351
- function mapInflateStreamError(readable) {
2346
+ function readSource(reader, sourceErrors) {
2347
+ const result = reader.read();
2348
+ return sourceErrors ? result.catch(error => {
2349
+ sourceErrors.add(error);
2350
+ throw error;
2351
+ }) : result;
2352
+ }
2353
+
2354
+ function mapCodecError(error, sourceErrors) {
2355
+ if (sourceErrors.has(error)) {
2356
+ return error;
2357
+ }
2358
+ return mapError(error, isMemoryError(error) ? ERR_CODEC_OUT_OF_MEMORY : ERR_INVALID_COMPRESSED_DATA);
2359
+ }
2360
+
2361
+ function mapMemoryError(error) {
2362
+ return isMemoryError(error) ? mapError(error, ERR_CODEC_OUT_OF_MEMORY) : error;
2363
+ }
2364
+
2365
+ function isMemoryError(error) {
2366
+ return isErrorObject(error) && error.code == Z_MEM_ERROR_CODE$1;
2367
+ }
2368
+
2369
+ function mapError(error, message) {
2370
+ const mappedError = new Error(message);
2371
+ mappedError.cause = error;
2372
+ return mappedError;
2373
+ }
2374
+
2375
+ function mapInflateStreamError(readable, sourceErrors) {
2352
2376
  const reader = readable.getReader();
2353
2377
  return new ReadableStream({
2354
2378
  async pull(controller) {
@@ -2361,12 +2385,7 @@ function mapInflateStreamError(readable) {
2361
2385
  }
2362
2386
  } catch (error) {
2363
2387
  await cancel(reader, error);
2364
- if (error && error.message) {
2365
- throw error;
2366
- }
2367
- const mappedError = new Error(ERR_INVALID_COMPRESSED_DATA);
2368
- mappedError.cause = error;
2369
- throw mappedError;
2388
+ throw mapCodecError(error, sourceErrors);
2370
2389
  }
2371
2390
  },
2372
2391
  cancel(reason) {
@@ -2734,10 +2753,11 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
2734
2753
  }
2735
2754
  codecStream = new CodecStream(options, config);
2736
2755
  chunkStream = new ChunkStream(getChunkSize(config));
2756
+ const { signal } = workerOptions.streamOptions;
2737
2757
  await readable
2738
2758
  .pipeThrough(codecStream)
2739
2759
  .pipeThrough(chunkStream)
2740
- .pipeTo(writable, { preventClose: true, preventAbort: true });
2760
+ .pipeTo(writable, { preventClose: true, preventAbort: true, signal });
2741
2761
  const {
2742
2762
  crc32,
2743
2763
  inputSize,
@@ -2805,6 +2825,7 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
2805
2825
  const MODULE_WORKER_OPTIONS = { type: "module" };
2806
2826
  const ERROR_EVENT_TYPE = "error";
2807
2827
  const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
2828
+ const ABORT_EVENT_TYPE = "abort";
2808
2829
 
2809
2830
  let webWorkerSource, webWorkerURI, webWorkerOptions;
2810
2831
  let transferStreamsSupported = true;
@@ -2981,6 +3002,13 @@ function watchClosedStream(writableSource, workerData) {
2981
3002
  Object.assign(workerData, { destinationFailed: true, destinationError: error });
2982
3003
  }
2983
3004
  });
3005
+ const { signal } = workerData.workerOptions.streamOptions;
3006
+ if (signal) {
3007
+ const onAbort = () => abortController.abort(signal.reason);
3008
+ const removeAbortListener = () => signal.removeEventListener(ABORT_EVENT_TYPE, onAbort);
3009
+ signal.addEventListener(ABORT_EVENT_TYPE, onAbort);
3010
+ closed.then(removeAbortListener, removeAbortListener);
3011
+ }
2984
3012
  return {
2985
3013
  writable, closed, abortPipe: () => {
2986
3014
  aborting = true;
@@ -3243,9 +3271,6 @@ function getResponseError(errorData, errorValue) {
3243
3271
  responseError = errorValue.value;
3244
3272
  } else {
3245
3273
  responseError = Object.assign(new Error(message), { stack, code, name });
3246
- if (cause) {
3247
- responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3248
- }
3249
3274
  }
3250
3275
  if (isErrorObject(responseError)) {
3251
3276
  try {
@@ -3255,6 +3280,9 @@ function getResponseError(errorData, errorValue) {
3255
3280
  if (codecImportFailed) {
3256
3281
  responseError.codecImportFailed = true;
3257
3282
  }
3283
+ if (cause && !isErrorObject(responseError.cause)) {
3284
+ responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3285
+ }
3258
3286
  if (errorValue) {
3259
3287
  if (responseError.name !== name) {
3260
3288
  responseError.name = name;
@@ -5597,6 +5625,7 @@ let ZipEntry$1 = class ZipEntry {
5597
5625
  ({ writable } = writer);
5598
5626
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5599
5627
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5628
+ throwIfAborted(signal);
5600
5629
  if (writtenSize != outputSize) {
5601
5630
  throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5602
5631
  }
@@ -6392,6 +6421,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
6392
6421
  ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
6393
6422
  ERR_BAD_FORMAT: ERR_BAD_FORMAT,
6394
6423
  ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
6424
+ ERR_CODEC_OUT_OF_MEMORY: ERR_CODEC_OUT_OF_MEMORY,
6395
6425
  ERR_ENCRYPTED: ERR_ENCRYPTED,
6396
6426
  ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
6397
6427
  ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
@@ -7839,6 +7869,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7839
7869
  const result = await runWorker({ readable, writable }, workerOptions);
7840
7870
  compressedSize = result.outputSize;
7841
7871
  writer.size += compressedSize;
7872
+ throwIfAborted(signal);
7842
7873
  if (!passThroughCompression) {
7843
7874
  uncompressedSize = result.inputSize;
7844
7875
  if (!encrypted || zipCrypto) {
@@ -9018,7 +9049,7 @@ function formatSupported(StreamClass, format) {
9018
9049
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9019
9050
  */
9020
9051
 
9021
- const VERSION = "2.16.1";
9052
+ const VERSION = "2.17.0";
9022
9053
 
9023
9054
  /*
9024
9055
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9501,6 +9532,10 @@ const FORMAT_DEFLATE = "deflate";
9501
9532
  const FORMAT_DEFLATE_RAW = "deflate-raw";
9502
9533
  const FORMAT_DEFLATE64_RAW = "deflate64-raw";
9503
9534
  const FORMAT_GZIP = "gzip";
9535
+ const Z_MEM_ERROR = -4;
9536
+ const Z_MEM_ERROR_CODE = "Z_MEM_ERROR";
9537
+ const COMPRESSION_FORMATS = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP];
9538
+ const DECOMPRESSION_FORMATS = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP, FORMAT_DEFLATE64_RAW];
9504
9539
 
9505
9540
  let wasm$1, malloc, free, memory, initError;
9506
9541
 
@@ -9521,7 +9556,17 @@ function resetWasmExports$1() {
9521
9556
  wasm$1 = malloc = free = memory = initError = null;
9522
9557
  }
9523
9558
 
9559
+ function setZlibCode(error, result) {
9560
+ if (result === Z_MEM_ERROR) {
9561
+ error.code = Z_MEM_ERROR_CODE;
9562
+ }
9563
+ return error;
9564
+ }
9565
+
9524
9566
  function _make(isCompress, type, options = {}) {
9567
+ if (!(isCompress ? COMPRESSION_FORMATS : DECOMPRESSION_FORMATS).includes(type)) {
9568
+ throw new TypeError("Unsupported format: " + type);
9569
+ }
9525
9570
  if (!wasm$1) {
9526
9571
  const error = new Error("WASM module not loaded");
9527
9572
  error.cause = initError;
@@ -9530,7 +9575,7 @@ function _make(isCompress, type, options = {}) {
9530
9575
  const level = (typeof options.level === "number") ? options.level : -1;
9531
9576
  const outBufferSize = (typeof options.outBuffer === "number") ? options.outBuffer : 64 * 1024;
9532
9577
  const inBufferSize = (typeof options.inBufferSize === "number") ? options.inBufferSize : 64 * 1024;
9533
- const state = { out: 0, in: 0, inBufferSize: 0, streamHandle: 0 };
9578
+ const state = { out: 0, in: 0, inBufferSize: 0, streamHandle: 0, streamEnded: false };
9534
9579
  let readableController, writableController, resolveWrite, cancelReason;
9535
9580
  let backpressure = true;
9536
9581
  let cancelled = false;
@@ -9583,7 +9628,7 @@ function _make(isCompress, type, options = {}) {
9583
9628
  }
9584
9629
  const result = disposeStream(state);
9585
9630
  if (result !== 0) {
9586
- const error = new Error("end error:" + result);
9631
+ const error = setZlibCode(new Error("end error:" + result), result);
9587
9632
  readableController.error(error);
9588
9633
  throw error;
9589
9634
  }
@@ -9603,7 +9648,7 @@ function _make(isCompress, type, options = {}) {
9603
9648
  state.in = malloc(inBufferSize);
9604
9649
  state.inBufferSize = inBufferSize;
9605
9650
  if (!state.out || !state.in) {
9606
- throw new Error("allocation failed");
9651
+ throw setZlibCode(new Error("allocation failed"), Z_MEM_ERROR);
9607
9652
  }
9608
9653
  if (isCompress) {
9609
9654
  state._process = wasm$1.deflate_process;
@@ -9639,7 +9684,7 @@ function _make(isCompress, type, options = {}) {
9639
9684
  }
9640
9685
  }
9641
9686
  if (result !== 0) {
9642
- throw new Error("init failed:" + result);
9687
+ throw setZlibCode(new Error("init failed:" + result), result);
9643
9688
  }
9644
9689
  } catch (error) {
9645
9690
  disposeStream(state);
@@ -9654,6 +9699,9 @@ function _make(isCompress, type, options = {}) {
9654
9699
  const out = state.out;
9655
9700
  let offset = 0;
9656
9701
  while (offset < chunk.length) {
9702
+ if (state.streamEnded) {
9703
+ throw new Error("trailing data after the end of the stream");
9704
+ }
9657
9705
  const toRead = Math.min(chunk.length - offset, 32 * 1024);
9658
9706
  if (!state.in || state.inBufferSize < toRead) {
9659
9707
  if (state.in && free) {
@@ -9663,7 +9711,7 @@ function _make(isCompress, type, options = {}) {
9663
9711
  state.in = malloc(toRead);
9664
9712
  state.inBufferSize = toRead;
9665
9713
  if (!state.in) {
9666
- throw new Error("allocation failed");
9714
+ throw setZlibCode(new Error("allocation failed"), Z_MEM_ERROR);
9667
9715
  }
9668
9716
  }
9669
9717
  heap.set(chunk.subarray(offset, offset + toRead), state.in);
@@ -9672,14 +9720,16 @@ function _make(isCompress, type, options = {}) {
9672
9720
  const code = (result >> 24) & 0xff;
9673
9721
  const signedCode = (code & 0x80) ? code - 256 : code;
9674
9722
  if (signedCode < 0) {
9675
- throw new Error("process error:" + signedCode);
9723
+ throw setZlibCode(new Error("process error:" + signedCode), signedCode);
9676
9724
  }
9677
9725
  const prod = result & 0x00ffffff;
9678
9726
  if (prod) {
9679
9727
  enqueue(heap.slice(out, out + prod));
9680
9728
  }
9681
9729
  const consumed = last_consumed(state.streamHandle);
9682
- if (consumed === 0 && prod === 0) {
9730
+ if (code === 1) {
9731
+ state.streamEnded = true;
9732
+ } else if (consumed === 0 && prod === 0) {
9683
9733
  break;
9684
9734
  }
9685
9735
  offset += consumed;
@@ -9695,7 +9745,7 @@ function _make(isCompress, type, options = {}) {
9695
9745
  const code = (result >> 24) & 0xff;
9696
9746
  const signedCode = (code & 0x80) ? code - 256 : code;
9697
9747
  if (signedCode < 0) {
9698
- throw new Error("process error:" + signedCode);
9748
+ throw setZlibCode(new Error("process error:" + signedCode), signedCode);
9699
9749
  }
9700
9750
  const produced = result & 0x00ffffff;
9701
9751
  if (produced) {
@@ -9754,10 +9804,10 @@ class DecompressionStreamZlib {
9754
9804
  CompressionStreamZlib.requiresModule = true;
9755
9805
  DecompressionStreamZlib.requiresModule = true;
9756
9806
  // Constructing these classes before the module is loaded throws, so capability probes cannot rely
9757
- // on trying the constructor; the formats are declared instead, next to the branches implementing
9758
- // them in _make().
9759
- CompressionStreamZlib.supportedFormats = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP];
9760
- DecompressionStreamZlib.supportedFormats = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP, FORMAT_DEFLATE64_RAW];
9807
+ // on trying the constructor; the formats are declared instead, the lists _make() checks a format
9808
+ // against before anything else.
9809
+ CompressionStreamZlib.supportedFormats = COMPRESSION_FORMATS;
9810
+ DecompressionStreamZlib.supportedFormats = DECOMPRESSION_FORMATS;
9761
9811
 
9762
9812
  /*
9763
9813
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -10053,6 +10103,7 @@ const ERR_INVALID_REQUEST_PASSWORD = "Invalid requestPassword option (must be a
10053
10103
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
10054
10104
  const ABORT_ERROR_NAME = "AbortError";
10055
10105
  const EMPTY_RAW_PASSWORD = new Uint8Array(0);
10106
+ const FALSE_ACCEPT_ERRORS = new Set([ERR_INVALID_CRC32, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_COMPRESSED_DATA]);
10056
10107
 
10057
10108
  class ZipEntry {
10058
10109
 
@@ -11040,7 +11091,12 @@ async function readEntryData(entry, options, passwordState) {
11040
11091
  release();
11041
11092
  }
11042
11093
  }
11043
- throw new Error(tried.size ? ERR_INVALID_PASSWORD : ERR_ENCRYPTED);
11094
+ if (!tried.size) {
11095
+ throw new Error(ERR_ENCRYPTED);
11096
+ }
11097
+ const passwordError = new Error(ERR_INVALID_PASSWORD);
11098
+ passwordError.cause = error;
11099
+ throw passwordError;
11044
11100
 
11045
11101
  async function tryPasswordCandidate(candidate) {
11046
11102
  tried.add(candidate.key);
@@ -11061,7 +11117,7 @@ async function readEntryData(entry, options, passwordState) {
11061
11117
  rememberPassword(passwordState, candidate);
11062
11118
  return { done: true, data };
11063
11119
  } catch (readError) {
11064
- if (isAbortError(readError, signal) || (!entry.zipCrypto && !isInvalidPasswordError(readError))) {
11120
+ if (isAbortError(readError, signal) || !isWrongPasswordError(readError, entry)) {
11065
11121
  throw readError;
11066
11122
  }
11067
11123
  return { done: false, error: readError };
@@ -11073,6 +11129,10 @@ function isInvalidPasswordError(error) {
11073
11129
  return isErrorObject(error) && error.message == ERR_INVALID_PASSWORD;
11074
11130
  }
11075
11131
 
11132
+ function isWrongPasswordError(error, entry) {
11133
+ return isInvalidPasswordError(error) || (entry.zipCrypto && isErrorObject(error) && FALSE_ACCEPT_ERRORS.has(error.message));
11134
+ }
11135
+
11076
11136
  function isAbortError(error, signal) {
11077
11137
  return Boolean(signal && signal.aborted) || (isErrorObject(error) && error.name == ABORT_ERROR_NAME);
11078
11138
  }
@@ -11557,4 +11617,4 @@ function decodeMimeTypes(data) {
11557
11617
  return mimeTypes;
11558
11618
  }
11559
11619
 
11560
- export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_ANCESTOR_ENTRY, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_DUPLICATED_NAME, ERR_DUPLICATE_IMPORTED_ENTRY, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_ENTRY_EXISTS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_HTTP_STATUS, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_BASE_URI, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_DUPLICATES, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORDS, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH, ERR_INVALID_PASS_THROUGH_VALUE, ERR_INVALID_READER, ERR_INVALID_READER_OPTIONS, ERR_INVALID_REQUEST_PASSWORD, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_URI, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_PARENT_NOT_DIRECTORY, ERR_READABLE_CONSUMED, ERR_RESERVED_COMPRESSION_METHOD, ERR_ROOT_DIRECTORY_NOT_MOVABLE, ERR_SPLIT_ZIP_FILE, ERR_TARGET_NOT_DIRECTORY, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_CRC32, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_PASS_THROUGH_VALUE, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_WRITER_SIZE_NOT_WRITABLE, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_CLAMPED_LAST_MODIFICATION_DATE, WARNING_COMPRESSED_PATCHED_DATA, WARNING_COMPRESSION_UNAVAILABLE, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipDirectoryEntry, ZipEntry, ZipFS, ZipFileEntry, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, fs, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, isZipFile, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };
11620
+ export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_ANCESTOR_ENTRY, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_CODEC_OUT_OF_MEMORY, ERR_DUPLICATED_NAME, ERR_DUPLICATE_IMPORTED_ENTRY, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_ENTRY_EXISTS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_HTTP_STATUS, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_BASE_URI, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_DUPLICATES, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORDS, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH, ERR_INVALID_PASS_THROUGH_VALUE, ERR_INVALID_READER, ERR_INVALID_READER_OPTIONS, ERR_INVALID_REQUEST_PASSWORD, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_URI, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_PARENT_NOT_DIRECTORY, ERR_READABLE_CONSUMED, ERR_RESERVED_COMPRESSION_METHOD, ERR_ROOT_DIRECTORY_NOT_MOVABLE, ERR_SPLIT_ZIP_FILE, ERR_TARGET_NOT_DIRECTORY, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_CRC32, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_PASS_THROUGH_VALUE, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_WRITER_SIZE_NOT_WRITABLE, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_CLAMPED_LAST_MODIFICATION_DATE, WARNING_COMPRESSED_PATCHED_DATA, WARNING_COMPRESSION_UNAVAILABLE, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipDirectoryEntry, ZipEntry, ZipFS, ZipFileEntry, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, fs, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, isZipFile, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };