@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.
@@ -234,6 +234,18 @@
234
234
  }
235
235
  }
236
236
 
237
+ function checkInteger(value, maxValue, errorMessage) {
238
+ if (!Number.isInteger(value) || value < 0 || value > maxValue) {
239
+ throw new Error(errorMessage);
240
+ }
241
+ }
242
+
243
+ function checkIntegerOption(value, maxValue, errorMessage) {
244
+ if (value !== UNDEFINED_VALUE) {
245
+ checkInteger(value, maxValue, errorMessage);
246
+ }
247
+ }
248
+
237
249
  function toNumber(value) {
238
250
  return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
239
251
  }
@@ -4460,8 +4472,15 @@
4460
4472
  yield entry;
4461
4473
  }
4462
4474
  let offsetAfterSignature = offset;
4463
- const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
4475
+ let digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
4464
4476
  (decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
4477
+ if (!digitalSignature && !decryptedDirectory) {
4478
+ const signatureRecordOffset = directoryDataOffset + offset;
4479
+ const signatureRecordLength = Math.min(centralDirectoryEndOffset - signatureRecordOffset, 6 + MAX_16_BITS);
4480
+ if (signatureRecordLength >= 6) {
4481
+ digitalSignature = readDigitalSignature(await readUint8Array(reader, signatureRecordOffset, signatureRecordLength));
4482
+ }
4483
+ }
4465
4484
  if (digitalSignature) {
4466
4485
  zipReader.digitalSignature = digitalSignature;
4467
4486
  offsetAfterSignature = offset + 6 + digitalSignature.length;
@@ -5496,6 +5515,8 @@
5496
5515
 
5497
5516
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
5498
5517
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
5518
+ const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
5519
+ const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
5499
5520
  const VENDOR_VERSION_AE_1 = 1;
5500
5521
  const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
5501
5522
  const UNIX_EXTRA_FIELD_TYPE = "unix";
@@ -5542,16 +5563,14 @@
5542
5563
  await zipReader$1.close();
5543
5564
  await initStream(this.writer);
5544
5565
  const { directoryOffset } = zipReader$1;
5545
- let splitZipSignatureLength = 0;
5546
5566
  if (this.addSplitZipSignature) {
5547
5567
  delete this.addSplitZipSignature;
5548
5568
  if (!await startsWithSplitZipSignature(reader)) {
5549
5569
  await writeData(this.writer, getSplitZipSignatureArray());
5550
- splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
5551
- this.offset += splitZipSignatureLength;
5570
+ this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
5552
5571
  }
5553
5572
  }
5554
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
5573
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
5555
5574
  this.filenames = new Set(entries.map(entry => entry.filename));
5556
5575
  this.fileEntries = new Map(entries.map(entry => {
5557
5576
  const {
@@ -5731,7 +5750,8 @@
5731
5750
  signature: options[PROPERTY_NAME_SIGNATURE],
5732
5751
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
5733
5752
  offset: zipWriter.offset - diskOffset,
5734
- diskNumberStart: diskNumber
5753
+ diskNumberStart: diskNumber,
5754
+ [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
5735
5755
  });
5736
5756
  const headerInfo = getHeaderInfo(options);
5737
5757
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -5763,15 +5783,9 @@
5763
5783
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
5764
5784
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
5765
5785
  let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
5766
- if (uid !== UNDEFINED_VALUE && (!Number.isInteger(uid) || uid < 0 || uid > MAX_32_BITS)) {
5767
- throw new Error(ERR_INVALID_UID);
5768
- }
5769
- if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
5770
- throw new Error(ERR_INVALID_GID);
5771
- }
5772
- if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
5773
- throw new Error(ERR_INVALID_UNIX_MODE);
5774
- }
5786
+ checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
5787
+ checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
5788
+ checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
5775
5789
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
5776
5790
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
5777
5791
  }
@@ -5793,9 +5807,7 @@
5793
5807
  msDosCompatible = true;
5794
5808
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
5795
5809
  }
5796
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
5797
- throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
5798
- }
5810
+ checkIntegerOption(msdosAttributesRaw, MAX_8_BITS, ERR_INVALID_MSDOS_ATTRIBUTES);
5799
5811
  if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
5800
5812
  throw new Error(ERR_INVALID_MSDOS_DATA);
5801
5813
  }
@@ -5935,9 +5947,7 @@
5935
5947
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
5936
5948
  }
5937
5949
  let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
