@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.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
  }
@@ -5065,8 +5077,15 @@ class ZipReader {
5065
5077
  yield entry;
5066
5078
  }
5067
5079
  let offsetAfterSignature = offset;
5068
- const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5080
+ let digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5069
5081
  (decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
5082
+ if (!digitalSignature && !decryptedDirectory) {
5083
+ const signatureRecordOffset = directoryDataOffset + offset;
5084
+ const signatureRecordLength = Math.min(centralDirectoryEndOffset - signatureRecordOffset, 6 + MAX_16_BITS);
5085
+ if (signatureRecordLength >= 6) {
5086
+ digitalSignature = readDigitalSignature(await readUint8Array(reader, signatureRecordOffset, signatureRecordLength));
5087
+ }
5088
+ }
5070
5089
  if (digitalSignature) {
5071
5090
  zipReader.digitalSignature = digitalSignature;
5072
5091
  offsetAfterSignature = offset + 6 + digitalSignature.length;
@@ -6143,6 +6162,8 @@ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6143
6162
 
6144
6163
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6145
6164
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6165
+ const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6166
+ const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6146
6167
  const VENDOR_VERSION_AE_1 = 1;
6147
6168
  const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6148
6169
  const UNIX_EXTRA_FIELD_TYPE = "unix";
@@ -6189,16 +6210,14 @@ class ZipWriter {
6189
6210
  await zipReader$1.close();
6190
6211
  await initStream(this.writer);
6191
6212
  const { directoryOffset } = zipReader$1;
6192
- let splitZipSignatureLength = 0;
6193
6213
  if (this.addSplitZipSignature) {
6194
6214
  delete this.addSplitZipSignature;
6195
6215
  if (!await startsWithSplitZipSignature(reader)) {
6196
6216
  await writeData(this.writer, getSplitZipSignatureArray());
6197
- splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6198
- this.offset += splitZipSignatureLength;
6217
+ this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6199
6218
  }
6200
6219
  }
6201
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
6220
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
6202
6221
  this.filenames = new Set(entries.map(entry => entry.filename));
6203
6222
  this.fileEntries = new Map(entries.map(entry => {
6204
6223
  const {
@@ -6440,7 +6459,8 @@ async function addFile(zipWriter, name, reader, options) {
6440
6459
  signature: options[PROPERTY_NAME_SIGNATURE],
6441
6460
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6442
6461
  offset: zipWriter.offset - diskOffset,
6443
- diskNumberStart: diskNumber
6462
+ diskNumberStart: diskNumber,
6463
+ [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6444
6464
  });
6445
6465
  const headerInfo = getHeaderInfo(options);
6446
6466
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -6472,15 +6492,9 @@ function resolveAttributes(zipWriter, name, options) {
6472
6492
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
6473
6493
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
6474
6494
  let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
6475
- if (uid !== UNDEFINED_VALUE && (!Number.isInteger(uid) || uid < 0 || uid > MAX_32_BITS)) {
6476
- throw new Error(ERR_INVALID_UID);
6477
- }
6478
- if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
6479
- throw new Error(ERR_INVALID_GID);
6480
- }
6481
- if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
6482
- throw new Error(ERR_INVALID_UNIX_MODE);
6483
- }
6495
+ checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6496
+ checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6497
+ checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6484
6498
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6485
6499
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6486
6500
  }
@@ -6502,9 +6516,7 @@ function resolveAttributes(zipWriter, name, options) {
6502
6516
  msDosCompatible = true;
6503
6517
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
6504
6518
  }
6505
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6506
- throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
6507
- }
6519
+ checkIntegerOption(msdosAttributesRaw, MAX_8_BITS, ERR_INVALID_MSDOS_ATTRIBUTES);
6508
6520
  if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
6509
6521
  throw new Error(ERR_INVALID_MSDOS_DATA);
6510
6522
  }
@@ -6644,9 +6656,7 @@ function resolveMetadata(zipWriter, name, options) {
6644
6656
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6645
6657
  }
6646
6658
  let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
6647
- if (level !== UNDEFINED_VALUE && (!Number.isInteger(level) || level < 0 || level > MAX_LEVEL)) {
6648
- throw new Error(ERR_INVALID_LEVEL);
6649
- }
6659
+ checkIntegerOption(level, MAX_LEVEL, ERR_INVALID_LEVEL);
6650
6660
  if (zipWriter.options[OPTION_USDZ]) {
6651
6661
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
6652
6662
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -6724,9 +6734,7 @@ function serializeExtraField(extraField) {
6724
6734
  let extraFieldSize = 0;
6725
6735
  let offset = 0;
6726
6736
  extraField.forEach((data, type) => {
6727
- if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
6728
- throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
6729
- }
6737
+ checkInteger(type, MAX_16_BITS, ERR_INVALID_EXTRAFIELD_TYPE);
6730
6738
  if (!(data instanceof Uint8Array)) {
6731
6739
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
6732
6740
  }
@@ -6841,7 +6849,9 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6841
6849
  const usdz = writerOptions[OPTION_USDZ];
6842
6850
  const files = new Map();
6843
6851
  let layoutDependsOnWriteOrder = Boolean(usdz);
6844
- let offset = 0;
6852
+ const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
6853
+ let offset = initialOffset;
6854
+ let minimumEntrySize = INFINITY_VALUE;
6845
6855
  for (const entry of entries) {
6846
6856
  let { name } = entry;
6847
6857
  const { size } = entry;
@@ -6865,7 +6875,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6865
6875
  if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
6866
6876
  throw new Error(ERR_UNDETERMINED_SIZE);
6867
6877
  }
6868
- const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
6878
+ const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
6869
6879
  const headerInfo = getHeaderInfo(entryOptions);
6870
6880
  const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
6871
6881
  const entryInfo = {
@@ -6876,15 +6886,17 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6876
6886
  appendExtraFieldUSDZ(entryInfo, offset);
6877
6887
  }
6878
6888
  const compressedSize = hasContent ? maximumCompressedSize : 0;
6879
- if (offset >= MAX_32_BITS) {
6880
- layoutDependsOnWriteOrder = true;
6881
- }
6882
6889
  files.set(name, Object.assign({}, entryOptions, headerInfo, {
6883
6890
  offset,
6884
6891
  diskNumberStart: 0,
6885
6892
  compressedSize
6886
6893
  }));
6887
- offset += entryInfo.metadataSize + compressedSize;
6894
+ const entrySize = entryInfo.metadataSize + compressedSize;
6895
+ minimumEntrySize = Math.min(minimumEntrySize, entrySize);
6896
+ offset += entrySize;
6897
+ }
6898
+ if (files.size && offset - minimumEntrySize >= MAX_32_BITS) {
6899
+ layoutDependsOnWriteOrder = true;
6888
6900
  }
6889
6901
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
6890
6902
  throw new Error(ERR_UNDETERMINED_SIZE);
@@ -6898,7 +6910,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6898
6910
  zip64 = true;
6899
6911
  }
6900
6912
  }
6901
- return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6913
+ return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6902
6914
  }
6903
6915
 
6904
6916
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
@@ -7395,12 +7407,13 @@ function getHeaderInfo(options) {
7395
7407
  if (passThrough && crc32 !== UNDEFINED_VALUE) {
7396
7408
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7397
7409
  }
7398
- rawExtraFieldAES[9] = compressionMethod;
7410
+ setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
7399
7411
  compressionMethod = COMPRESSION_METHOD_AES;
7400
7412
  }
7401
7413
  const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
7402
7414
  const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
7403
- if (extraFieldLength > MAX_16_BITS) {
7415
+ const maximumUsdzExtraFieldLength = options[OPTION_USDZ] ? EXTRAFIELD_USDZ_MAX_LENGTH : 0;
7416
+ if (extraFieldLength + maximumUsdzExtraFieldLength > MAX_16_BITS) {
7404
7417
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
7405
7418
  }
7406
7419
  const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
@@ -7801,7 +7814,11 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7801
7814
  signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7802
7815
  signatureRecord.writeUint16(signatureDataLength);
7803
7816
  signatureRecord.writeBytes(signatureData);
7804
- await writeData(zipWriter.writer, signatureRecord.array);
7817
+ const { writer } = zipWriter;
7818
+ if (exceedsAvailableSize(writer, getLength(signatureRecord.array))) {
7819
+ await writer.closeDisk();
7820
+ }
7821
+ await writeData(writer, signatureRecord.array);
7805
7822
  return 6 + signatureDataLength;
7806
7823
  }
7807
7824
  return 0;
@@ -7912,7 +7929,7 @@ async function startsWithSplitZipSignature(reader) {
7912
7929
  return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7913
7930
  }
7914
7931
 
7915
- async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7932
+ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
7916
7933
  const { writer } = zipWriter;
7917
7934
  const entryPositions = new Map();
7918
7935
  if (writer.closeDisk) {
@@ -7933,9 +7950,10 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZip
7933
7950
  }
7934
7951
  await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7935
7952
  } else {
7953
+ const baseOffset = zipWriter.offset;
7936
7954
  await copyData(zipWriter, reader, 0, directoryOffset);
7937
7955
  entries.forEach(entry => entryPositions.set(entry, {
7938
- offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7956
+ offset: baseOffset + getSourceOffset(reader, entry),
7939
7957
  diskNumberStart: 0
7940
7958
  }));
7941
7959
  }
package/index.d.cts CHANGED
@@ -265,6 +265,11 @@ export interface CodecDefinition {
265
265
  * The URL of a module exporting the `CompressionStream` and/or `DecompressionStream` classes of
266
266
  * the codec. Relative URLs are resolved against {@link Configuration#baseURI}; passing an absolute
267
267
  * URL (e.g. via `import.meta.resolve()`) is recommended.
268
+ *
269
+ * @remarks
270
+ * The module is imported dynamically at runtime. Bundlers and single-file builds (e.g.
271
+ * `deno compile`) cannot follow this import, so the module must be included explicitly
272
+ * (e.g. with `deno compile --include` or the equivalent option of the bundler).
268
273
  */
269
274
  codecURI?: string;
270
275
  /**
package/index.d.ts CHANGED
@@ -265,6 +265,11 @@ export interface CodecDefinition {
265
265
  * The URL of a module exporting the `CompressionStream` and/or `DecompressionStream` classes of
266
266
  * the codec. Relative URLs are resolved against {@link Configuration#baseURI}; passing an absolute
267
267
  * URL (e.g. via `import.meta.resolve()`) is recommended.
268
+ *
269
+ * @remarks
270
+ * The module is imported dynamically at runtime. Bundlers and single-file builds (e.g.
271
+ * `deno compile`) cannot follow this import, so the module must be included explicitly
272
+ * (e.g. with `deno compile --include` or the equivalent option of the bundler).
268
273
  */
269
274
  codecURI?: string;
270
275
  /**