@zip.js/zip.js 2.8.45 → 2.8.47

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 (56) hide show
  1. package/README.md +28 -2
  2. package/deno.json +13 -3
  3. package/dist/zip-core-external.js +146 -35
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +154 -32
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +146 -35
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +124 -30
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +146 -35
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +160 -36
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +160 -36
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +156 -34
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-native.js +158 -36
  20. package/dist/zip-native.min.js +1 -1
  21. package/dist/zip-web-worker-native.js +1 -1
  22. package/dist/zip-web-worker.js +1 -1
  23. package/dist/zip.js +158 -36
  24. package/dist/zip.min.js +1 -1
  25. package/index-native.cjs +160 -36
  26. package/index-native.min.js +1 -1
  27. package/index.cjs +160 -36
  28. package/index.d.cts +232 -1
  29. package/index.d.ts +232 -1
  30. package/index.min.js +1 -1
  31. package/lib/core/codec-pool.js +9 -5
  32. package/lib/core/codec-worker.js +30 -13
  33. package/lib/core/configuration.js +20 -2
  34. package/lib/core/constants.js +2 -0
  35. package/lib/core/options.js +4 -0
  36. package/lib/core/streams/codec-stream.js +2 -0
  37. package/lib/core/streams/common-crypto.js +2 -1
  38. package/lib/core/streams/zip-entry-stream.js +12 -10
  39. package/lib/core/util/sync-access-handle-temp-stream.js +2 -1
  40. package/lib/core/web-worker-base.js +27 -0
  41. package/lib/core/web-worker-inline-native.js +1 -1
  42. package/lib/core/web-worker-inline-wasm.js +1 -1
  43. package/lib/core/web-worker-native.js +7 -9
  44. package/lib/core/web-worker-wasm.js +9 -12
  45. package/lib/core/zip-fs.js +1 -1
  46. package/lib/core/zip-reader.js +58 -5
  47. package/lib/core/zip-writer.js +43 -8
  48. package/lib/zip-core-base.js +2 -1
  49. package/lib/{core/web-worker-inline-template.js → zip-core-custom.js} +13 -20
  50. package/lib/zip-core-reader.js +2 -1
  51. package/lib/zip-core-writer.js +10 -1
  52. package/lib/zip-module-native.js +3 -3
  53. package/lib/zip-module-wasm-base.js +3 -3
  54. package/package.json +20 -2
  55. package/lib/core/web-worker-inline-template-native.js +0 -48
  56. package/lib/core/zlib-streams-inline-template.js +0 -45
package/dist/zip-core.js CHANGED
@@ -47,6 +47,7 @@
47
47
  const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
48
48
  const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
49
49
  const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
50
+ const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
50
51
  const CENTRAL_FILE_HEADER_SIGNATURE = 0x02014b50;
51
52
  const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;
52
53
  const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 0x06064b50;
@@ -176,6 +177,7 @@
176
177
  "baseURI",
177
178
  "wasmURI",
178
179
  "workerURI",
180
+ "createWorker",
179
181
  "chunkSize",
180
182
  "maxWorkers",
181
183
  "terminateWorkerTimeout",
@@ -186,8 +188,8 @@
186
188
  "transferStreams",
187
189
  "CompressionStream",
188
190
  "DecompressionStream",
189
- "CompressionStreamZlib",
190
- "DecompressionStreamZlib"
191
+ "CompressionStreamFallback",
192
+ "DecompressionStreamFallback"
191
193
  ];
192
194
 
193
195
  const config = { ...DEFAULT_CONFIGURATION };
@@ -201,6 +203,7 @@
201
203
  }
202
204
 
203
205
  function configure(configuration) {
206
+ configuration = normalizeConfiguration(configuration);
204
207
  for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
205
208
  const propertyValue = configuration[propertyName];
206
209
  if (propertyValue !== UNDEFINED_VALUE) {
@@ -209,7 +212,23 @@
209
212
  }
210
213
  }
211
214
 
