@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/dist/zip-fs.js CHANGED
@@ -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
  }
@@ -5071,8 +5083,15 @@
5071
5083
  yield entry;
5072
5084
  }
5073
5085
  let offsetAfterSignature = offset;
5074
- const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5086
+ let digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5075
5087
  (decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
5088
+ if (!digitalSignature && !decryptedDirectory) {
5089
+ const signatureRecordOffset = directoryDataOffset + offset;
5090
+ const signatureRecordLength = Math.min(centralDirectoryEndOffset - signatureRecordOffset, 6 + MAX_16_BITS);
5091
+ if (signatureRecordLength >= 6) {
5092
+ digitalSignature = readDigitalSignature(await readUint8Array(reader, signatureRecordOffset, signatureRecordLength));
5093
+ }
5094
+ }
5076
5095
  if (digitalSignature) {
5077
5096
  zipReader.digitalSignature = digitalSignature;
5078
5097
  offsetAfterSignature = offset + 6 + digitalSignature.length;
@@ -6149,6 +6168,8 @@
6149
6168
 
6150
6169
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6151
6170
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6171
+ const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6172
+ const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6152
6173
  const VENDOR_VERSION_AE_1 = 1;
6153
6174
  const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6154
6175
  const UNIX_EXTRA_FIELD_TYPE = "unix";
@@ -6195,16 +6216,14 @@
6195
6216
  await zipReader$1.close();
6196
6217
  await initStream(this.writer);
6197
6218
  const { directoryOffset } = zipReader$1;
6198
- let splitZipSignatureLength = 0;
6199
6219
  if (this.addSplitZipSignature) {
6200
6220
  delete this.addSplitZipSignature;
6201
6221
  if (!await startsWithSplitZipSignature(reader)) {
6202
6222
  await writeData(this.writer, getSplitZipSignatureArray());
6203
- splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6204
- this.offset += splitZipSignatureLength;
6223
+ this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6205
6224
  }
6206
6225
  }
6207
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
6226
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
6208
6227
  this.filenames = new Set(entries.map(entry => entry.filename));
6209
6228
  this.fileEntries = new Map(entries.map(entry => {
6210
6229
  const {
@@ -6446,7 +6465,8 @@
6446
6465
  signature: options[PROPERTY_NAME_SIGNATURE],
6447
6466
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6448
6467
  offset: zipWriter.offset - diskOffset,
6449
- diskNumberStart: diskNumber
6468
+ diskNumberStart: diskNumber,
6469
+ [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6450
6470
  });
6451
6471
  const headerInfo = getHeaderInfo(options);
6452
6472
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -6478,15 +6498,9 @@
6478
6498
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
6479
6499
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
6480
6500
  let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
6481
- if (uid !== UNDEFINED_VALUE && (!Number.isInteger(uid) || uid < 0 || uid > MAX_32_BITS)) {
6482
- throw new Error(ERR_INVALID_UID);
6483
- }
6484
- if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
6485
- throw new Error(ERR_INVALID_GID);
6486
- }
6487
- if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
6488
- throw new Error(ERR_INVALID_UNIX_MODE);
6489
- }
6501
+ checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6502
+ checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6503
+ checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6490
6504
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6491
6505
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6492
6506
  }
@@ -6508,9 +6522,7 @@
6508
6522
  msDosCompatible = true;
6509
6523
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
6510
6524
  }
6511
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6512
- throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
6513
- }
6525
+ checkIntegerOption(msdosAttributesRaw, MAX_8_BITS, ERR_INVALID_MSDOS_ATTRIBUTES);
6514
6526
  if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
6515
6527
  throw new Error(ERR_INVALID_MSDOS_DATA);
6516
6528
  }
@@ -6650,9 +6662,7 @@
6650
6662
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6651
6663
  }
6652
6664
  let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
