@zip.js/zip.js 2.8.46 → 2.8.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +85 -9
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +95 -8
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +85 -9
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +86 -8
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +85 -9
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +99 -10
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +98 -9
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +97 -10
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +97 -10
  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 +96 -9
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +99 -10
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +98 -9
  27. package/index.d.cts +141 -0
  28. package/index.d.ts +141 -0
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-pool.js +6 -3
  31. package/lib/core/codec-worker.js +2 -1
  32. package/lib/core/constants.js +2 -0
  33. package/lib/core/options.js +4 -0
  34. package/lib/core/streams/codec-stream.js +2 -0
  35. package/lib/core/streams/common-crypto.js +2 -1
  36. package/lib/core/streams/zip-entry-stream.js +4 -2
  37. package/lib/core/util/sync-access-handle-temp-stream.js +2 -1
  38. package/lib/core/web-worker-inline-native.js +1 -1
  39. package/lib/core/web-worker-inline-wasm.js +1 -1
  40. package/lib/core/zip-fs.js +1 -1
  41. package/lib/core/zip-reader.js +58 -5
  42. package/lib/core/zip-writer.js +43 -8
  43. package/lib/zip-core-base.js +2 -1
  44. package/lib/zip-core-reader.js +2 -1
  45. package/lib/zip-core-writer.js +10 -1
  46. package/package.json +1 -1
package/dist/zip-core.js CHANGED
@@ -47,6 +47,7 @@
47
47
  const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
48
48
  const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
49
49
  const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
50
+ const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
50
51
  const CENTRAL_FILE_HEADER_SIGNATURE = 0x02014b50;
51
52
  const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;
52
53
  const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 0x06064b50;
@@ -4454,6 +4455,8 @@
4454
4455
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
4455
4456
  const OPTION_STRICTNESS = "strictness";
4456
4457
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
4458
+ const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
4459
+ const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
4457
4460
  const STRICTNESS_STRICT = "strict";
4458
4461
  const STRICTNESS_BALANCED = "balanced";
4459
4462
  const STRICTNESS_TOLERANT = "tolerant";
@@ -4579,6 +4582,7 @@
4579
4582
  let startOffset;
4580
4583
  let zip64EndOfDirectory;
4581
4584
  let zip64EndOfDirectoryVersion2;
4585
+ let directoryEncryptionInfo;
4582
4586
  const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
4583
4587
  if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
4584
4588
  directoryDataOffset += getDiskOffset$1(reader, diskNumber);
@@ -4609,6 +4613,15 @@
4609
4613
  }
4610
4614
  zip64EndOfDirectory = true;
4611
4615
  zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
4616
+ if (zip64EndOfDirectoryVersion2) {
4617
+ const extensibleDataLength = Math.min(
4618
+ Number(getBigUint64(endOfDirectoryView, 4)) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
4619
+ reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4620
+ if (extensibleDataLength > 0) {
4621
+ const rawExtensibleData = await readUint8Array(reader, directoryDataOffset + ZIP64_END_OF_CENTRAL_DIR_LENGTH, extensibleDataLength);
4622
+ directoryEncryptionInfo = getDirectoryEncryptionInfo(rawExtensibleData);
4623
+ }
4624
+ }
4612
4625
  if (lastDiskNumber == MAX_16_BITS) {
4613
4626
  lastDiskNumber = getUint32(endOfDirectoryView, 16);
4614
4627
  } else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
@@ -4632,7 +4645,7 @@
4632
4645
  directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4633
4646
  }
4634
4647
  }
4635
- const declaredDirectoryDataLength = directoryDataLength;
4648
+ let declaredDirectoryDataLength = directoryDataLength;
4636
4649
  const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