215
+ function normalizeConfiguration(configuration) {
216
+ const { CompressionStreamZlib, DecompressionStreamZlib } = configuration;
217
+ if (CompressionStreamZlib === UNDEFINED_VALUE && DecompressionStreamZlib === UNDEFINED_VALUE) {
218
+ return configuration;
219
+ }
220
+ const normalizedConfiguration = Object.assign({}, configuration);
221
+ if (normalizedConfiguration.CompressionStreamFallback === UNDEFINED_VALUE) {
222
+ normalizedConfiguration.CompressionStreamFallback = CompressionStreamZlib;
223
+ }
224
+ if (normalizedConfiguration.DecompressionStreamFallback === UNDEFINED_VALUE) {
225
+ normalizedConfiguration.DecompressionStreamFallback = DecompressionStreamZlib;
226
+ }
227
+ return normalizedConfiguration;
228
+ }
229
+
212
230
  function setDefaultConfiguration(configuration) {
231
+ configuration = normalizeConfiguration(configuration);
213
232
  for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
214
233
  const propertyValue = configuration[propertyName];
215
234
  if (propertyValue !== UNDEFINED_VALUE) {
@@ -1936,7 +1955,7 @@
1936
1955
 
1937
1956
  class DeflateStream extends TransformStream {
1938
1957
 
1939
- constructor(options, { chunkSize, CompressionStreamZlib, CompressionStream }) {
1958
+ constructor(options, { chunkSize, CompressionStreamFallback, CompressionStream }) {
1940
1959
  super({});
1941
1960
  const { compressed, encrypted, useCompressionStream, zipCrypto, computeCrc32, level, deflate64, format, compressionMethod } = options;
1942
1961
  const stream = this;
@@ -1958,7 +1977,7 @@
1958
1977
  readable = pipeThrough(readable, gzipCrc32Stream);
1959
1978
  } else {
1960
1979
  try {
1961
- readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamZlib);
1980
+ readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamFallback);
1962
1981
  } catch (error) {
1963
1982
  let gzipStream;
1964
1983
  try {
@@ -2100,7 +2119,7 @@
2100
2119
 
2101
2120
  class InflateStream extends TransformStream {
2102
2121
 
2103
- constructor(options, { chunkSize, DecompressionStreamZlib, DecompressionStream }) {
2122
+ constructor(options, { chunkSize, DecompressionStreamFallback, DecompressionStream }) {
2104
2123
  super({});
2105
2124
  const { zipCrypto, encrypted, checkCrc32, crc32, compressed, useCompressionStream, deflate64, format, compressionMethod, rawBitFlag, outputSize } = options;
2106
2125
  let crc32Stream, decryptionStream;
@@ -2119,7 +2138,7 @@
2119
2138
  readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }));
2120
2139
  } else {
2121
2140
  try {
2122
- readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamZlib);
2141
+ readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback);
2123
2142
  } catch (error) {
2124
2143
  if (deflate64 || outputSize === UNDEFINED_VALUE) {
2125
2144
  throw error;
@@ -2198,17 +2217,17 @@
2198
2217
  return new CodecStreamClass(format, options);
2199
2218
  }
2200
2219
 
2201
- function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamZlib) {
2220
+ function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
2202
2221
  const Stream = useCompressionStream && CompressionStreamNative ?
2203
2222
  CompressionStreamNative :
2204
- CompressionStreamZlib || CompressionStreamNative;
2223
+ CompressionStreamFallback || CompressionStreamNative;
2205
2224
  const format = options.deflate64 ? FORMAT_DEFLATE64_RAW : FORMAT_DEFLATE_RAW;
2206
2225
  let codecStream;
2207
2226
  try {
2208
2227
  codecStream = new Stream(format, options);
2209
2228
  } catch (error) {
2210
- if (useCompressionStream && CompressionStreamZlib && Stream != CompressionStreamZlib) {
2211
- codecStream = new CompressionStreamZlib(format, options);
2229
+ if (useCompressionStream && CompressionStreamFallback && Stream != CompressionStreamFallback) {
2230
+ codecStream = new CompressionStreamFallback(format, options);
2212
2231
  } else {
2213
2232
  throw error;
2214
2233
  }
@@ -2471,7 +2490,7 @@
2471
2490
  const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
2472
2491
  const ERR_WORKER_STARTUP_TIMEOUT = "Worker startup timeout";
2473
2492
 
2474
- let webWorkerSupported, webWorkerSource, webWorkerURI, webWorkerOptions;
2493
+ let webWorkerSupported, webWorkerSource, webWorkerURI, webWorkerOptions, createWorkerFailed;
2475
2494
  let transferStreamsSupported = true;
2476
2495
  try {
2477
2496
  transferStreamsSupported = typeof structuredClone == FUNCTION_TYPE && structuredClone(new DOMException("", "AbortError")).code !== UNDEFINED_VALUE;
@@ -2481,14 +2500,14 @@
2481
2500
  let initModule = () => { };
2482
2501
 
2483
2502
  async function supportsDeflate(config) {
2484
- const { CompressionStream: NativeStream, CompressionStreamZlib: ZlibStream } = config;
2485
- if (ZlibStream && !ZlibStream.requiresModule) {
2503
+ const { CompressionStream: NativeStream, CompressionStreamFallback: FallbackStream } = config;
2504
+ if (FallbackStream && !FallbackStream.requiresModule) {
2486
2505
  return true;
2487
2506
  }
2488
2507
  if (supportsDeflateRaw(NativeStream) || supportsGzip(NativeStream)) {
2489
2508
  return true;
2490
2509
  }
2491
- if (ZlibStream) {
2510
+ if (FallbackStream) {
2492
2511
  try {
2493
2512
  await initModule(config);
2494
2513
  return true;
@@ -2501,12 +2520,16 @@
2501
2520
 
2502
2521
  function resetWebWorkerSupport() {
2503
2522
  webWorkerSupported = UNDEFINED_VALUE;
2523
+ createWorkerFailed = false;
2504
2524
  }
2505
2525
 
2506
2526
  class CodecWorker {
2507
2527
 
2508
- constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI }, onTaskFinished) {
2528
+ constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI, createWorker }, onTaskFinished) {
2509
2529
  const { signal } = streamOptions;
2530
+ if (createWorkerFailed) {
2531
+ createWorker = UNDEFINED_VALUE;
2532
+ }
2510
2533
  Object.assign(workerData, {
2511
2534
  busy: true,
2512
2535
  generation: (workerData.generation || 0) + 1,
@@ -2516,6 +2539,7 @@
2516
2539
  writable,
2517
2540
  options: Object.assign({}, options),
2518
2541
  workerURI,
2542
+ createWorker,
2519
2543
  transferStreams,
2520
2544
  terminate() {
2521
2545
  return new Promise(resolve => {
@@ -2551,7 +2575,7 @@
2551
2575
  // deno-lint-ignore valid-typeof
2552
2576
  webWorkerSupported = typeof Worker != UNDEFINED_TYPE;
2553
2577
  }
2554
- return (useWebWorkers && webWorkerSupported ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
2578
+ return (useWebWorkers && ((webWorkerSupported && workerURI) || createWorker) ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
2555
2579
  }
2556
2580
  }
2557
2581
 
@@ -2608,7 +2632,11 @@
2608
2632
  try {
2609
2633
  worker = getWebWorker(workerData.workerURI, baseURI, workerData);
2610
2634
  } catch {
2611
- webWorkerSupported = false;
2635
+ if (workerData.createWorker) {
2636
+ createWorkerFailed = true;
2637
+ } else {
2638
+ webWorkerSupported = false;
2639
+ }
2612
2640
  return createWorkerInterface(workerData, config);
2613
2641
  }
2614
2642
  Object.assign(workerData, {
@@ -2621,7 +2649,11 @@
2621
2649
  return await runWebWorker(workerData, { chunkSize, wasmURI, baseURI, workerStartupTimeout });
2622
2650
  } catch (error) {
2623
2651
  if (error && error.workerStartupFailed) {
2624
- webWorkerSupported = false;
2652
+ if (workerData.createWorker) {
2653
+ createWorkerFailed = true;
2654
+ } else {
2655
+ webWorkerSupported = false;
2656
+ }
2625
2657
  const { reader } = workerData;
2626
2658
  if (reader) {
2627
2659
  reader.releaseLock();
@@ -2644,17 +2676,17 @@
2644
2676
  try {
2645
2677
  if (options.compressed && !options.format) {
2646
2678
  const deflate = options.codecType.startsWith(CODEC_DEFLATE);
2647
- const ZlibStream = deflate ? config.CompressionStreamZlib : config.DecompressionStreamZlib;
2679
+ const FallbackStream = deflate ? config.CompressionStreamFallback : config.DecompressionStreamFallback;
2648
2680
  const NativeStream = deflate ? config.CompressionStream : config.DecompressionStream;
2649
2681
  if (!options.useCompressionStream) {
2650
2682
  try {
2651
2683
  await initModule(config);
2652
2684
  } catch {
2653
- if (!ZlibStream || ZlibStream.requiresModule) {
2685
+ if (!FallbackStream || FallbackStream.requiresModule) {
2654
2686
  options.useCompressionStream = true;
2655
2687
  }
2656
2688
  }
2657
- } else if (ZlibStream && ZlibStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
2689
+ } else if (FallbackStream && FallbackStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
2658
2690
  try {
2659
2691
  await initModule(config);
2660
2692
  } catch {
@@ -2779,8 +2811,11 @@
2779
2811
  }
2780
2812
 
2781
2813
  function getWebWorker(url, baseURI, workerData, isModuleType, useBlobURI = true) {
2814
+ const { createWorker } = workerData;
2782
2815
  let worker, resolvedURI, resolvedOptions;
2783
- if (webWorkerURI === UNDEFINED_VALUE || webWorkerSource !== url) {
2816
+ if (createWorker) {
2817
+ worker = createWorker();
2818
+ } else if (webWorkerURI === UNDEFINED_VALUE || webWorkerSource !== url) {
2784
2819
  // deno-lint-ignore valid-typeof
2785
2820
  const isFunctionURI = typeof url == FUNCTION_TYPE;
2786
2821
  if (isFunctionURI) {
@@ -3035,7 +3070,7 @@
3035
3070
  async function runWorker(stream, workerOptions) {
3036
3071
  const { options, config } = workerOptions;
3037
3072
  const { transferStreams, useWebWorkers, useCompressionStream, compressed, checkCrc32, computeCrc32, encrypted, format, codecURI } = options;
3038
- const { workerURI, maxWorkers } = config;
3073
+ const { workerURI, createWorker, maxWorkers } = config;
3039
3074
  if (format) {
3040
3075
  if (codecURI) {
3041
3076
  options.codecURI = resolveCodecURI(codecURI, config.baseURI);
@@ -3047,6 +3082,7 @@
3047
3082
  const workerSupported = format === UNDEFINED_VALUE || Boolean(options.codecURI);
3048
3083
  workerOptions.useWebWorkers = !streamCopy && workerSupported && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
3049
3084
  workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
3085
+ workerOptions.createWorker = workerOptions.useWebWorkers && createWorker ? createWorker : UNDEFINED_VALUE;
3050
3086
  options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
3051
3087
  return (await getWorker()).run();
3052
3088
 
@@ -3110,7 +3146,7 @@
3110
3146
  starvationTimeout = null;
3111
3147
  if (pendingRequests.length) {
3112
3148
  const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
3113
- const inlineWorkerOptions = Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE });
3149
+ const inlineWorkerOptions = Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE, createWorker: UNDEFINED_VALUE });
3114
3150
  resolve(new CodecWorker({}, stream, inlineWorkerOptions, onInlineTaskFinished));
3115
3151
  armStarvationTimeout();
3116
3152
  }
@@ -4419,6 +4455,8 @@
4419
4455
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
4420
4456
  const OPTION_STRICTNESS = "strictness";
4421
4457
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
4458
+ const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
4459
+ const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
4422
4460
  const STRICTNESS_STRICT = "strict";
4423
4461
  const STRICTNESS_BALANCED = "balanced";
4424
4462
  const STRICTNESS_TOLERANT = "tolerant";
@@ -4544,6 +4582,7 @@
4544
4582
  let startOffset;
4545
4583
  let zip64EndOfDirectory;
4546
4584
  let zip64EndOfDirectoryVersion2;
4585
+ let directoryEncryptionInfo;
4547
4586
  const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
4548
4587
  if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
4549
4588
  directoryDataOffset += getDiskOffset$1(reader, diskNumber);
@@ -4574,6 +4613,15 @@
4574
4613
  }
4575
4614
  zip64EndOfDirectory = true;
4576
4615
  zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
4616
+ if (zip64EndOfDirectoryVersion2) {
4617
+ const extensibleDataLength = Math.min(
4618
+ Number(getBigUint64(endOfDirectoryView, 4)) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
4619
+ reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4620
+ if (extensibleDataLength > 0) {
4621
+ const rawExtensibleData = await readUint8Array(reader, directoryDataOffset + ZIP64_END_OF_CENTRAL_DIR_LENGTH, extensibleDataLength);
4622
+ directoryEncryptionInfo = getDirectoryEncryptionInfo(rawExtensibleData);
4623
+ }
4624
+ }
4577
4625
  if (lastDiskNumber == MAX_16_BITS) {
4578
4626
  lastDiskNumber = getUint32(endOfDirectoryView, 16);
4579
4627
  } else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
@@ -4597,7 +4645,7 @@
4597
4645
  directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4598
4646
  }
4599
4647
  }
4600
- const declaredDirectoryDataLength = directoryDataLength;
4648
+ let declaredDirectoryDataLength = directoryDataLength;
4601
4649
  const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
4602
4650
  (zip64EndOfDirectory ? ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
4603
4651
  if (directoryDataOffset >= reader.size) {
@@ -4645,6 +4693,18 @@
4645
4693
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
4646
4694
  throw new Error(ERR_BAD_FORMAT);
4647
4695
  }
4696
+ zipReader.directoryOffset = directoryDataOffset;
4697
+ zipReader.directoryLength = declaredDirectoryDataLength;
4698
+ const decryptCentralDirectory = getOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4699
+ let decryptedDirectory;
4700
+ if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
4701
+ getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4702
+ (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4703
+ directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
4704
+ directoryView = getDataView(directoryArray);
4705
+ declaredDirectoryDataLength = directoryArray.length;
4706
+ decryptedDirectory = true;
4707
+ }
4648
4708
  startOffset = directoryDataOffset;
4649
4709
  const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
4650
4710
  const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
@@ -4653,7 +4713,7 @@
4653
4713
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4654
4714
  const fileEntry = new ZipEntry(reader, config, zipReader.options);
4655
4715
  if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4656
- if (indexFile == 0 && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4716
+ if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4657
4717
  throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
4658
4718
  }
4659
4719
  throw new Error(ERR_CENTRAL_DIRECTORY_NOT_FOUND);
@@ -4766,7 +4826,15 @@
4766
4826
  }
4767
4827
  yield entry;
4768
4828
  }
4769
- if (checkAmbiguity && offset != declaredDirectoryDataLength) {
4829
+ let offsetAfterSignature = offset;
4830
+ if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
4831
+ const signatureDataLength = getUint16(directoryView, offset + 4);
4832
+ if (offset + 6 + signatureDataLength <= directoryArray.length) {
4833
+ zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
4834
+ offsetAfterSignature = offset + 6 + signatureDataLength;
4835
+ }
4836
+ }
4837
+ if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
4770
4838
  throwAmbiguousArchive("trailing central directory data");
4771
4839
  }
4772
4840
  if (duplicateFilename) {
@@ -5038,6 +5106,25 @@
5038
5106
  return false;
5039
5107
  }
5040
5108
 
5109
+ function getDirectoryEncryptionInfo(rawExtensibleData) {
5110
+ const directoryEncryptionInfo = { rawExtensibleData };
5111
+ if (rawExtensibleData.length >= 28) {
5112
+ const extensibleDataView = getDataView(rawExtensibleData);
5113
+ const hashDataLength = getUint16(extensibleDataView, 26);
5114
+ Object.assign(directoryEncryptionInfo, {
5115
+ compressionMethod: getUint16(extensibleDataView, 0),
5116
+ compressedSize: Number(getBigUint64(extensibleDataView, 2)),
5117
+ uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
5118
+ encryptionAlgorithm: getUint16(extensibleDataView, 18),
5119
+ bitLength: getUint16(extensibleDataView, 20),
5120
+ flags: getUint16(extensibleDataView, 22),
5121
+ hashAlgorithm: getUint16(extensibleDataView, 24),
5122
+ hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
5123
+ });
5124
+ }
5125
+ return directoryEncryptionInfo;
5126
+ }
5127
+
5041
5128
  function readCommonHeader(directory, dataView, offset) {
5042
5129
  const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
5043
5130
  const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
@@ -5589,6 +5676,7 @@
5589
5676
  ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
5590
5677
  ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
5591
5678
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
5679
+ ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
5592
5680
  ZipReader: ZipReader,
5593
5681
  ZipReaderStream: ZipReaderStream
5594
5682
  });
@@ -5647,6 +5735,7 @@
5647
5735
  const ERR_INVALID_UNIX_ID_SIZE = "uid/gid must be 0..65535 for unixExtraFieldType 'unix' (use 'infozip' for larger ids)";
5648
5736
  const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
5649
5737
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
5738
+ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
5650
5739
 
5651
5740
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
5652
5741
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
@@ -7006,8 +7095,9 @@
7006
7095
 
7007
7096
  async function closeFile(zipWriter, comment, options) {
7008
7097
  const directoryDataLength = createDirectoryRecords(zipWriter.files);
7009
- const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7010
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
7098
+ const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7099
+ const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
7100
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
7011
7101
  }
7012
7102
 
7013
7103
  function createDirectoryRecords(files) {
@@ -7164,12 +7254,33 @@
7164
7254
  }
7165
7255
  }
7166
7256
  await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
7167
- return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
7257
+ return {
7258
+ directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
7259
+ directoryArray
7260
+ };
7261
+ }
7262
+
7263
+ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7264
+ const signCentralDirectory = getOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
7265
+ if (signCentralDirectory) {
7266
+ const signatureData = await signCentralDirectory(directoryArray);
7267
+ const signatureDataLength = getLength(signatureData);
7268
+ if (signatureDataLength > MAX_16_BITS) {
7269
+ throw new Error(ERR_INVALID_SIGNATURE_DATA);
7270
+ }
7271
+ const signatureRecord = createRecordWriter(6 + signatureDataLength);
7272
+ signatureRecord.uint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7273
+ signatureRecord.uint16(signatureDataLength);
7274
+ signatureRecord.bytes(signatureData);
7275
+ await writeData(zipWriter.writer, signatureRecord.array);
7276
+ return 6 + signatureDataLength;
7277
+ }
7278
+ return 0;
7168
7279
  }
7169
7280
 
7170
7281
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7171
7282
  const { writer } = zipWriter;
7172
- const { directoryStart } = cdInfo;
7283
+ const { directoryStart, signatureLength } = cdInfo;
7173
7284
  let { directoryDataLength } = cdInfo;
7174
7285
  let filesLength = zipWriter.files.size;
7175
7286
  let diskNumber = directoryStart.diskNumber;
@@ -7208,7 +7319,7 @@
7208
7319
  endOfdirectoryRecord.uint64(directoryOffset);
7209
7320
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
7210
7321
  endOfdirectoryRecord.uint32(lastDiskNumber);
7211
- endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
7322
+ endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
7212
7323
  endOfdirectoryRecord.uint32(lastDiskNumber + 1);
7213
7324
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
7214
7325
  if (supportZip64SplitFile) {
@@ -7913,9 +8024,17 @@
7913
8024
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
7914
8025
  exports.ERR_INVALID_EXTRAFIELD_DATA = ERR_INVALID_EXTRAFIELD_DATA;
7915
8026
  exports.ERR_INVALID_EXTRAFIELD_TYPE = ERR_INVALID_EXTRAFIELD_TYPE;
8027
+ exports.ERR_INVALID_GID = ERR_INVALID_GID;
8028
+ exports.ERR_INVALID_MSDOS_ATTRIBUTES = ERR_INVALID_MSDOS_ATTRIBUTES;
8029
+ exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
7916
8030
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
7917
8031
  exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
8032
+ exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
8033
+ exports.ERR_INVALID_UID = ERR_INVALID_UID;
7918
8034
  exports.ERR_INVALID_UNCOMPRESSED_SIZE = ERR_INVALID_UNCOMPRESSED_SIZE;
8035
+ exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
8036
+ exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
8037
+ exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
7919
8038
  exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
7920
8039
  exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
7921
8040
  exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
@@ -7925,9 +8044,12 @@
7925
8044
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
7926
8045
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
7927
8046
  exports.ERR_UNSUPPORTED_COMPRESSION = ERR_UNSUPPORTED_COMPRESSION$1;
8047
+ exports.ERR_UNSUPPORTED_CONTEXT = ERR_UNSUPPORTED_CONTEXT;
8048
+ exports.ERR_UNSUPPORTED_CRYPTO_API = ERR_UNSUPPORTED_CRYPTO_API;
7928
8049
  exports.ERR_UNSUPPORTED_ENCRYPTION = ERR_UNSUPPORTED_ENCRYPTION;
7929
8050
  exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
7930
8051
  exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
8052
+ exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
7931
8053
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
7932
8054
  exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
7933
8055
  exports.HttpRangeReader = HttpRangeReader;