@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
@@ -46,6 +46,7 @@
46
46
  const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
47
47
  const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
48
48
  const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
49
+ const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
49
50
  const CENTRAL_FILE_HEADER_SIGNATURE = 0x02014b50;
50
51
  const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;
51
52
  const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 0x06064b50;
@@ -4329,6 +4330,8 @@
4329
4330
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
4330
4331
  const OPTION_STRICTNESS = "strictness";
4331
4332
  const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
4333
+ const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
4334
+ const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
4332
4335
  const STRICTNESS_STRICT = "strict";
4333
4336
  const STRICTNESS_BALANCED = "balanced";
4334
4337
  const STRICTNESS_TOLERANT = "tolerant";
@@ -4454,6 +4457,7 @@
4454
4457
  let startOffset;
4455
4458
  let zip64EndOfDirectory;
4456
4459
  let zip64EndOfDirectoryVersion2;
4460
+ let directoryEncryptionInfo;
4457
4461
  const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
4458
4462
  if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
4459
4463
  directoryDataOffset += getDiskOffset$1(reader, diskNumber);
@@ -4484,6 +4488,15 @@
4484
4488
  }
4485
4489
  zip64EndOfDirectory = true;
4486
4490
  zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
4491
+ if (zip64EndOfDirectoryVersion2) {
4492
+ const extensibleDataLength = Math.min(
4493
+ Number(getBigUint64(endOfDirectoryView, 4)) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
4494
+ reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4495
+ if (extensibleDataLength > 0) {
4496
+ const rawExtensibleData = await readUint8Array(reader, directoryDataOffset + ZIP64_END_OF_CENTRAL_DIR_LENGTH, extensibleDataLength);
4497
+ directoryEncryptionInfo = getDirectoryEncryptionInfo(rawExtensibleData);
4498
+ }
4499
+ }
4487
4500
  if (lastDiskNumber == MAX_16_BITS) {
4488
4501
  lastDiskNumber = getUint32(endOfDirectoryView, 16);
4489
4502
  } else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
@@ -4507,7 +4520,7 @@
4507
4520
  directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4508
4521
  }
4509
4522
  }
4510
- const declaredDirectoryDataLength = directoryDataLength;
4523
+ let declaredDirectoryDataLength = directoryDataLength;
4511
4524
  const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
4512
4525
  (zip64EndOfDirectory ? ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
4513
4526
  if (directoryDataOffset >= reader.size) {
@@ -4555,6 +4568,18 @@
4555
4568
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
4556
4569
  throw new Error(ERR_BAD_FORMAT);
4557
4570
  }
4571
+ zipReader.directoryOffset = directoryDataOffset;
4572
+ zipReader.directoryLength = declaredDirectoryDataLength;
4573
+ const decryptCentralDirectory = getOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
4574
+ let decryptedDirectory;
4575
+ if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
4576
+ getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
4577
+ (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4578
+ directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
4579
+ directoryView = getDataView(directoryArray);
4580
+ declaredDirectoryDataLength = directoryArray.length;
4581
+ decryptedDirectory = true;
4582
+ }
4558
4583
  startOffset = directoryDataOffset;
4559
4584
  const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
4560
4585
  const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
@@ -4563,7 +4588,7 @@
4563
4588
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4564
4589
  const fileEntry = new ZipEntry$1(reader, config, zipReader.options);
4565
4590
  if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
4566
- if (indexFile == 0 && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4591
+ if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
4567
4592
  throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
4568
4593
  }
4569
4594
  throw new Error(ERR_CENTRAL_DIRECTORY_NOT_FOUND);
@@ -4676,7 +4701,15 @@
4676
4701
  }
4677
4702
  yield entry;
4678
4703
  }
4679
- if (checkAmbiguity && offset != declaredDirectoryDataLength) {
4704
+ let offsetAfterSignature = offset;
4705
+ if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
4706
+ const signatureDataLength = getUint16(directoryView, offset + 4);
4707
+ if (offset + 6 + signatureDataLength <= directoryArray.length) {
4708
+ zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
4709
+ offsetAfterSignature = offset + 6 + signatureDataLength;
4710
+ }
4711
+ }
4712
+ if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
4680
4713
  throwAmbiguousArchive("trailing central directory data");
4681
4714
  }
4682
4715
  if (duplicateFilename) {
@@ -4908,6 +4941,25 @@
4908
4941
  return false;
4909
4942
  }
