@zip.js/zip.js 2.16.1 → 2.18.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 +211 -130
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +180 -117
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +223 -132
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +192 -119
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +223 -132
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +194 -121
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +224 -132
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +181 -118
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +182 -119
  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 +212 -130
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +194 -121
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +224 -132
  27. package/index.d.cts +87 -24
  28. package/index.d.ts +87 -24
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-pool.js +2 -0
  31. package/lib/core/codec-worker-web.js +16 -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 +2 -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 +16 -3
  42. package/lib/core/zip-reader.js +40 -11
  43. package/lib/core/zip-writer.js +1 -0
  44. package/lib/zip-core-reader.js +1 -0
  45. package/package.json +1 -1
package/dist/zip-core.js CHANGED
@@ -1900,7 +1900,9 @@
1900
1900
 
1901
1901
  const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
1902
1902
  const ERR_INVALID_COMPRESSED_DATA = "Invalid compressed data";
1903
+ const ERR_CODEC_OUT_OF_MEMORY = "Codec out of memory";
1903
1904
  const ERR_INVALID_CRC32 = "Invalid CRC32";
1905
+ const Z_MEM_ERROR_CODE = "Z_MEM_ERROR";
1904
1906
  const FORMAT_DEFLATE_RAW = "deflate-raw";
1905
1907
  const FORMAT_DEFLATE64_RAW = "deflate64-raw";
1906
1908
  const FORMAT_GZIP = "gzip";
@@ -1935,13 +1937,13 @@
1935
1937
  readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamFallback);
1936
1938
  } catch (error) {
1937
1939
  if (!useCompressionStream && CompressionStreamFallback) {
1938
- throw error;
1940
+ throw mapMemoryError(error);
1939
1941
  }
1940
1942
  let gzipStream;
1941
1943
  try {
1942
1944
  gzipStream = new CompressionStream(FORMAT_GZIP);
1943
1945
  } catch {
1944
- throw error;
1946
+ throw mapMemoryError(error);
1945
1947
  }
1946
1948
  readable = pipeThroughBackpressured(readable, gzipStream);
1947
1949
  readable = pipeThrough(readable, new GzipToRawDeflateStream());
@@ -2005,50 +2007,30 @@
2005
2007
  }
2006
2008
  }
2007
2009
 
