@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.
@@ -235,6 +235,18 @@
235
235
  }
236
236
  }
237
237
 
238
+ function checkInteger(value, maxValue, errorMessage) {
239
+ if (!Number.isInteger(value) || value < 0 || value > maxValue) {
240
+ throw new Error(errorMessage);
241
+ }
242
+ }
243
+
244
+ function checkIntegerOption(value, maxValue, errorMessage) {
245
+ if (value !== UNDEFINED_VALUE) {
246
+ checkInteger(value, maxValue, errorMessage);
247
+ }
248
+ }
249
+
238
250
  function toNumber(value) {
239
251
  return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
240
252
  }
@@ -5067,8 +5079,15 @@
5067
5079
  yield entry;
5068
5080
  }
5069
5081
  let offsetAfterSignature = offset;
5070
- const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5082
+ let digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5071
5083
  (decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
5084
+ if (!digitalSignature && !decryptedDirectory) {
5085
+ const signatureRecordOffset = directoryDataOffset + offset;
5086
+ const signatureRecordLength = Math.min(centralDirectoryEndOffset - signatureRecordOffset, 6 + MAX_16_BITS);
5087
+ if (signatureRecordLength >= 6) {
5088
+ digitalSignature = readDigitalSignature(await readUint8Array(reader, signatureRecordOffset, signatureRecordLength));
5089
+ }
5090
+ }
5072
5091
  if (digitalSignature) {
5073
5092
  zipReader.digitalSignature = digitalSignature;
5074
5093
  offsetAfterSignature = offset + 6 + digitalSignature.length;
@@ -6145,6 +6164,8 @@
6145
6164
 
6146
6165
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6147
6166
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6167
+ const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6168
+ const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6148
6169
  const VENDOR_VERSION_AE_1 = 1;
6149
6170
  const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6150
6171
  const UNIX_EXTRA_FIELD_TYPE = "unix";
@@ -6191,16 +6212,14 @@
6191
6212
  await zipReader$1.close();
6192
6213
  await initStream(this.writer);
6193
6214
  const { directoryOffset } = zipReader$1;
6194
- let splitZipSignatureLength = 0;
6195
6215
  if (this.addSplitZipSignature) {
6196
6216
  delete this.addSplitZipSignature;
6197
6217
  if (!await startsWithSplitZipSignature(reader)) {
6198
6218
  await writeData(this.writer, getSplitZipSignatureArray());
6199
- splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6200
- this.offset += splitZipSignatureLength;
6219
+ this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6201
6220
  }
6202
6221
  }
6203
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
6222
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
6204
6223
  this.filenames = new Set(entries.map(entry => entry.filename));
6205
6224
  this.fileEntries = new Map(entries.map(entry => {
6206
6225
  const {
@@ -6442,7 +6461,8 @@
6442
6461
  signature: options[PROPERTY_NAME_SIGNATURE],
6443
6462
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6444
6463
  offset: zipWriter.offset - diskOffset,
6445
- diskNumberStart: diskNumber
6464
+ diskNumberStart: diskNumber,
6465
+ [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6446
6466
  });
6447
6467
  const headerInfo = getHeaderInfo(options);
6448
6468
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -6474,15 +6494,9 @@
6474
6494
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
6475
6495
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
6476
6496
  let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
6477
- if (uid !== UNDEFINED_VALUE && (!Number.isInteger(uid) || uid < 0 || uid > MAX_32_BITS)) {
6478
- throw new Error(ERR_INVALID_UID);
6479
- }
6480
- if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
6481
- throw new Error(ERR_INVALID_GID);
6482
- }
6483
- if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
6484
- throw new Error(ERR_INVALID_UNIX_MODE);
6485
- }
6497
+ checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6498
+ checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6499
+ checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6486
6500
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6487
6501
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6488
6502
  }
@@ -6504,9 +6518,7 @@
6504
6518
  msDosCompatible = true;
6505
6519
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
6506
6520
  }
6507
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6508
- throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
6509
- }
6521
+ checkIntegerOption(msdosAttributesRaw, MAX_8_BITS, ERR_INVALID_MSDOS_ATTRIBUTES);
6510
6522
  if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
6511
6523
  throw new Error(ERR_INVALID_MSDOS_DATA);
6512
6524
  }
@@ -6646,9 +6658,7 @@
6646
6658
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6647
6659
  }
6648
6660
  let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