6653
- if (level !== UNDEFINED_VALUE && (!Number.isInteger(level) || level < 0 || level > MAX_LEVEL)) {
6654
- throw new Error(ERR_INVALID_LEVEL);
6655
- }
6665
+ checkIntegerOption(level, MAX_LEVEL, ERR_INVALID_LEVEL);
6656
6666
  if (zipWriter.options[OPTION_USDZ]) {
6657
6667
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
6658
6668
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -6730,9 +6740,7 @@
6730
6740
  let extraFieldSize = 0;
6731
6741
  let offset = 0;
6732
6742
  extraField.forEach((data, type) => {
6733
- if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
6734
- throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
6735
- }
6743
+ checkInteger(type, MAX_16_BITS, ERR_INVALID_EXTRAFIELD_TYPE);
6736
6744
  if (!(data instanceof Uint8Array)) {
6737
6745
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
6738
6746
  }
@@ -6847,7 +6855,9 @@
6847
6855
  const usdz = writerOptions[OPTION_USDZ];
6848
6856
  const files = new Map();
6849
6857
  let layoutDependsOnWriteOrder = Boolean(usdz);
6850
- let offset = 0;
6858
+ const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
6859
+ let offset = initialOffset;
6860
+ let minimumEntrySize = INFINITY_VALUE;
6851
6861
  for (const entry of entries) {
6852
6862
  let { name } = entry;
6853
6863
  const { size } = entry;
@@ -6871,7 +6881,7 @@
6871
6881
  if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
6872
6882
  throw new Error(ERR_UNDETERMINED_SIZE);
6873
6883
  }
6874
- const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
6884
+ const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
6875
6885
  const headerInfo = getHeaderInfo(entryOptions);
6876
6886
  const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
6877
6887
  const entryInfo = {
@@ -6882,15 +6892,17 @@
6882
6892
  appendExtraFieldUSDZ(entryInfo, offset);
6883
6893
  }
6884
6894
  const compressedSize = hasContent ? maximumCompressedSize : 0;
6885
- if (offset >= MAX_32_BITS) {
6886
- layoutDependsOnWriteOrder = true;
6887
- }
6888
6895
  files.set(name, Object.assign({}, entryOptions, headerInfo, {
6889
6896
  offset,
6890
6897
  diskNumberStart: 0,
6891
6898
  compressedSize
6892
6899
  }));
6893
- offset += entryInfo.metadataSize + compressedSize;
6900
+ const entrySize = entryInfo.metadataSize + compressedSize;
6901
+ minimumEntrySize = Math.min(minimumEntrySize, entrySize);
6902
+ offset += entrySize;
6903
+ }
6904
+ if (files.size && offset - minimumEntrySize >= MAX_32_BITS) {
6905
+ layoutDependsOnWriteOrder = true;
6894
6906
  }
6895
6907
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
6896
6908
  throw new Error(ERR_UNDETERMINED_SIZE);
@@ -6904,7 +6916,7 @@
6904
6916
  zip64 = true;
6905
6917
  }
6906
6918
  }
6907
- return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6919
+ return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6908
6920
  }
6909
6921
 
6910
6922
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
@@ -7401,12 +7413,13 @@
7401
7413
  if (passThrough && crc32 !== UNDEFINED_VALUE) {
7402
7414
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7403
7415
  }
7404
- rawExtraFieldAES[9] = compressionMethod;
7416
+ setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
7405
7417
  compressionMethod = COMPRESSION_METHOD_AES;
7406
7418
  }
7407
7419
  const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
7408
7420
  const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
7409
- if (extraFieldLength > MAX_16_BITS) {
7421
+ const maximumUsdzExtraFieldLength = options[OPTION_USDZ] ? EXTRAFIELD_USDZ_MAX_LENGTH : 0;
7422
+ if (extraFieldLength + maximumUsdzExtraFieldLength > MAX_16_BITS) {
7410
7423
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
7411
7424
  }
7412
7425
  const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
@@ -7807,7 +7820,11 @@
7807
7820
  signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7808
7821
  signatureRecord.writeUint16(signatureDataLength);
7809
7822
  signatureRecord.writeBytes(signatureData);
7810
- await writeData(zipWriter.writer, signatureRecord.array);
7823
+ const { writer } = zipWriter;
7824
+ if (exceedsAvailableSize(writer, getLength(signatureRecord.array))) {
7825
+ await writer.closeDisk();
7826
+ }
7827
+ await writeData(writer, signatureRecord.array);
7811
7828
  return 6 + signatureDataLength;
7812
7829
  }
7813
7830
  return 0;
@@ -7918,7 +7935,7 @@
7918
7935
  return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7919
7936
  }
7920
7937
 
7921
- async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7938
+ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
7922
7939
  const { writer } = zipWriter;
7923
7940
  const entryPositions = new Map();
7924
7941
  if (writer.closeDisk) {
@@ -7939,9 +7956,10 @@
7939
7956
  }
7940
7957
  await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7941
7958
  } else {
7959
+ const baseOffset = zipWriter.offset;
7942
7960
  await copyData(zipWriter, reader, 0, directoryOffset);
7943
7961
  entries.forEach(entry => entryPositions.set(entry, {
7944
- offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7962
+ offset: baseOffset + getSourceOffset(reader, entry),
7945
7963
  diskNumberStart: 0
7946
7964
  }));
7947
7965
  }