4910
4943
 
4944
+ function getDirectoryEncryptionInfo(rawExtensibleData) {
4945
+ const directoryEncryptionInfo = { rawExtensibleData };
4946
+ if (rawExtensibleData.length >= 28) {
4947
+ const extensibleDataView = getDataView(rawExtensibleData);
4948
+ const hashDataLength = getUint16(extensibleDataView, 26);
4949
+ Object.assign(directoryEncryptionInfo, {
4950
+ compressionMethod: getUint16(extensibleDataView, 0),
4951
+ compressedSize: Number(getBigUint64(extensibleDataView, 2)),
4952
+ uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
4953
+ encryptionAlgorithm: getUint16(extensibleDataView, 18),
4954
+ bitLength: getUint16(extensibleDataView, 20),
4955
+ flags: getUint16(extensibleDataView, 22),
4956
+ hashAlgorithm: getUint16(extensibleDataView, 24),
4957
+ hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
4958
+ });
4959
+ }
4960
+ return directoryEncryptionInfo;
4961
+ }
4962
+
4911
4963
  function readCommonHeader(directory, dataView, offset) {
4912
4964
  const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
4913
4965
  const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
@@ -5459,6 +5511,7 @@
5459
5511
  ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
5460
5512
  ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
5461
5513
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
5514
+ ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
5462
5515
  ZipReader: ZipReader
5463
5516
  });
5464
5517
 
@@ -5516,6 +5569,7 @@
5516
5569
  const ERR_INVALID_UNIX_ID_SIZE = "uid/gid must be 0..65535 for unixExtraFieldType 'unix' (use 'infozip' for larger ids)";
5517
5570
  const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
5518
5571
  const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
5572
+ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
5519
5573
 
5520
5574
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
5521
5575
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
@@ -6813,8 +6867,9 @@
6813
6867
 
6814
6868
  async function closeFile(zipWriter, comment, options) {
6815
6869
  const directoryDataLength = createDirectoryRecords(zipWriter.files);
6816
- const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
6817
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
6870
+ const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
6871
+ const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
6872
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
6818
6873
  }
6819
6874
 
6820
6875
  function createDirectoryRecords(files) {
@@ -6971,12 +7026,33 @@
6971
7026
  }
6972
7027
  }
6973
7028
  await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
6974
- return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
7029
+ return {
7030
+ directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
7031
+ directoryArray
7032
+ };
7033
+ }
7034
+
7035
+ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7036
+ const signCentralDirectory = getOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
7037
+ if (signCentralDirectory) {
7038
+ const signatureData = await signCentralDirectory(directoryArray);
7039
+ const signatureDataLength = getLength(signatureData);
7040
+ if (signatureDataLength > MAX_16_BITS) {
7041
+ throw new Error(ERR_INVALID_SIGNATURE_DATA);
7042
+ }
7043
+ const signatureRecord = createRecordWriter(6 + signatureDataLength);
7044
+ signatureRecord.uint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7045
+ signatureRecord.uint16(signatureDataLength);
7046
+ signatureRecord.bytes(signatureData);
7047
+ await writeData(zipWriter.writer, signatureRecord.array);
7048
+ return 6 + signatureDataLength;
7049
+ }
7050
+ return 0;
6975
7051
  }
6976
7052
 
6977
7053
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
6978
7054
  const { writer } = zipWriter;
6979
- const { directoryStart } = cdInfo;
7055
+ const { directoryStart, signatureLength } = cdInfo;
6980
7056
  let { directoryDataLength } = cdInfo;
6981
7057
  let filesLength = zipWriter.files.size;
6982
7058
  let diskNumber = directoryStart.diskNumber;
@@ -7015,7 +7091,7 @@
7015
7091
  endOfdirectoryRecord.uint64(directoryOffset);
7016
7092
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
7017
7093
  endOfdirectoryRecord.uint32(lastDiskNumber);
7018
- endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
7094
+ endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
7019
7095
  endOfdirectoryRecord.uint32(lastDiskNumber + 1);
7020
7096
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
7021
7097
  if (supportZip64SplitFile) {
@@ -8288,6 +8364,8 @@
8288
8364
  }
8289
8365
  }
8290
8366
 
8367
+ exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
8368
+ exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
8291
8369
  exports.fs = fs;
8292
8370
 
8293
8371
  }));