@zip.js/zip.js 2.19.0 → 2.21.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.
@@ -117,6 +117,10 @@ const MIN_DATE = new Date(1980, 0, 1);
117
117
 
118
118
  const UNDEFINED_VALUE = undefined;
119
119
  const INFINITY_VALUE = Infinity;
120
+ const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
121
+ const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
122
+ const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
123
+
120
124
  const UNDEFINED_TYPE = "undefined";
121
125
  const FUNCTION_TYPE = "function";
122
126
  const OBJECT_TYPE = "object";
@@ -4790,12 +4794,9 @@ const ERR_BAD_FORMAT = "File format is not recognized";
4790
4794
  const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
4791
4795
  const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
4792
4796
  const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
4793
- const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
4794
- const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
4795
4797
  const ERR_ENCRYPTED = "File contains encrypted entry";
4796
4798
  const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
4797
4799
  const ERR_SPLIT_ZIP_FILE = "Split zip file";
4798
- const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
4799
4800
  const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
4800
4801
  const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
4801
4802
  const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
@@ -4814,6 +4815,8 @@ const WARNING_APPENDED_DATA = "appended data";
4814
4815
  const WARNING_PREPENDED_DATA = "prepended data";
4815
4816
  const WARNING_PREPENDED_CENTRAL_DIRECTORY = "prepended central directory";
4816
4817
  const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4818
+ const WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET = "mismatched central directory offset";
4819
+ const WARNING_MISSING_ZIP64_EXTRA_FIELD = "missing zip64 extra field";
4817
4820
  const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4818
4821
  const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
4819
4822
  const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
@@ -4858,7 +4861,8 @@ class ZipReader {
4858
4861
  Object.assign(this, {
4859
4862
  reader: new GenericReader(reader),
4860
4863
  options,
4861
- readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
4864
+ readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
4865
+ entriesMissingZip64ExtraField: new WeakSet()
4862
4866
  });
4863
4867
  }
4864
4868
 
@@ -4929,16 +4933,22 @@ class ZipReader {
4929
4933
  directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
4930
4934
  let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4931
4935
  let endOfDirectoryView = getDataView(endOfDirectoryArray);
4932
- const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
4933
- if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
4934
- directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
4935
- const originalDirectoryDataOffset = directoryDataOffset;
4936
- directoryDataOffset = expectedDirectoryDataOffset;
4937
- if (directoryDataOffset > originalDirectoryDataOffset) {
4938
- prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
4936
+ if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
4937
+ const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
4938
+ let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
4939
+ if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
4940
+ expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
4941
+ }
4942
+ if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
4943
+ directoryDataOffset != expectedDirectoryDataOffset) {
4944
+ const originalDirectoryDataOffset = directoryDataOffset;
4945
+ directoryDataOffset = expectedDirectoryDataOffset;
4946
+ if (directoryDataOffset > originalDirectoryDataOffset) {
4947
+ prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
4948
+ }
4949
+ endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4950
+ endOfDirectoryView = getDataView(endOfDirectoryArray);
4939
4951
  }
4940
- endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4941
- endOfDirectoryView = getDataView(endOfDirectoryArray);
4942
4952
  }
4943
4953
  if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
4944
4954
  throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
@@ -4976,15 +4986,13 @@ class ZipReader {
4976
4986
  reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4977
4987
  }
4978
4988
  directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4989
+ } else if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || diskNumber == MAX_16_BITS) {
4990
+ throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
4979
4991
  }
4980
4992
  }
4981
4993
  let declaredDirectoryDataLength = directoryDataLength;
4982
4994
  const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
4983
4995
  (zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
4984
- if (directoryDataOffset >= reader.size) {
4985
- prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
4986
- directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
4987
- }
4988
4996
  if (expectedLastDiskNumber != lastDiskNumber) {
4989
4997
  throw new Error(ERR_SPLIT_ZIP_FILE);
4990
4998
  }
@@ -4992,33 +5000,64 @@ class ZipReader {
4992
5000
  throw new Error(ERR_BAD_FORMAT);
4993
5001
  }
4994
5002
  let offset = 0;
4995
- let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
5003
+ let directoryArray = directoryDataOffset < reader.size ?
5004
+ await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
5005
+ EMPTY_UINT8_ARRAY;
4996
5006
  let directoryView = getDataView(directoryArray);
4997
5007
  if (directoryDataLength) {
4998
- if (directoryArray.length < 4) {
4999
- throw new Error(ERR_BAD_FORMAT);
5000
- }
5001
- const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
5008
+ let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
5002
5009
  if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
5003
- const storedPointsAtDirectory = getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
5010
+ const storedPointsAtDirectory = directoryArray.length >= 4 && (
5011
+ getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
5004
5012
  Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
5005
- detectEncryptedCentralDirectory(directoryView);
5013
+ detectEncryptedCentralDirectory(directoryView));
5014
+ if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
5015
+ throw new Error(ERR_BAD_FORMAT);
5016
+ }
5006
5017
  let reconcile = !storedPointsAtDirectory;
5007
- if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
5008
- const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
5009
- reconcile = getUint32$1(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
5018
+ if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
5019
+ let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
5020
+ if (!expectedPointsAtDirectory) {
5021
+ const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
5022
+ const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
5023
+ if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
5024
+ await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
5025
+ expectedDirectoryDataOffset = signedDirectoryDataOffset;
5026
+ expectedPointsAtDirectory = true;
5027
+ }
5028
+ }
5029
+ if (storedPointsAtDirectory) {
5030
+ reconcile = expectedPointsAtDirectory;
5031
+ }
5010
5032
  }