2008
- function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32) {
2010
+ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32, sourceErrors) {
2009
2011
  const writer = gzipStream.writable.getWriter();
2010
2012
  const reader = gzipStream.readable.getReader();
2011
2013
  const outputCrc32 = crc32 === UNDEFINED_VALUE ? new Crc32() : UNDEFINED_VALUE;
2012
2014
  let outputLength = 0;
2013
- let inputDone = false;
2014
2015
  let trailerWritten = false;
2015
- let idleCheckArmed = false;
2016
- let readCount = 0;
2017
- let readPending = false;
2018
- let resolveTrailerReady, rejectTrailerReady;
2019
- const trailerReady = new Promise((resolve, reject) => {
2020
- resolveTrailerReady = resolve;
2021
- rejectTrailerReady = reject;
2022
- });
2023
- trailerReady.catch(() => { });
2024
- pump();
2025
- return new ReadableStream({
2026
- async pull(controller) {
2027
- try {
2028
- const { value, done } = await read();
2029
- if (done) {
2030
- controller.close();
2031
- } else {
2032
- outputLength += value.length;
2033
- if (outputLength > outputSize) {
2034
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
2035
- }
2036
- if (outputCrc32) {
2037
- outputCrc32.append(value);
2038
- }
2039
- controller.enqueue(value);
2040
- }
2041
- } catch (error) {
2042
- rejectTrailerReady(error);
2043
- await cancel(reader, error);
2044
- throw trailerWritten ? getTrailerError(error) : error;
2045
- }
2016
+ let settled = false;
2017
+ let resolvePull, controller;
2018
+ const output = new ReadableStream({
2019
+ start(streamController) {
2020
+ controller = streamController;
2021
+ },
2022
+ pull() {
2023
+ resumePump();
2046
2024
  },
2047
2025
  cancel(reason) {
2048
- rejectTrailerReady(reason);
2026
+ settled = true;
2027
+ resumePump();
2049
2028
  return reader.cancel(reason);
2050
2029
  }
2051
2030
  });
2031
+ pump();
2032
+ drain();
2033
+ return output;
2052
2034
 
2053
2035
  async function pump() {
2054
2036
  const inputReader = readable.getReader();
@@ -2057,19 +2039,16 @@
2057
2039
  header.set(GZIP_HEADER_BYTES);
2058
2040
  await writer.write(header);
2059
2041
  for (; ;) {
2042
+ await outputCapacity();
2060
2043
  await writer.ready;
2061
- const { value, done } = await inputReader.read();
2044
+ const { value, done } = await readSource(inputReader, sourceErrors);
2062
2045
  if (done) {
2063
2046
  break;
2064
2047
  }
2065
2048
  await writer.write(value);
2066
2049
  }
2067
- inputDone = true;
2068
2050
  if (outputCrc32) {
2069
- if (readPending) {
2070
- armIdleCheck();
2071
- }
2072
- await trailerReady;
2051
+ await writer.write(new Uint8Array(0));
2073
2052
  }
2074
2053
  const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
2075
2054
  const dataView = getDataView(trailer);
@@ -2084,54 +2063,68 @@
2084
2063
  }
2085
2064
  }
2086
2065
 
2087
- function read() {
2088
- readCount++;
2089
- readPending = true;
2090
- const result = reader.read();
2091
- result.then(onReadSettled, onReadSettled);
2092
- if (inputDone && outputCrc32) {
2093
- armIdleCheck();
2066
+ async function drain() {
2067
+ try {
2068
+ for (; ;) {
2069
+ const { value, done } = await read();
2070
+ if (done) {
2071
+ break;
2072
+ }
2073
+ outputLength += value.length;
2074
+ if (outputLength > outputSize) {
2075
+ throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
2076
+ }
2077
+ if (outputCrc32) {
2078
+ outputCrc32.append(value);
2079
+ }
2080
+ controller.enqueue(value);
2081
+ }
2082
+ if (!settled) {
2083
+ settled = true;
2084
+ controller.close();
2085
+ }
2086
+ } catch (error) {
2087
+ fail(error);
2088
+ await cancel(reader, error);
2094
2089
  }
2095
- return result;
2096
- }
2097
-
2098
- function onReadSettled() {
2099
- readPending = false;
2100
2090
  }
2101
2091
 
2102
- async function armIdleCheck() {
2103
- if (!idleCheckArmed) {
2104
- idleCheckArmed = true;
2105
- const count = readCount;
2106
- await nextTask();
2107
- idleCheckArmed = false;
2108
- if (readPending) {
2109
- if (readCount == count) {
2110
- resolveTrailerReady();
2111
- } else {
2112
- armIdleCheck();
2092
+ function read() {
2093
+ return reader.read().catch(error => {
2094
+ if (trailerWritten) {
2095
+ if (!outputCrc32) {
2096
+ throw mapError(error, ERR_INVALID_CRC32);
2097
+ }
2098
+ if (outputLength != outputSize) {
2099
+ throw mapError(error, ERR_INVALID_UNCOMPRESSED_SIZE);
2113
2100
  }
2101
+ return { done: true };
2114
2102
  }
2115
- }
2103
+ throw mapCodecError(error, sourceErrors);
2104
+ });
2116
2105
  }
2117
2106
 
2118
- function getTrailerError(error) {
2119
- const trailerError = new Error(outputLength == outputSize ? ERR_INVALID_CRC32 : ERR_INVALID_UNCOMPRESSED_SIZE);
2120
- trailerError.cause = error;
2121
- return trailerError;
2107
+ function outputCapacity() {
2108
+ if (!settled && controller.desiredSize <= 0) {
2109
+ return new Promise(resolve => resolvePull = resolve);
2110
+ }
2122
2111
  }
2123
- }
2124
2112
 
2125
- function nextTask() {
2126
- return new Promise(resolve => {
2127
- const { port1, port2 } = new MessageChannel();
2128
- port2.onmessage = () => {
2129
- port1.close();
2130
- port2.close();
2113
+ function resumePump() {
2114
+ if (resolvePull) {
2115
+ const resolve = resolvePull;
2116
+ resolvePull = UNDEFINED_VALUE;
2131
2117
  resolve();
2132
- };
2133
- port1.postMessage(UNDEFINED_VALUE);
2134
- });
2118
+ }
2119
+ }
2120
+
2121
+ function fail(error) {
2122
+ if (!settled) {
2123
+ settled = true;
2124
+ controller.error(error);
2125
+ resumePump();
2126
+ }
2127
+ }
2135
2128
  }
2136
2129
 
2137
2130
  class InflateStream extends TransformStream {
@@ -2150,11 +2143,12 @@
2150
2143
  }
2151
2144
  }
2152
2145
  if (compressed) {
2146
+ const sourceErrors = new Set();
2153
2147
  const codecStreams = format && getCodecStreams(format);
2148
+ let gzipStream;
2154
2149
  if (codecStreams) {
2155
- readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }));
2150
+ readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }), sourceErrors);
2156
2151
  } else {
2157
- let gzipStream;
2158
2152
  const GzipDecompressionStream = getGzipCodecStream(useCompressionStream, DecompressionStream, DecompressionStreamFallback);
2159
2153
  if (checkCrc32 && !deflate64 && crc32 !== UNDEFINED_VALUE && outputSize !== UNDEFINED_VALUE && GzipDecompressionStream) {
2160
2154
  try {
@@ -2165,24 +2159,25 @@
2165
2159
  }
2166
2160
  if (!gzipStream) {
2167
2161
  try {
2168
- readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback);
2162
+ readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback, sourceErrors);
2169
2163
  } catch (error) {
2170
2164
  if (deflate64 || outputSize === UNDEFINED_VALUE || (!useCompressionStream && DecompressionStreamFallback)) {
2171
- throw error;
2165
+ throw mapMemoryError(error);
2172
2166
  }
2173
2167
  try {
2174
2168
  gzipStream = new DecompressionStream(FORMAT_GZIP);
2175
2169
  } catch {
2176
- throw error;
2170
+ throw mapMemoryError(error);
2177
2171
  }
2178
2172
  }
2179
2173
  }
2180
- if (gzipStream) {
2181
- gzipCrc32 = true;
2182
- readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32);
2183
- }
2184
2174
  }
