@zip.js/zip.js 2.8.58 → 2.8.60

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 +2 -2
  2. package/dist/zip-core-external.js +295 -57
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +286 -40
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +295 -58
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +5867 -4360
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +295 -58
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +288 -43
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +313 -58
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +288 -42
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +288 -42
  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 +313 -57
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +288 -43
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +313 -58
  27. package/index.d.cts +318 -2
  28. package/index.d.ts +318 -2
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-registry.js +5 -0
  31. package/lib/core/compression-methods.js +93 -0
  32. package/lib/core/constants.js +2 -0
  33. package/lib/core/options.js +2 -0
  34. package/lib/core/streams/zip-entry-stream.js +7 -3
  35. package/lib/core/streams/zlib-wasm/zlib-streams.js +18 -8
  36. package/lib/core/version.js +31 -0
  37. package/lib/core/web-worker-inline-native.js +1 -1
  38. package/lib/core/web-worker-inline-wasm.js +1 -1
  39. package/lib/core/zip-reader.js +143 -33
  40. package/lib/core/zip-writer.js +14 -6
  41. package/lib/zip-core-base.js +7 -0
  42. package/lib/zip-core-reader.js +16 -1
  43. package/lib/zip-fs-core.js +32 -0
  44. package/package.json +3 -3
  45. package/sync-versions.js +26 -0
package/dist/zip-core.js CHANGED
@@ -83,6 +83,7 @@
83
83
  const BITFLAG_LEVEL_FAST_MASK = 0b100;
84
84
  const BITFLAG_LEVEL_SUPER_FAST_MASK = 0b110;
85
85
  const BITFLAG_DATA_DESCRIPTOR = 0b1000;
86
+ const BITFLAG_COMPRESSED_PATCHED_DATA = 0b100000;
86
87
  const BITFLAG_STRONG_ENCRYPTION = 0b1000000;
87
88
  const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
88
89
  const BITFLAG_MASKED_LOCAL_HEADERS = 0b10000000000000;
@@ -200,6 +201,7 @@
200
201
  const OPTION_USDZ = "usdz";
201
202
  const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
202
203
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
204
+ const OPTION_CENTRAL_EXTRA_FIELD = "centralExtraField";
203
205
  const OPTION_STRICTNESS = "strictness";
204
206
  const OPTION_FILENAME_VALIDATION = "filenameValidation";
205
207
  const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
@@ -2080,6 +2082,10 @@
2080
2082
  return registeredCodecs.get(compressionMethod);
2081
2083
  }
2082
2084
 
2085
+ function getRegisteredCodecs() {
2086
+ return Array.from(registeredCodecs.values(), codec => Object.assign({}, codec, codecStreams.get(codec.format)));
2087
+ }
2088
+
2083
2089
  function getCodecStreams(format) {
2084
2090
  return codecStreams.get(format);
2085
2091
  }
@@ -2143,7 +2149,7 @@
2143
2149
 
2144
2150
  constructor(options, { chunkSize, CompressionStreamFallback, CompressionStream }) {
2145
2151
  super({});
2146
- const { compressed, encrypted, useCompressionStream, zipCrypto, computeCrc32, level, deflate64, format, compressionMethod } = options;
2152
+ const { compressed, encrypted, useCompressionStream, zipCrypto, computeCrc32, level, deflate64, format, compressionMethod, inputSize } = options;
2147
2153
  const stream = this;
2148
2154
  let crc32Stream, encryptionStream, gzipCrc32Stream;
2149
2155
  let readable = super.readable;
@@ -2156,7 +2162,7 @@
2156
2162
  }