5011
- if (reconcile) {
5033
+ if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
5012
5034
  const originalDirectoryDataOffset = directoryDataOffset;
5013
5035
  directoryDataOffset = expectedDirectoryDataOffset;
5014
- if (directoryDataOffset > originalDirectoryDataOffset) {
5015
- prependedDataLength += directoryDataOffset - originalDirectoryDataOffset;
5016
- prependedCentralDirectory = storedPointsAtDirectory;
5017
- }
5018
5036
  directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
5019
5037
  directoryView = getDataView(directoryArray);
5038
+ const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
5039
+ const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
5040
+ const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
5041
+ await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
5042
+ const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
5043
+ await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
5044
+ if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
5045
+ prependedDataLength += offsetDelta;
5046
+ prependedCentralDirectory = storedPointsAtDirectory;
5047
+ } else {
5048
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
5049
+ if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
5050
+ prependedDataLength += offsetDelta;
5051
+ }
5052
+ }
5020
5053
  }
5021
5054
  }
5055
+ if (directoryArray.length < 4) {
5056
+ throw new Error(ERR_BAD_FORMAT);
5057
+ }
5058
+ } else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
5059
+ prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
5060
+ directoryDataOffset = centralDirectoryEndOffset;
5022
5061
  }
5023
5062
  const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
5024
5063
  if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
@@ -5060,8 +5099,10 @@ class ZipReader {
5060
5099
  addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
5061
5100
  }
5062
5101
  }
5102
+ const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
5103
+ delete entryOptions[OPTION_CHECK_AMBIGUITY];
5063
5104
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
5064
- const fileEntry = new ZipEntry(reader, zipReader.options);
5105
+ const fileEntry = new ZipEntry(reader, entryOptions);
5065
5106
  if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
5066
5107
  if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
5067
5108
  throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
@@ -5127,7 +5168,16 @@ class ZipReader {
5127
5168
  filename,
5128
5169
  comment
5129
5170
  });
5130
- const malformedExtraField = readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
5171
+ let malformedExtraField;
5172
+ try {
5173
+ malformedExtraField = readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
5174
+ } catch (error) {
5175
+ if (checkAmbiguity || error.message != ERR_EXTRAFIELD_ZIP64_NOT_FOUND) {
5176
+ throw error;
5177
+ }
5178
+ fileEntry.zip64ExtraFieldMissing = true;
5179
+ addWarning(warnings, WARNING_MISSING_ZIP64_EXTRA_FIELD, fileEntry.filename);
5180
+ }
5131
5181
  filename = fileEntry.filename;