6649
- if (level !== UNDEFINED_VALUE && (!Number.isInteger(level) || level < 0 || level > MAX_LEVEL)) {
6650
- throw new Error(ERR_INVALID_LEVEL);
6651
- }
6661
+ checkIntegerOption(level, MAX_LEVEL, ERR_INVALID_LEVEL);
6652
6662
  if (zipWriter.options[OPTION_USDZ]) {
6653
6663
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
6654
6664
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -6726,9 +6736,7 @@
6726
6736
  let extraFieldSize = 0;
6727
6737
  let offset = 0;
6728
6738
  extraField.forEach((data, type) => {
6729
- if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
6730
- throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
6731
- }
6739
+ checkInteger(type, MAX_16_BITS, ERR_INVALID_EXTRAFIELD_TYPE);
6732
6740
  if (!(data instanceof Uint8Array)) {
6733
6741
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
6734
6742
  }
@@ -6843,7 +6851,9 @@
6843
6851
  const usdz = writerOptions[OPTION_USDZ];
6844
6852
  const files = new Map();
6845
6853
  let layoutDependsOnWriteOrder = Boolean(usdz);
6846
- let offset = 0;
6854
+ const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
6855
+ let offset = initialOffset;
6856
+ let minimumEntrySize = INFINITY_VALUE;
6847
6857
  for (const entry of entries) {
6848
6858
  let { name } = entry;
6849
6859
  const { size } = entry;
@@ -6867,7 +6877,7 @@
6867
6877
  if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
6868
6878
  throw new Error(ERR_UNDETERMINED_SIZE);
6869
6879
  }
6870
- const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
6880
+ const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
6871
6881
  const headerInfo = getHeaderInfo(entryOptions);
6872
6882
  const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
6873
6883
  const entryInfo = {
@@ -6878,15 +6888,17 @@
6878
6888
  appendExtraFieldUSDZ(entryInfo, offset);
6879
6889
  }
6880
6890
  const compressedSize = hasContent ? maximumCompressedSize : 0;
6881
- if (offset >= MAX_32_BITS) {
6882
- layoutDependsOnWriteOrder = true;
6883
- }
6884
6891
  files.set(name, Object.assign({}, entryOptions, headerInfo, {
6885
6892
  offset,
6886
6893
  diskNumberStart: 0,
6887
6894
  compressedSize
6888
6895
  }));
6889
- offset += entryInfo.metadataSize + compressedSize;
6896
+ const entrySize = entryInfo.metadataSize + compressedSize;
6897
+ minimumEntrySize = Math.min(minimumEntrySize, entrySize);
6898
+ offset += entrySize;
6899
+ }
6900
+ if (files.size && offset - minimumEntrySize >= MAX_32_BITS) {
6901
+ layoutDependsOnWriteOrder = true;
6890
6902
  }
6891
6903
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
6892
6904
  throw new Error(ERR_UNDETERMINED_SIZE);
@@ -6900,7 +6912,7 @@
6900
6912
  zip64 = true;
6901
6913
  }
6902
6914
  }
6903
- return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6915
+ return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6904
6916
  }
6905
6917
 
6906
6918
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
@@ -7397,12 +7409,13 @@
7397
7409
  if (passThrough && crc32 !== UNDEFINED_VALUE) {
7398
7410
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7399
7411
  }
7400
- rawExtraFieldAES[9] = compressionMethod;
7412
+ setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
7401
7413
  compressionMethod = COMPRESSION_METHOD_AES;
7402
7414
  }
7403
7415
  const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
7404
7416
  const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
7405
- if (extraFieldLength > MAX_16_BITS) {
7417
+ const maximumUsdzExtraFieldLength = options[OPTION_USDZ] ? EXTRAFIELD_USDZ_MAX_LENGTH : 0;
7418
+ if (extraFieldLength + maximumUsdzExtraFieldLength > MAX_16_BITS) {
7406
7419
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
7407
7420
  }
7408
7421
  const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
@@ -7803,7 +7816,11 @@
7803
7816
  signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7804
7817
  signatureRecord.writeUint16(signatureDataLength);
7805
7818
  signatureRecord.writeBytes(signatureData);
7806
- await writeData(zipWriter.writer, signatureRecord.array);
7819
+ const { writer } = zipWriter;
7820
+ if (exceedsAvailableSize(writer, getLength(signatureRecord.array))) {
7821
+ await writer.closeDisk();
7822
+ }
7823
+ await writeData(writer, signatureRecord.array);
7807
7824
  return 6 + signatureDataLength;
7808
7825
  }
7809
7826
  return 0;
@@ -7914,7 +7931,7 @@
7914
7931
  return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7915
7932
  }
7916
7933
 
7917
- async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7934
+ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
7918
7935
  const { writer } = zipWriter;
7919
7936
  const entryPositions = new Map();
7920
7937
  if (writer.closeDisk) {
@@ -7935,9 +7952,10 @@
7935
7952
  }
7936
7953
  await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7937
7954
  } else {
7955
+ const baseOffset = zipWriter.offset;
7938
7956
  await copyData(zipWriter, reader, 0, directoryOffset);
7939
7957
  entries.forEach(entry => entryPositions.set(entry, {
7940
- offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7958
+ offset: baseOffset + getSourceOffset(reader, entry),
7941
7959
  diskNumberStart: 0
7942
7960
  }));
7943
7961
  }