@zip.js/zip.js 2.8.52 → 2.8.53

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.
@@ -101,6 +101,9 @@
101
101
  const VERSION_ZIP64 = 0x2D;
102
102
  const VERSION_AES = 0x33;
103
103
 
104
+ const VERSION_MADE_BY_MSDOS = 0x0014;
105
+ const VERSION_MADE_BY_UNIX = 0x0300;
106
+
104
107
  const DIRECTORY_SIGNATURE = "/";
105
108
 
106
109
  const HEADER_SIZE = 30;
@@ -1090,9 +1093,8 @@
1090
1093
 
1091
1094
  async init() {
1092
1095
  const reader = this;
1093
- const { readers } = reader;
1094
1096
  reader.lastDiskNumber = 0;
1095
- await Promise.all(readers.map(diskReader => initStream(diskReader)));
1097
+ const readers = reader.readers = await Promise.all(reader.readers.map(initDiskReader));
1096
1098
  reader.diskOffsets = readers.map(diskReader => {
1097
1099
  const diskOffset = reader.size;
1098
1100
  reader.size += diskReader.size;
@@ -1287,6 +1289,16 @@
1287
1289
  }
1288
1290
  }
1289
1291
 
1292
+ async function initDiskReader(diskReader) {
1293
+ diskReader = new GenericReader(diskReader);
1294
+ await initStream(diskReader);
1295
+ if (diskReader.size === UNDEFINED_VALUE || !diskReader.readUint8Array) {
1296
+ diskReader = new BlobReader(await streamToBlob(diskReader.readable));
1297
+ await initStream(diskReader);
1298
+ }
1299
+ return diskReader;
1300
+ }
1301
+
1290
1302
  function readUint8Array(reader, offset, size) {
1291
1303
  return reader.readUint8Array(offset, size);
1292
1304
  }
@@ -3836,6 +3848,10 @@
3836
3848
  const PROPERTY_NAME_SETGID = "setgid";
3837
3849
  const PROPERTY_NAME_STICKY = "sticky";
3838
3850
  const PROPERTY_NAME_BITFLAG = "bitFlag";
3851
+ const PROPERTY_NAME_RAW_BITFLAG = "rawBitFlag";
3852
+ const PROPERTY_NAME_FILENAME_LENGTH = "filenameLength";
3853
+ const PROPERTY_NAME_EXTRA_FIELD_LENGTH = "extraFieldLength";
3854
+ const PROPERTY_NAME_UNIX_EXTERNAL_UPPER = "unixExternalUpper";
3839
3855
  const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
3840
3856
  const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
3841
3857
  const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
@@ -3888,10 +3904,14 @@
3888
3904
  PROPERTY_NAME_UID,
3889
3905
  PROPERTY_NAME_GID,
3890
3906
  PROPERTY_NAME_UNIX_MODE,
3907
+ PROPERTY_NAME_UNIX_EXTERNAL_UPPER,
3891
3908
  PROPERTY_NAME_SETUID,
3892
3909
  PROPERTY_NAME_SETGID,
3893
3910
  PROPERTY_NAME_STICKY,
3894
3911
  PROPERTY_NAME_BITFLAG,
3912
+ PROPERTY_NAME_RAW_BITFLAG,
3913
+ PROPERTY_NAME_FILENAME_LENGTH,
3914
+ PROPERTY_NAME_EXTRA_FIELD_LENGTH,
3895
3915
  PROPERTY_NAME_FILENAME_UTF8,
3896
3916
  PROPERTY_NAME_COMMENT_UTF8,
3897
3917
  PROPERTY_NAME_RAW_EXTRA_FIELD,
@@ -3953,6 +3973,7 @@
3953
3973
  const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
3954
3974
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
3955
3975
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
3976
+ const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
3956
3977
  const OPTION_CHECK_SIGNATURE = "checkSignature";
3957
3978
  const OPTION_CHECK_CRC32 = "checkCrc32";
3958
3979
  const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
@@ -4084,7 +4105,7 @@
4084
4105
  if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
4085
4106
  throw new Error(ERR_BAD_FORMAT);
4086
4107
  }
4087
- const strictness = getStrictness(getOptionValue$1(zipReader, options, OPTION_STRICTNESS), getOptionValue$1(zipReader, options, OPTION_CHECK_AMBIGUITY));
4108
+ const strictness = getStrictness(options, zipReader.options);
4088
4109
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4089
4110
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
4090
4111
  const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
@@ -4306,6 +4327,7 @@
4306
4327
  index: indexFile,
4307
4328
  versionMadeBy,
4308
4329
  msDosCompatible,
4330
+ zip64: false,
4309
4331
  compressedSize: 0,