5132
5182
  if (normalizeFilename) {
5133
5183
  const normalizedFilename = normalizeFilename(filename);
@@ -5143,13 +5193,17 @@ class ZipReader {
5143
5193
  if (malformedExtraField) {
5144
5194
  addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
5145
5195
  }
5146
- fileEntry.offset += prependedDataLength;
5147
- const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
5148
- startOffset = Math.min(entryPosition, startOffset);
5149
- if (entryPosition < previousEntryPosition) {
5150
- addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
5196
+ if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
5197
+ startOffset = 0;
5198
+ } else {
5199
+ fileEntry.offset += prependedDataLength;
5200
+ const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
5201
+ startOffset = Math.min(entryPosition, startOffset);
5202
+ if (entryPosition < previousEntryPosition) {
5203
+ addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
5204
+ }
5205
+ previousEntryPosition = entryPosition;
5151
5206
  }
5152
- previousEntryPosition = entryPosition;
5153
5207
  if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
5154
5208
  addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
5155
5209
  }
@@ -5169,11 +5223,12 @@ class ZipReader {
5169
5223
  const sticky = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_STICKY_MASK);
5170
5224
  const unixType = fileEntry.unixMode === UNDEFINED_VALUE ? unixExternalUpper : fileEntry.unixMode;
5171
5225
  const symlink = (unixType & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK;
5172
- const executable = !symlink && ((fileEntry.unixMode !== UNDEFINED_VALUE)
5173
- ? ((fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)
5174
- : (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)));
5175
5226
  const modeIsDir = fileEntry.unixMode !== UNDEFINED_VALUE && ((fileEntry.unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
5176
5227
  const upperIsDir = ((unixExternalUpper & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
5228
+ const directory = modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE);
5229
+ const executable = !symlink && !directory && ((fileEntry.unixMode !== UNDEFINED_VALUE)
5230
+ ? ((fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)
5231
+ : (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)));
5177
5232
  Object.assign(fileEntry, {
5178
5233
  setuid,
5179
5234
  setgid,
@@ -5181,16 +5236,19 @@ class ZipReader {
5181
5236
  symlink,
5182
5237
  unixExternalUpper,
5183
5238
  executable,
5184
- directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE),
5239
+ directory,
5185
5240
  zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
5186
5241
  });
5187
5242
  const entry = new Entry(fileEntry);
5188
- entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader.readRanges, options);
5243
+ if (fileEntry.zip64ExtraFieldMissing) {
5244
+ zipReader.entriesMissingZip64ExtraField.add(entry);
5245
+ }
5246
+ entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
5189
5247
  entry.arrayBuffer = async options => {
5190
5248
  const writer = new TransformStream();
5191
5249
  const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
5192
5250
  arrayBufferPromise.catch(() => { });
5193
- await fileEntry.getData(writer, entry, zipReader.readRanges,
5251
+ await fileEntry.getData(writer, entry, zipReader,
5194
5252
  Object.assign({}, options, { preventClose: false }));
5195
5253
  return arrayBufferPromise;
5196
5254
  };
@@ -5237,10 +5295,10 @@ class ZipReader {
5237
5295
  const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
5238
5296
  const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
5239
5297
  startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
5240
- if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
5298
+ if (checkAmbiguity && (prependedDataLength > 0 || (filesLength && startOffset > splitZipSignatureLength))) {
5241
5299
  throwAmbiguousArchive(WARNING_PREPENDED_DATA);
5242
5300
  }
5243
- if (prependedDataLength || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
5301
+ if (prependedDataLength > 0 || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
5244
5302
  addWarning(warnings, WARNING_PREPENDED_DATA);
5245
5303
  }
5246
5304
  if (prependedCentralDirectory) {
@@ -5398,8 +5456,12 @@ class ZipEntry {
5398
5456
  });
5399
5457
  }
5400
5458
 
5401
- async getData(writer, fileEntry, readRanges, options = {}) {
5459
+ async getData(writer, fileEntry, zipReader, options = {}) {
5402
5460
  const zipEntry = this;
5461
+ const { readRanges, directoryOffset } = zipReader;
5462
+ if (zipEntry.zip64ExtraFieldMissing) {
5463
+ throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
5464
+ }
5403
5465
  const config = getConfiguration();
5404
5466
  const {
5405
5467
  reader,
@@ -5470,10 +5532,10 @@ class ZipEntry {
5470
5532
  }
5471
5533
  validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
5472
5534
  const { lastAccessDate, creationDate, uid, gid } = localDirectory;
5473
- if (lastAccessDate) {
5535
+ if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
5474
5536
  fileEntry.lastAccessDate = lastAccessDate;
5475
5537
  }
5476
- if (creationDate) {
5538
+ if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
5477
5539
  fileEntry.creationDate = creationDate;
5478
5540
  }
5479
5541
  if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
@@ -5502,7 +5564,7 @@ class ZipEntry {
5502
5564
  throw new Error(ERR_ENCRYPTED);
5503
5565
  }
5504
5566
  }
5505
- if (dataOffset + compressedSize > reader.size) {
5567
+ if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
5506
5568
  throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
5507
5569
  }
5508
5570
  const size = compressedSize;
@@ -5568,6 +5630,7 @@ class ZipEntry {
5568
5630
  extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
5569
5631
  readRanges
5570
5632
  });
5633
+ validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
5571
5634
  }
5572
5635
  let writable, abortError, aborted;
5573
5636
  try {
@@ -5587,10 +5650,7 @@ class ZipEntry {
5587
5650
  writer.size += writtenSize;
5588
5651
  }
5589
5652
  } catch (error) {
5590
- const { outputSize: failedOutputSize } = workerOptions;
5591
- if (failedOutputSize !== UNDEFINED_VALUE) {
5592
- writer.size += failedOutputSize;
5593
- } else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
5653
+ if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
5594
5654
  writer.size += error.outputSize;
5595
5655
  }
5596
5656
  if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
@@ -5618,13 +5678,7 @@ class ZipEntry {
5618
5678
  }
5619
5679
 
5620
5680
  function detectEncryptedCentralDirectory(directoryView) {
5621
- const maxOffset = Math.min(directoryView.byteLength, 1024) - 3;
5622
- for (let offset = 0; offset < maxOffset; offset++) {
5623
- if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
5624
- return true;
5625
- }
5626
- }
5627
- return false;
5681
+ return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
5628
5682
  }
5629
5683
 
5630
5684
  function getWrappedFilesLength(directoryView, directoryArray, offset) {
@@ -5637,6 +5691,70 @@ function getWrappedFilesLength(directoryView, directoryArray, offset) {
5637
5691
  return wrappedFilesLength % (MAX_16_BITS + 1) ? 0 : wrappedFilesLength;
5638
5692
  }
5639
5693
 
5694
+ function pointsAtDirectory(reader, offset) {
5695
+ return startsWithSignature(reader, offset, CENTRAL_FILE_HEADER_SIGNATURE);
5696
+ }
5697
+
5698
+ async function startsWithSignature(reader, offset, signature) {
5699
+ if (offset < 0 || offset + 4 > reader.size) {
5700
+ return false;
5701
+ }
5702
+ const signatureArray = await readUint8Array(reader, offset, 4);
5703
+ return getUint32$1(getDataView(signatureArray), 0) == signature;
5704
+ }
5705
+
5706
+ async function findDigitalSignatureRecordOffset(reader, endOffset) {
5707
+ const startOffset = Math.max(0, endOffset - (6 + MAX_16_BITS));
5708
+ const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
5709
+ const tailView = getDataView(tailArray);
5710
+ for (let indexByte = tailArray.length - 6; indexByte >= 0; indexByte--) {
5711
+ if (getUint32$1(tailView, indexByte) == DIGITAL_SIGNATURE_RECORD_SIGNATURE &&
5712
+ indexByte + 6 + getUint16$1(tailView, indexByte + 4) == tailArray.length) {
5713
+ return startOffset + indexByte;
5714
+ }
5715
+ }
5716
+ }
5717
+
5718
+ async function findZip64EndOfDirectoryOffset(reader, endOffset) {
5719
+ const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
5720
+ const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
5721
+ const tailView = getDataView(tailArray);
5722
+ for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
5723
+ if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
5724
+ indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
5725
+ return startOffset + indexByte;
5726
+ }
5727
+ }
5728
+ }
5729
+
5730
+ function getFirstLocalHeaderOffset(directoryArray, directoryView) {
5731
+ if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
5732
+ return UNDEFINED_VALUE;
5733
+ }
5734
+ const localHeaderOffset = getUint32$1(directoryView, 42);
5735
+ if (localHeaderOffset != MAX_32_BITS) {
5736
+ return localHeaderOffset;
5737
+ }
5738
+ let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
5739
+ const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
5740
+ while (offsetExtraField + 4 <= endExtraField) {
5741
+ const type = getUint16$1(directoryView, offsetExtraField);
5742
+ const size = getUint16$1(directoryView, offsetExtraField + 2);
5743
+ if (type == EXTRAFIELD_TYPE_ZIP64) {
5744
+ let offsetValue = offsetExtraField + 4;
5745
+ if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
5746
+ offsetValue += 8;
5747
+ }
5748
+ if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
5749
+ offsetValue += 8;
5750
+ }
5751
+ return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
5752
+ }
5753
+ offsetExtraField += 4 + size;
5754
+ }
5755
+ return UNDEFINED_VALUE;
5756
+ }
5757
+
5640
5758
  function readDigitalSignature(signatureRecordArray) {
5641
5759
  if (signatureRecordArray.length >= 6) {
5642
5760
  const signatureRecordView = getDataView(signatureRecordArray);
@@ -5726,6 +5844,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5726
5844
  uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
5727
5845
  });
5728
5846
  const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
5847
+ let extraFieldZip64Missing;
5729
5848
  if (extraFieldZip64) {
5730
5849
  if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
5731
5850
  malformedExtraField = true;
@@ -5735,7 +5854,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5735
5854
  if (localDirectory) {
5736
5855
  malformedExtraField = true;
5737
5856
  } else {
5738
- throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
5857
+ extraFieldZip64Missing = true;
5739
5858
  }
5740
5859
  }
5741
5860
  const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
@@ -5768,6 +5887,11 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5768
5887
  readExtraFieldUnixDates(extraFieldUnixType1, directory);
5769
5888
  directory.extraFieldUnixType1 = extraFieldUnixType1;
5770
5889
  }
