@zip.js/zip.js 2.8.42 → 2.8.44

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 (46) hide show
  1. package/README.md +0 -37
  2. package/deno.json +1 -1
  3. package/dist/zip-core-external.js +178 -77
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +179 -76
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +178 -77
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +177 -76
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +178 -77
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +180 -77
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +180 -77
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +180 -77
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-native.js +180 -77
  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 +180 -77
  24. package/dist/zip.min.js +1 -1
  25. package/index-native.cjs +180 -77
  26. package/index-native.min.js +1 -1
  27. package/index.cjs +180 -77
  28. package/index.d.cts +80 -7
  29. package/index.d.ts +80 -7
  30. package/index.min.js +1 -1
  31. package/lib/core/codec-pool.js +6 -2
  32. package/lib/core/codec-worker.js +23 -2
  33. package/lib/core/options.js +4 -0
  34. package/lib/core/streams/aes-crypto-stream.js +4 -4
  35. package/lib/core/streams/codec-stream.js +8 -2
  36. package/lib/core/streams/common-crypto.js +2 -0
  37. package/lib/core/streams/zip-entry-stream.js +102 -36
  38. package/lib/core/web-worker-inline-native.js +1 -1
  39. package/lib/core/web-worker-inline-wasm.js +1 -1
  40. package/lib/core/web-worker-wasm.js +4 -8
  41. package/lib/core/zip-entry.js +3 -0
  42. package/lib/core/zip-reader.js +35 -26
  43. package/lib/core/zip-writer.js +22 -10
  44. package/lib/zip-core-reader.js +2 -0
  45. package/package.json +1 -1
  46. package/worker-message-property-names.js +1 -1
package/dist/zip-core.js CHANGED
@@ -1369,6 +1369,7 @@
1369
1369
 
1370
1370
  const ERR_INVALID_PASSWORD = "Invalid password";
1371
1371
  const ERR_INVALID_SIGNATURE = "Invalid signature";
1372
+ const ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_SIGNATURE;
1372
1373
  const ERR_ABORT_CHECK_PASSWORD = "zipjs-abort-check-password";
1373
1374
  const ERR_UNSUPPORTED_CRYPTO_API = "Crypto API not supported";
1374
1375
 
@@ -1435,7 +1436,7 @@
1435
1436
 
1436
1437
  class AESDecryptionStream extends TransformStream {
1437
1438
 
1438
- constructor({ password, rawPassword, encryptionStrength, checkPasswordOnly }) {
1439
+ constructor({ password, rawPassword, encryptionStrength, checkPasswordOnly, checkAuthenticationCode = true }) {
1439
1440
  super({
1440
1441
  start() {
1441
1442
  initAesCrypto(this, password, rawPassword, encryptionStrength);
@@ -1485,8 +1486,8 @@
1485
1486
  for (let indexSignature = 0; indexSignature < SIGNATURE_LENGTH; indexSignature++) {
1486
1487
  invalidSignature |= signature[indexSignature] ^ originalSignature[indexSignature];
1487
1488
  }
1488
- if (invalidSignature) {
1489
- throw new Error(ERR_INVALID_SIGNATURE);
1489
+ if (invalidSignature && checkAuthenticationCode) {
1490
+ throw new Error(ERR_INVALID_AUTHENTICATION_CODE);
1490
1491
  }
1491
1492
  controller.enqueue(decryptedChunkArray);
1492
1493
  }
@@ -1924,6 +1925,7 @@
1924
1925
 
1925
1926
  const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
1926
1927
  const ERR_INVALID_COMPRESSED_DATA = "Invalid compressed data";
1928
+ const ERR_INVALID_CRC32 = ERR_INVALID_SIGNATURE;
1927
1929
  const ERR_UNSUPPORTED_COMPRESSION$2 = "Compression method not supported";
1928
1930
  const FORMAT_DEFLATE_RAW = "deflate-raw";
1929
1931
  const FORMAT_DEFLATE64_RAW = "deflate64-raw";
@@ -1931,19 +1933,20 @@
1931
1933
  const GZIP_HEADER_LENGTH = 10;
1932
1934
  const GZIP_TRAILER_LENGTH = 8;
1933
1935
  const GZIP_HEADER_BYTES = [0x1f, 0x8b, 0x08];
1936
+ const GZIP_OUTPUT_STALL_TIMEOUT = 5000;
1934
1937
 
1935
1938
  class DeflateStream extends TransformStream {
1936
1939
 
1937
1940
  constructor(options, { chunkSize, CompressionStreamZlib, CompressionStream }) {
1938
1941
  super({});
1939
- const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level, deflate64, format, compressionMethod } = options;
1942
+ const { compressed, encrypted, useCompressionStream, zipCrypto, computeCrc32, level, deflate64, format, compressionMethod } = options;
1940
1943
  const stream = this;
1941
1944
  let crc32Stream, encryptionStream, gzipCrc32Stream;
1942
1945
  let readable = super.readable;
1943
1946
  const codecStreams = format && getCodecStreams(format);
1944
- const useGzipCrc32 = signed && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) &&
1947
+ const useGzipCrc32 = computeCrc32 && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) &&
1945
1948
  Boolean(useCompressionStream && CompressionStream);
1946
- if ((!encrypted || zipCrypto) && signed && !useGzipCrc32) {
1949
+ if ((!encrypted || zipCrypto) && computeCrc32 && !useGzipCrc32) {
1947
1950
  crc32Stream = new Crc32Stream();
1948
1951
  readable = pipeThrough(readable, crc32Stream);
1949
1952
  }
@@ -1982,7 +1985,7 @@
1982
1985
  if (encrypted && !zipCrypto) {
1983
1986
  signature = encryptionStream.signature;
1984
1987
  }
1985
- if ((!encrypted || zipCrypto) && signed) {
1988
+ if ((!encrypted || zipCrypto) && computeCrc32) {
1986
1989
  signature = useGzipCrc32 ? gzipCrc32Stream.signature : new DataView(crc32Stream.value.buffer).getUint32(0);
1987
1990
  }
1988
1991
  stream.signature = signature;
@@ -2031,26 +2034,73 @@
2031
2034
  }
2032
2035
  }
2033
2036
 
2034
- class RawDeflateToGzipStream extends TransformStream {
2037
+ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize) {
2038
+ const crc32 = new Crc32();
2039
+ let outputLength = 0;
2040
+ let inputDone = false;
2041
+ let watchdogTimeout;
2042
+ let resolveTrailerReady, rejectTrailerReady;
2043
+ const trailerReady = new Promise((resolve, reject) => {
2044
+ resolveTrailerReady = resolve;
2045
+ rejectTrailerReady = reject;
2046
+ });
2047
+ trailerReady.catch(() => { });
2048
+ if (!outputSize) {
2049
+ resolveTrailerReady();
2050
+ }
2051
+ const gzipWrapStream = new TransformStream({
2052
+ start(controller) {
2053
+ const header = new Uint8Array(GZIP_HEADER_LENGTH);
2054
+ header.set(GZIP_HEADER_BYTES);
2055
+ controller.enqueue(header);
2056
+ },
2057
+ transform(chunk, controller) {
2058
+ controller.enqueue(chunk);
2059
+ },
2060
+ async flush(controller) {
2061
+ inputDone = true;
2062
+ startWatchdog();
2063
+ try {
2064
+ await trailerReady;
2065
+ } finally {
2066
+ stopWatchdog();
2067
+ }
2068
+ const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
2069
+ const dataView = getDataView(trailer);
2070
+ dataView.setUint32(0, crc32.get(), true);
2071
+ dataView.setUint32(4, outputSize, true);
2072
+ controller.enqueue(trailer);
2073
+ },
2074
+ cancel(reason) {
2075
+ rejectTrailerReady(reason);
2076
+ }
2077
+ });
2078
+ const outputStream = new TransformStream({
2079
+ transform(chunk, controller) {
2080
+ crc32.append(chunk);
2081
+ outputLength += chunk.length;
2082
+ if (outputLength >= outputSize) {
2083
+ resolveTrailerReady();
2084
+ } else if (inputDone) {
2085
+ startWatchdog();
2086
+ }
2087
+ controller.enqueue(chunk);
2088
+ },
2089
+ cancel(reason) {
2090
+ rejectTrailerReady(reason);
2091
+ }
2092
+ });
2093
+ readable = pipeThrough(readable, gzipWrapStream);
2094
+ readable = pipeThroughBackpressured(readable, gzipStream);
2095
+ return pipeThrough(readable, outputStream);
2035
2096
 
2036
- constructor(signature, uncompressedSize) {
2037
- super({
2038
- start(controller) {
2039
- const header = new Uint8Array(GZIP_HEADER_LENGTH);
2040
- header.set(GZIP_HEADER_BYTES);
2041
- controller.enqueue(header);
2042
- },
2043
- transform(chunk, controller) {
2044
- controller.enqueue(chunk);
2045
- },
2046
- flush(controller) {
2047
- const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
2048
- const dataView = getDataView(trailer);
2049
- dataView.setUint32(0, signature, true);
2050
- dataView.setUint32(4, uncompressedSize, true);
2051
- controller.enqueue(trailer);
2052
- }
2053
- });
2097
+ function startWatchdog() {
2098
+ stopWatchdog();
2099
+ watchdogTimeout = setTimeout(() => rejectTrailerReady(new Error(ERR_INVALID_UNCOMPRESSED_SIZE)), GZIP_OUTPUT_STALL_TIMEOUT);
2100
+ }
2101
+
2102
+ function stopWatchdog() {
2103
+ clearTimeout(watchdogTimeout);
2054
2104
  }
2055
2105
  }
2056
2106
 
@@ -2058,7 +2108,7 @@
2058
2108
 
2059
2109
  constructor(options, { chunkSize, DecompressionStreamZlib, DecompressionStream }) {
2060
2110
  super({});
2061
- const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream, deflate64, format, compressionMethod, rawBitFlag, outputSize } = options;
2111
+ const { zipCrypto, encrypted, checkCrc32, signature, compressed, useCompressionStream, deflate64, format, compressionMethod, rawBitFlag, outputSize } = options;
2062
2112
  let crc32Stream, decryptionStream;
2063
2113
  let readable = super.readable;
2064
2114
  if (encrypted) {
@@ -2077,7 +2127,7 @@
2077
2127
  try {
2078
2128
  readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamZlib);
2079
2129
  } catch (error) {
2080
- if (deflate64 || (encrypted && !zipCrypto) || signature === UNDEFINED_VALUE || outputSize === UNDEFINED_VALUE) {
2130
+ if (deflate64 || outputSize === UNDEFINED_VALUE) {
2081
2131
  throw error;
2082
2132
  }
2083
2133
  let gzipStream;
@@ -2086,46 +2136,58 @@
2086
2136
  } catch {
2087
2137
  throw error;
2088
2138
  }
2089
- readable = pipeThrough(readable, new RawDeflateToGzipStream(signature, outputSize));
2090
- readable = pipeThroughBackpressured(readable, gzipStream);
2139
+ readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize);
2091
2140
  }
2092
2141
  }
2093
2142
  readable = mapInflateStreamError(readable);
2094
2143
  }
2095
- if ((!encrypted || zipCrypto) && signed) {
2144
+ if (checkCrc32) {
2096
2145
  crc32Stream = new Crc32Stream();
2097
2146
  readable = pipeThrough(readable, crc32Stream);
2098
2147
  }
2099
2148
  setReadable(this, readable, () => {
2100
- if ((!encrypted || zipCrypto) && signed) {
2149
+ if (checkCrc32) {
2101
2150
  const dataViewSignature = new DataView(crc32Stream.value.buffer);
2102
2151
  if (signature != dataViewSignature.getUint32(0, false)) {
2103
- throw new Error(ERR_INVALID_SIGNATURE);
2152
+ throw new Error(ERR_INVALID_CRC32);
2104
2153
  }
2105
2154
  }
2106
2155
  });
2107
2156
  }
2108
2157
  }
2109
2158
 
2110
- const deflateRawSupportByStream = new Map();
2159
+ const formatSupportByStream = new Map();
2111
2160
 
2112
- function supportsDeflateRaw(StreamClass) {
2161
+ function supportsFormat(StreamClass, format) {
2113
2162
  if (!StreamClass) {
2114
2163
  return false;
2115
2164
  }
2116
- let supported = deflateRawSupportByStream.get(StreamClass);
2165
+ let supportByFormat = formatSupportByStream.get(StreamClass);
2166
+ if (!supportByFormat) {
2167
+ supportByFormat = new Map();
2168
+ formatSupportByStream.set(StreamClass, supportByFormat);
2169
+ }
2170
+ let supported = supportByFormat.get(format);
2117
2171
  if (supported === UNDEFINED_VALUE) {
2118
2172
  try {
2119
- new StreamClass(FORMAT_DEFLATE_RAW);
2173
+ new StreamClass(format);
2120
2174
  supported = true;
2121
2175
  } catch {
2122
2176
  supported = false;
2123
2177
  }
2124
- deflateRawSupportByStream.set(StreamClass, supported);
2178
+ supportByFormat.set(format, supported);
2125
2179
  }
2126
2180
  return supported;
2127
2181
  }
2128
2182
 
2183
+ function supportsDeflateRaw(StreamClass) {
2184
+ return supportsFormat(StreamClass, FORMAT_DEFLATE_RAW);
2185
+ }
2186
+
2187
+ function supportsGzip(StreamClass) {
2188
+ return supportsFormat(StreamClass, FORMAT_GZIP);
2189
+ }
2190
+
2129
2191
  function setReadable(stream, readable, flush) {
2130
2192
  readable = pipeThrough(readable, new TransformStream({ flush }));
2131
2193
  Object.defineProperty(stream, "readable", {
@@ -2424,6 +2486,25 @@
2424
2486
  }
2425
2487
  let initModule = () => { };
2426
2488
 
2489
+ async function supportsDeflate(config) {
2490
+ const { CompressionStream: NativeStream, CompressionStreamZlib: ZlibStream } = config;
2491
+ if (ZlibStream && !ZlibStream.requiresModule) {
2492
+ return true;
2493
+ }
2494
+ if (supportsDeflateRaw(NativeStream) || supportsGzip(NativeStream)) {
2495
+ return true;
2496
+ }
2497
+ if (ZlibStream) {
2498
+ try {
2499
+ await initModule(config);
2500
+ return true;
2501
+ } catch {
2502
+ return false;
2503
+ }
2504
+ }
2505
+ return false;
2506
+ }
2507
+
2427
2508
  function resetWebWorkerSupport() {
2428
2509
  webWorkerSupported = UNDEFINED_VALUE;
2429
2510
  }
@@ -2959,7 +3040,7 @@
2959
3040
 
2960
3041
  async function runWorker(stream, workerOptions) {
2961
3042
  const { options, config } = workerOptions;
2962
- const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted, format, codecURI } = options;
3043
+ const { transferStreams, useWebWorkers, useCompressionStream, compressed, checkCrc32, computeCrc32, encrypted, format, codecURI } = options;
2963
3044
  const { workerURI, maxWorkers } = config;
2964
3045
  if (format) {
2965
3046
  if (codecURI) {
@@ -2968,7 +3049,7 @@
2968
3049
  await ensureCodecStreams(format, options.codecURI);
2969
3050
  }
2970
3051
  workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
2971
- const streamCopy = !compressed && !signed && !encrypted;
3052
+ const streamCopy = !compressed && !checkCrc32 && !computeCrc32 && !encrypted;
2972
3053
  const workerSupported = format === UNDEFINED_VALUE || Boolean(options.codecURI);
2973
3054
  workerOptions.useWebWorkers = !streamCopy && workerSupported && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
2974
3055
  workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
@@ -4192,6 +4273,7 @@
4192
4273
  const PROPERTY_NAME_EXECUTABLE = "executable";
4193
4274
  const PROPERTY_NAME_COMPRESSION_METHOD = "compressionMethod";
4194
4275
  const PROPERTY_NAME_SIGNATURE = "signature";
4276
+ const PROPERTY_NAME_CRC32 = "crc32";
4195
4277
  const PROPERTY_NAME_EXTRA_FIELD = "extraField";
4196
4278
  const PROPERTY_NAME_EXTRA_FIELD_INFOZIP = "extraFieldInfoZip";
4197
4279
  const PROPERTY_NAME_EXTRA_FIELD_UNIX = "extraFieldUnix";
@@ -4240,6 +4322,7 @@
4240
4322
  PROPERTY_NAME_EXECUTABLE,
4241
4323
  PROPERTY_NAME_COMPRESSION_METHOD,
4242
4324
  PROPERTY_NAME_SIGNATURE,
4325
+ PROPERTY_NAME_CRC32,
4243
4326
  PROPERTY_NAME_EXTRA_FIELD,
4244
4327
  PROPERTY_NAME_EXTRA_FIELD_UNIX,
4245
4328
  PROPERTY_NAME_EXTRA_FIELD_INFOZIP,
@@ -4311,6 +4394,8 @@
4311
4394
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
4312
4395
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
4313
4396
  const OPTION_CHECK_SIGNATURE = "checkSignature";
4397
+ const OPTION_CHECK_CRC32 = "checkCrc32";
4398
+ const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
4314
4399
  const OPTION_USE_WEB_WORKERS = "useWebWorkers";
4315
4400
  const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
4316
4401
  const OPTION_TRANSFER_STREAMS = "transferStreams";
@@ -4382,6 +4467,7 @@
4382
4467
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
4383
4468
  const CHARSET_CP437 = "cp437";
4384
4469
  const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_LANG_ENCODING_FLAG;
4470
+ const VENDOR_VERSION_AE_1 = 1;
4385
4471
  const ZIP64_PROPERTIES = [
4386
4472
  [PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS],
4387
4473
  [PROPERTY_NAME_COMPRESSED_SIZE, MAX_32_BITS],
@@ -4861,6 +4947,11 @@
4861
4947
  if (deflate64) {
4862
4948
  useCompressionStream = false;
4863
4949
  }
4950
+ const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
4951
+ const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
4952
+ getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
4953
+ checkCrc32Option) && !passThrough &&
4954
+ (!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1));
4864
4955
  const workerOptions = {
4865
4956
  options: {
4866
4957
  codecType: CODEC_INFLATE,
@@ -4868,7 +4959,8 @@
4868
4959
  rawPassword,
4869
4960
  zipCrypto,
4870
4961
  encryptionStrength: extraFieldAES && extraFieldAES.strength,
4871
- signed: getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) && !passThrough,
4962
+ checkCrc32,
4963
+ checkAuthenticationCode: getOptionValue$1(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
4872
4964
  passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((signature >>> 24) & MAX_8_BITS)),
4873
4965
  outputSize: passThrough ? compressedSize : uncompressedSize,
4874
4966
  signature,
@@ -4984,6 +5076,7 @@
4984
5076
  const compressionMethod = getUint16(dataView, offset + 4);
4985
5077
  Object.assign(directory, {
4986
5078
  signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
5079
+ crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
4987
5080
  compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
4988
5081
  uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
4989
5082
  });
@@ -5085,6 +5178,9 @@
5085
5178
  compressionMethod: getUint16(extraFieldView, 5)
5086
5179
  });
5087
5180
  directory.compressionMethod = extraFieldAES.compressionMethod;
5181
+ if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1) {
5182
+ directory.crc32 = UNDEFINED_VALUE;
5183
+ }
5088
5184
  }
5089
5185
 
5090
5186
  function readExtraFieldNTFS(extraFieldNTFS, directory) {
@@ -5103,26 +5199,22 @@
5103
5199
  } catch {
5104
5200
  // ignored
5105
5201
  }
5106
- try {
5107
- if (tag1Data && tag1Data.length == 24) {
5108
- const tag1View = getDataView(tag1Data);
5109
- const rawLastModDate = tag1View.getBigUint64(0, true);
5110
- const rawLastAccessDate = tag1View.getBigUint64(8, true);
5111
- const rawCreationDate = tag1View.getBigUint64(16, true);
5112
- Object.assign(extraFieldNTFS, {
5113
- rawLastModDate,
5114
- rawLastAccessDate,
5115
- rawCreationDate
5116
- });
5117
- const lastModDate = getDateNTFS(rawLastModDate);
5118
- const lastAccessDate = getDateNTFS(rawLastAccessDate);
5119
- const creationDate = getDateNTFS(rawCreationDate);
5120
- const extraFieldData = { lastModDate, lastAccessDate, creationDate };
5121
- Object.assign(extraFieldNTFS, extraFieldData);
5122
- Object.assign(directory, extraFieldData);
5123
- }
5124
- } catch {
5125
- // ignored
5202
+ if (tag1Data && tag1Data.length == 24) {
5203
+ const tag1View = getDataView(tag1Data);
5204
+ const rawLastModDate = tag1View.getBigUint64(0, true);
5205
+ const rawLastAccessDate = tag1View.getBigUint64(8, true);
5206
+ const rawCreationDate = tag1View.getBigUint64(16, true);
5207
+ Object.assign(extraFieldNTFS, {
5208
+ rawLastModDate,
5209
+ rawLastAccessDate,
5210
+ rawCreationDate
5211
+ });
5212
+ const lastModDate = getDateNTFS(rawLastModDate);
5213
+ const lastAccessDate = getDateNTFS(rawLastAccessDate);
5214
+ const creationDate = getDateNTFS(rawCreationDate);
5215
+ const extraFieldData = { lastModDate, lastAccessDate, creationDate };
5216
+ Object.assign(extraFieldNTFS, extraFieldData);
5217
+ Object.assign(directory, extraFieldData);
5126
5218
  }
5127
5219
  }
5128
5220
 
@@ -5425,11 +5517,7 @@
5425
5517
 
5426
5518
  function getDate(timeRaw) {
5427
5519
  const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
5428
- try {
5429
- return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
5430
- } catch {
5431
- // ignored
5432
- }
5520
+ return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
5433
5521
  }
5434
5522
 
5435
5523
  function getDateNTFS(timeRaw) {
@@ -5462,7 +5550,9 @@
5462
5550
  ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
5463
5551
  ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
5464
5552
  ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
5553
+ ERR_INVALID_AUTHENTICATION_CODE: ERR_INVALID_AUTHENTICATION_CODE,
5465
5554
  ERR_INVALID_COMPRESSED_DATA: ERR_INVALID_COMPRESSED_DATA,
5555
+ ERR_INVALID_CRC32: ERR_INVALID_CRC32,
5466
5556
  ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
5467
5557
  ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
5468
5558
  ERR_INVALID_UNCOMPRESSED_SIZE: ERR_INVALID_UNCOMPRESSED_SIZE,
@@ -5516,6 +5606,8 @@
5516
5606
  const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
5517
5607
  const MIN_UNIX_TIME = -2147483648;
5518
5608
  const MAX_UNIX_TIME = 2147483647;
5609
+ const MIN_NTFS_TIME = BigInt(0);
5610
+ const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
5519
5611
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
5520
5612
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
5521
5613
  const ERR_UNDEFINED_READER = "Undefined reader";
@@ -5797,6 +5889,11 @@
5797
5889
  zipWriter.files.set(name, UNDEFINED_VALUE);
5798
5890
  let fileEntry;
5799
5891
  try {
5892
+ const { resolvedOptions } = metadataInfo;
5893
+ if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
5894
+ !resolvedOptions.passThrough && !(await supportsDeflate(zipWriter.config))) {
5895
+ resolvedOptions.level = 0;
5896
+ }
5800
5897
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
5801
5898
  ({ reader } = sizesInfo);
5802
5899
  const diskOffset = getDiskOffset(zipWriter.writer);
@@ -6017,9 +6114,6 @@
6017
6114
  if (level !== UNDEFINED_VALUE && level != 6) {
6018
6115
  useCompressionStream = false;
6019
6116
  }
6020
- if (!useCompressionStream && !registeredCodec && (zipWriter.config.CompressionStream === UNDEFINED_VALUE && zipWriter.config.CompressionStreamZlib === UNDEFINED_VALUE)) {
6021
- level = 0;
6022
- }
6023
6117
  const zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
6024
6118
  if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(encryptionStrength >= 1 && encryptionStrength <= 3)) {
6025
6119
  throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
@@ -6407,9 +6501,12 @@
6407
6501
  msdosAttributes
6408
6502
  };
6409
6503
  let {
6410
- signature,
6504
+ crc32: signature,
6411
6505
  uncompressedSize
6412
6506
  } = options;
6507
+ if (signature === UNDEFINED_VALUE) {
6508
+ ({ signature } = options);
6509
+ }
6413
6510
  let compressedSize = 0;
6414
6511
  if (!passThrough) {
6415
6512
  uncompressedSize = 0;
@@ -6427,7 +6524,7 @@
6427
6524
  encryptionStrength,
6428
6525
  zipCrypto: encrypted && zipCrypto,
6429
6526
  passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
6430
- signed: !passThrough,
6527
+ computeCrc32: !passThrough,
6431
6528
  compressed: compressed && !passThrough,
6432
6529
  encrypted: encrypted && !passThrough,
6433
6530
  useWebWorkers,
@@ -6446,7 +6543,9 @@
6446
6543
  writer.size += compressedSize;
6447
6544
  if (!passThrough) {
6448
6545
  uncompressedSize = result.inputSize;
6449
- signature = result.signature;
6546
+ if (!encrypted || zipCrypto) {
6547
+ signature = result.signature;
6548
+ }
6450
6549
  }
6451
6550
  if ((!zip64CompressedSize && compressedSize >= MAX_32_BITS) ||
6452
6551
  (!zip64UncompressedSize && uncompressedSize >= MAX_32_BITS)) {
@@ -6485,6 +6584,7 @@
6485
6584
  headerArray,
6486
6585
  headerView,
6487
6586
  signature,
6587
+ crc32: encrypted && !zipCrypto ? UNDEFINED_VALUE : signature,
6488
6588
  extraFieldExtendedTimestampFlag,
6489
6589
  zip64UncompressedSize,
6490
6590
  zip64CompressedSize
@@ -6585,8 +6685,8 @@
6585
6685
  extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS_TAG1);
6586
6686
  extraFieldNTFS.uint16(24);
6587
6687
  extraFieldNTFS.uint64(lastModTimeNTFS);
6588
- extraFieldNTFS.uint64(getTimeNTFS(lastAccessDate) || lastModTimeNTFS);
6589
- extraFieldNTFS.uint64(getTimeNTFS(creationDate) || lastModTimeNTFS);
6688
+ extraFieldNTFS.uint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
6689
+ extraFieldNTFS.uint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
6590
6690
  rawExtraFieldNTFS = extraFieldNTFS.array;
6591
6691
  } catch {
6592
6692
  rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
@@ -6646,7 +6746,7 @@
6646
6746
  if (extraFieldLength > MAX_16_BITS) {
6647
6747
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
6648
6748
  }
6649
- const dosLastModDate = new Date(Math.ceil(lastModDate.getTime() / 2000) * 2000);
6749
+ const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
6650
6750
  const {
6651
6751
  headerArray,
6652
6752
  headerView,
@@ -7155,7 +7255,8 @@
7155
7255
 
7156
7256
  function getTimeNTFS(date) {
7157
7257
  if (date) {
7158
- return ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
7258
+ const timeNTFS = ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
7259
+ return timeNTFS < MIN_NTFS_TIME ? MIN_NTFS_TIME : timeNTFS > MAX_NTFS_TIME ? MAX_NTFS_TIME : timeNTFS;
7159
7260
  }
7160
7261
  }
7161
7262
 
@@ -7760,10 +7861,12 @@
7760
7861
  exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
7761
7862
  exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
7762
7863
  exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
7864
+ exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
7763
7865
  exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
7764
7866
  exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
7765
7867
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
7766
7868
  exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
7869
+ exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
7767
7870
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
7768
7871
  exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
7769
7872
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;