4310
4332
  uncompressedSize: 0,
4311
4333
  commentLength,
@@ -4476,9 +4498,12 @@
4476
4498
  extraFieldLength,
4477
4499
  filenameLength
4478
4500
  } = localDirectory;
4479
- const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
4501
+ const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
4502
+ const entryStrictness = getStrictness(options, zipEntry.options);
4503
+ const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
4504
+ const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
4480
4505
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
4481
- if (checkAmbiguity && (filenameLength || extraFieldLength)) {
4506
+ if (checkLocalFilename && (filenameLength || extraFieldLength)) {
4482
4507
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
4483
4508
  rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
4484
4509
  localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
@@ -4487,17 +4512,26 @@
4487
4512
  await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
4488
4513
  EMPTY_UINT8_ARRAY;
4489
4514
  }
4515
+ if (checkLocalFilename) {
4516
+ localDirectory.rawFilename = rawLocalFilename;
4517
+ }
4490
4518
  readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
4491
- if (checkAmbiguity) {
4492
- checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename);
4519
+ if (checkLocalDirectory) {
4520
+ validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
4493
4521
  }
4494
- const { lastAccessDate, creationDate } = localDirectory;
4522
+ const { lastAccessDate, creationDate, uid, gid } = localDirectory;
4495
4523
  if (lastAccessDate) {
4496
4524
  fileEntry.lastAccessDate = lastAccessDate;
4497
4525
  }
4498
4526
  if (creationDate) {
4499
4527
  fileEntry.creationDate = creationDate;
4500
4528
  }
4529
+ if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
4530
+ fileEntry.uid = uid;
4531
+ }
4532
+ if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
4533
+ fileEntry.gid = gid;
4534
+ }
4501
4535
  const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
4502
4536
  const zipCrypto = encrypted && !extraFieldAES;
4503
4537
  if (!passThrough) {
@@ -4733,10 +4767,12 @@
4733
4767
  directory.extraFieldNTFS = extraFieldNTFS;
4734
4768
  }
4735
4769
  const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
4770
+ let unixIdsRead;
4736
4771
  if (extraFieldUnix) {
4737
- readExtraFieldUnix(extraFieldUnix, directory, false);
4772
+ unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
4738
4773
  directory.extraFieldUnix = extraFieldUnix;
4739
- } else {
4774
+ }
4775
+ if (!unixIdsRead) {
4740
4776
  const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
4741
4777
  if (extraFieldInfoZip) {
4742
4778
  readExtraFieldUnix(extraFieldInfoZip, directory, true);
@@ -4839,7 +4875,7 @@
4839
4875
  const creationDate = getDateNTFS(rawCreationDate);
4840
4876
  const extraFieldData = { lastModDate, lastAccessDate, creationDate };
4841
4877
  Object.assign(extraFieldNTFS, extraFieldData);
4842
- Object.assign(directory, extraFieldData);
4878
+ Object.assign(directory, extraFieldData, { rawLastAccessDate, rawCreationDate });
4843
4879
  }
4844
4880
  }
4845
4881
 
@@ -4883,6 +4919,7 @@
4883
4919
  if (gid !== UNDEFINED_VALUE) {
4884
4920
  directory.gid = gid;
4885
4921
  }
4922
+ return uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE;
4886
4923
  } catch {
4887
4924
  // ignored
4888
4925
  }
@@ -4955,26 +4992,25 @@
4955
4992
  }
4956
4993
  if (dataDescriptorLength) {
4957
4994
  const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
4958
- const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
4959
- getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
4960
- if (dataDescriptorSignature) {
4961
- const readCrc32 = getUint32(getDataView(dataDescriptorArray), 4);
4962
- let readCompressedSize;
4963
- let readUncompressedSize;
4964
- if (extraFieldZip64) {
4965
- readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
4966
- readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
4967
- } else {
4968
- readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
4969
- readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
4970
- }
4971
- const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
4995
+ const dataDescriptorView = getDataView(dataDescriptorArray);
4996
+ let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
4997
+ getUint32(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
4998
+ if (signature) {
4999
+ const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
5000
+ const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
4972
5001
  if (matchCrc32 &&
4973
- readCompressedSize == compressedSize &&
4974
- readUncompressedSize == uncompressedSize) {
5002
+ signedDataDescriptor.compressedSize == compressedSize &&
5003
+ signedDataDescriptor.uncompressedSize == uncompressedSize) {
4975
5004
  dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
5005
+ } else {
5006
+ signature = false;
4976
5007
  }
4977
5008
  }
5009
+ if (dataDescriptorArray.length >= dataDescriptorLength) {
5010
+ const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
5011
+ localDataDescriptor.signature = signature;
5012
+ fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
5013
+ }
4978
5014
  }
4979
5015
  const range = {
4980
5016
  start: offset,
@@ -4991,6 +5027,20 @@
4991
5027
  readRanges.set(index, range);
4992
5028
  }
4993
5029
 
5030
+ function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
5031
+ const crc32 = getUint32(dataDescriptorView, offset);
5032
+ let compressedSize;
5033
+ let uncompressedSize;
5034
+ if (extraFieldZip64) {
5035
+ compressedSize = getBigUint64(dataDescriptorView, offset + 4);
5036
+ uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
5037
+ } else {
5038
+ compressedSize = getUint32(dataDescriptorView, offset + 4);
5039
+ uncompressedSize = getUint32(dataDescriptorView, offset + 8);
5040
+ }
5041
+ return { crc32, compressedSize, uncompressedSize };
5042
+ }
5043
+
4994
5044
  function getDiskOffset$1(reader, diskNumber) {
4995
5045
  return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
4996
5046
  }
@@ -4999,14 +5049,40 @@
4999
5049
  return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
5000
5050
  }
5001
5051
 
5002
- function getStrictness(strictness, checkAmbiguity) {
5003
- if (strictness === UNDEFINED_VALUE) {
5004
- return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
5052
+ function getStrictness(options, inheritedOptions) {
5053
+ return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
5054
+ }
5055
+
5056
+ function resolveStrictness(options, inheritedStrictness) {
5057
+ const strictness = options[OPTION_STRICTNESS];
5058
+ if (strictness !== UNDEFINED_VALUE) {
5059
+ if (!isStrictnessValue(strictness)) {
5060
+ throw new Error(ERR_INVALID_STRICTNESS);
5061
+ }
5062
+ return strictness;
5063
+ }
5064
+ const checkAmbiguity = options[OPTION_CHECK_AMBIGUITY];
5065
+ if (checkAmbiguity === UNDEFINED_VALUE) {
5066
+ return inheritedStrictness;
5005
5067
  }
5006
- if (!isStrictnessValue(strictness)) {
5007
- throw new Error(ERR_INVALID_STRICTNESS);
5068
+ if (checkAmbiguity) {
5069
+ return STRICTNESS_STRICT;
5070
+ }
5071
+ return inheritedStrictness == STRICTNESS_TOLERANT ? STRICTNESS_TOLERANT : STRICTNESS_BALANCED;
5072
+ }
5073
+
5074
+ function getCheckLocalDirectory(checkLocalDirectory, strictness) {
5075
+ if (checkLocalDirectory === UNDEFINED_VALUE) {
5076
+ return strictness != STRICTNESS_TOLERANT;
5008
5077
  }
5009
- return strictness;
5078
+ return Boolean(checkLocalDirectory);
5079
+ }
5080
+
5081
+ function getCheckLocalFilename(checkLocalFilename, strictness) {
5082
+ if (checkLocalFilename === UNDEFINED_VALUE) {
5083
+ return strictness == STRICTNESS_STRICT;
5084
+ }
5085
+ return Boolean(checkLocalFilename);
5010
5086
  }
5011
5087
 
5012
5088
  function getFilenameValidation(filenameValidation, strictness) {
@@ -5154,10 +5230,11 @@
5154
5230
  return UNDEFINED_VALUE;
5155
5231
  }
5156
5232
 
5157
- function checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename) {
5233
+ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
5158
5234
  const { rawFilename } = zipEntry;
5159
- if (rawLocalFilename.length != rawFilename.length ||
5160
- rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte])) {
5235
+ if (checkLocalFilename &&
5236
+ (rawLocalFilename.length != rawFilename.length ||
5237
+ rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
5161
5238
  throwAmbiguousArchive("mismatched local file header (filename)");
5162
5239
  }
5163
5240
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
@@ -5273,6 +5350,7 @@
5273
5350
 
5274
5351
  const ERR_DUPLICATED_NAME = "File already exists";
5275
5352
  const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
5353
+ const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
5276
5354
  const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
5277
5355
  const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
5278
5356
  const ERR_INVALID_VERSION = "Version exceeds 65535";
@@ -5341,6 +5419,10 @@
5341
5419
  }
5342
5420
  reader = new GenericReader(reader);
5343
5421
  await initStream(reader);
5422
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
5423
+ reader = new BlobReader(await streamToBlob(reader.readable));
5424
+ await initStream(reader);
5425
+ }
5344
5426
  const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
5345
5427
  const zipReader$1 = new ZipReader(reader.readable);
5346
5428
  const entries = await zipReader$1.getEntries();
@@ -5489,6 +5571,9 @@
5489
5571
  const zipWriter = this;
5490
5572
  const { pendingAddFileCalls, writer } = this;
5491
5573
  const { writable } = writer;
5574
+ if (!(comment instanceof Uint8Array)) {
5575
+ throw new Error(ERR_INVALID_COMMENT_TYPE);
5576
+ }
5492
5577
  if (getLength(comment) > MAX_16_BITS) {
5493
5578
  throw new Error(ERR_INVALID_COMMENT);
5494
5579
  }
@@ -5523,8 +5608,6 @@
5523
5608
  const diskOffset = getDiskOffset(zipWriter.writer);
5524
5609
  const diskNumber = getDiskNumber(zipWriter.writer);
5525
5610
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
5526
- internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
5527
- externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
5528
5611
  signature: options[PROPERTY_NAME_SIGNATURE],
5529
5612
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
5530
5613
  offset: zipWriter.offset - diskOffset,
@@ -5538,14 +5621,20 @@
5538
5621
  zipWriter.files.delete(name);
5539
5622
  throw error;
5540
5623
  }