5890
+ const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
5891
+ if (extraFieldExtendedTimestamp) {
5892
+ readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory);
5893
+ directory.extraFieldExtendedTimestamp = extraFieldExtendedTimestamp;
5894
+ }
5771
5895
  const extraFieldNTFS = extraField.get(EXTRAFIELD_TYPE_NTFS);
5772
5896
  if (extraFieldNTFS) {
5773
5897
  readExtraFieldNTFS(extraFieldNTFS, directory);
@@ -5784,15 +5908,13 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5784
5908
  readExtraFieldUnix(extraFieldUnix, unixIdsRead ? {} : directory, false);
5785
5909
  directory.extraFieldUnix = extraFieldUnix;
5786
5910
  }
5787
- const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
5788
- if (extraFieldExtendedTimestamp) {
5789
- readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory);
5790
- directory.extraFieldExtendedTimestamp = extraFieldExtendedTimestamp;
5791
- }
5792
5911
  const extraFieldUSDZ = extraField.get(EXTRAFIELD_TYPE_USDZ);
5793
5912
  if (extraFieldUSDZ) {
5794
5913
  directory.extraFieldUSDZ = extraFieldUSDZ;
5795
5914
  }
5915
+ if (extraFieldZip64Missing) {
5916
+ throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
5917
+ }
5796
5918
  return malformedExtraField;
5797
5919
  }
5798
5920
 