4637
4650
  (zip64EndOfDirectory ? ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
4638
4651
  if (directoryDataOffset >= reader.size) {
@@ -4680,6 +4693,18 @@
4680
4693
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
4681
4694
  throw new Error(ERR_BAD_FORMAT);
4682
4695
  }
4696
+ zipReader.directoryOffset = directoryDataOffset;
4697
+ zipReader.directoryLength = declaredDirectoryDataLength;
4698
+ const decryptCentralDirectory = getOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4699
+ let decryptedDirectory;
4700
+ if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
4701
+ getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4702
+ (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4703
+ directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
4704
+ directoryView = getDataView(directoryArray);
4705
+ declaredDirectoryDataLength = directoryArray.length;
4706
+ decryptedDirectory = true;
4707
+ }
4683
4708
  startOffset = directoryDataOffset;
4684
4709
  const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
4685
4710
  const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
@@ -4688,7 +4713,7 @@
4688
4713
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4689
4714
  const fileEntry = new ZipEntry(reader, config, zipReader.options);
4690
4715
  if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4691
- if (indexFile == 0 && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4716
+ if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4692
4717
  throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
4693
4718
  }
4694
4719
  throw new Error(ERR_CENTRAL_DIRECTORY_NOT_FOUND);
@@ -4801,7 +4826,15 @@
4801
4826
  }
4802
4827
  yield entry;
4803
4828
  }
4804
- if (checkAmbiguity && offset != declaredDirectoryDataLength) {
4829
+ let offsetAfterSignature = offset;
4830
+ if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
4831
+ const signatureDataLength = getUint16(directoryView, offset + 4);
4832
+ if (offset + 6 + signatureDataLength <= directoryArray.length) {
4833
+ zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
4834
+ offsetAfterSignature = offset + 6 + signatureDataLength;
4835
+ }
4836
+ }
4837
+ if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
4805
4838
  throwAmbiguousArchive("trailing central directory data");
4806
4839
  }
4807
4840
  if (duplicateFilename) {
@@ -5073,6 +5106,25 @@
5073
5106
  return false;
5074
5107
  }
5075
5108
 
5109
+ function getDirectoryEncryptionInfo(rawExtensibleData) {
5110
+ const directoryEncryptionInfo = { rawExtensibleData };
5111
+ if (rawExtensibleData.length >= 28) {
5112
+ const extensibleDataView = getDataView(rawExtensibleData);
5113
+ const hashDataLength = getUint16(extensibleDataView, 26);
5114
+ Object.assign(directoryEncryptionInfo, {
5115
+ compressionMethod: getUint16(extensibleDataView, 0),
5116
+ compressedSize: Number(getBigUint64(extensibleDataView, 2)),
5117
+ uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
5118
+ encryptionAlgorithm: getUint16(extensibleDataView, 18),
5119
+ bitLength: getUint16(extensibleDataView, 20),
5120
+ flags: getUint16(extensibleDataView, 22),
5121
+ hashAlgorithm: getUint16(extensibleDataView, 24),
5122
+ hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
5123
+ });
5124
+ }
5125
+ return directoryEncryptionInfo;
5126
+ }
5127
+
5076
5128
  function readCommonHeader(directory, dataView, offset) {
5077
5129
  const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
5078
5130
  const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
@@ -5624,6 +5676,7 @@
5624
5676
  ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
5625
5677
  ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
5626
5678
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
5679
+ ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
5627
5680
  ZipReader: ZipReader,
5628
5681
  ZipReaderStream: ZipReaderStream
5629
5682
  });
@@ -5682,6 +5735,7 @@
5682
5735
  const ERR_INVALID_UNIX_ID_SIZE = "uid/gid must be 0..65535 for unixExtraFieldType 'unix' (use 'infozip' for larger ids)";
5683
5736
  const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
5684
5737
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
5738
+ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
5685
5739
 
5686
5740
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
5687
5741
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
@@ -7041,8 +7095,9 @@
7041
7095
 
7042
7096
  async function closeFile(zipWriter, comment, options) {
7043
7097
  const directoryDataLength = createDirectoryRecords(zipWriter.files);
7044
- const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7045
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
7098
+ const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7099
+ const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
7100
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
7046
7101
  }
