@zip.js/zip.js 2.8.55 → 2.8.57

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
  }
@@ -4715,6 +4727,7 @@ const ERR_UNSAFE_FILENAME = "Unsafe filename";
4715
4727
  const ERR_INVALID_STRICTNESS = "Invalid strictness (must be 'strict', 'balanced' or 'tolerant')";
4716
4728
  const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
4717
4729
  const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
4730
+ const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
4718
4731
  const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
4719
4732
  const CHARSET_UTF8 = "utf-8";
4720
4733
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
@@ -4737,6 +4750,7 @@ const ZIP64_EXTRACTION = {
4737
4750
  bytes: 8
4738
4751
  }
4739
4752
  };
4753
+ const MAX_SAFE_UINT64 = BigInt(Number.MAX_SAFE_INTEGER);
4740
4754
  const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
4741
4755
  const MAX_DEFLATE_EXPANSION_RATIO = 1032;
4742
4756
  const CENTRAL_DIRECTORY_UNREACHABLE = 0;
@@ -4832,7 +4846,7 @@ class ZipReader {
4832
4846
  zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
4833
4847
  if (zip64EndOfDirectoryVersion2) {
4834
4848
  const extensibleDataLength = Math.min(
4835
- Number(getBigUint64(endOfDirectoryView, 4)) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
4849
+ getBigUint64(endOfDirectoryView, 4) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
4836
4850
  reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4837
4851
  if (extensibleDataLength > 0) {
4838
4852
  zip64EndOfDirectoryLength += extensibleDataLength;
@@ -5065,8 +5079,15 @@ class ZipReader {
5065
5079
  yield entry;
5066
5080
  }
5067
5081
  let offsetAfterSignature = offset;
5068
- const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5082
+ let digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
5069
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
+ }
5070
5091
  if (digitalSignature) {
5071
5092
  zipReader.digitalSignature = digitalSignature;
5072
5093
  offsetAfterSignature = offset + 6 + digitalSignature.length;
@@ -5406,8 +5427,8 @@ function getDirectoryEncryptionInfo(rawExtensibleData) {
5406
5427
  const hashDataLength = getUint16$1(extensibleDataView, 26);
5407
5428
  Object.assign(directoryEncryptionInfo, {
5408
5429
  compressionMethod: getUint16$1(extensibleDataView, 0),
5409
- compressedSize: Number(getBigUint64(extensibleDataView, 2)),
5410
- uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
5430
+ compressedSize: getBigUint64(extensibleDataView, 2),
5431
+ uncompressedSize: getBigUint64(extensibleDataView, 10),
5411
5432
  encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
5412
5433
  bitLength: getUint16$1(extensibleDataView, 20),
5413
5434
  flags: getUint16$1(extensibleDataView, 22),
@@ -6042,7 +6063,11 @@ function getUint32$1(view, offset) {
6042
6063
  }
6043
6064
 
6044
6065
  function getBigUint64(view, offset) {
6045
- return Number(view.getBigUint64(offset, true));
6066
+ const value = view.getBigUint64(offset, true);
6067
+ if (value > MAX_SAFE_UINT64) {
6068
+ throw new Error(ERR_UNSUPPORTED_UINT64);
6069
+ }
6070
+ return Number(value);
6046
6071
  }
6047
6072
 
6048
6073
  var zipReader = /*#__PURE__*/Object.freeze({
@@ -6071,6 +6096,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
6071
6096
  ERR_UNSAFE_FILENAME: ERR_UNSAFE_FILENAME,
6072
6097
  ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
6073
6098
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
6099
+ ERR_UNSUPPORTED_UINT64: ERR_UNSUPPORTED_UINT64,
6074
6100
  ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
6075
6101
  ZipReader: ZipReader,
6076
6102
  ZipReaderStream: ZipReaderStream
@@ -6143,6 +6169,8 @@ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
6143
6169
 
6144
6170
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
6145
6171
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
6172
+ const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
6173
+ const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
6146
6174
  const VENDOR_VERSION_AE_1 = 1;
6147
6175
  const INFOZIP_EXTRA_FIELD_TYPE$1 = "infozip";
6148
6176
  const UNIX_EXTRA_FIELD_TYPE = "unix";
@@ -6189,16 +6217,14 @@ class ZipWriter {
6189
6217
  await zipReader$1.close();
6190
6218
  await initStream(this.writer);
6191
6219
  const { directoryOffset } = zipReader$1;
6192
- let splitZipSignatureLength = 0;
6193
6220
  if (this.addSplitZipSignature) {
6194
6221
  delete this.addSplitZipSignature;
6195
6222
  if (!await startsWithSplitZipSignature(reader)) {
6196
6223
  await writeData(this.writer, getSplitZipSignatureArray());
6197
- splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6198
- this.offset += splitZipSignatureLength;
6224
+ this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6199
6225
  }
6200
6226
  }
6201
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
6227
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
6202
6228
  this.filenames = new Set(entries.map(entry => entry.filename));
6203
6229
  this.fileEntries = new Map(entries.map(entry => {
6204
6230
  const {
@@ -6211,7 +6237,7 @@ class ZipWriter {
6211
6237
  encrypted,
6212
6238
  uncompressedSize,
6213
6239
  compressedSize,
6214
- zip64
6240
+ extraFieldZip64
6215
6241
  } = entry;
6216
6242
  let {
6217
6243
  compressionMethod,
@@ -6228,13 +6254,13 @@ class ZipWriter {
6228
6254
  rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
6229
6255
  rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
6230
6256
  rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
6231
- rawExtraField = rawExtraField || EMPTY_UINT8_ARRAY;
6257
+ rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
6232
6258
  if (entry.extraFieldAES) {
6233
6259
  compressionMethod = COMPRESSION_METHOD_AES;
6234
6260
  }
6235
6261
  const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
6236
- const zip64UncompressedSize = zip64 && uncompressedSize >= MAX_32_BITS;
6237
- const zip64CompressedSize = zip64 && compressedSize >= MAX_32_BITS;
6262
+ const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
6263
+ const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
6238
6264
  const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
6239
6265
  const {
6240
6266
  headerArray,
@@ -6440,7 +6466,8 @@ async function addFile(zipWriter, name, reader, options) {
6440
6466
  signature: options[PROPERTY_NAME_SIGNATURE],
6441
6467
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6442
6468
  offset: zipWriter.offset - diskOffset,
6443
- diskNumberStart: diskNumber
6469
+ diskNumberStart: diskNumber,
6470
+ [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
6444
6471
  });
6445
6472
  const headerInfo = getHeaderInfo(options);
6446
6473
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -6472,15 +6499,9 @@ function resolveAttributes(zipWriter, name, options) {
6472
6499
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
6473
6500
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
6474
6501
  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
- }
6502
+ checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
6503
+ checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
6504
+ checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
6484
6505
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE$1 && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
6485
6506
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
6486
6507
  }
@@ -6502,9 +6523,7 @@ function resolveAttributes(zipWriter, name, options) {
6502
6523
  msDosCompatible = true;
6503
6524
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
6504
6525
  }
6505
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
6506
- throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
6507
- }
6526
+ checkIntegerOption(msdosAttributesRaw, MAX_8_BITS, ERR_INVALID_MSDOS_ATTRIBUTES);
6508
6527
  if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
6509
6528
  throw new Error(ERR_INVALID_MSDOS_DATA);
6510
6529
  }
@@ -6644,9 +6663,7 @@ function resolveMetadata(zipWriter, name, options) {
6644
6663
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
6645
6664
  }
6646
6665
  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
- }
6666
+ checkIntegerOption(level, MAX_LEVEL, ERR_INVALID_LEVEL);
6650
6667
  if (zipWriter.options[OPTION_USDZ]) {
6651
6668
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
6652
6669
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -6724,9 +6741,7 @@ function serializeExtraField(extraField) {
6724
6741
  let extraFieldSize = 0;
6725
6742
  let offset = 0;
6726
6743
  extraField.forEach((data, type) => {
6727
- if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
6728
- throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
6729
- }
6744
+ checkInteger(type, MAX_16_BITS, ERR_INVALID_EXTRAFIELD_TYPE);
6730
6745
  if (!(data instanceof Uint8Array)) {
6731
6746
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
6732
6747
  }
@@ -6801,6 +6816,10 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
6801
6816
  maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
6802
6817
  }
6803
6818
  }
6819
+ const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
6820
+ if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
6821
+ dataDescriptor = false;
6822
+ }
6804
6823
  const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
6805
6824
  const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
6806
6825
  if (zip64UncompressedSize || zip64CompressedSize) {
@@ -6815,6 +6834,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
6815
6834
  maximumCompressedSize,
6816
6835
  resolvedOptions: {
6817
6836
  dataDescriptor,
6837
+ emptyEntry,
6818
6838
  zip64,
6819
6839
  zip64UncompressedSize,
6820
6840
  zip64CompressedSize,
@@ -6841,7 +6861,9 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6841
6861
  const usdz = writerOptions[OPTION_USDZ];
6842
6862
  const files = new Map();
6843
6863
  let layoutDependsOnWriteOrder = Boolean(usdz);
6844
- let offset = 0;
6864
+ const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
6865
+ let offset = initialOffset;
6866
+ let minimumEntrySize = INFINITY_VALUE;
6845
6867
  for (const entry of entries) {
6846
6868
  let { name } = entry;
6847
6869
  const { size } = entry;
@@ -6865,7 +6887,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6865
6887
  if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
6866
6888
  throw new Error(ERR_UNDETERMINED_SIZE);
6867
6889
  }
6868
- const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
6890
+ const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
6869
6891
  const headerInfo = getHeaderInfo(entryOptions);
6870
6892
  const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
6871
6893
  const entryInfo = {
@@ -6876,15 +6898,17 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6876
6898
  appendExtraFieldUSDZ(entryInfo, offset);
6877
6899
  }
6878
6900
  const compressedSize = hasContent ? maximumCompressedSize : 0;
6879
- if (offset >= MAX_32_BITS) {
6880
- layoutDependsOnWriteOrder = true;
6881
- }
6882
6901
  files.set(name, Object.assign({}, entryOptions, headerInfo, {
6883
6902
  offset,
6884
6903
  diskNumberStart: 0,
6885
6904
  compressedSize
6886
6905
  }));
6887
- offset += entryInfo.metadataSize + compressedSize;
6906
+ const entrySize = entryInfo.metadataSize + compressedSize;
6907
+ minimumEntrySize = Math.min(minimumEntrySize, entrySize);
6908
+ offset += entrySize;
6909
+ }
6910
+ if (files.size && offset - minimumEntrySize >= MAX_32_BITS) {
6911
+ layoutDependsOnWriteOrder = true;
6888
6912
  }
6889
6913
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
6890
6914
  throw new Error(ERR_UNDETERMINED_SIZE);
@@ -6898,7 +6922,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6898
6922
  zip64 = true;
6899
6923
  }
6900
6924
  }
6901
- return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6925
+ return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6902
6926
  }
6903
6927
 
6904
6928
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
@@ -6909,6 +6933,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6909
6933
  const {
6910
6934
  keepOrder,
6911
6935
  dataDescriptor,
6936
+ emptyEntry,
6912
6937
  signal
6913
6938
  } = options;
6914
6939
  const {
@@ -6933,7 +6958,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6933
6958
  lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
6934
6959
  requestLockCurrentFileEntry();
6935
6960
  }
6936
- if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
6961
+ if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || (!dataDescriptor && !emptyEntry)) {
6937
6962
  bufferedWrite = true;
6938
6963
  zipWriter.bufferedWrites++;
6939
6964
  if (options.createTempStream) {
@@ -7355,8 +7380,8 @@ function getHeaderInfo(options) {
7355
7380
  try {
7356
7381
  const { uid, gid, unixExtraFieldType } = options;
7357
7382
  if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE$1 && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
7358
- const uidBytes = packUnixId(uid);
7359
- const gidBytes = packUnixId(gid);
7383
+ const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
7384
+ const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
7360
7385
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
7361
7386
  const extraFieldUnix = createRecordWriter(4 + payloadLength);
7362
7387
  extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
@@ -7395,12 +7420,13 @@ function getHeaderInfo(options) {
7395
7420
  if (passThrough && crc32 !== UNDEFINED_VALUE) {
7396
7421
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
7397
7422
  }
7398
- rawExtraFieldAES[9] = compressionMethod;
7423
+ setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
7399
7424
  compressionMethod = COMPRESSION_METHOD_AES;
7400
7425
  }
7401
7426
  const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
7402
7427
  const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
7403
- if (extraFieldLength > MAX_16_BITS) {
7428
+ const maximumUsdzExtraFieldLength = options[OPTION_USDZ] ? EXTRAFIELD_USDZ_MAX_LENGTH : 0;
7429
+ if (extraFieldLength + maximumUsdzExtraFieldLength > MAX_16_BITS) {
7404
7430
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
7405
7431
  }
7406
7432
  const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
@@ -7486,18 +7512,14 @@ function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
7486
7512
  }
7487
7513
 
7488
7514
  function packUnixId(id) {
7489
- if (id === UNDEFINED_VALUE) {
7490
- return EMPTY_UINT8_ARRAY;
7491
- } else {
7492
- const dataArray = new Uint8Array(4);
7493
- const dataView = getDataView(dataArray);
7494
- dataView.setUint32(0, id, true);
7495
- let length = 4;
7496
- while (length > 1 && dataArray[length - 1] === 0) {
7497
- length--;
7498
- }
7499
- return dataArray.subarray(0, length);
7515
+ const dataArray = new Uint8Array(4);
7516
+ const dataView = getDataView(dataArray);
7517
+ dataView.setUint32(0, id, true);
7518
+ let length = 4;
7519
+ while (length > 1 && dataArray[length - 1] === 0) {
7520
+ length--;
7500
7521
  }
7522
+ return dataArray.subarray(0, length);
7501
7523
  }
7502
7524
 
7503
7525
  function normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes) {
@@ -7801,7 +7823,11 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7801
7823
  signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
7802
7824
  signatureRecord.writeUint16(signatureDataLength);
7803
7825
  signatureRecord.writeBytes(signatureData);
7804
- await writeData(zipWriter.writer, signatureRecord.array);
7826
+ const { writer } = zipWriter;
7827
+ if (exceedsAvailableSize(writer, getLength(signatureRecord.array))) {
7828
+ await writer.closeDisk();
7829
+ }
7830
+ await writeData(writer, signatureRecord.array);
7805
7831
  return 6 + signatureDataLength;
7806
7832
  }
7807
7833
  return 0;
@@ -7912,7 +7938,22 @@ async function startsWithSplitZipSignature(reader) {
7912
7938
  return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
7913
7939
  }
7914
7940
 
7915
- async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
7941
+ function removeExtraFieldZip64(rawExtraField) {
7942
+ const rawExtraFieldView = getDataView(rawExtraField);
7943
+ let offsetExtraField = 0;
7944
+ while (offsetExtraField + 4 <= getLength(rawExtraField)) {
7945
+ const size = 4 + getUint16(rawExtraFieldView, offsetExtraField + 2);
7946
+ if (getUint16(rawExtraFieldView, offsetExtraField) == EXTRAFIELD_TYPE_ZIP64) {
7947
+ return removeExtraFieldZip64(concat(
7948
+ rawExtraField.subarray(0, offsetExtraField),
7949
+ rawExtraField.subarray(Math.min(offsetExtraField + size, getLength(rawExtraField)))));
7950
+ }
7951
+ offsetExtraField += size;
7952
+ }
7953
+ return rawExtraField;
7954
+ }
7955
+
7956
+ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
7916
7957
  const { writer } = zipWriter;
7917
7958
  const entryPositions = new Map();
7918
7959
  if (writer.closeDisk) {
@@ -7933,9 +7974,10 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZip
7933
7974
  }
7934
7975
  await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
7935
7976
  } else {
7977
+ const baseOffset = zipWriter.offset;
7936
7978
  await copyData(zipWriter, reader, 0, directoryOffset);
7937
7979
  entries.forEach(entry => entryPositions.set(entry, {
7938
- offset: splitZipSignatureLength + getSourceOffset(reader, entry),
7980
+ offset: baseOffset + getSourceOffset(reader, entry),
7939
7981
  diskNumberStart: 0
7940
7982
  }));
7941
7983
  }
@@ -9843,7 +9885,7 @@ function keepsContentType(writer, data) {
9843
9885
  } else if (writer.constructor == BlobWriter) {
9844
9886
  return data.type == contentType;
9845
9887
  } else if (writer.constructor == Data64URIWriter) {
9846
- return data.startsWith(writer.data);
9888
+ return data.startsWith("data:" + (contentType || "") + ";base64,");
9847
9889
  } else {
9848
9890
  return true;
9849
9891
  }
@@ -10516,6 +10558,7 @@ exports.ERR_UNSUPPORTED_ENCRYPTION = ERR_UNSUPPORTED_ENCRYPTION;
10516
10558
  exports.ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH;
10517
10559
  exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
10518
10560
  exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
10561
+ exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
10519
10562
  exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
10520
10563
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
10521
10564
  exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
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
  /**
@@ -2947,7 +2952,9 @@ export interface ZipWriterConstructorOptions extends WorkerConfiguration {
2947
2952
  *
2948
2953
  * When set to `false`, the {@link ZipWriterConstructorOptions#bufferedWrite} option will automatically be
2949
2954
  * set to `true`. It will be automatically set to `false` when it is `undefined` and the
2950
- * {@link ZipWriterConstructorOptions#bufferedWrite} option is set to `true`, or when the
2955
+ * {@link ZipWriterConstructorOptions#bufferedWrite} option is set to `true`, or when the entry is a folder
2956
+ * or an empty entry stored without compression or encryption, since the header can then carry the sizes and
2957
+ * the CRC-32 directly. It will be automatically set to `true` when the
2951
2958
  * {@link ZipWriterConstructorOptions#zipCrypto} option is set to `true`. Otherwise, the default value is `true`.
2952
2959
  */
2953
2960
  dataDescriptor?: boolean;
@@ -3024,6 +3031,9 @@ export interface ZipWriterConstructorOptions extends WorkerConfiguration {
3024
3031
  * - "unix": Info-ZIP Unix extra field type 2 (0x7855), storing fixed 2-byte uid/gid (0..65535); a
3025
3032
  * larger uid or gid is rejected. The Unix mode is not part of this field; it is written to the
3026
3033
  * external file attributes.
3034
+ *
3035
+ * When {@link ZipFS} exports imported entries, their uid/gid are re-emitted as "infozip" regardless
3036
+ * of the field type found in the imported zip file, unless this option is set explicitly.
3027
3037
  */
3028
3038
  unixExtraFieldType?: "infozip" | "unix";
3029
3039
  /**
@@ -4315,6 +4325,13 @@ export const ERR_INVALID_FILENAME_VALIDATION: string;
4315
4325
  * Invalid maxAppendedDataSize error (thrown when the `maxAppendedDataSize` option is not a number greater than or equal to 0)
4316
4326
  */
4317
4327
  export const ERR_INVALID_MAX_APPENDED_DATA_SIZE: string;
4328
+ /**
4329
+ * Unsupported 64-bit value error
4330
+ *
4331
+ * @remarks Thrown when a 64-bit size, offset, or entry count read from a zip file exceeds `Number.MAX_SAFE_INTEGER`,
4332
+ * instead of processing the value with a loss of precision.
4333
+ */
4334
+ export const ERR_UNSUPPORTED_UINT64: string;
4318
4335
  /**
4319
4336
  * Iteration completed too soon error
4320
4337
  */
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
  /**
@@ -2947,7 +2952,9 @@ export interface ZipWriterConstructorOptions extends WorkerConfiguration {
2947
2952
  *
2948
2953
  * When set to `false`, the {@link ZipWriterConstructorOptions#bufferedWrite} option will automatically be
2949
2954
  * set to `true`. It will be automatically set to `false` when it is `undefined` and the
2950
- * {@link ZipWriterConstructorOptions#bufferedWrite} option is set to `true`, or when the
2955
+ * {@link ZipWriterConstructorOptions#bufferedWrite} option is set to `true`, or when the entry is a folder
2956
+ * or an empty entry stored without compression or encryption, since the header can then carry the sizes and
2957
+ * the CRC-32 directly. It will be automatically set to `true` when the
2951
2958
  * {@link ZipWriterConstructorOptions#zipCrypto} option is set to `true`. Otherwise, the default value is `true`.
2952
2959
  */
2953
2960
  dataDescriptor?: boolean;
@@ -3024,6 +3031,9 @@ export interface ZipWriterConstructorOptions extends WorkerConfiguration {
3024
3031
  * - "unix": Info-ZIP Unix extra field type 2 (0x7855), storing fixed 2-byte uid/gid (0..65535); a
3025
3032
  * larger uid or gid is rejected. The Unix mode is not part of this field; it is written to the
3026
3033
  * external file attributes.
3034
+ *
3035
+ * When {@link ZipFS} exports imported entries, their uid/gid are re-emitted as "infozip" regardless
3036
+ * of the field type found in the imported zip file, unless this option is set explicitly.
3027
3037
  */
3028
3038
  unixExtraFieldType?: "infozip" | "unix";
3029
3039
  /**
@@ -4315,6 +4325,13 @@ export const ERR_INVALID_FILENAME_VALIDATION: string;
4315
4325
  * Invalid maxAppendedDataSize error (thrown when the `maxAppendedDataSize` option is not a number greater than or equal to 0)
4316
4326
  */
4317
4327
  export const ERR_INVALID_MAX_APPENDED_DATA_SIZE: string;
4328
+ /**
4329
+ * Unsupported 64-bit value error
4330
+ *
4331
+ * @remarks Thrown when a 64-bit size, offset, or entry count read from a zip file exceeds `Number.MAX_SAFE_INTEGER`,
4332
+ * instead of processing the value with a loss of precision.
4333
+ */
4334
+ export const ERR_UNSUPPORTED_UINT64: string;
4318
4335
  /**
4319
4336
  * Iteration completed too soon error
4320
4337
  */