@@ -6007,13 +6129,7 @@ async function detectOverlappingEntry({
6007
6129
  let dataDescriptorLength = 0;
6008
6130
  if (dataDescriptor) {
6009
6131
  const zip64 = Boolean(extraFieldZip64);
6010
- const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
6011
- const dataDescriptorView = getDataView(dataDescriptorArray);
6012
- const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
6013
- .map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
6014
- .filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
6015
- const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
6016
- readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
6132
+ const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
6017
6133
  if (localDataDescriptor) {
6018
6134
  fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
6019
6135
  dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
@@ -6083,6 +6199,25 @@ function mergeRanges(sortedRanges, pendingRanges) {
6083
6199
  return mergedRanges;
6084
6200
  }
6085
6201
 
6202
+ async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
6203
+ const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
6204
+ const length = Math.min(maxLength, Math.max(0, reader.size - offset));
6205
+ const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
6206
+ const dataDescriptorView = getDataView(dataDescriptorArray);
6207
+ const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
6208
+ .map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
6209
+ .filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
6210
+ return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
6211
+ readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
6212
+ }
6213
+
6214
+ async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
6215
+ const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
6216
+ if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
6217
+ return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
6218
+ }
6219
+ }
6220
+
6086
6221
  function readDataDescriptor(dataDescriptorView, zip64, signature) {
6087
6222
  const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
6088
6223
  if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
@@ -6342,6 +6477,18 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
6342
6477
  }
6343
6478
  }
6344
6479
 
