@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.
@@ -226,6 +226,18 @@ function checkPasswordOption(password, rawPassword) {
226
226
  }
227
227
  }
228
228
 
229
+ function checkInteger(value, maxValue, errorMessage) {
230
+ if (!Number.isInteger(value) || value < 0 || value > maxValue) {
231
+ throw new Error(errorMessage);
232
+ }
233
+ }
234
+
235
+ function checkIntegerOption(value, maxValue, errorMessage) {
236
+ if (value !== UNDEFINED_VALUE) {
237
+ checkInteger(value, maxValue, errorMessage);
238
+ }
239
+ }
240
+
229
241
  function toNumber(value) {
230
242
  return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
231
243
  }
@@ -5096,8 +5108,15 @@ class ZipReader {
5096
5108
  yield entry;
5097
5109
  }
5098
5110
  let offsetAfterSignature = offset;
5099
- const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5111
+ let digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5100
5112
  (decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
5113
+ if (!digitalSignature && !decryptedDirectory) {
5114
+ const signatureRecordOffset = directoryDataOffset + offset;
5115
+ const signatureRecordLength = Math.min(centralDirectoryEndOffset - signatureRecordOffset, 6 + MAX_16_BITS);
5116
+ if (signatureRecordLength >= 6) {
5117
+ digitalSignature = readDigitalSignature(await readUint8Array(reader, signatureRecordOffset, signatureRecordLength));
5118
+ }
5119
+ }
5101
5120
  if (digitalSignature) {
5102
5121
  zipReader.digitalSignature = digitalSignature;
5103
5122
  offsetAfterSignature = offset + 6 + digitalSignature.length;
@@ -6174,6 +6193,8 @@ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6174
6193
 
6175
6194
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6176
6195
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6196
+ const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6197
+ const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6177
6198
  const VENDOR_VERSION_AE_1 = 1;
6178
6199
  const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6179
6200
  const UNIX_EXTRA_FIELD_TYPE = "unix";
@@ -6220,16 +6241,14 @@ class ZipWriter {
6220
6241
  await zipReader$1.close();
6221
6242
  await initStream(this.writer);
6222
6243
  const { directoryOffset } = zipReader$1;
6223
- let splitZipSignatureLength = 0;
6224
6244
  if (this.addSplitZipSignature) {
6225
6245
  delete this.addSplitZipSignature;
6226
6246
  if (!await startsWithSplitZipSignature(reader)) {
6227
6247
  await writeData(this.writer, getSplitZipSignatureArray());
6228
- splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6229
- this.offset += splitZipSignatureLength;
6248
+ this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6230
6249
  }
6231
6250
  }
6232
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
6251
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
6233
6252
  this.filenames = new Set(entries.map(entry => entry.filename));
6234
6253
  this.fileEntries = new Map(entries.map(entry => {
6235
6254
  const {
@@ -6471,7 +6490,8 @@ async function addFile(zipWriter, name, reader, options) {
6471
6490
  signature: options[PROPERTY_NAME_SIGNATURE],
6472
6491
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6473
6492
  offset: zipWriter.offset - diskOffset,
6474
- diskNumberStart: diskNumber
6493
+ diskNumberStart: diskNumber,
6494
+ [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6475
6495
  });
6476
6496
  const headerInfo = getHeaderInfo(options);
6477
6497
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -6503,15 +6523,9 @@ function resolveAttributes(zipWriter, name, options) {
6503
6523
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
6504
6524
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
6505
6525
  let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
6506
- if (uid !== UNDEFINED_VALUE && (!Number.isInteger(uid) || uid < 0 || uid > MAX_32_BITS)) {
6507
- throw new Error(ERR_INVALID_UID);
6508
- }
6509
- if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
6510
- throw new Error(ERR_INVALID_GID);
6511
- }
6512
- if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
6513
- throw new Error(ERR_INVALID_UNIX_MODE);
6514
- }
6526
+ checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6527
+ checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6528
+ checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6515
6529
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6516
6530
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6517
6531
  }
@@ -6533,9 +6547,7 @@ function resolveAttributes(zipWriter, name, options) {
6533
6547
  msDosCompatible = true;
6534
6548
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
6535
6549
  }
6536
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6537
- throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
6538
- }
6550
+ checkIntegerOption(msdosAttributesRaw, MAX_8_BITS, ERR_INVALID_MSDOS_ATTRIBUTES);
6539
6551
  if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
6540
6552
  throw new Error(ERR_INVALID_MSDOS_DATA);
6541
6553
  }
@@ -6675,9 +6687,7 @@ function resolveMetadata(zipWriter, name, options) {
6675
6687
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6676
6688
  }
6677
6689
  let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
6678
- if (level !== UNDEFINED_VALUE && (!Number.isInteger(level) || level < 0 || level > MAX_LEVEL)) {
6679
- throw new Error(ERR_INVALID_LEVEL);
6680
- }
6690
+ checkIntegerOption(level, MAX_LEVEL, ERR_INVALID_LEVEL);
6681
6691
  if (zipWriter.options[OPTION_USDZ]) {
6682
6692
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
6683
6693
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -6755,9 +6765,7 @@ function serializeExtraField(extraField) {
6755
6765
  let extraFieldSize = 0;
6756
6766
  let offset = 0;
6757
6767
  extraField.forEach((data, type) => {
6758
- if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
6759
- throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
6760
- }
6768
+ checkInteger(type, MAX_16_BITS, ERR_INVALID_EXTRAFIELD_TYPE);
6761
6769
  if (!(data instanceof Uint8Array)) {
6762
6770
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
6763
6771
  }
@@ -6872,7 +6880,9 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6872
6880
  const usdz = writerOptions[OPTION_USDZ];
6873
6881
  const files = new Map();
6874
6882
  let layoutDependsOnWriteOrder = Boolean(usdz);
6875
- let offset = 0;
6883
+ const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
6884
+ let offset = initialOffset;
6885
+ let minimumEntrySize = INFINITY_VALUE;
6876
6886
  for (const entry of entries) {
6877
6887
  let { name } = entry;
6878
6888
  const { size } = entry;
@@ -6896,7 +6906,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6896
6906
  if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
6897
6907
  throw new Error(ERR_UNDETERMINED_SIZE);
6898
6908
  }
6899
- const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
6909
+ const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
6900
6910
  const headerInfo = getHeaderInfo(entryOptions);
6901
6911
  const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
6902
6912
  const entryInfo = {
@@ -6907,15 +6917,17 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6907
6917
  appendExtraFieldUSDZ(entryInfo, offset);
6908
6918
  }
6909
6919
  const compressedSize = hasContent ? maximumCompressedSize : 0;
6910
- if (offset >= MAX_32_BITS) {
6911
- layoutDependsOnWriteOrder = true;
6912
- }
6913
6920
  files.set(name, Object.assign({}, entryOptions, headerInfo, {
6914
6921
  offset,
6915
6922
  diskNumberStart: 0,
6916
6923
  compressedSize
6917
6924
  }));
6918
- offset += entryInfo.metadataSize + compressedSize;
6925
+ const entrySize = entryInfo.metadataSize + compressedSize;
6926
+ minimumEntrySize = Math.min(minimumEntrySize, entrySize);
6927
+ offset += entrySize;
6928
+ }
6929
+ if (files.size && offset - minimumEntrySize >= MAX_32_BITS) {
6930
+ layoutDependsOnWriteOrder = true;
6919
6931
  }
6920
6932
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
6921
6933
  throw new Error(ERR_UNDETERMINED_SIZE);
@@ -6929,7 +6941,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6929
6941
  zip64 = true;
6930
6942
  }
6931
6943
  }
6932
- return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6944
+ return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6933
6945
  }
6934
6946
 
6935
6947
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
@@ -7426,12 +7438,13 @@ function getHeaderInfo(options) {
7426
7438
  if (passThrough && crc32 !== UNDEFINED_VALUE) {
7427
7439
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7428
7440
  }
7429
- rawExtraFieldAES[9] = compressionMethod;
7441
+ setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
7430
7442
  compressionMethod = COMPRESSION_METHOD_AES;
7431
7443
  }
7432
7444
  const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
7433
7445
  const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
7434
- if (extraFieldLength > MAX_16_BITS) {
7446
+ const maximumUsdzExtraFieldLength = options[OPTION_USDZ] ? EXTRAFIELD_USDZ_MAX_LENGTH : 0;
7447
+ if (extraFieldLength + maximumUsdzExtraFieldLength > MAX_16_BITS) {
7435
7448
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
7436
7449
  }
7437
7450
  const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
@@ -7832,7 +7845,11 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7832
7845
  signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7833
7846
  signatureRecord.writeUint16(signatureDataLength);
7834
7847
  signatureRecord.writeBytes(signatureData);
7835
- await writeData(zipWriter.writer, signatureRecord.array);
7848
+ const { writer } = zipWriter;
7849
+ if (exceedsAvailableSize(writer, getLength(signatureRecord.array))) {
7850
+ await writer.closeDisk();
7851
+ }
7852
+ await writeData(writer, signatureRecord.array);
7836
7853
  return 6 + signatureDataLength;
7837
7854
  }
7838
7855
  return 0;
@@ -7943,7 +7960,7 @@ async function startsWithSplitZipSignature(reader) {
7943
7960
  return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7944
7961
  }
7945
7962
 
7946
- async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7963
+ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
7947
7964
  const { writer } = zipWriter;
7948
7965
  const entryPositions = new Map();
7949
7966
  if (writer.closeDisk) {
@@ -7964,9 +7981,10 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZip
7964
7981
  }
7965
7982
  await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7966
7983
  } else {
7984
+ const baseOffset = zipWriter.offset;
7967
7985
  await copyData(zipWriter, reader, 0, directoryOffset);
7968
7986
  entries.forEach(entry => entryPositions.set(entry, {
7969
- offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7987
+ offset: baseOffset + getSourceOffset(reader, entry),
7970
7988
  diskNumberStart: 0
7971
7989
  }));
7972
7990
  }