2185
- readable = mapInflateStreamError(readable);
2175
+ if (gzipStream) {
2176
+ gzipCrc32 = true;
2177
+ readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32, sourceErrors);
2178
+ } else {
2179
+ readable = mapInflateStreamError(readable, sourceErrors);
2180
+ }
2186
2181
  }
2187
2182
  if (checkCrc32 && !gzipCrc32) {
2188
2183
  crc32Stream = new Crc32Stream();
@@ -2255,7 +2250,7 @@
2255
2250
  }
2256
2251
  }
2257
2252
 
2258
- function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
2253
+ function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback, sourceErrors) {
2259
2254
  const Stream = useCompressionStream && CompressionStreamNative ?
2260
2255
  CompressionStreamNative :
2261
2256
  CompressionStreamFallback || CompressionStreamNative;
@@ -2270,14 +2265,14 @@
2270
2265
  throw error;
2271
2266
  }
2272
2267
  }
2273
- return pipeThroughBackpressured(readable, codecStream);
2268
+ return pipeThroughBackpressured(readable, codecStream, sourceErrors);
2274
2269
  }
2275
2270
 
2276
2271
  function pipeThrough(readable, transformStream) {
2277
2272
  return toCompatibleReadable(readable).pipeThrough(transformStream);
2278
2273
  }
2279
2274
 