6480
+ function validateDataDescriptor(zipEntry, localDirectory, warnings) {
6481
+ const { dataDescriptor } = localDirectory;
6482
+ const maskedLocalDirectory = zipEntry.decryptedDirectory &&
6483
+ (localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
6484
+ if (dataDescriptor && !maskedLocalDirectory &&
6485
+ ((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
6486
+ dataDescriptor.compressedSize != zipEntry.compressedSize ||
6487
+ dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
6488
+ reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
6489
+ }
6490
+ }
6491
+
6345
6492
  function reportAmbiguity(reject, warnings, reason) {
6346
6493
  if (reject) {
6347
6494
  throwAmbiguousArchive(reason);
@@ -6427,11 +6574,13 @@ var zipReader = /*#__PURE__*/Object.freeze({
6427
6574
  WARNING_COMPRESSED_PATCHED_DATA: WARNING_COMPRESSED_PATCHED_DATA,
6428
6575
  WARNING_DUPLICATE_FILENAME: WARNING_DUPLICATE_FILENAME,
6429
6576
  WARNING_MALFORMED_EXTRA_FIELD: WARNING_MALFORMED_EXTRA_FIELD,
6577
+ WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET: WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET,
6430
6578
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6431
6579
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6432
6580
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
6433
6581
  WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
6434
6582
  WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
6583
+ WARNING_MISSING_ZIP64_EXTRA_FIELD: WARNING_MISSING_ZIP64_EXTRA_FIELD,
6435
6584
  WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
6436
6585
  WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
6437
6586
  WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
@@ -6442,6 +6591,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
6442
6591
  WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
6443
6592
  ZipReader: ZipReader,
6444
6593
  ZipReaderStream: ZipReaderStream,
6594
+ getEntryDataDescriptorLength: getEntryDataDescriptorLength,
6445
6595
  isZipFile: isZipFile
6446
6596
  });
6447
6597
 
@@ -6564,130 +6714,8 @@ class ZipWriter {
6564
6714
  return watchPromiseError(this, prependZipEntries(this, reader));
6565
6715
  }
6566
6716
 
6567
- appendZip(reader) {
6568
- return watchPromiseError(this, this.appendZipEntries(reader));
6569
- }
6570
-
6571
- async appendZipEntries(reader) {
6572
- const zipWriter = this;
6573
- const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
6574
- while (pendingAddFileCalls.size) {
6575
- await Promise.allSettled(Array.from(pendingAddFileCalls));
6576
- }
6577
- let resolveAppendZip;
6578
- const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
6579
- pendingAddFileCalls.add(promiseAppendZip);
6580
- const appendedFilenames = [];
6581
- let releaseLockWriter;
6582
- try {
6583
- reader = new GenericReader(reader);
6584
- await initStream(reader);
6585
- if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
6586
- reader = new BlobReader(await streamToBlob(reader.readable));
6587
- await initStream(reader);
6588
- }
6589
- const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
6590
- const zipReader$1 = new ZipReader(reader);
6591
- const entries = await zipReader$1.getEntries();
6592
- await zipReader$1.close();
6593
- await initStream(zipWriter.writer);
6594
- const { directoryOffset } = zipReader$1;
6595
- entries.forEach(({ filename }) => {
6596
- if (filenames.has(filename)) {
6597
- throw new Error(ERR_DUPLICATED_NAME);
6598
- }
6599
- filenames.add(filename);
6600
- appendedFilenames.push(filename);
6601
- });
6602
- zipWriter.writerLocked = true;
6603
- const { lockWriter } = zipWriter;
6604
- zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
6605
- zipWriter.writerLocked = false;
6606
- resolve();
6607
- });
6608
- await lockWriter;
6609
- if (zipWriter.addSplitZipSignature) {
6610
- delete zipWriter.addSplitZipSignature;
6611
- if (!await startsWithSplitZipSignature(reader)) {
6612
- await writeData(zipWriter.writer, getSplitZipSignatureArray());
6613
- zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6614
- }
6615
- }
6616
- const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
6617
- entries.forEach(entry => {
6618
- const {
6619
- version,
6620
- rawLastModDate,
6621
- rawFilename,
6622
- bitFlag,
6623
- encrypted,
6624
- uncompressedSize,
6625
- compressedSize,
6626
- extraFieldZip64
6627
- } = entry;
6628
- let {
6629
- compressionMethod,
6630
- rawExtraField,
6631
- } = entry;
6632
- const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
6633
- rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
6634
- if (entry.extraFieldAES) {
6635
- compressionMethod = COMPRESSION_METHOD_AES;
6636
- }
6637
- const extraFieldLength = getLength(rawExtraField);
6638
- const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
6639
- const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
6640
- const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
6641
- const {
6642
- headerArray,
6643
- headerView
6644
- } = getHeaderArrayData({
6645
- version,
6646
- bitFlag: bitFlagValue,
6647
- compressionMethod,
6648
- uncompressedSize,
6649
- compressedSize,
6650
- rawLastModDate,
6651
- rawFilename,
6652
- zip64CompressedSize,
6653
- zip64UncompressedSize,
6654
- extraFieldLength
6655
- });
6656
- const { crc32 } = entry;
6657
- if (crc32 !== UNDEFINED_VALUE) {
6658
- setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
6659
- }
6660
- const { offset, diskNumberStart } = entryPositions.get(entry);
6661
- Object.assign(entry, {
6662
- zip64Enabled: true,
6663
- zip64UncompressedSize,
6664
- zip64CompressedSize,
6665
- offset,
6666
- diskNumberStart,
6667
- zip64DiskNumberStart: false,
6668
- rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
6669
- rawExtraFieldAES: EMPTY_UINT8_ARRAY,
6670
- rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
6671
- rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
6672
- rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
6673
- rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
6674
- rawExtraField,
6675
- rawCentralExtraField: EMPTY_UINT8_ARRAY,
6676
- headerArray,
6677
- headerView
6678
- });
6679
- fileEntries.set(entry.filename, entry);
6680
- });
6681
- } catch (error) {
6682
- appendedFilenames.forEach(filename => filenames.delete(filename));
6683
- throw error;
6684
- } finally {
6685
- resolveAppendZip();
6686
- pendingAddFileCalls.delete(promiseAppendZip);
6687
- if (releaseLockWriter) {
6688
- releaseLockWriter();
6689
- }
6690
- }
6717
+ appendZip(reader, options = {}) {
6718
+ return watchPromiseError(this, appendZipEntries(this, reader, options));
6691
6719
  }
6692
6720
 
6693
6721
  add(name = "", reader, options = {}) {
@@ -6849,11 +6877,140 @@ function watchPromiseError(zipWriter, promise) {
6849
6877
  return watchedPromise;
6850
6878
  }
6851
6879
 
6880
+ async function appendZipEntries(zipWriter, reader, options = {}) {
6881
+ const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
6882
+ const filter = checkFunctionOption(options.filter);
6883
+ while (pendingAddFileCalls.size) {
6884
+ await Promise.allSettled(Array.from(pendingAddFileCalls));
6885
+ }
6886
+ let resolveAppendZip;
6887
+ const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
6888
+ pendingAddFileCalls.add(promiseAppendZip);
6889
+ const appendedFilenames = [];
6890
+ let releaseLockWriter;
6891
+ try {
6892
+ reader = new GenericReader(reader);
6893
+ await initStream(reader);
6894
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
6895
+ reader = new BlobReader(await streamToBlob(reader.readable));
6896
+ await initStream(reader);
6897
+ }
6898
+ const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
6899
+ const zipReader$1 = new ZipReader(reader);
6900
+ const entries = await zipReader$1.getEntries();
6901
+ const keptEntries = [];
6902
+ for (const entry of entries) {
6903
+ if (!filter || await filter(entry)) {
6904
+ keptEntries.push(entry);
6905
+ }
6906
+ }
6907
+ await zipReader$1.close();
6908
+ await initStream(zipWriter.writer);
6909
+ const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
6910
+ keptEntries.forEach(entry => {
6911
+ const { filename } = entry;
6912
+ if (entriesMissingZip64ExtraField.has(entry)) {
6913
+ throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
6914
+ }
6915
+ if (filenames.has(filename)) {
6916
+ throw new Error(ERR_DUPLICATED_NAME);
6917
+ }
6918
+ filenames.add(filename);
6919
+ appendedFilenames.push(filename);
6920
+ });
6921
+ zipWriter.writerLocked = true;
6922
+ const { lockWriter } = zipWriter;
6923
+ zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
6924
+ zipWriter.writerLocked = false;
6925
+ resolve();
6926
+ });
6927
+ await lockWriter;
6928
+ if (zipWriter.addSplitZipSignature) {
6929
+ delete zipWriter.addSplitZipSignature;
6930
+ if (filter || !await startsWithSplitZipSignature(reader)) {
6931
+ await writeData(zipWriter.writer, getSplitZipSignatureArray());
6932
+ zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6933
+ }
6934
+ }
6935
+ const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
6936
+ keptEntries.forEach(entry => {
6937
+ const {
6938
+ version,
6939
+ rawLastModDate,
6940
+ rawFilename,
6941
+ rawBitFlag,
6942
+ uncompressedSize,
6943
+ compressedSize,
6944
+ extraFieldZip64
6945
+ } = entry;
6946
+ let {
6947
+ compressionMethod,
6948
+ rawExtraField,
6949
+ } = entry;
6950
+ rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
6951
+ if (entry.extraFieldAES) {
6952
+ compressionMethod = COMPRESSION_METHOD_AES;
6953
+ }
6954
+ const extraFieldLength = getLength(rawExtraField);
6955
+ const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
6956
+ const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
6957
+ const {
6958
+ headerArray,
6959
+ headerView
6960
+ } = getHeaderArrayData({
6961
+ version,
6962
+ bitFlag: rawBitFlag,
6963
+ compressionMethod,
6964
+ uncompressedSize,
6965
+ compressedSize,
6966
+ rawLastModDate,
6967
+ rawFilename,
6968
+ zip64CompressedSize,
6969
+ zip64UncompressedSize,
6970
+ extraFieldLength
6971
+ });
6972
+ const { crc32 } = entry;
6973
+ if (crc32 !== UNDEFINED_VALUE) {
6974
+ setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
6975
+ }
6976
+ const { offset, diskNumberStart } = entryPositions.get(entry);
6977
+ Object.assign(entry, {
6978
+ zip64Enabled: true,
6979
+ zip64UncompressedSize,
6980
+ zip64CompressedSize,
6981
+ offset,
6982
+ diskNumberStart,
6983
+ zip64DiskNumberStart: false,
6984
+ rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
6985
+ rawExtraFieldAES: EMPTY_UINT8_ARRAY,
6986
+ rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
6987
+ rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
6988
+ rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
6989
+ rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
6990
+ rawExtraField,
6991
+ rawCentralExtraField: EMPTY_UINT8_ARRAY,
6992
+ headerArray,
6993
+ headerView
6994
+ });
6995
+ fileEntries.set(entry.filename, entry);
6996
+ });
6997
+ } catch (error) {
6998
+ appendedFilenames.forEach(filename => filenames.delete(filename));
6999
+ throw error;
7000
+ } finally {
7001
+ resolveAppendZip();
7002
+ pendingAddFileCalls.delete(promiseAppendZip);
7003
+ if (releaseLockWriter) {
7004
+ releaseLockWriter();
7005
+ }
7006
+ }
7007
+ }
7008
+
6852
7009
  async function prependZipEntries(zipWriter, reader) {
6853
7010
  if (zipWriter.filenames.size) {
6854
7011
  throw new Error(ERR_ZIP_NOT_EMPTY);
6855
7012
  }
6856
- await zipWriter.appendZipEntries(reader);
7013
+ await appendZipEntries(zipWriter, reader);
6857
7014
  }
6858
7015
 
6859
7016
  async function addFileEntry(zipWriter, name, reader, options) {
@@ -8527,26 +8684,63 @@ function removeExtraFieldZip64(rawExtraField) {
8527
8684
  return rawExtraField;
8528
8685
  }
8529
8686
 
8530
- async function copyZipData(zipWriter, reader, entries, directoryOffset) {
8687
+ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
8531
8688
  const { writer } = zipWriter;
8532
8689
  const entryPositions = new Map();
8533
- if (writer.closeDisk) {
8690
+ if (writer.closeDisk || compact) {
8534
8691
  const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
8535
8692
  getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
8536
- let copiedLength = 0;
8537
- for (const entry of sortedEntries) {
8538
- const sourceOffset = getSourceOffset(reader, entry);
8539
- await copyData(zipWriter, reader, copiedLength, sourceOffset - copiedLength);
8540
- if (exceedsAvailableSize(writer, await getLocalHeaderLength(reader, sourceOffset))) {
8541
- await writer.closeDisk();
8542
- }
8543
- entryPositions.set(entry, {
8544
- offset: getSegmentOffset(zipWriter, writer),
8545
- diskNumberStart: getDiskNumber(writer)
8546
- });
8547
- copiedLength = sourceOffset;
8693
+ const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
8694
+ const keptEntrySet = new Set(keptEntries);
8695
+ const localHeaderLengths = new Map();
8696
+ for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
8697
+ const entry = sortedEntries[indexEntry];
8698
+ if (keptEntrySet.has(entry)) {
8699
+ const sourceOffset = getSourceOffset(reader, entry);
8700
+ const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
8701
+ if (localHeaderLength === UNDEFINED_VALUE) {
8702
+ throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
8703
+ }
8704
+ let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
8705
+ if (entry.bitFlag.dataDescriptor) {
8706
+ const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
8707
+ entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
8708
+ }
8709
+ if (entryEnd > regionEnds[indexEntry]) {
8710
+ throw new Error(ERR_OVERLAPPING_ENTRY);
8711
+ }
8712
+ regionEnds[indexEntry] = entryEnd;
8713
+ localHeaderLengths.set(entry, localHeaderLength);
8714
+ }
8715
+ }
8716
+ let copiedOffset = 0;
8717
+ let lastPosition;
8718
+ for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
8719
+ const entry = sortedEntries[indexEntry];
8720
+ if (keptEntrySet.has(entry)) {
8721
+ const sourceOffset = getSourceOffset(reader, entry);
8722
+ if (sourceOffset < copiedOffset) {
8723
+ entryPositions.set(entry, lastPosition);
8724
+ } else {
8725
+ if (!compact) {
8726
+ await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
8727
+ }
8728
+ if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
8729
+ await writer.closeDisk();
8730
+ }
8731
+ lastPosition = {
8732
+ offset: getSegmentOffset(zipWriter, writer),
8733
+ diskNumberStart: getDiskNumber(writer)
8734
+ };
8735
+ entryPositions.set(entry, lastPosition);
8736
+ await copyData(zipWriter, reader, sourceOffset, regionEnds[indexEntry] - sourceOffset);
8737
+ copiedOffset = regionEnds[indexEntry];
8738
+ }
8739
+ }
8740
+ }
8741
+ if (!compact) {
8742
+ await copyData(zipWriter, reader, copiedOffset, directoryOffset - copiedOffset);
8548
8743
  }
8549
- await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
8550
8744
  } else {
8551
8745
  const baseOffset = zipWriter.offset;
8552
8746
  await copyData(zipWriter, reader, 0, directoryOffset);
@@ -8558,6 +8752,20 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
8558
8752
  return entryPositions;
8559
8753
  }
8560
8754
 
8755
+ function getRegionEnds(reader, sortedEntries, directoryOffset) {
8756
+ const regionEnds = new Array(sortedEntries.length);
8757
+ let regionEnd = directoryOffset;
8758
+ for (let indexEntry = sortedEntries.length - 1; indexEntry >= 0; indexEntry--) {
8759
+ const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
8760
+ const nextEntry = sortedEntries[indexEntry + 1];
8761
+ if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
8762
+ regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
8763
+ }
8764
+ regionEnds[indexEntry] = regionEnd;
8765
+ }
8766
+ return regionEnds;
8767
+ }
8768
+
8561
8769
  async function copyData(zipWriter, reader, offset, size) {
8562
8770
  if (size > 0) {
8563
8771
  const { writer } = zipWriter;
@@ -8565,11 +8773,13 @@ async function copyData(zipWriter, reader, offset, size) {
8565
8773
  try {
8566
8774
  await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
8567
8775
  } catch (error) {
8568
- zipWriter.hasCorruptedEntries = true;
8569
- try {
8570
- error.corruptedEntry = true;
8571
- } catch {
8572
- // ignored
8776
+ if (copiedLength) {
8777
+ zipWriter.hasCorruptedEntries = true;
8778
+ try {
8779
+ error.corruptedEntry = true;
8780
+ } catch {
8781
+ // ignored
8782
+ }
8573
8783
  }
8574
8784
  throw error;
8575
8785
  } finally {
@@ -8580,11 +8790,16 @@ async function copyData(zipWriter, reader, offset, size) {
8580
8790
  }
8581
8791
 
8582
8792
  async function getLocalHeaderLength(reader, offset) {
8583
- const headerArray = await readUint8Array(reader, offset, HEADER_SIZE);
8793
+ const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
8794
+ await readUint8Array(reader, offset, HEADER_SIZE) :
8795
+ EMPTY_UINT8_ARRAY;
8584
8796
  if (getLength(headerArray) < HEADER_SIZE) {
8585
- return HEADER_SIZE;
8797
+ return UNDEFINED_VALUE;
8586
8798
  }
8587
8799
  const headerView = getDataView(headerArray);
8800
+ if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
8801
+ return UNDEFINED_VALUE;
8802
+ }
8588
8803
  return HEADER_SIZE +
8589
8804
  getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
8590
8805
  getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
@@ -8935,7 +9150,7 @@ function formatSupported(StreamClass, format) {
8935
9150
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8936
9151
  */
8937
9152
 
8938
- const VERSION = "2.19.0";
9153
+ const VERSION = "2.21.0";
8939
9154
 
8940
9155
  /*
8941
9156
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9940,4 +10155,4 @@ async function terminateWorkersAndModule() {
9940
10155
 
9941
10156
  configureExternalAssets();
9942
10157
 
9943
- export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_CODEC_OUT_OF_MEMORY, ERR_DUPLICATED_NAME, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_HTTP_STATUS, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_BASE_URI, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH_VALUE, ERR_INVALID_READER, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_URI, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_RESERVED_COMPRESSION_METHOD, ERR_SPLIT_ZIP_FILE, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_CRC32, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_WRITER_SIZE_NOT_WRITABLE, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_CLAMPED_LAST_MODIFICATION_DATE, WARNING_COMPRESSED_PATCHED_DATA, WARNING_COMPRESSION_UNAVAILABLE, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, isZipFile, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };
10158
+ export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_CODEC_OUT_OF_MEMORY, ERR_DUPLICATED_NAME, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_HTTP_STATUS, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_BASE_URI, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH_VALUE, ERR_INVALID_READER, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_URI, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_RESERVED_COMPRESSION_METHOD, ERR_SPLIT_ZIP_FILE, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_CRC32, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_WRITER_SIZE_NOT_WRITABLE, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_CLAMPED_LAST_MODIFICATION_DATE, WARNING_COMPRESSED_PATCHED_DATA, WARNING_COMPRESSION_UNAVAILABLE, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_MISSING_ZIP64_EXTRA_FIELD, WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, isZipFile, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };