@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.
package/dist/zip.js CHANGED
@@ -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;
@@ -2762,6 +2765,7 @@
2762
2765
  worker,
2763
2766
  workerAlive: false,
2764
2767
  terminated: false,
2768
+ startupError: null,
2765
2769
  interface: {
2766
2770
  run: async () => {
2767
2771
  try {
@@ -2789,6 +2793,13 @@
2789
2793
  }
2790
2794
 
2791
2795
  async function runWebWorker(workerData, config) {
2796
+ if (!workerData.worker) {
2797
+ const { startupError } = workerData;
2798
+ workerData.startupError = null;
2799
+ const error = startupError || new Error(ERR_WORKER_STARTUP_TIMEOUT);
2800
+ error.workerStartupFailed = true;
2801
+ throw error;
2802
+ }
2792
2803
  let resolveResult, rejectResult;
2793
2804
  const result = new Promise((resolve, reject) => {
2794
2805
  resolveResult = resolve;
@@ -3002,11 +3013,12 @@
3002
3013
  if (!workerAlive) {
3003
3014
  workerData.worker = null;
3004
3015
  }
3016
+ let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
3017
+ if (!workerAlive) {
3018
+ error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
3019
+ workerData.startupError = error;
3020
+ }
3005
3021
  if (rejectResult) {
3006
- let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
3007
- if (!workerAlive) {
3008
- error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
3009
- }
3010
3022
  rejectResult(error);
3011
3023
  if (writer) {
3012
3024
  writer.releaseLock();
@@ -4035,9 +4047,8 @@
4035
4047
 
4036
4048
  async init() {
4037
4049
  const reader = this;
4038
- const { readers } = reader;
4039
4050
  reader.lastDiskNumber = 0;
4040
- await Promise.all(readers.map(diskReader => initStream(diskReader)));
4051
+ const readers = reader.readers = await Promise.all(reader.readers.map(initDiskReader));
4041
4052
  reader.diskOffsets = readers.map(diskReader => {
4042
4053
  const diskOffset = reader.size;
4043
4054
  reader.size += diskReader.size;
@@ -4232,6 +4243,16 @@
4232
4243
  }
4233
4244
  }
4234
4245
 
4246
+ async function initDiskReader(diskReader) {
4247
+ diskReader = new GenericReader(diskReader);
4248
+ await initStream(diskReader);
4249
+ if (diskReader.size === UNDEFINED_VALUE || !diskReader.readUint8Array) {
4250
+ diskReader = new BlobReader(await streamToBlob(diskReader.readable));
4251
+ await initStream(diskReader);
4252
+ }
4253
+ return diskReader;
4254
+ }
4255
+
4235
4256
  function readUint8Array(reader, offset, size) {
4236
4257
  return reader.readUint8Array(offset, size);
4237
4258
  }
@@ -4390,6 +4411,10 @@
4390
4411
  const PROPERTY_NAME_SETGID = "setgid";
4391
4412
  const PROPERTY_NAME_STICKY = "sticky";
4392
4413
  const PROPERTY_NAME_BITFLAG = "bitFlag";
4414
+ const PROPERTY_NAME_RAW_BITFLAG = "rawBitFlag";
4415
+ const PROPERTY_NAME_FILENAME_LENGTH = "filenameLength";
4416
+ const PROPERTY_NAME_EXTRA_FIELD_LENGTH = "extraFieldLength";
4417
+ const PROPERTY_NAME_UNIX_EXTERNAL_UPPER = "unixExternalUpper";
4393
4418
  const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
4394
4419
  const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
4395
4420
  const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
@@ -4442,10 +4467,14 @@
4442
4467
  PROPERTY_NAME_UID,
4443
4468
  PROPERTY_NAME_GID,
4444
4469
  PROPERTY_NAME_UNIX_MODE,
4470
+ PROPERTY_NAME_UNIX_EXTERNAL_UPPER,
4445
4471
  PROPERTY_NAME_SETUID,
4446
4472
  PROPERTY_NAME_SETGID,
4447
4473
  PROPERTY_NAME_STICKY,
4448
4474
  PROPERTY_NAME_BITFLAG,
4475
+ PROPERTY_NAME_RAW_BITFLAG,
4476
+ PROPERTY_NAME_FILENAME_LENGTH,
4477
+ PROPERTY_NAME_EXTRA_FIELD_LENGTH,
4449
4478
  PROPERTY_NAME_FILENAME_UTF8,
4450
4479
  PROPERTY_NAME_COMMENT_UTF8,
4451
4480
  PROPERTY_NAME_RAW_EXTRA_FIELD,
@@ -4507,6 +4536,7 @@
4507
4536
  const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
4508
4537
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
4509
4538
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
4539
+ const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
4510
4540
  const OPTION_CHECK_SIGNATURE = "checkSignature";
4511
4541
  const OPTION_CHECK_CRC32 = "checkCrc32";
4512
4542
  const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
@@ -4638,7 +4668,7 @@
4638
4668
  if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
4639
4669
  throw new Error(ERR_BAD_FORMAT);
4640
4670
  }
4641
- const strictness = getStrictness(getOptionValue$1(zipReader, options, OPTION_STRICTNESS), getOptionValue$1(zipReader, options, OPTION_CHECK_AMBIGUITY));
4671
+ const strictness = getStrictness(options, zipReader.options);
4642
4672
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4643
4673
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
4644
4674
  const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
@@ -4860,6 +4890,7 @@
4860
4890
  index: indexFile,
4861
4891
  versionMadeBy,
4862
4892
  msDosCompatible,
4893
+ zip64: false,
4863
4894
  compressedSize: 0,
4864
4895
  uncompressedSize: 0,
4865
4896
  commentLength,
@@ -5070,9 +5101,12 @@
5070
5101
  extraFieldLength,
5071
5102
  filenameLength
5072
5103
  } = localDirectory;
5073
- const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
5104
+ const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5105
+ const entryStrictness = getStrictness(options, zipEntry.options);
5106
+ const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
5107
+ const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
5074
5108
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
5075
- if (checkAmbiguity && (filenameLength || extraFieldLength)) {
5109
+ if (checkLocalFilename && (filenameLength || extraFieldLength)) {
5076
5110
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
5077
5111
  rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
5078
5112
  localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
@@ -5081,17 +5115,26 @@
5081
5115
  await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
5082
5116
  EMPTY_UINT8_ARRAY;
5083
5117
  }
5118
+ if (checkLocalFilename) {
5119
+ localDirectory.rawFilename = rawLocalFilename;
5120
+ }
5084
5121
  readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
5085
- if (checkAmbiguity) {
5086
- checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename);
5122
+ if (checkLocalDirectory) {
5123
+ validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
5087
5124
  }
5088
- const { lastAccessDate, creationDate } = localDirectory;
5125
+ const { lastAccessDate, creationDate, uid, gid } = localDirectory;
5089
5126
  if (lastAccessDate) {
5090
5127
  fileEntry.lastAccessDate = lastAccessDate;
5091
5128
  }
5092
5129
  if (creationDate) {
5093
5130
  fileEntry.creationDate = creationDate;
5094
5131
  }
5132
+ if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
5133
+ fileEntry.uid = uid;
5134
+ }
5135
+ if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
5136
+ fileEntry.gid = gid;
5137
+ }
5095
5138
  const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
5096
5139
  const zipCrypto = encrypted && !extraFieldAES;
5097
5140
  if (!passThrough) {
@@ -5327,10 +5370,12 @@
5327
5370
  directory.extraFieldNTFS = extraFieldNTFS;
5328
5371
  }
5329
5372
  const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
5373
+ let unixIdsRead;
5330
5374
  if (extraFieldUnix) {
5331
- readExtraFieldUnix(extraFieldUnix, directory, false);
5375
+ unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
5332
5376
  directory.extraFieldUnix = extraFieldUnix;
5333
- } else {
5377
+ }
5378
+ if (!unixIdsRead) {
5334
5379
  const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
5335
5380
  if (extraFieldInfoZip) {
5336
5381
  readExtraFieldUnix(extraFieldInfoZip, directory, true);
@@ -5433,7 +5478,7 @@
5433
5478
  const creationDate = getDateNTFS(rawCreationDate);
5434
5479
  const extraFieldData = { lastModDate, lastAccessDate, creationDate };
5435
5480
  Object.assign(extraFieldNTFS, extraFieldData);
5436
- Object.assign(directory, extraFieldData);
5481
+ Object.assign(directory, extraFieldData, { rawLastAccessDate, rawCreationDate });
5437
5482
  }
5438
5483
  }
5439
5484
 
@@ -5477,6 +5522,7 @@
5477
5522
  if (gid !== UNDEFINED_VALUE) {
5478
5523
  directory.gid = gid;
5479
5524
  }
5525
+ return uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE;
5480
5526
  } catch {
5481
5527
  // ignored
5482
5528
  }
@@ -5549,26 +5595,25 @@
5549
5595
  }
5550
5596
  if (dataDescriptorLength) {
5551
5597
  const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
5552
- const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
5553
- getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5554
- if (dataDescriptorSignature) {
5555
- const readCrc32 = getUint32(getDataView(dataDescriptorArray), 4);
5556
- let readCompressedSize;
5557
- let readUncompressedSize;
5558
- if (extraFieldZip64) {
5559
- readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
5560
- readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
5561
- } else {
5562
- readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
5563
- readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
5564
- }
5565
- const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
5598
+ const dataDescriptorView = getDataView(dataDescriptorArray);
5599
+ let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
5600
+ getUint32(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5601
+ if (signature) {
5602
+ const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
5603
+ const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
5566
5604
  if (matchCrc32 &&
5567
- readCompressedSize == compressedSize &&
5568
- readUncompressedSize == uncompressedSize) {
5605
+ signedDataDescriptor.compressedSize == compressedSize &&
5606
+ signedDataDescriptor.uncompressedSize == uncompressedSize) {
5569
5607
  dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
5608
+ } else {
5609
+ signature = false;
5570
5610
  }
5571
5611
  }
5612
+ if (dataDescriptorArray.length >= dataDescriptorLength) {
5613
+ const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
5614
+ localDataDescriptor.signature = signature;
5615
+ fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
5616
+ }
5572
5617
  }
5573
5618
  const range = {
5574
5619
  start: offset,
@@ -5585,6 +5630,20 @@
5585
5630
  readRanges.set(index, range);
5586
5631
  }
5587
5632
 
5633
+ function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
5634
+ const crc32 = getUint32(dataDescriptorView, offset);
5635
+ let compressedSize;
5636
+ let uncompressedSize;
5637
+ if (extraFieldZip64) {
5638
+ compressedSize = getBigUint64(dataDescriptorView, offset + 4);
5639
+ uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
5640
+ } else {
5641
+ compressedSize = getUint32(dataDescriptorView, offset + 4);
5642
+ uncompressedSize = getUint32(dataDescriptorView, offset + 8);
5643
+ }
5644
+ return { crc32, compressedSize, uncompressedSize };
5645
+ }
5646
+
5588
5647
  function getDiskOffset$1(reader, diskNumber) {
5589
5648
  return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
5590
5649
  }
@@ -5593,14 +5652,40 @@
5593
5652
  return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
5594
5653
  }
5595
5654
 
5596
- function getStrictness(strictness, checkAmbiguity) {
5597
- if (strictness === UNDEFINED_VALUE) {
5598
- return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
5655
+ function getStrictness(options, inheritedOptions) {
5656
+ return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
5657
+ }
5658
+
5659
+ function resolveStrictness(options, inheritedStrictness) {
5660
+ const strictness = options[OPTION_STRICTNESS];
5661
+ if (strictness !== UNDEFINED_VALUE) {
5662
+ if (!isStrictnessValue(strictness)) {
5663
+ throw new Error(ERR_INVALID_STRICTNESS);
5664
+ }
5665
+ return strictness;
5666
+ }
5667
+ const checkAmbiguity = options[OPTION_CHECK_AMBIGUITY];
5668
+ if (checkAmbiguity === UNDEFINED_VALUE) {
5669
+ return inheritedStrictness;
5670
+ }
5671
+ if (checkAmbiguity) {
5672
+ return STRICTNESS_STRICT;
5673
+ }
5674
+ return inheritedStrictness == STRICTNESS_TOLERANT ? STRICTNESS_TOLERANT : STRICTNESS_BALANCED;
5675
+ }
5676
+
5677
+ function getCheckLocalDirectory(checkLocalDirectory, strictness) {
5678
+ if (checkLocalDirectory === UNDEFINED_VALUE) {
5679
+ return strictness != STRICTNESS_TOLERANT;
5599
5680
  }
5600
- if (!isStrictnessValue(strictness)) {
5601
- throw new Error(ERR_INVALID_STRICTNESS);
5681
+ return Boolean(checkLocalDirectory);
5682
+ }
5683
+
5684
+ function getCheckLocalFilename(checkLocalFilename, strictness) {
5685
+ if (checkLocalFilename === UNDEFINED_VALUE) {
5686
+ return strictness == STRICTNESS_STRICT;
5602
5687
  }
5603
- return strictness;
5688
+ return Boolean(checkLocalFilename);
5604
5689
  }
5605
5690
 
5606
5691
  function getFilenameValidation(filenameValidation, strictness) {
@@ -5748,10 +5833,11 @@
5748
5833
  return UNDEFINED_VALUE;
5749
5834
  }
5750
5835
 
5751
- function checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename) {
5836
+ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
5752
5837
  const { rawFilename } = zipEntry;
5753
- if (rawLocalFilename.length != rawFilename.length ||
5754
- rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte])) {
5838
+ if (checkLocalFilename &&
5839
+ (rawLocalFilename.length != rawFilename.length ||
5840
+ rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
5755
5841
  throwAmbiguousArchive("mismatched local file header (filename)");
5756
5842
  }
5757
5843
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
@@ -5869,6 +5955,7 @@
5869
5955
 
5870
5956
  const ERR_DUPLICATED_NAME = "File already exists";
5871
5957
  const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
5958
+ const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
5872
5959
  const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
5873
5960
  const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
5874
5961
  const ERR_INVALID_VERSION = "Version exceeds 65535";
@@ -5937,6 +6024,10 @@
5937
6024
  }
5938
6025
  reader = new GenericReader(reader);
5939
6026
  await initStream(reader);
6027
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
6028
+ reader = new BlobReader(await streamToBlob(reader.readable));
6029
+ await initStream(reader);
6030
+ }
5940
6031
  const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
5941
6032
  const zipReader$1 = new ZipReader(reader.readable);
5942
6033
  const entries = await zipReader$1.getEntries();
@@ -6085,6 +6176,9 @@
6085
6176
  const zipWriter = this;
6086
6177
  const { pendingAddFileCalls, writer } = this;
6087
6178
  const { writable } = writer;
6179
+ if (!(comment instanceof Uint8Array)) {
6180
+ throw new Error(ERR_INVALID_COMMENT_TYPE);
6181
+ }
6088
6182
  if (getLength(comment) > MAX_16_BITS) {
6089
6183
  throw new Error(ERR_INVALID_COMMENT);
6090
6184
  }
@@ -6181,8 +6275,6 @@
6181
6275
  const diskOffset = getDiskOffset(zipWriter.writer);
6182
6276
  const diskNumber = getDiskNumber(zipWriter.writer);
6183
6277
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
6184
- internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
6185
- externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
6186
6278
  signature: options[PROPERTY_NAME_SIGNATURE],
6187
6279
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6188
6280
  offset: zipWriter.offset - diskOffset,
@@ -6196,14 +6288,20 @@
6196
6288
  zipWriter.files.delete(name);
6197
6289
  throw error;
6198
6290
  }
6199
- Object.assign(fileEntry, { name, comment, extraField });
6291
+ Object.assign(fileEntry, {
6292
+ name,
6293
+ comment,
6294
+ extraField,
6295
+ [PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
6296
+ [PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
6297
+ });
6200
6298
  return new Entry(fileEntry);
6201
6299
  }
6202
6300
 
6203
6301
  function resolveAttributes(zipWriter, name, options) {
6204
6302
  name = name.trim();
6205
6303
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6206
- let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
6304
+ let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
6207
6305
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
6208
6306
  const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
6209
6307
  const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
@@ -6237,7 +6335,7 @@
6237
6335
  const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
6238
6336
  if (hasUnixMetadata) {
6239
6337
  msDosCompatible = false;
6240
- versionMadeBy = (versionMadeBy & MAX_16_BITS) | (3 << 8);
6338
+ versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
6241
6339
  } else if (hasMsDosProvided) {
6242
6340
  msDosCompatible = true;
6243
6341
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
@@ -6277,11 +6375,10 @@
6277
6375
  externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
6278
6376
  }
6279
6377
  }
6280
- let unixExternalUpper;
6281
6378
  if (!msDosCompatible) {
6282
6379
  const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
6283
- unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
6284
- unixMode = unixMode === UNDEFINED_VALUE ? unixExternalUpper : (unixMode & MAX_16_BITS);
6380
+ const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
6381
+ unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
6285
6382
  if (setuid) {
6286
6383
  unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
6287
6384
  } else {
@@ -6310,17 +6407,20 @@
6310
6407
  if (hasMsDosProvided) {
6311
6408
  externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
6312
6409
  }
6410
+ const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
6411
+ const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
6313
6412
  return {
6314
6413
  name,
6315
6414
  resolvedOptions: {
6316
6415
  versionMadeBy,
6317
- msDosCompatible,
6416
+ msDosCompatible: Boolean(msDosCompatible),
6318
6417
  externalFileAttributes,
6319
6418
  unixExternalUpper,
6320
6419
  uid,
6321
6420
  gid,
6322
6421
  unixMode,
6323
6422
  unixExtraFieldType,
6423
+ symlink,
6324
6424
  setuid,
6325
6425
  setgid,
6326
6426
  sticky,
@@ -6762,6 +6862,7 @@
6762
6862
  uid,
6763
6863
  gid,
6764
6864
  unixMode,
6865
+ symlink,
6765
6866
  setuid,
6766
6867
  setgid,
6767
6868
  sticky,
@@ -6798,6 +6899,7 @@
6798
6899
  uid,
6799
6900
  gid,
6800
6901
  unixMode,
6902
+ symlink: Boolean(symlink),
6801
6903
  setuid,
6802
6904
  setgid,
6803
6905
  sticky,
@@ -6878,8 +6980,8 @@
6878
6980
  rawLastModDate,
6879
6981
  creationDate,
6880
6982
  lastAccessDate,
6881
- encrypted,
6882
- zipCrypto,
6983
+ encrypted: Boolean(encrypted),
6984
+ zipCrypto: Boolean(zipCrypto),
6883
6985
  size: metadataSize + compressedSize,
6884
6986
  compressionMethod,
6885
6987
  version,
@@ -8666,6 +8768,7 @@
8666
8768
  exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
8667
8769
  exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
8668
8770
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
8771
+ exports.ERR_INVALID_COMMENT_TYPE = ERR_INVALID_COMMENT_TYPE;
8669
8772
  exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
8670
8773
  exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
8671
8774
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;