2280
- function pipeThroughBackpressured(readable, transformStream) {
2275
+ function pipeThroughBackpressured(readable, transformStream, sourceErrors) {
2281
2276
  const writer = transformStream.writable.getWriter();
2282
2277
  const reader = readable.getReader();
2283
2278
  pump();
@@ -2287,7 +2282,7 @@
2287
2282
  try {
2288
2283
  for (; ;) {
2289
2284
  await writer.ready;
2290
- const result = await reader.read();
2285
+ const result = await readSource(reader, sourceErrors);
2291
2286
  if (result.done) {
2292
2287
  await writer.close();
2293
2288
  break;
@@ -2317,7 +2312,36 @@
2317
2312
  }
2318
2313
  }
2319
2314
 
2320
- function mapInflateStreamError(readable) {
2315
+ function readSource(reader, sourceErrors) {
2316
+ const result = reader.read();
2317
+ return sourceErrors ? result.catch(error => {
2318
+ sourceErrors.add(error);
2319
+ throw error;
2320
+ }) : result;
2321
+ }
2322
+
2323
+ function mapCodecError(error, sourceErrors) {
2324
+ if (sourceErrors.has(error)) {
2325
+ return error;
2326
+ }
2327
+ return mapError(error, isMemoryError(error) ? ERR_CODEC_OUT_OF_MEMORY : ERR_INVALID_COMPRESSED_DATA);
2328
+ }
2329
+
2330
+ function mapMemoryError(error) {
2331
+ return isMemoryError(error) ? mapError(error, ERR_CODEC_OUT_OF_MEMORY) : error;
2332
+ }
2333
+
2334
+ function isMemoryError(error) {
2335
+ return isErrorObject(error) && error.code == Z_MEM_ERROR_CODE;
2336
+ }
2337
+
2338
+ function mapError(error, message) {
2339
+ const mappedError = new Error(message);
2340
+ mappedError.cause = error;
2341
+ return mappedError;
2342
+ }
2343
+
2344
+ function mapInflateStreamError(readable, sourceErrors) {
2321
2345
  const reader = readable.getReader();
2322
2346
  return new ReadableStream({
2323
2347
  async pull(controller) {
@@ -2330,12 +2354,7 @@
2330
2354
  }
2331
2355
  } catch (error) {
2332
2356
  await cancel(reader, error);
2333
- if (error && error.message) {
2334
- throw error;
2335
- }
2336
- const mappedError = new Error(ERR_INVALID_COMPRESSED_DATA);
2337
- mappedError.cause = error;
2338
- throw mappedError;
2357
+ throw mapCodecError(error, sourceErrors);
2339
2358
  }
2340
2359
  },
2341
2360
  cancel(reason) {
@@ -2699,10 +2718,11 @@
2699
2718
  }
2700
2719
  codecStream = new CodecStream(options, config);
2701
2720
  chunkStream = new ChunkStream(getChunkSize(config));
2721
+ const { signal } = workerOptions.streamOptions;
2702
2722
  await readable
2703
2723
  .pipeThrough(codecStream)
2704
2724
  .pipeThrough(chunkStream)
2705
- .pipeTo(writable, { preventClose: true, preventAbort: true });
2725
+ .pipeTo(writable, { preventClose: true, preventAbort: true, signal });
2706
2726
  const {
2707
2727
  crc32,
2708
2728
  inputSize,
@@ -2770,6 +2790,7 @@
2770
2790
  const MODULE_WORKER_OPTIONS = { type: "module" };
2771
2791
  const ERROR_EVENT_TYPE = "error";
2772
2792
  const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
2793
+ const ABORT_EVENT_TYPE = "abort";
2773
2794
 
2774
2795
  let webWorkerSource, webWorkerURI, webWorkerOptions;
2775
2796
  let transferStreamsSupported = true;
@@ -2946,6 +2967,13 @@
2946
2967
  Object.assign(workerData, { destinationFailed: true, destinationError: error });
2947
2968
  }
2948
2969
  });
2970
+ const { signal } = workerData.workerOptions.streamOptions;
2971
+ if (signal) {
2972
+ const onAbort = () => abortController.abort(signal.reason);
2973
+ const removeAbortListener = () => signal.removeEventListener(ABORT_EVENT_TYPE, onAbort);
2974
+ signal.addEventListener(ABORT_EVENT_TYPE, onAbort);
2975
+ closed.then(removeAbortListener, removeAbortListener);
2976
+ }
2949
2977
  return {
2950
2978
  writable, closed, abortPipe: () => {
2951
2979
  aborting = true;
@@ -3208,9 +3236,6 @@
3208
3236
  responseError = errorValue.value;
3209
3237
  } else {
3210
3238
  responseError = Object.assign(new Error(message), { stack, code, name });
3211
- if (cause) {
3212
- responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3213
- }
3214
3239
  }
3215
3240
  if (isErrorObject(responseError)) {
3216
3241
  try {
@@ -3220,6 +3245,14 @@
3220
3245
  if (codecImportFailed) {
3221
3246
  responseError.codecImportFailed = true;
3222
3247
  }
3248
+ if (cause) {
3249
+ if (!isErrorObject(responseError.cause)) {
3250
+ responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3251
+ }
3252
+ if (cause.code !== UNDEFINED_VALUE && responseError.cause.code !== cause.code) {
3253
+ responseError.cause.code = cause.code;
3254
+ }
3255
+ }
3223
3256
  if (errorValue) {
3224
3257
  if (responseError.name !== name) {
3225
3258
  responseError.name = name;
@@ -4790,7 +4823,7 @@
4790
4823
  const CHARSET_UTF8 = "utf-8";
4791
4824
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
4792
4825
  const CHARSET_CP437 = "cp437";
4793
- const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_LANG_ENCODING_FLAG;
4826
+ const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_STRONG_ENCRYPTION | BITFLAG_LANG_ENCODING_FLAG;
4794
4827
  const VENDOR_VERSION_AE_1$1 = 1;
4795
4828
  const ZIP64_PROPERTIES = [
4796
4829
  [PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS],
@@ -5444,12 +5477,12 @@
5444
5477
  fileEntry.gid = gid;
5445
5478
  }
5446
5479
  const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5447
- const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
5480
+ const encrypted = zipEntry.encrypted && (!passThroughEncryption || checkPasswordOnly);
5448
5481
  const zipCrypto = encrypted && !extraFieldAES;
5449
5482
  if (!passThroughEncryption) {
5450
5483
  fileEntry.zipCrypto = zipCrypto;
5451
5484
  }
5452
- if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5485
+ if (encrypted && (zipEntry.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5453
5486
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
5454
5487
  }
5455
5488
  const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
@@ -5542,6 +5575,7 @@
5542
5575
  ({ writable } = writer);
5543
5576
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5544
5577
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5578
+ throwIfAborted(signal);
5545
5579
  if (writtenSize != outputSize) {
5546
5580
  throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5547
5581
  }
@@ -5688,8 +5722,16 @@
5688
5722
  });
5689
5723
  const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
5690
5724
  if (extraFieldZip64) {
5691
- readExtraFieldZip64(extraFieldZip64, directory);
5725
+ if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
5726
+ malformedExtraField = true;
5727
+ }
5692
5728
  directory.extraFieldZip64 = extraFieldZip64;
5729
+ } else if (ZIP64_PROPERTIES.some(([propertyName, max]) => directory[propertyName] == max)) {
5730
+ if (localDirectory) {
5731
+ malformedExtraField = true;
5732
+ } else {
5733
+ throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
5734
+ }
5693
5735
  }
5694
5736
  const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
5695
5737
  if (extraFieldUnicodePath) {
@@ -5702,10 +5744,13 @@
5702
5744
  directory.extraFieldUnicodeComment = extraFieldUnicodeComment;
5703
5745
  }
5704
5746
  const extraFieldAES = extraField.get(EXTRAFIELD_TYPE_AES);
5705
- if (extraFieldAES && extraFieldAES.data.length >= 7) {
5747
+ if (extraFieldAES && (compressionMethod == COMPRESSION_METHOD_AES || directory.encrypted) && extraFieldAES.data.length >= 7) {
5706
5748
  readExtraFieldAES(extraFieldAES, directory, compressionMethod);
5707
5749
  directory.extraFieldAES = extraFieldAES;
5708
5750
  } else {
5751
+ if (extraFieldAES) {
5752
+ malformedExtraField = true;
5753
+ }
5709
5754
  directory.compressionMethod = compressionMethod;
5710
5755
  }
5711
5756
  const extraFieldPkwareUnix = extraField.get(EXTRAFIELD_TYPE_PKWARE_UNIX);
@@ -5748,20 +5793,35 @@
5748
5793
  return malformedExtraField;
5749
5794
  }
5750
5795
 
5751
- function readExtraFieldZip64(extraFieldZip64, directory) {
5796
+ function readExtraFieldZip64(extraFieldZip64, directory, localDirectory) {
5752
5797
  directory.zip64 = true;
5753
5798
  const extraFieldView = getDataView(extraFieldZip64.data);
5754
5799
  const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
5755
5800
  const requiredLength = missingProperties.reduce((length, [, max]) => length + ZIP64_EXTRACTION[max].bytes, 0);
5756
5801
  if (extraFieldZip64.data.length < requiredLength) {
5802
+ if (localDirectory) {
5803
+ return false;
5804
+ }
5757
5805
  throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
5758
5806
  }
5759
- for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
5760
- const [propertyName, max] = missingProperties[indexMissingProperty];
5761
- const extraction = ZIP64_EXTRACTION[max];
5762
- directory[propertyName] = extraFieldZip64[propertyName] = extraction.getValue(extraFieldView, offset);
5763
- offset += extraction.bytes;
5807
+ const values = [];
5808
+ try {
5809
+ for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
5810
+ const [, max] = missingProperties[indexMissingProperty];
5811
+ const extraction = ZIP64_EXTRACTION[max];
5812
+ values.push(extraction.getValue(extraFieldView, offset));
5813
+ offset += extraction.bytes;
5814
+ }
5815
+ } catch (error) {
5816
+ if (localDirectory) {
5817
+ return false;
5818
+ }
5819
+ throw error;
5764
5820
  }
5821
+ missingProperties.forEach(([propertyName], indexMissingProperty) => {
5822
+ directory[propertyName] = extraFieldZip64[propertyName] = values[indexMissingProperty];
5823
+ });
5824
+ return true;
5765
5825
  }
5766
5826
 
5767
5827
  function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) {
@@ -6337,6 +6397,7 @@
6337
6397
  ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
6338
6398
  ERR_BAD_FORMAT: ERR_BAD_FORMAT,
6339
6399
  ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
6400
+ ERR_CODEC_OUT_OF_MEMORY: ERR_CODEC_OUT_OF_MEMORY,
6340
6401
  ERR_ENCRYPTED: ERR_ENCRYPTED,
6341
6402
  ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
6342
6403
  ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
@@ -7686,6 +7747,7 @@
7686
7747
  const result = await runWorker({ readable, writable }, workerOptions);
7687
7748
  compressedSize = result.outputSize;
7688
7749
  writer.size += compressedSize;
7750
+ throwIfAborted(signal);
7689
7751
  if (!passThroughCompression) {
7690
7752
  uncompressedSize = result.inputSize;
7691
7753
  if (!encrypted || zipCrypto) {
@@ -8865,7 +8927,7 @@
8865
8927
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8866
8928
  */
8867
8929
 
8868
- const VERSION = "2.16.1";
8930
+ const VERSION = "2.18.0";
8869
8931
 
8870
8932
  /*
8871
8933
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9322,6 +9384,7 @@
9322
9384
  exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
9323
9385
  exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
9324
9386
  exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
9387
+ exports.ERR_CODEC_OUT_OF_MEMORY = ERR_CODEC_OUT_OF_MEMORY;
9325
9388
  exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
9326
9389
  exports.ERR_ENCRYPTED = ERR_ENCRYPTED;
9327
9390
  exports.ERR_ENCRYPTED_CENTRAL_DIRECTORY = ERR_ENCRYPTED_CENTRAL_DIRECTORY;