@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.
@@ -102,6 +102,9 @@
102
102
  const VERSION_ZIP64 = 0x2D;
103
103
  const VERSION_AES = 0x33;
104
104
 
105
+ const VERSION_MADE_BY_MSDOS = 0x0014;
106
+ const VERSION_MADE_BY_UNIX = 0x0300;
107
+
105
108
  const DIRECTORY_SIGNATURE = "/";
106
109
 
107
110
  const HEADER_SIZE = 30;
@@ -2758,6 +2761,7 @@
2758
2761
  worker,
2759
2762
  workerAlive: false,
2760
2763
  terminated: false,
2764
+ startupError: null,
2761
2765
  interface: {
2762
2766
  run: async () => {
2763
2767
  try {
@@ -2785,6 +2789,13 @@
2785
2789
  }
2786
2790
 
2787
2791
  async function runWebWorker(workerData, config) {
2792
+ if (!workerData.worker) {
2793
+ const { startupError } = workerData;
2794
+ workerData.startupError = null;
2795
+ const error = startupError || new Error(ERR_WORKER_STARTUP_TIMEOUT);
2796
+ error.workerStartupFailed = true;
2797
+ throw error;
2798
+ }
2788
2799
  let resolveResult, rejectResult;
2789
2800
  const result = new Promise((resolve, reject) => {
2790
2801
  resolveResult = resolve;
@@ -2998,11 +3009,12 @@
2998
3009
  if (!workerAlive) {
2999
3010
  workerData.worker = null;
3000
3011
  }
3012
+ let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
3013
+ if (!workerAlive) {
3014
+ error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
3015
+ workerData.startupError = error;
3016
+ }
3001
3017
  if (rejectResult) {
3002
- let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
3003
- if (!workerAlive) {
3004
- error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
3005
- }
3006
3018
  rejectResult(error);
3007
3019
  if (writer) {
3008
3020
  writer.releaseLock();
@@ -4031,9 +4043,8 @@
4031
4043
 
4032
4044
  async init() {
4033
4045
  const reader = this;
4034
- const { readers } = reader;
4035
4046
  reader.lastDiskNumber = 0;
4036
- await Promise.all(readers.map(diskReader => initStream(diskReader)));
4047
+ const readers = reader.readers = await Promise.all(reader.readers.map(initDiskReader));
4037
4048
  reader.diskOffsets = readers.map(diskReader => {
4038
4049
  const diskOffset = reader.size;
4039
4050
  reader.size += diskReader.size;
@@ -4228,6 +4239,16 @@
4228
4239
  }
4229
4240
  }
4230
4241
 
4242
+ async function initDiskReader(diskReader) {
4243
+ diskReader = new GenericReader(diskReader);
4244
+ await initStream(diskReader);
4245
+ if (diskReader.size === UNDEFINED_VALUE || !diskReader.readUint8Array) {
4246
+ diskReader = new BlobReader(await streamToBlob(diskReader.readable));
4247
+ await initStream(diskReader);
4248
+ }
4249
+ return diskReader;
4250
+ }
4251
+
4231
4252
  function readUint8Array(reader, offset, size) {
4232
4253
  return reader.readUint8Array(offset, size);
4233
4254
  }
@@ -4386,6 +4407,10 @@
4386
4407
  const PROPERTY_NAME_SETGID = "setgid";
4387
4408
  const PROPERTY_NAME_STICKY = "sticky";
4388
4409
  const PROPERTY_NAME_BITFLAG = "bitFlag";
4410
+ const PROPERTY_NAME_RAW_BITFLAG = "rawBitFlag";
4411
+ const PROPERTY_NAME_FILENAME_LENGTH = "filenameLength";
4412
+ const PROPERTY_NAME_EXTRA_FIELD_LENGTH = "extraFieldLength";
4413
+ const PROPERTY_NAME_UNIX_EXTERNAL_UPPER = "unixExternalUpper";
4389
4414
  const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
4390
4415
  const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
4391
4416
  const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
@@ -4438,10 +4463,14 @@
4438
4463
  PROPERTY_NAME_UID,
4439
4464
  PROPERTY_NAME_GID,
4440
4465
  PROPERTY_NAME_UNIX_MODE,
4466
+ PROPERTY_NAME_UNIX_EXTERNAL_UPPER,
4441
4467
  PROPERTY_NAME_SETUID,
4442
4468
  PROPERTY_NAME_SETGID,
4443
4469
  PROPERTY_NAME_STICKY,
4444
4470
  PROPERTY_NAME_BITFLAG,
4471
+ PROPERTY_NAME_RAW_BITFLAG,
4472
+ PROPERTY_NAME_FILENAME_LENGTH,
4473
+ PROPERTY_NAME_EXTRA_FIELD_LENGTH,
4445
4474
  PROPERTY_NAME_FILENAME_UTF8,
4446
4475
  PROPERTY_NAME_COMMENT_UTF8,
4447
4476
  PROPERTY_NAME_RAW_EXTRA_FIELD,
@@ -4503,6 +4532,7 @@
4503
4532
  const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
4504
4533
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
4505
4534
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
4535
+ const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
4506
4536
  const OPTION_CHECK_SIGNATURE = "checkSignature";
4507
4537
  const OPTION_CHECK_CRC32 = "checkCrc32";
4508
4538
  const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
@@ -4634,7 +4664,7 @@
4634
4664
  if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
4635
4665
  throw new Error(ERR_BAD_FORMAT);
4636
4666
  }
4637
- const strictness = getStrictness(getOptionValue$1(zipReader, options, OPTION_STRICTNESS), getOptionValue$1(zipReader, options, OPTION_CHECK_AMBIGUITY));
4667
+ const strictness = getStrictness(options, zipReader.options);
4638
4668
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4639
4669
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
4640
4670
  const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
@@ -4856,6 +4886,7 @@
4856
4886
  index: indexFile,
4857
4887
  versionMadeBy,
4858
4888
  msDosCompatible,
4889
+ zip64: false,
4859
4890
  compressedSize: 0,
4860
4891
  uncompressedSize: 0,
4861
4892
  commentLength,
@@ -5066,9 +5097,12 @@
5066
5097
  extraFieldLength,
5067
5098
  filenameLength
5068
5099
  } = localDirectory;
5069
- const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
5100
+ const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5101
+ const entryStrictness = getStrictness(options, zipEntry.options);
5102
+ const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
5103
+ const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
5070
5104
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
5071
- if (checkAmbiguity && (filenameLength || extraFieldLength)) {
5105
+ if (checkLocalFilename && (filenameLength || extraFieldLength)) {
5072
5106
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
5073
5107
  rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
5074
5108
  localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
@@ -5077,17 +5111,26 @@
5077
5111
  await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
5078
5112
  EMPTY_UINT8_ARRAY;
5079
5113
  }
5114
+ if (checkLocalFilename) {
5115
+ localDirectory.rawFilename = rawLocalFilename;
5116
+ }
5080
5117
  readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
5081
- if (checkAmbiguity) {
5082
- checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename);
5118
+ if (checkLocalDirectory) {
5119
+ validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
5083
5120
  }
5084
- const { lastAccessDate, creationDate } = localDirectory;
5121
+ const { lastAccessDate, creationDate, uid, gid } = localDirectory;
5085
5122
  if (lastAccessDate) {
5086
5123
  fileEntry.lastAccessDate = lastAccessDate;
5087
5124
  }
5088
5125
  if (creationDate) {
5089
5126
  fileEntry.creationDate = creationDate;
5090
5127
  }
5128
+ if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
5129
+ fileEntry.uid = uid;
5130
+ }
5131
+ if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
5132
+ fileEntry.gid = gid;
5133
+ }
5091
5134
  const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
5092
5135
  const zipCrypto = encrypted && !extraFieldAES;
5093
5136
  if (!passThrough) {
@@ -5323,10 +5366,12 @@
5323
5366
  directory.extraFieldNTFS = extraFieldNTFS;
5324
5367
  }
5325
5368
  const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
5369
+ let unixIdsRead;
5326
5370
  if (extraFieldUnix) {
5327
- readExtraFieldUnix(extraFieldUnix, directory, false);
5371
+ unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
5328
5372
  directory.extraFieldUnix = extraFieldUnix;
5329
- } else {
5373
+ }
5374
+ if (!unixIdsRead) {
5330
5375
  const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
5331
5376
  if (extraFieldInfoZip) {
5332
5377
  readExtraFieldUnix(extraFieldInfoZip, directory, true);
@@ -5429,7 +5474,7 @@
5429
5474
  const creationDate = getDateNTFS(rawCreationDate);
5430
5475
  const extraFieldData = { lastModDate, lastAccessDate, creationDate };
5431
5476
  Object.assign(extraFieldNTFS, extraFieldData);
5432
- Object.assign(directory, extraFieldData);
5477
+ Object.assign(directory, extraFieldData, { rawLastAccessDate, rawCreationDate });
5433
5478
  }
5434
5479
  }
5435
5480
 
@@ -5473,6 +5518,7 @@
5473
5518
  if (gid !== UNDEFINED_VALUE) {
5474
5519
  directory.gid = gid;
5475
5520
  }
5521
+ return uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE;
5476
5522
  } catch {
5477
5523
  // ignored
5478
5524
  }
@@ -5545,26 +5591,25 @@
5545
5591
  }
5546
5592
  if (dataDescriptorLength) {
5547
5593
  const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
5548
- const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
5549
- getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5550
- if (dataDescriptorSignature) {
5551
- const readCrc32 = getUint32(getDataView(dataDescriptorArray), 4);
5552
- let readCompressedSize;
5553
- let readUncompressedSize;
5554
- if (extraFieldZip64) {
5555
- readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
5556
- readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
5557
- } else {
5558
- readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
5559
- readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
5560
- }
5561
- const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
5594
+ const dataDescriptorView = getDataView(dataDescriptorArray);
5595
+ let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
5596
+ getUint32(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5597
+ if (signature) {
5598
+ const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
5599
+ const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
5562
5600
  if (matchCrc32 &&
5563
- readCompressedSize == compressedSize &&
5564
- readUncompressedSize == uncompressedSize) {
5601
+ signedDataDescriptor.compressedSize == compressedSize &&
5602
+ signedDataDescriptor.uncompressedSize == uncompressedSize) {
5565
5603
  dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
5604
+ } else {
5605
+ signature = false;
5566
5606
  }
5567
5607
  }
5608
+ if (dataDescriptorArray.length >= dataDescriptorLength) {
5609
+ const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
5610
+ localDataDescriptor.signature = signature;
5611
+ fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
5612
+ }
5568
5613
  }
5569
5614
  const range = {
5570
5615
  start: offset,
@@ -5581,6 +5626,20 @@
5581
5626
  readRanges.set(index, range);
5582
5627
  }
5583
5628
 
5629
+ function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
5630
+ const crc32 = getUint32(dataDescriptorView, offset);
5631
+ let compressedSize;
5632
+ let uncompressedSize;
5633
+ if (extraFieldZip64) {
5634
+ compressedSize = getBigUint64(dataDescriptorView, offset + 4);
5635
+ uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
5636
+ } else {
5637
+ compressedSize = getUint32(dataDescriptorView, offset + 4);
5638
+ uncompressedSize = getUint32(dataDescriptorView, offset + 8);
5639
+ }
5640
+ return { crc32, compressedSize, uncompressedSize };
5641
+ }
5642
+
5584
5643
  function getDiskOffset$1(reader, diskNumber) {
5585
5644
  return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
5586
5645
  }
@@ -5589,14 +5648,40 @@
5589
5648
  return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
5590
5649
  }
5591
5650
 
5592
- function getStrictness(strictness, checkAmbiguity) {
5593
- if (strictness === UNDEFINED_VALUE) {
5594
- return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
5651
+ function getStrictness(options, inheritedOptions) {
5652
+ return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
5653
+ }
5654
+
5655
+ function resolveStrictness(options, inheritedStrictness) {
5656
+ const strictness = options[OPTION_STRICTNESS];
5657
+ if (strictness !== UNDEFINED_VALUE) {
5658
+ if (!isStrictnessValue(strictness)) {
5659
+ throw new Error(ERR_INVALID_STRICTNESS);
5660
+ }
5661
+ return strictness;
5662
+ }
5663
+ const checkAmbiguity = options[OPTION_CHECK_AMBIGUITY];
5664
+ if (checkAmbiguity === UNDEFINED_VALUE) {
5665
+ return inheritedStrictness;
5666
+ }
5667
+ if (checkAmbiguity) {
5668
+ return STRICTNESS_STRICT;
5669
+ }
5670
+ return inheritedStrictness == STRICTNESS_TOLERANT ? STRICTNESS_TOLERANT : STRICTNESS_BALANCED;
5671
+ }
5672
+
5673
+ function getCheckLocalDirectory(checkLocalDirectory, strictness) {
5674
+ if (checkLocalDirectory === UNDEFINED_VALUE) {
5675
+ return strictness != STRICTNESS_TOLERANT;
5595
5676
  }
5596
- if (!isStrictnessValue(strictness)) {
5597
- throw new Error(ERR_INVALID_STRICTNESS);
5677
+ return Boolean(checkLocalDirectory);
5678
+ }
5679
+
5680
+ function getCheckLocalFilename(checkLocalFilename, strictness) {
5681
+ if (checkLocalFilename === UNDEFINED_VALUE) {
5682
+ return strictness == STRICTNESS_STRICT;
5598
5683
  }
5599
- return strictness;
5684
+ return Boolean(checkLocalFilename);
5600
5685
  }
5601
5686
 
5602
5687
  function getFilenameValidation(filenameValidation, strictness) {
@@ -5744,10 +5829,11 @@
5744
5829
  return UNDEFINED_VALUE;
5745
5830
  }
5746
5831
 
5747
- function checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename) {
5832
+ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
5748
5833
  const { rawFilename } = zipEntry;
5749
- if (rawLocalFilename.length != rawFilename.length ||
5750
- rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte])) {
5834
+ if (checkLocalFilename &&
5835
+ (rawLocalFilename.length != rawFilename.length ||
5836
+ rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
5751
5837
  throwAmbiguousArchive("mismatched local file header (filename)");
5752
5838
  }
5753
5839
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
@@ -5865,6 +5951,7 @@
5865
5951
 
5866
5952
  const ERR_DUPLICATED_NAME = "File already exists";
5867
5953
  const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
5954
+ const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
5868
5955
  const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
5869
5956
  const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
5870
5957
  const ERR_INVALID_VERSION = "Version exceeds 65535";
@@ -5933,6 +6020,10 @@
5933
6020
  }
5934
6021
  reader = new GenericReader(reader);
5935
6022
  await initStream(reader);
6023
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
6024
+ reader = new BlobReader(await streamToBlob(reader.readable));
6025
+ await initStream(reader);
6026
+ }
5936
6027
  const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
5937
6028
  const zipReader$1 = new ZipReader(reader.readable);
5938
6029
  const entries = await zipReader$1.getEntries();
@@ -6081,6 +6172,9 @@
6081
6172
  const zipWriter = this;
6082
6173
  const { pendingAddFileCalls, writer } = this;
6083
6174
  const { writable } = writer;
6175
+ if (!(comment instanceof Uint8Array)) {
6176
+ throw new Error(ERR_INVALID_COMMENT_TYPE);
6177
+ }
6084
6178
  if (getLength(comment) > MAX_16_BITS) {
6085
6179
  throw new Error(ERR_INVALID_COMMENT);
6086
6180
  }
@@ -6177,8 +6271,6 @@
6177
6271
  const diskOffset = getDiskOffset(zipWriter.writer);
6178
6272
  const diskNumber = getDiskNumber(zipWriter.writer);
6179
6273
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
6180
- internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
6181
- externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
6182
6274
  signature: options[PROPERTY_NAME_SIGNATURE],
6183
6275
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6184
6276
  offset: zipWriter.offset - diskOffset,
@@ -6192,14 +6284,20 @@
6192
6284
  zipWriter.files.delete(name);
6193
6285
  throw error;
6194
6286
  }
6195
- Object.assign(fileEntry, { name, comment, extraField });
6287
+ Object.assign(fileEntry, {
6288
+ name,
6289
+ comment,
6290
+ extraField,
6291
+ [PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
6292
+ [PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
6293
+ });
6196
6294
  return new Entry(fileEntry);
6197
6295
  }
6198
6296
 
6199
6297
  function resolveAttributes(zipWriter, name, options) {
6200
6298
  name = name.trim();
6201
6299
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6202
- let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
6300
+ let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
6203
6301
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
6204
6302
  const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
6205
6303
  const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
@@ -6233,7 +6331,7 @@
6233
6331
  const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
6234
6332
  if (hasUnixMetadata) {
6235
6333
  msDosCompatible = false;
6236
- versionMadeBy = (versionMadeBy & MAX_16_BITS) | (3 << 8);
6334
+ versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
6237
6335
  } else if (hasMsDosProvided) {
6238
6336
  msDosCompatible = true;
6239
6337
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
@@ -6273,11 +6371,10 @@
6273
6371
  externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
6274
6372
  }
6275
6373
  }
6276
- let unixExternalUpper;
6277
6374
  if (!msDosCompatible) {
6278
6375
  const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
6279
- unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
6280
- unixMode = unixMode === UNDEFINED_VALUE ? unixExternalUpper : (unixMode & MAX_16_BITS);
6376
+ const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
6377
+ unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
6281
6378
  if (setuid) {
6282
6379
  unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
6283
6380
  } else {
@@ -6306,17 +6403,20 @@
6306
6403
  if (hasMsDosProvided) {
6307
6404
  externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
6308
6405
  }
6406
+ const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
6407
+ const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
6309
6408
  return {
6310
6409
  name,
6311
6410
  resolvedOptions: {
6312
6411
  versionMadeBy,
6313
- msDosCompatible,
6412
+ msDosCompatible: Boolean(msDosCompatible),
6314
6413
  externalFileAttributes,
6315
6414
  unixExternalUpper,
6316
6415
  uid,
6317
6416
  gid,
6318
6417
  unixMode,
6319
6418
  unixExtraFieldType,
6419
+ symlink,
6320
6420
  setuid,
6321
6421
  setgid,
6322
6422
  sticky,
@@ -6758,6 +6858,7 @@
6758
6858
  uid,
6759
6859
  gid,
6760
6860
  unixMode,
6861
+ symlink,
6761
6862
  setuid,
6762
6863
  setgid,
6763
6864
  sticky,
@@ -6794,6 +6895,7 @@
6794
6895
  uid,
6795
6896
  gid,
6796
6897
  unixMode,
6898
+ symlink: Boolean(symlink),
6797
6899
  setuid,
6798
6900
  setgid,
6799
6901
  sticky,
@@ -6874,8 +6976,8 @@
6874
6976
  rawLastModDate,
6875
6977
  creationDate,
6876
6978
  lastAccessDate,
6877
- encrypted,
6878
- zipCrypto,
6979
+ encrypted: Boolean(encrypted),
6980
+ zipCrypto: Boolean(zipCrypto),
6879
6981
  size: metadataSize + compressedSize,
6880
6982
  compressionMethod,
6881
6983
  version,
@@ -8297,6 +8399,7 @@
8297
8399
  exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
8298
8400
  exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
8299
8401
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
8402
+ exports.ERR_INVALID_COMMENT_TYPE = ERR_INVALID_COMMENT_TYPE;
8300
8403
  exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
8301
8404
  exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
8302
8405
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;