2157
2163
  if (compressed) {
2158
2164
  if (codecStreams) {
2159
- readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.CompressionStream, format, { level, chunkSize, compressionMethod }));
2165
+ readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.CompressionStream, format, { level, chunkSize, compressionMethod, uncompressedSize: inputSize }));
2160
2166
  } else if (useGzipCrc32) {
2161
2167
  gzipCrc32Stream = new GzipToRawDeflateStream();
2162
2168
  readable = pipeThroughBackpressured(readable, new CompressionStream(FORMAT_GZIP));
@@ -4709,6 +4715,21 @@
4709
4715
  const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
4710
4716
  const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
4711
4717
  const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
4718
+ const WARNING_UNSORTED_CENTRAL_DIRECTORY = "unsorted central directory";
4719
+ const WARNING_UNKNOWN_VERSION = "unknown version needed to extract";
4720
+ const WARNING_COMPRESSED_PATCHED_DATA = "compressed patched data";
4721
+ const WARNING_MALFORMED_EXTRA_FIELD = "malformed extra field";
4722
+ const WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = "unknown zip64 extensible data";
4723
+ const WARNING_WRAPPED_ENTRIES_COUNT = "wrapped entries count";
4724
+ const WARNING_APPENDED_DATA = "appended data";
4725
+ const WARNING_PREPENDED_DATA = "prepended data";
4726
+ const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4727
+ const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4728
+ const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
4729
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
4730
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
4731
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
4732
+ const MAX_KNOWN_VERSION = 63;
4712
4733
  const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
4713
4734
  const CHARSET_UTF8 = "utf-8";
4714
4735
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
@@ -4759,6 +4780,7 @@
4759
4780
  if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
4760
4781
  throw new Error(ERR_BAD_FORMAT);
4761
4782
  }
4783
+ const warnings = zipReader.warnings = [];
4762
4784
  const strictness = getStrictness(options, zipReader.options);
4763
4785
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4764
4786
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
@@ -4782,8 +4804,12 @@
4782
4804
  const commentOffset = endOfDirectoryInfo.offset;
4783
4805
  const commentLength = getUint16$1(endOfDirectoryView, 20);
4784
4806
  const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
4785
- if (reader.size - appendedDataOffset > maxAppendedDataSize) {
4786
- throwAmbiguousArchive("appended data");
4807
+ const appendedDataLength = reader.size - appendedDataOffset;
4808
+ if (appendedDataLength > maxAppendedDataSize) {
4809
+ throwAmbiguousArchive(WARNING_APPENDED_DATA);
4810
+ }
4811
+ if (appendedDataLength > 0) {
4812
+ addWarning(warnings, WARNING_APPENDED_DATA);
4787
4813
  }
4788
4814
  let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
4789
4815
  const expectedLastDiskNumber = reader.lastDiskNumber || 0;
@@ -4837,23 +4863,23 @@
4837
4863
  }
4838
4864
  if (lastDiskNumber == MAX_16_BITS) {
4839
4865
  lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
4840
- } else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
4841
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4866
+ } else if (lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
4867
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4842
4868
  }
4843
4869
  if (diskNumber == MAX_16_BITS) {
4844
4870
  diskNumber = getUint32$1(endOfDirectoryView, 20);
4845
- } else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
4846
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4871
+ } else if (diskNumber != getUint32$1(endOfDirectoryView, 20)) {
4872
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4847
4873
  }
4848
4874
  if (filesLength == MAX_16_BITS) {
4849
4875
  filesLength = getBigUint64(endOfDirectoryView, 32);
4850
- } else if (checkAmbiguity && filesLength != getBigUint64(endOfDirectoryView, 32)) {
4851
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4876
+ } else if (filesLength != getBigUint64(endOfDirectoryView, 32)) {
4877
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4852
4878
  }
4853
4879
  if (directoryDataLength == MAX_32_BITS) {
4854
4880
  directoryDataLength = getBigUint64(endOfDirectoryView, 40);
4855
- } else if (checkAmbiguity && directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
4856
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4881
+ } else if (directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
4882
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4857
4883
  }
4858
4884
  directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4859
4885
  }
@@ -4922,14 +4948,22 @@
4922
4948
  declaredDirectoryDataLength = directoryArray.length;
4923
4949
  decryptedDirectory = true;
4924
4950
  }
4951
+ if (directoryEncryptionInfo && !decryptedDirectory &&
4952
+ (directoryArray.length < 4 || getUint32$1(directoryView, 0) == CENTRAL_FILE_HEADER_SIGNATURE)) {
4953
+ addWarning(warnings, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA);
4954
+ }
4925
4955
  startOffset = directoryDataOffset;
4926
4956
  const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
4927
4957
  const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
4928
- const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
4958
+ const filenames = new Set();
4929
4959
  let duplicateFilename;
4960
+ let previousEntryPosition = -1;
4930
4961
  const recoverWrappedFilesLength = !checkAmbiguity && !zip64EndOfDirectory;
4931
4962
  if (!filesLength && recoverWrappedFilesLength) {
4932
4963
  filesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
4964
+ if (filesLength) {
4965
+ addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
4966
+ }
4933
4967
  }
4934
4968
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4935
4969
  const fileEntry = new ZipEntry(reader, zipReader.options);