5938
- if (level !== UNDEFINED_VALUE && (!Number.isInteger(level) || level < 0 || level > MAX_LEVEL)) {
5939
- throw new Error(ERR_INVALID_LEVEL);
5940
- }
5950
+ checkIntegerOption(level, MAX_LEVEL, ERR_INVALID_LEVEL);
5941
5951
  if (zipWriter.options[OPTION_USDZ]) {
5942
5952
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
5943
5953
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -6015,9 +6025,7 @@
6015
6025
  let extraFieldSize = 0;
6016
6026
  let offset = 0;
6017
6027
  extraField.forEach((data, type) => {
6018
- if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
6019
- throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
6020
- }
6028
+ checkInteger(type, MAX_16_BITS, ERR_INVALID_EXTRAFIELD_TYPE);
6021
6029
  if (!(data instanceof Uint8Array)) {
6022
6030
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
6023
6031
  }
@@ -6132,7 +6140,9 @@
6132
6140
  const usdz = writerOptions[OPTION_USDZ];
6133
6141
  const files = new Map();
6134
6142
  let layoutDependsOnWriteOrder = Boolean(usdz);
6135
- let offset = 0;
6143
+ const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
6144
+ let offset = initialOffset;
6145
+ let minimumEntrySize = INFINITY_VALUE;
6136
6146
  for (const entry of entries) {
6137
6147
  let { name } = entry;
6138
6148
  const { size } = entry;
@@ -6156,7 +6166,7 @@
6156
6166
  if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
6157
6167
  throw new Error(ERR_UNDETERMINED_SIZE);
6158
6168
  }
6159
- const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
6169
+ const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
6160
6170
  const headerInfo = getHeaderInfo(entryOptions);
6161
6171
  const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
6162
6172
  const entryInfo = {
@@ -6167,15 +6177,17 @@
6167
6177
  appendExtraFieldUSDZ(entryInfo, offset);
6168
6178
  }
6169
6179
  const compressedSize = hasContent ? maximumCompressedSize : 0;
6170
- if (offset >= MAX_32_BITS) {
6171
- layoutDependsOnWriteOrder = true;
6172
- }
6173
6180
  files.set(name, Object.assign({}, entryOptions, headerInfo, {
6174
6181
  offset,
6175
6182
  diskNumberStart: 0,
6176
6183
  compressedSize
6177
6184
  }));
6178
- offset += entryInfo.metadataSize + compressedSize;
6185
+ const entrySize = entryInfo.metadataSize + compressedSize;
6186
+ minimumEntrySize = Math.min(minimumEntrySize, entrySize);
6187
+ offset += entrySize;
6188
+ }
6189
+ if (files.size && offset - minimumEntrySize >= MAX_32_BITS) {
6190
+ layoutDependsOnWriteOrder = true;
6179
6191
  }
6180
6192
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
6181
6193
  throw new Error(ERR_UNDETERMINED_SIZE);
@@ -6189,7 +6201,7 @@
6189
6201
  zip64 = true;
6190
6202
  }
6191
6203
  }
6192
- return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6204
+ return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6193
6205
  }
6194
6206
 
6195
6207
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
@@ -6686,12 +6698,13 @@
6686
6698
  if (passThrough && crc32 !== UNDEFINED_VALUE) {
6687
6699
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
6688
6700
  }
6689
- rawExtraFieldAES[9] = compressionMethod;
6701
+ setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
6690
6702
  compressionMethod = COMPRESSION_METHOD_AES;
6691
6703
  }
6692
6704
  const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
6693
6705
  const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
6694
- if (extraFieldLength > MAX_16_BITS) {
6706
+ const maximumUsdzExtraFieldLength = options[OPTION_USDZ] ? EXTRAFIELD_USDZ_MAX_LENGTH : 0;
6707
+ if (extraFieldLength + maximumUsdzExtraFieldLength > MAX_16_BITS) {
6695
6708
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
6696
6709
  }
6697
6710
  const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
@@ -7092,7 +7105,11 @@
7092
7105
  signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7093
7106
  signatureRecord.writeUint16(signatureDataLength);
7094
7107
  signatureRecord.writeBytes(signatureData);
7095
- await writeData(zipWriter.writer, signatureRecord.array);
7108
+ const { writer } = zipWriter;
7109
+ if (exceedsAvailableSize(writer, getLength(signatureRecord.array))) {
7110
+ await writer.closeDisk();
7111
+ }
7112
+ await writeData(writer, signatureRecord.array);
7096
7113
  return 6 + signatureDataLength;
7097
7114
  }
7098
7115
  return 0;
@@ -7203,7 +7220,7 @@
7203
7220
  return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7204
7221
  }
7205
7222
 
7206
- async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7223
+ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
7207
7224
  const { writer } = zipWriter;
7208
7225
  const entryPositions = new Map();
7209
7226
  if (writer.closeDisk) {
@@ -7224,9 +7241,10 @@
7224
7241
  }
7225
7242
  await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7226
7243
  } else {
7244
+ const baseOffset = zipWriter.offset;
7227
7245
  await copyData(zipWriter, reader, 0, directoryOffset);
7228
7246
  entries.forEach(entry => entryPositions.set(entry, {
7229
- offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7247
+ offset: baseOffset + getSourceOffset(reader, entry),
7230
7248
  diskNumberStart: 0
7231
7249
  }));
7232
7250
  }