5541
- Object.assign(fileEntry, { name, comment, extraField });
5624
+ Object.assign(fileEntry, {
5625
+ name,
5626
+ comment,
5627
+ extraField,
5628
+ [PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
5629
+ [PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
5630
+ });
5542
5631
  return new Entry(fileEntry);
5543
5632
  }
5544
5633
 
5545
5634
  function resolveAttributes(zipWriter, name, options) {
5546
5635
  name = name.trim();
5547
5636
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
5548
- let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
5637
+ let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
5549
5638
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
5550
5639
  const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
5551
5640
  const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
@@ -5579,7 +5668,7 @@
5579
5668
  const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
5580
5669
  if (hasUnixMetadata) {
5581
5670
  msDosCompatible = false;
5582
- versionMadeBy = (versionMadeBy & MAX_16_BITS) | (3 << 8);
5671
+ versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
5583
5672
  } else if (hasMsDosProvided) {
5584
5673
  msDosCompatible = true;
5585
5674
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
@@ -5619,11 +5708,10 @@
5619
5708
  externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
5620
5709
  }
5621
5710
  }
5622
- let unixExternalUpper;
5623
5711
  if (!msDosCompatible) {
5624
5712
  const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
5625
- unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
5626
- unixMode = unixMode === UNDEFINED_VALUE ? unixExternalUpper : (unixMode & MAX_16_BITS);
5713
+ const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
5714
+ unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
5627
5715
  if (setuid) {
5628
5716
  unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
5629
5717
  } else {
@@ -5652,17 +5740,20 @@
5652
5740
  if (hasMsDosProvided) {
5653
5741
  externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
5654
5742
  }
5743
+ const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
5744
+ const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
5655
5745
  return {
5656
5746
  name,
5657
5747
  resolvedOptions: {
5658
5748
  versionMadeBy,
5659
- msDosCompatible,
5749
+ msDosCompatible: Boolean(msDosCompatible),
5660
5750
  externalFileAttributes,
5661
5751
  unixExternalUpper,
5662
5752
  uid,
5663
5753
  gid,
5664
5754
  unixMode,
5665
5755
  unixExtraFieldType,
5756
+ symlink,
5666
5757
  setuid,
5667
5758
  setgid,
5668
5759
  sticky,
@@ -5895,6 +5986,9 @@
5895
5986
  if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
5896
5987
  throw new Error(ERR_UNDETERMINED_SIZE);
5897
5988
  }
5989
+ if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
5990
+ throw new Error(ERR_INVALID_COMMENT_TYPE);
5991
+ }
5898
5992
  const commentLength = getLength(comment);
5899
5993
  if (commentLength > MAX_16_BITS) {
5900
5994
  throw new Error(ERR_INVALID_COMMENT);
@@ -6176,6 +6270,7 @@
6176
6270
  uid,
6177
6271
  gid,
6178
6272
  unixMode,
6273
+ symlink,
6179
6274
  setuid,
6180
6275
  setgid,
6181
6276
  sticky,
@@ -6212,6 +6307,7 @@
6212
6307
  uid,
6213
6308
  gid,
6214
6309
  unixMode,
6310
+ symlink: Boolean(symlink),
6215
6311
  setuid,
6216
6312
  setgid,
6217
6313
  sticky,
@@ -6292,8 +6388,8 @@
6292
6388
  rawLastModDate,
6293
6389
  creationDate,
6294
6390
  lastAccessDate,
6295
- encrypted,
6296
- zipCrypto,
6391
+ encrypted: Boolean(encrypted),
6392
+ zipCrypto: Boolean(zipCrypto),
6297
6393
  size: metadataSize + compressedSize,
6298
6394
  compressionMethod,
6299
6395
  version,