@zip.js/zip.js 2.8.55 → 2.8.56

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.
package/index-native.cjs CHANGED
@@ -229,6 +229,18 @@ function checkPasswordOption(password, rawPassword) {
229
229
  }
230
230
  }
231
231
 
232
+ function checkInteger(value, maxValue, errorMessage) {
233
+ if (!Number.isInteger(value) || value < 0 || value > maxValue) {
234
+ throw new Error(errorMessage);
235
+ }
236
+ }
237
+
238
+ function checkIntegerOption(value, maxValue, errorMessage) {
239
+ if (value !== UNDEFINED_VALUE) {
240
+ checkInteger(value, maxValue, errorMessage);
241
+ }
242
+ }
243
+
232
244
  function toNumber(value) {
233
245
  return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
234
246
  }
@@ -5061,8 +5073,15 @@ class ZipReader {
5061
5073
  yield entry;
5062
5074
  }
5063
5075
  let offsetAfterSignature = offset;
5064
- const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5076
+ let digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5065
5077
  (decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
5078
+ if (!digitalSignature && !decryptedDirectory) {
5079
+ const signatureRecordOffset = directoryDataOffset + offset;
5080
+ const signatureRecordLength = Math.min(centralDirectoryEndOffset - signatureRecordOffset, 6 + MAX_16_BITS);
5081
+ if (signatureRecordLength >= 6) {
5082
+ digitalSignature = readDigitalSignature(await readUint8Array(reader, signatureRecordOffset, signatureRecordLength));
5083
+ }
5084
+ }
5066
5085
  if (digitalSignature) {
5067
5086
  zipReader.digitalSignature = digitalSignature;
5068
5087
  offsetAfterSignature = offset + 6 + digitalSignature.length;
@@ -6139,6 +6158,8 @@ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6139
6158
 
6140
6159
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6141
6160
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6161
+ const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6162
+ const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6142
6163
  const VENDOR_VERSION_AE_1 = 1;
6143
6164
  const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6144
6165
  const UNIX_EXTRA_FIELD_TYPE = "unix";
@@ -6185,16 +6206,14 @@ class ZipWriter {
6185
6206
  await zipReader$1.close();
6186
6207
  await initStream(this.writer);
6187
6208
  const { directoryOffset } = zipReader$1;
6188
- let splitZipSignatureLength = 0;
6189
6209
  if (this.addSplitZipSignature) {
6190
6210
  delete this.addSplitZipSignature;
6191
6211
  if (!await startsWithSplitZipSignature(reader)) {
6192
6212
  await writeData(this.writer, getSplitZipSignatureArray());
6193
- splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6194
- this.offset += splitZipSignatureLength;
6213
+ this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6195
6214
  }
6196
6215
  }
6197
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
6216
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
6198
6217
  this.filenames = new Set(entries.map(entry => entry.filename));
6199
6218
  this.fileEntries = new Map(entries.map(entry => {
6200
6219
  const {
@@ -6436,7 +6455,8 @@ async function addFile(zipWriter, name, reader, options) {
6436
6455
  signature: options[PROPERTY_NAME_SIGNATURE],
6437
6456
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6438
6457
  offset: zipWriter.offset - diskOffset,
6439
- diskNumberStart: diskNumber
6458
+ diskNumberStart: diskNumber,
6459
+ [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6440
6460
  });
6441
6461
  const headerInfo = getHeaderInfo(options);
6442
6462
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -6468,15 +6488,9 @@ function resolveAttributes(zipWriter, name, options) {
6468
6488
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
6469
6489
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
6470
6490
  let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
6471
- if (uid !== UNDEFINED_VALUE && (!Number.isInteger(uid) || uid < 0 || uid > MAX_32_BITS)) {
6472
- throw new Error(ERR_INVALID_UID);
6473
- }
6474
- if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
6475
- throw new Error(ERR_INVALID_GID);
6476
- }
6477
- if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
6478
- throw new Error(ERR_INVALID_UNIX_MODE);
6479
- }
6491
+ checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6492
+ checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6493
+ checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6480
6494
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6481
6495
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6482
6496
  }
@@ -6498,9 +6512,7 @@ function resolveAttributes(zipWriter, name, options) {
6498
6512
  msDosCompatible = true;
6499
6513
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
6500
6514
  }
6501
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6502
- throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
6503
- }
6515
+ checkIntegerOption(msdosAttributesRaw, MAX_8_BITS, ERR_INVALID_MSDOS_ATTRIBUTES);
6504
6516
  if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
6505
6517
  throw new Error(ERR_INVALID_MSDOS_DATA);
6506
6518
  }
@@ -6640,9 +6652,7 @@ function resolveMetadata(zipWriter, name, options) {
6640
6652
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6641
6653
  }
6642
6654
  let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
6643
- if (level !== UNDEFINED_VALUE && (!Number.isInteger(level) || level < 0 || level > MAX_LEVEL)) {
6644
- throw new Error(ERR_INVALID_LEVEL);
6645
- }
6655
+ checkIntegerOption(level, MAX_LEVEL, ERR_INVALID_LEVEL);
6646
6656
  if (zipWriter.options[OPTION_USDZ]) {
6647
6657
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
6648
6658
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -6720,9 +6730,7 @@ function serializeExtraField(extraField) {
6720
6730
  let extraFieldSize = 0;
6721
6731
  let offset = 0;
6722
6732
  extraField.forEach((data, type) => {
6723
- if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
6724
- throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
6725
- }
6733
+ checkInteger(type, MAX_16_BITS, ERR_INVALID_EXTRAFIELD_TYPE);
6726
6734
  if (!(data instanceof Uint8Array)) {
6727
6735
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
6728
6736
  }
@@ -6837,7 +6845,9 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6837
6845
  const usdz = writerOptions[OPTION_USDZ];
6838
6846
  const files = new Map();
6839
6847
  let layoutDependsOnWriteOrder = Boolean(usdz);
6840
- let offset = 0;
6848
+ const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
6849
+ let offset = initialOffset;
6850
+ let minimumEntrySize = INFINITY_VALUE;
6841
6851
  for (const entry of entries) {
6842
6852
  let { name } = entry;
6843
6853
  const { size } = entry;
@@ -6861,7 +6871,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6861
6871
  if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
6862
6872
  throw new Error(ERR_UNDETERMINED_SIZE);
6863
6873
  }
6864
- const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
6874
+ const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
6865
6875
  const headerInfo = getHeaderInfo(entryOptions);
6866
6876
  const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
6867
6877
  const entryInfo = {
@@ -6872,15 +6882,17 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6872
6882
  appendExtraFieldUSDZ(entryInfo, offset);
6873
6883
  }
6874
6884
  const compressedSize = hasContent ? maximumCompressedSize : 0;
6875
- if (offset >= MAX_32_BITS) {
6876
- layoutDependsOnWriteOrder = true;
6877
- }
6878
6885
  files.set(name, Object.assign({}, entryOptions, headerInfo, {
6879
6886
  offset,
6880
6887
  diskNumberStart: 0,
6881
6888
  compressedSize
6882
6889
  }));
6883
- offset += entryInfo.metadataSize + compressedSize;
6890
+ const entrySize = entryInfo.metadataSize + compressedSize;
6891
+ minimumEntrySize = Math.min(minimumEntrySize, entrySize);
6892
+ offset += entrySize;
6893
+ }
6894
+ if (files.size && offset - minimumEntrySize >= MAX_32_BITS) {
6895
+ layoutDependsOnWriteOrder = true;
6884
6896
  }
6885
6897
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
6886
6898
  throw new Error(ERR_UNDETERMINED_SIZE);
@@ -6894,7 +6906,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6894
6906
  zip64 = true;
6895
6907
  }
6896
6908
  }
6897
- return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6909
+ return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6898
6910
  }
6899
6911
 
6900
6912
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
@@ -7391,12 +7403,13 @@ function getHeaderInfo(options) {
7391
7403
  if (passThrough && crc32 !== UNDEFINED_VALUE) {
7392
7404
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7393
7405
  }
7394
- rawExtraFieldAES[9] = compressionMethod;
7406
+ setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
7395
7407
  compressionMethod = COMPRESSION_METHOD_AES;
7396
7408
  }
7397
7409
  const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
7398
7410
  const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
7399
- if (extraFieldLength > MAX_16_BITS) {
7411
+ const maximumUsdzExtraFieldLength = options[OPTION_USDZ] ? EXTRAFIELD_USDZ_MAX_LENGTH : 0;
7412
+ if (extraFieldLength + maximumUsdzExtraFieldLength > MAX_16_BITS) {
7400
7413
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
7401
7414
  }
7402
7415
  const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
@@ -7797,7 +7810,11 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7797
7810
  signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7798
7811
  signatureRecord.writeUint16(signatureDataLength);
7799
7812
  signatureRecord.writeBytes(signatureData);
7800
- await writeData(zipWriter.writer, signatureRecord.array);
7813
+ const { writer } = zipWriter;
7814
+ if (exceedsAvailableSize(writer, getLength(signatureRecord.array))) {
7815
+ await writer.closeDisk();
7816
+ }
7817
+ await writeData(writer, signatureRecord.array);
7801
7818
  return 6 + signatureDataLength;
7802
7819
  }
7803
7820
  return 0;
@@ -7908,7 +7925,7 @@ async function startsWithSplitZipSignature(reader) {
7908
7925
  return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7909
7926
  }
7910
7927
 
7911
- async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7928
+ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
7912
7929
  const { writer } = zipWriter;
7913
7930
  const entryPositions = new Map();
7914
7931
  if (writer.closeDisk) {
@@ -7929,9 +7946,10 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZip
7929
7946
  }
7930
7947
  await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7931
7948
  } else {
7949
+ const baseOffset = zipWriter.offset;
7932
7950
  await copyData(zipWriter, reader, 0, directoryOffset);
7933
7951
  entries.forEach(entry => entryPositions.set(entry, {
7934
- offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7952
+ offset: baseOffset + getSourceOffset(reader, entry),
7935
7953
  diskNumberStart: 0
7936
7954
  }));
7937
7955
  }