7047
7102
 
7048
7103
  function createDirectoryRecords(files) {
@@ -7199,12 +7254,33 @@
7199
7254
  }
7200
7255
  }
7201
7256
  await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
7202
- return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
7257
+ return {
7258
+ directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
7259
+ directoryArray
7260
+ };
7261
+ }
7262
+
7263
+ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7264
+ const signCentralDirectory = getOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
7265
+ if (signCentralDirectory) {
7266
+ const signatureData = await signCentralDirectory(directoryArray);
7267
+ const signatureDataLength = getLength(signatureData);
7268
+ if (signatureDataLength > MAX_16_BITS) {
7269
+ throw new Error(ERR_INVALID_SIGNATURE_DATA);
7270
+ }
7271
+ const signatureRecord = createRecordWriter(6 + signatureDataLength);
7272
+ signatureRecord.uint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7273
+ signatureRecord.uint16(signatureDataLength);
7274
+ signatureRecord.bytes(signatureData);
7275
+ await writeData(zipWriter.writer, signatureRecord.array);
7276
+ return 6 + signatureDataLength;
7277
+ }
7278
+ return 0;
7203
7279
  }
7204
7280
 
7205
7281
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7206
7282
  const { writer } = zipWriter;
7207
- const { directoryStart } = cdInfo;
7283
+ const { directoryStart, signatureLength } = cdInfo;
7208
7284
  let { directoryDataLength } = cdInfo;
7209
7285
  let filesLength = zipWriter.files.size;
7210
7286
  let diskNumber = directoryStart.diskNumber;
@@ -7243,7 +7319,7 @@
7243
7319
  endOfdirectoryRecord.uint64(directoryOffset);
7244
7320
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
7245
7321
  endOfdirectoryRecord.uint32(lastDiskNumber);
7246
- endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
7322
+ endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
7247
7323
  endOfdirectoryRecord.uint32(lastDiskNumber + 1);
7248
7324
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
7249
7325
  if (supportZip64SplitFile) {
@@ -7948,9 +8024,17 @@
7948
8024
  exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
7949
8025
  exports.ERR_INVALID_EXTRAFIELD_DATA = ERR_INVALID_EXTRAFIELD_DATA;
7950
8026
  exports.ERR_INVALID_EXTRAFIELD_TYPE = ERR_INVALID_EXTRAFIELD_TYPE;
8027
+ exports.ERR_INVALID_GID = ERR_INVALID_GID;
8028
+ exports.ERR_INVALID_MSDOS_ATTRIBUTES = ERR_INVALID_MSDOS_ATTRIBUTES;
8029
+ exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
7951
8030
  exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
7952
8031
  exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
8032
+ exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
8033
+ exports.ERR_INVALID_UID = ERR_INVALID_UID;
7953
8034
  exports.ERR_INVALID_UNCOMPRESSED_SIZE = ERR_INVALID_UNCOMPRESSED_SIZE;
8035
+ exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
8036
+ exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
8037
+ exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
7954
8038
  exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
7955
8039
  exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
7956
8040
  exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
@@ -7960,9 +8044,12 @@
7960
8044
  exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
7961
8045
  exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
7962
8046
  exports.ERR_UNSUPPORTED_COMPRESSION = ERR_UNSUPPORTED_COMPRESSION$1;
8047
+ exports.ERR_UNSUPPORTED_CONTEXT = ERR_UNSUPPORTED_CONTEXT;
8048
+ exports.ERR_UNSUPPORTED_CRYPTO_API = ERR_UNSUPPORTED_CRYPTO_API;
7963
8049
  exports.ERR_UNSUPPORTED_ENCRYPTION = ERR_UNSUPPORTED_ENCRYPTION;
7964
8050
  exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
7965
8051
  exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
8052
+ exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
7966
8053
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
7967
8054
  exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
7968
8055
  exports.HttpRangeReader = HttpRangeReader;