@zip.js/zip.js 2.17.0 → 2.18.1

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.
@@ -3280,8 +3280,13 @@ function getResponseError(errorData, errorValue) {
3280
3280
  if (codecImportFailed) {
3281
3281
  responseError.codecImportFailed = true;
3282
3282
  }
3283
- if (cause && !isErrorObject(responseError.cause)) {
3284
- responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3283
+ if (cause) {
3284
+ if (!isErrorObject(responseError.cause)) {
3285
+ responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3286
+ }
3287
+ if (cause.code !== UNDEFINED_VALUE && responseError.cause.code !== cause.code) {
3288
+ responseError.cause.code = cause.code;
3289
+ }
3285
3290
  }
3286
3291
  if (errorValue) {
3287
3292
  if (responseError.name !== name) {
@@ -4873,7 +4878,7 @@ const PARENT_DIRECTORY_REGEXP = /(^|[\\/])\.\.([\\/]|$)/;
4873
4878
  const CHARSET_UTF8 = "utf-8";
4874
4879
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
4875
4880
  const CHARSET_CP437 = "cp437";
4876
- const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_LANG_ENCODING_FLAG;
4881
+ const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_STRONG_ENCRYPTION | BITFLAG_LANG_ENCODING_FLAG;
4877
4882
  const VENDOR_VERSION_AE_1$1 = 1;
4878
4883
  const ZIP64_PROPERTIES = [
4879
4884
  [PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS],
@@ -5527,12 +5532,12 @@ let ZipEntry$1 = class ZipEntry {
5527
5532
  fileEntry.gid = gid;
5528
5533
  }
5529
5534
  const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
5530
- const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
5535
+ const encrypted = zipEntry.encrypted && (!passThroughEncryption || checkPasswordOnly);
5531
5536
  const zipCrypto = encrypted && !extraFieldAES;
5532
5537
  if (!passThroughEncryption) {
5533
5538
  fileEntry.zipCrypto = zipCrypto;
5534
5539
  }
5535
- if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5540
+ if (encrypted && (zipEntry.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
5536
5541
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
5537
5542
  }
5538
5543
  const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
@@ -5772,8 +5777,16 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5772
5777
  });
5773
5778
  const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
5774
5779
  if (extraFieldZip64) {
5775
- readExtraFieldZip64(extraFieldZip64, directory);
5780
+ if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
5781
+ malformedExtraField = true;
5782
+ }
5776
5783
  directory.extraFieldZip64 = extraFieldZip64;
5784
+ } else if (ZIP64_PROPERTIES.some(([propertyName, max]) => directory[propertyName] == max)) {
5785
+ if (localDirectory) {
5786
+ malformedExtraField = true;
5787
+ } else {
5788
+ throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
5789
+ }
5777
5790
  }
5778
5791
  const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
5779
5792
  if (extraFieldUnicodePath) {
@@ -5786,10 +5799,13 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5786
5799
  directory.extraFieldUnicodeComment = extraFieldUnicodeComment;
5787
5800
  }
5788
5801
  const extraFieldAES = extraField.get(EXTRAFIELD_TYPE_AES);
5789
- if (extraFieldAES && extraFieldAES.data.length >= 7) {
5802
+ if (extraFieldAES && (compressionMethod == COMPRESSION_METHOD_AES || directory.encrypted) && extraFieldAES.data.length >= 7) {
5790
5803
  readExtraFieldAES(extraFieldAES, directory, compressionMethod);
5791
5804
  directory.extraFieldAES = extraFieldAES;
5792
5805
  } else {
5806
+ if (extraFieldAES) {
5807
+ malformedExtraField = true;
5808
+ }
5793
5809
  directory.compressionMethod = compressionMethod;
5794
5810
  }
5795
5811
  const extraFieldPkwareUnix = extraField.get(EXTRAFIELD_TYPE_PKWARE_UNIX);
@@ -5832,20 +5848,35 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5832
5848
  return malformedExtraField;
5833
5849
  }
5834
5850
 
5835
- function readExtraFieldZip64(extraFieldZip64, directory) {
5851
+ function readExtraFieldZip64(extraFieldZip64, directory, localDirectory) {
5836
5852
  directory.zip64 = true;
5837
5853
  const extraFieldView = getDataView(extraFieldZip64.data);
5838
5854
  const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
5839
5855
  const requiredLength = missingProperties.reduce((length, [, max]) => length + ZIP64_EXTRACTION[max].bytes, 0);
5840
5856
  if (extraFieldZip64.data.length < requiredLength) {
5857
+ if (localDirectory) {
5858
+ return false;
5859
+ }
5841
5860
  throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
5842
5861
  }
5843
- for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
5844
- const [propertyName, max] = missingProperties[indexMissingProperty];
5845
- const extraction = ZIP64_EXTRACTION[max];
5846
- directory[propertyName] = extraFieldZip64[propertyName] = extraction.getValue(extraFieldView, offset);
5847
- offset += extraction.bytes;
5862
+ const values = [];
5863
+ try {
5864
+ for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
5865
+ const [, max] = missingProperties[indexMissingProperty];
5866
+ const extraction = ZIP64_EXTRACTION[max];
5867
+ values.push(extraction.getValue(extraFieldView, offset));
5868
+ offset += extraction.bytes;
5869
+ }
5870
+ } catch (error) {
5871
+ if (localDirectory) {
5872
+ return false;
5873
+ }
5874
+ throw error;
5848
5875
  }
5876
+ missingProperties.forEach(([propertyName], indexMissingProperty) => {
5877
+ directory[propertyName] = extraFieldZip64[propertyName] = values[indexMissingProperty];
5878
+ });
5879
+ return true;
5849
5880
  }
5850
5881
 
5851
5882
  function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) {
@@ -6027,32 +6058,27 @@ async function detectOverlappingEntry({
6027
6058
  }) {
6028
6059
  let dataDescriptorLength = 0;
6029
6060
  if (dataDescriptor) {
6030
- if (extraFieldZip64) {
6031
- dataDescriptorLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH;
6032
- } else {
6033
- dataDescriptorLength = DATA_DESCRIPTOR_RECORD_LENGTH;
6034
- }
6035
- }
6036
- if (dataDescriptorLength) {
6037
- const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
6061
+ const zip64 = Boolean(extraFieldZip64);
6062
+ const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
6038
6063
  const dataDescriptorView = getDataView(dataDescriptorArray);
6039
- let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
6040
- getUint32$1(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
6041
- if (signature) {
6042
- const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
6043
- const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
6044
- if (matchCrc32 &&
6045
- signedDataDescriptor.compressedSize == compressedSize &&
6046
- signedDataDescriptor.uncompressedSize == uncompressedSize) {
6047
- dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
6048
- } else {
6049
- signature = false;
6064
+ const ignoreCrc32 = fileEntry.encrypted && !fileEntry.zipCrypto;
6065
+ let localDataDescriptor;
6066
+ for (const [zip64Layout, signature] of [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]) {
6067
+ const candidate = readDataDescriptor(dataDescriptorView, zip64Layout, signature);
6068
+ if (candidate && (ignoreCrc32 || candidate.crc32 == crc32) &&
6069
+ candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize) {
6070
+ localDataDescriptor = candidate;
6071
+ break;
6050
6072
  }
6051
6073
  }
6052
- if (dataDescriptorArray.length >= dataDescriptorLength) {
6053
- const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
6054
- localDataDescriptor.signature = signature;
6074
+ if (!localDataDescriptor) {
6075
+ localDataDescriptor = readDataDescriptor(dataDescriptorView, zip64, false);
6076
+ }
6077
+ if (localDataDescriptor) {
6055
6078
  fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
6079
+ dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
6080
+ } else {
6081
+ dataDescriptorLength = getDataDescriptorLength(zip64, false);
6056
6082
  }
6057
6083
  }
6058
6084
  const range = {
@@ -6117,18 +6143,31 @@ function mergeRanges(sortedRanges, pendingRanges) {
6117
6143
  return mergedRanges;
6118
6144
  }
6119
6145
 
6120
- function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
6146
+ function readDataDescriptor(dataDescriptorView, zip64, signature) {
6147
+ const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
6148
+ if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
6149
+ (signature && getUint32$1(dataDescriptorView, 0) != DATA_DESCRIPTOR_RECORD_SIGNATURE)) {
6150
+ return UNDEFINED_VALUE;
6151
+ }
6121
6152
  const crc32 = getUint32$1(dataDescriptorView, offset);
6122
6153
  let compressedSize;
6123
6154
  let uncompressedSize;
6124
- if (extraFieldZip64) {
6125
- compressedSize = getBigUint64(dataDescriptorView, offset + 4);
6126
- uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
6127
- } else {
6128
- compressedSize = getUint32$1(dataDescriptorView, offset + 4);
6129
- uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
6155
+ try {
6156
+ if (zip64) {
6157
+ compressedSize = getBigUint64(dataDescriptorView, offset + 4);
6158
+ uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
6159
+ } else {
6160
+ compressedSize = getUint32$1(dataDescriptorView, offset + 4);
6161
+ uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
6162
+ }
6163
+ } catch {
6164
+ return UNDEFINED_VALUE;
6130
6165
  }
6131
- return { crc32, compressedSize, uncompressedSize };
6166
+ return { signature, zip64, crc32, compressedSize, uncompressedSize };
6167
+ }
6168
+
6169
+ function getDataDescriptorLength(zip64, signature) {
6170
+ return (zip64 ? DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH : DATA_DESCRIPTOR_RECORD_LENGTH) + (signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0);
6132
6171
  }
6133
6172
 
6134
6173
  function getDiskOffset$1(reader, diskNumber) {
@@ -9049,7 +9088,7 @@ function formatSupported(StreamClass, format) {
9049
9088
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9050
9089
  */
9051
9090
 
9052
- const VERSION = "2.17.0";
9091
+ const VERSION = "2.18.1";
9053
9092
 
9054
9093
  /*
9055
9094
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.