@@ -5008,15 +5042,26 @@
5008
5042
  filename,
5009
5043
  comment
5010
5044
  });
5011
- readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
5045
+ if (readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)) {
5046
+ addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
5047
+ }
5012
5048
  fileEntry.offset += prependedDataLength;
5013
- startOffset = Math.min(getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset, startOffset);
5014
- if (checkAmbiguity) {
5015
- if (filenames.has(fileEntry.filename)) {
5016
- duplicateFilename = true;
5017
- }
5018
- filenames.add(fileEntry.filename);
5049
+ const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
5050
+ startOffset = Math.min(entryPosition, startOffset);
5051
+ if (entryPosition < previousEntryPosition) {
5052
+ addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
5019
5053
  }
5054
+ previousEntryPosition = entryPosition;
5055
+ if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
5056
+ addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
5057
+ }
5058
+ if ((fileEntry.rawBitFlag & BITFLAG_COMPRESSED_PATCHED_DATA) == BITFLAG_COMPRESSED_PATCHED_DATA) {
5059
+ addWarning(warnings, WARNING_COMPRESSED_PATCHED_DATA, filename);
5060
+ }
5061
+ if (filenames.has(fileEntry.filename)) {
5062
+ duplicateFilename = true;
5063
+ }
5064
+ filenames.add(fileEntry.filename);
5020
5065
  const unixExternalUpper = (fileEntry.externalFileAttributes >> 16) & MAX_16_BITS;
5021
5066
  if (fileEntry.unixMode === UNDEFINED_VALUE && (unixExternalUpper & (FILE_ATTR_UNIX_DEFAULT_MASK | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_TYPE_DIR)) != 0) {
5022
5067
  fileEntry.unixMode = unixExternalUpper;
@@ -5054,7 +5099,11 @@
5054
5099
  };
5055
5100
  offset = endOffset;
5056
5101
  if (indexFile == filesLength - 1 && recoverWrappedFilesLength) {
5057
- filesLength += getWrappedFilesLength(directoryView, directoryArray, offset);
5102
+ const wrappedFilesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
5103
+ if (wrappedFilesLength) {
5104
+ filesLength += wrappedFilesLength;
5105
+ addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
5106
+ }
5058
5107
  }
5059
5108
  const { onprogress } = options;
5060
5109
  if (onprogress) {
@@ -5080,18 +5129,22 @@
5080
5129
  zipReader.digitalSignature = digitalSignature;
5081
5130
  offsetAfterSignature = offset + 6 + digitalSignature.length;
5082
5131
  }
5083
- if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
5084
- throwAmbiguousArchive("trailing central directory data");
5132
+ if ((offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) ||
5133
+ (!decryptedDirectory && offset != directoryDataLength && offsetAfterSignature != directoryDataLength)) {
5134
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA);
5085
5135
  }
5086
5136
  if (duplicateFilename) {
5087
- throwAmbiguousArchive("duplicate filename");
5137
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_DUPLICATE_FILENAME);
5088
5138
  }
5089
5139
  const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
5090
5140
  const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
5091
5141
  const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
5092
5142
  startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
5093
5143
  if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
5094
- throwAmbiguousArchive("prepended data");
5144
+ throwAmbiguousArchive(WARNING_PREPENDED_DATA);
5145
+ }
5146
+ if (prependedDataLength || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
5147
+ addWarning(warnings, WARNING_PREPENDED_DATA);
5095
5148
  }
5096
5149
  if (extractPrependedData) {
5097
5150
  zipReader.prependedData = startOffset > splitZipSignatureLength ?
@@ -5161,6 +5214,28 @@
5161
5214
  }
5162
5215
  }
5163
5216
 
5217
+ async function isZipFile(reader, options = {}) {
5218
+ reader = new GenericReader(reader);
5219
+ await initStream(reader);
5220
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
5221
+ reader = new BlobReader(await streamToBlob(reader.readable));
5222
+ await initStream(reader);
5223
+ }
5224
+ if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
5225
+ return false;
5226
+ }
5227
+ const strictness = getStrictness(options, {});
5228
+ const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
5229
+ const maxAppendedDataSize = getMaxAppendedDataSize(options[OPTION_MAX_APPENDED_DATA_SIZE], strictness);
5230
+ const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
5231
+ if (!endOfDirectoryInfo || (strictness == STRICTNESS_STRICT && endOfDirectoryReachingEndCount > 1)) {
5232
+ return false;
5233
+ }
5234
+ const commentLength = getUint16$1(getDataView(endOfDirectoryInfo), 20);
5235
+ const appendedDataOffset = endOfDirectoryInfo.offset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
5236
+ return reader.size - appendedDataOffset <= maxAppendedDataSize;
5237
+ }
5238
+
5164
5239
  class ZipEntry {
5165
5240
 
5166
5241
  constructor(reader, options) {
@@ -5192,6 +5267,7 @@
5192
5267
  dataDescriptor
5193
5268
  } = bitFlag;
5194
5269
  const localDirectory = fileEntry.localDirectory = {};
5270
+ const warnings = fileEntry.warnings = [];
5195
5271
  const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
5196
5272
  const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
5197
5273
  const dataView = getDataView(dataArray);
@@ -5232,10 +5308,10 @@
5232
5308
  if (checkLocalFilename) {
5233
5309
  localDirectory.rawFilename = rawLocalFilename;
5234
5310
  }
5235
- readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
5236
- if (checkLocalDirectory) {
5237
- validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
5311
+ if (readCommonFooter(zipEntry, localDirectory, dataView, 4, true)) {
5312
+ addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD);
5238
5313
  }
5314
+ validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
5239
5315
  const { lastAccessDate, creationDate, uid, gid } = localDirectory;
5240
5316
  if (lastAccessDate) {
5241
5317
  fileEntry.lastAccessDate = lastAccessDate;
@@ -5461,6 +5537,7 @@
5461
5537
  const extraField = directory.extraField = new Map();
5462
5538
  const rawExtraFieldView = getDataView(rawExtraField);
5463
5539
  let offsetExtraField = 0;
5540
+ let malformedExtraField = false;
5464
5541
  try {
5465
5542
  while (offsetExtraField < rawExtraField.length) {
5466
5543
  const type = getUint16$1(rawExtraFieldView, offsetExtraField);
@@ -5472,7 +5549,10 @@
5472
5549
  offsetExtraField += 4 + size;
5473
5550
  }
5474
5551
  } catch {
5475
- // ignored
5552
+ malformedExtraField = true;
5553
+ }
5554
+ if (offsetExtraField > rawExtraField.length) {
5555
+ malformedExtraField = true;
5476
5556
  }
5477
5557
  const compressionMethod = getUint16$1(dataView, offset + 4);
5478
5558
  Object.assign(directory, {
@@ -5540,6 +5620,7 @@
5540
5620
  if (extraFieldUSDZ) {
5541
5621
  directory.extraFieldUSDZ = extraFieldUSDZ;
5542
5622
  }
5623
+ return malformedExtraField;
5543
5624
  }
5544
5625
 
5545
5626
  function readExtraFieldZip64(extraFieldZip64, directory) {
@@ -6001,27 +6082,46 @@
6001
6082
  return UNDEFINED_VALUE;
6002
6083
  }
6003
6084
 
6004
- function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
6085
+ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, warnings) {
6005
6086
  const { rawFilename } = zipEntry;
6087
+ const reject = !warnings;
6006
6088
  const maskedLocalDirectory = zipEntry.decryptedDirectory &&
6007
6089
  (localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
6008
6090
  if (checkLocalFilename && !maskedLocalDirectory &&
6009
6091
  (rawLocalFilename.length != rawFilename.length ||
6010
6092
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
6011
- throwAmbiguousArchive("mismatched local file header (filename)");
6093
+ reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
6012
6094
  }
6013
6095
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
6014
- throwAmbiguousArchive("mismatched local file header (general purpose bit flag)");
6096
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
6015
6097
  }
6016
6098
  if (localDirectory.compressionMethod != zipEntry.compressionMethod) {
6017
- throwAmbiguousArchive("mismatched local file header (compression method)");
6099
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD);
6018
6100
  }
6019
6101
  if (!localDirectory.bitFlag.dataDescriptor && !maskedLocalDirectory &&
6020
6102
  (localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
6021
6103
  (localDirectory.crc32 != zipEntry.crc32 ||
6022
6104
  localDirectory.compressedSize != zipEntry.compressedSize ||
6023
6105
  localDirectory.uncompressedSize != zipEntry.uncompressedSize)) {
6024
- throwAmbiguousArchive("mismatched local file header (crc32 or sizes)");
6106
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
6107
+ }
6108
+ }
6109
+
6110
+ function reportAmbiguity(reject, warnings, reason) {
6111
+ if (reject) {
6112
+ throwAmbiguousArchive(reason);
6113
+ } else {
6114
+ addWarning(warnings, reason);
6115
+ }
6116
+ }
6117
+
6118
+ function addWarning(warnings, reason, filename) {
6119
+ if (!warnings.some(warning => warning.reason == reason)) {
6120
+ const warning = { reason };
6121
+ if (filename !== UNDEFINED_VALUE) {
6122
+ warning.filename = filename;
6123
+ }
6124
+ warnings.push(warning);
6025
6125
  }
6026
6126
  }
6027
6127
 
@@ -6098,8 +6198,23 @@
6098
6198
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
6099
6199
  ERR_UNSUPPORTED_UINT64: ERR_UNSUPPORTED_UINT64,
6100
6200
  ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
6201
+ WARNING_APPENDED_DATA: WARNING_APPENDED_DATA,
6202
+ WARNING_COMPRESSED_PATCHED_DATA: WARNING_COMPRESSED_PATCHED_DATA,
6203
+ WARNING_DUPLICATE_FILENAME: WARNING_DUPLICATE_FILENAME,
6204
+ WARNING_MALFORMED_EXTRA_FIELD: WARNING_MALFORMED_EXTRA_FIELD,
6205
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6206
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6207
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
6208
+ WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
6209
+ WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
6210
+ WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
6211
+ WARNING_UNKNOWN_VERSION: WARNING_UNKNOWN_VERSION,
6212
+ WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA: WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA,
6213
+ WARNING_UNSORTED_CENTRAL_DIRECTORY: WARNING_UNSORTED_CENTRAL_DIRECTORY,
6214
+ WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
6101
6215
  ZipReader: ZipReader,
6102
- ZipReaderStream: ZipReaderStream
6216
+ ZipReaderStream: ZipReaderStream,
6217
+ isZipFile: isZipFile
6103
6218
  });
6104
6219
 
6105
6220
  /*
@@ -6312,6 +6427,7 @@
6312
6427
  rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
6313
6428
  rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
6314
6429
  rawExtraField,
6430
+ rawCentralExtraField: EMPTY_UINT8_ARRAY,
6315
6431
  extendedTimestamp: false,
6316
6432
  headerArray,
6317
6433
  headerView
@@ -6485,7 +6601,6 @@
6485
6601
 
6486
6602
  async function addFileEntry(zipWriter, name, reader, options) {
6487
6603
  options = Object.assign({}, options);
6488
- name = name.trim();
6489
6604
  if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6490
6605
  name += DIRECTORY_SIGNATURE;
6491
6606
  }
@@ -6576,7 +6691,6 @@
6576
6691
  }
6577
6692
 
6578
6693
  function resolveAttributes(zipWriter, name, options) {
6579
- name = name.trim();
6580
6694
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6581
6695
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
6582
6696
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
@@ -6781,6 +6895,7 @@
6781
6895
  }
6782
6896
  const rawExtraField = serializeExtraField(options[PROPERTY_NAME_EXTRA_FIELD]);
6783
6897
  const rawLocalExtraField = serializeExtraField(options[OPTION_LOCAL_EXTRA_FIELD]);
6898
+ const rawCentralExtraField = serializeExtraField(options[OPTION_CENTRAL_EXTRA_FIELD]);
6784
6899
  return {
6785
6900
  comment,
6786
6901
  resolvedOptions: {
@@ -6816,7 +6931,8 @@
6816
6931
  dataDescriptor,
6817
6932
  zip64,
6818
6933
  rawExtraField,
6819
- rawLocalExtraField
6934
+ rawLocalExtraField,
6935
+ rawCentralExtraField
6820
6936
  }
6821
6937
  };
6822
6938
  }
@@ -7135,6 +7251,7 @@
7135
7251
  versionMadeBy,
7136
7252
  rawComment,
7137
7253
  rawExtraField,
7254
+ rawCentralExtraField,
7138
7255
  useWebWorkers,
7139
7256
  transferStreams,
7140
7257
  onstart,
@@ -7178,6 +7295,7 @@
7178
7295
  rawExtraFieldUnix,
7179
7296
  rawExtraFieldAES,
7180
7297
  rawExtraField,
7298
+ rawCentralExtraField,
7181
7299
  extendedTimestamp,
7182
7300
  msDosCompatible,
7183
7301
  internalFileAttributes,
@@ -7209,6 +7327,7 @@
7209
7327
  const workerOptions = {
7210
7328
  options: {
7211
7329
  codecType: CODEC_DEFLATE,
7330
+ inputSize: size,
7212
7331
  level,
7213
7332
  rawPassword,
7214
7333
  password,
@@ -7678,6 +7797,7 @@
7678
7797
  rawExtraFieldNTFS,
7679
7798
  rawExtraFieldUnix,
7680
7799
  rawExtraField,
7800
+ rawCentralExtraField,
7681
7801
  extendedTimestamp,
7682
7802
  extraFieldExtendedTimestampFlag,
7683
7803
  lastModDate,
@@ -7732,7 +7852,8 @@
7732
7852
  rawExtraFieldNTFS,
7733
7853
  rawExtraFieldUnix,
7734
7854
  rawExtraFieldTimestamp,
7735
- rawExtraField);
7855
+ rawExtraField,
7856
+ rawCentralExtraField);
7736
7857
  if (extraFieldLength > MAX_16_BITS) {
7737
7858
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
7738
7859
  }
@@ -7760,6 +7881,7 @@
7760
7881
  rawExtraFieldNTFS,
7761
7882
  rawExtraFieldUnix,
7762
7883
  rawExtraField,
7884
+ rawCentralExtraField,
7763
7885
  rawComment,
7764
7886
  versionMadeBy,
7765
7887
  headerArray,
@@ -7774,7 +7896,7 @@
7774
7896
  uncompressedSize,
7775
7897
  compressedSize
7776
7898
  } = fileEntry;
7777
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
7899
+ const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawCentralExtraField);
7778
7900
  const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
7779
7901
  if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
7780
7902
  await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
@@ -7812,6 +7934,7 @@
7812
7934
  directoryRecord.writeBytes(rawExtraFieldNTFS);
7813
7935
  directoryRecord.writeBytes(rawExtraFieldUnix);
7814
7936
  directoryRecord.writeBytes(rawExtraField);
7937
+ directoryRecord.writeBytes(rawCentralExtraField);
7815
7938
  directoryRecord.writeBytes(rawComment);
7816
7939
  arraySet(directoryArray, directoryRecord.array, offset);
7817
7940
  offset += directoryRecordLength;
@@ -8315,6 +8438,111 @@
8315
8438
  */
8316
8439
 
8317
8440
 
8441
+ function getSupportedCompressionMethods() {
8442
+ const { CompressionStream, DecompressionStream, CompressionStreamFallback, DecompressionStreamFallback } = getConfiguration();
8443
+ const supportedMethods = [{
8444
+ compressionMethod: COMPRESSION_METHOD_STORE,
8445
+ compression: true,
8446
+ decompression: true,
8447
+ registered: false
8448
+ }, {
8449
+ compressionMethod: COMPRESSION_METHOD_DEFLATE,
8450
+ compression: formatSupported(CompressionStreamFallback, FORMAT_DEFLATE_RAW) ||
8451
+ formatSupported(CompressionStream, FORMAT_DEFLATE_RAW) || formatSupported(CompressionStream, FORMAT_GZIP),
8452
+ decompression: formatSupported(DecompressionStreamFallback, FORMAT_DEFLATE_RAW) ||
8453
+ formatSupported(DecompressionStream, FORMAT_DEFLATE_RAW) || formatSupported(DecompressionStream, FORMAT_GZIP),
8454
+ registered: false
8455
+ }, {
8456
+ compressionMethod: COMPRESSION_METHOD_DEFLATE_64,
8457
+ compression: false,
8458
+ decompression: formatSupported(DecompressionStreamFallback, FORMAT_DEFLATE64_RAW) ||
8459
+ formatSupported(DecompressionStream, FORMAT_DEFLATE64_RAW),
8460
+ registered: false
8461
+ }];
8462
+ for (const codec of getRegisteredCodecs()) {
8463
+ const codecStreams = getCodecStreams(codec.format);
8464
+ supportedMethods.push({
8465
+ compressionMethod: codec.compressionMethod,
8466
+ // deno-lint-ignore valid-typeof
8467
+ compression: codecStreams ? typeof codecStreams.CompressionStream == FUNCTION_TYPE : UNDEFINED_VALUE,
8468
+ // deno-lint-ignore valid-typeof
8469
+ decompression: codecStreams ? typeof codecStreams.DecompressionStream == FUNCTION_TYPE : UNDEFINED_VALUE,
8470
+ registered: true
8471
+ });
8472
+ }
8473
+ return supportedMethods;
8474
+ }
8475
+
8476
+ function formatSupported(StreamClass, format) {
8477
+ if (!StreamClass) {
8478
+ return false;
8479
+ }
8480
+ const { supportedFormats } = StreamClass;
8481
+ if (supportedFormats) {
8482
+ return supportedFormats.includes(format);
8483
+ }
8484
+ return supportsFormat(StreamClass, format);
8485
+ }
8486
+
8487
+ /*
8488
+ Copyright (c) 2025 Gildas Lormeau. All rights reserved.
8489
+
8490
+ Redistribution and use in source and binary forms, with or without
8491
+ modification, are permitted provided that the following conditions are met:
8492
+
8493
+ 1. Redistributions of source code must retain the above copyright notice,
8494
+ this list of conditions and the following disclaimer.
8495
+
8496
+ 2. Redistributions in binary form must reproduce the above copyright
8497
+ notice, this list of conditions and the following disclaimer in
8498
+ the documentation and/or other materials provided with the distribution.
8499
+
8500
+ 3. The names of the authors may not be used to endorse or promote products
8501
+ derived from this software without specific prior written permission.
8502
+
8503
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
8504
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
8505
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
8506
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
8507
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
8508
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
8509
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
8510
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8511
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
8512
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8513
+ */
8514
+
8515
+ const VERSION = "2.8.60";
8516
+
8517
+ /*
8518
+ Copyright (c) 2025 Gildas Lormeau. All rights reserved.
8519
+
8520
+ Redistribution and use in source and binary forms, with or without
8521
+ modification, are permitted provided that the following conditions are met:
8522
+
8523
+ 1. Redistributions of source code must retain the above copyright notice,
8524
+ this list of conditions and the following disclaimer.
8525
+
8526
+ 2. Redistributions in binary form must reproduce the above copyright
8527
+ notice, this list of conditions and the following disclaimer in
8528
+ the documentation and/or other materials provided with the distribution.
8529
+
8530
+ 3. The names of the authors may not be used to endorse or promote products
8531
+ derived from this software without specific prior written permission.
8532
+
8533
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
8534
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
8535
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
8536
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
8537
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
8538
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
8539
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
8540
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8541
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
8542
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8543
+ */
8544
+
8545
+
8318
8546
  const DEFAULT_THRESHOLD$2 = 1024 * 1024;
8319
8547
  const DEFAULT_DIRECTORY_NAME$1 = ".zip.js-temp";
8320
8548
 
@@ -8815,6 +9043,21 @@
8815
9043
  exports.TextWriter = TextWriter;
8816
9044
  exports.Uint8ArrayReader = Uint8ArrayReader;
8817
9045
  exports.Uint8ArrayWriter = Uint8ArrayWriter;
9046
+ exports.VERSION = VERSION;
9047
+ exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
9048
+ exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
9049
+ exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
9050
+ exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
9051
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
9052
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
9053
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
9054
+ exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
9055
+ exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
9056
+ exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;
9057
+ exports.WARNING_UNKNOWN_VERSION = WARNING_UNKNOWN_VERSION;
9058
+ exports.WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA;
9059
+ exports.WARNING_UNSORTED_CENTRAL_DIRECTORY = WARNING_UNSORTED_CENTRAL_DIRECTORY;
9060
+ exports.WARNING_WRAPPED_ENTRIES_COUNT = WARNING_WRAPPED_ENTRIES_COUNT;
8818
9061
  exports.Writer = Writer;
8819
9062
  exports.ZipReader = ZipReader;
8820
9063
  exports.ZipReaderStream = ZipReaderStream;
@@ -8825,6 +9068,9 @@
8825
9068
  exports.createOPFSTempStream = createOPFSTempStream;
8826
9069
  exports.createSyncAccessHandleTempStream = createSyncAccessHandleTempStream;
8827
9070
  exports.getMimeType = getMimeType;
9071
+ exports.getRegisteredCodecs = getRegisteredCodecs;
9072
+ exports.getSupportedCompressionMethods = getSupportedCompressionMethods;
9073
+ exports.isZipFile = isZipFile;
8828
9074
  exports.registerCodec = registerCodec;
8829
9075
  exports.resetConfiguration = resetConfiguration;
8830
9076
  exports.terminateWorkers = terminateWorkers;