@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-fs.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();
@@ -4055,9 +4067,8 @@
4055
4067
 
4056
4068
  async init() {
4057
4069
  const reader = this;
4058
- const { readers } = reader;
4059
4070
  reader.lastDiskNumber = 0;
4060
- await Promise.all(readers.map(diskReader => initStream(diskReader)));
4071
+ const readers = reader.readers = await Promise.all(reader.readers.map(initDiskReader));
4061
4072
  reader.diskOffsets = readers.map(diskReader => {
4062
4073
  const diskOffset = reader.size;
4063
4074
  reader.size += diskReader.size;
@@ -4252,6 +4263,16 @@
4252
4263
  }
4253
4264
  }
4254
4265
 
4266
+ async function initDiskReader(diskReader) {
4267
+ diskReader = new GenericReader(diskReader);
4268
+ await initStream(diskReader);
4269
+ if (diskReader.size === UNDEFINED_VALUE || !diskReader.readUint8Array) {
4270
+ diskReader = new BlobReader(await streamToBlob(diskReader.readable));
4271
+ await initStream(diskReader);
4272
+ }
4273
+ return diskReader;
4274
+ }
4275
+
4255
4276
  function readUint8Array(reader, offset, size) {
4256
4277
  return reader.readUint8Array(offset, size);
4257
4278
  }
@@ -4410,6 +4431,10 @@
4410
4431
  const PROPERTY_NAME_SETGID = "setgid";
4411
4432
  const PROPERTY_NAME_STICKY = "sticky";
4412
4433
  const PROPERTY_NAME_BITFLAG = "bitFlag";
4434
+ const PROPERTY_NAME_RAW_BITFLAG = "rawBitFlag";
4435
+ const PROPERTY_NAME_FILENAME_LENGTH = "filenameLength";
4436
+ const PROPERTY_NAME_EXTRA_FIELD_LENGTH = "extraFieldLength";
4437
+ const PROPERTY_NAME_UNIX_EXTERNAL_UPPER = "unixExternalUpper";
4413
4438
  const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
4414
4439
  const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
4415
4440
  const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
@@ -4462,10 +4487,14 @@
4462
4487
  PROPERTY_NAME_UID,
4463
4488
  PROPERTY_NAME_GID,
4464
4489
  PROPERTY_NAME_UNIX_MODE,
4490
+ PROPERTY_NAME_UNIX_EXTERNAL_UPPER,
4465
4491
  PROPERTY_NAME_SETUID,
4466
4492
  PROPERTY_NAME_SETGID,
4467
4493
  PROPERTY_NAME_STICKY,
4468
4494
  PROPERTY_NAME_BITFLAG,
4495
+ PROPERTY_NAME_RAW_BITFLAG,
4496
+ PROPERTY_NAME_FILENAME_LENGTH,
4497
+ PROPERTY_NAME_EXTRA_FIELD_LENGTH,
4469
4498
  PROPERTY_NAME_FILENAME_UTF8,
4470
4499
  PROPERTY_NAME_COMMENT_UTF8,
4471
4500
  PROPERTY_NAME_RAW_EXTRA_FIELD,
@@ -4527,6 +4556,7 @@
4527
4556
  const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
4528
4557
  const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
4529
4558
  const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
4559
+ const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
4530
4560
  const OPTION_CHECK_SIGNATURE = "checkSignature";
4531
4561
  const OPTION_CHECK_CRC32 = "checkCrc32";
4532
4562
  const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
@@ -4658,7 +4688,7 @@
4658
4688
  if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
4659
4689
  throw new Error(ERR_BAD_FORMAT);
4660
4690
  }
4661
- const strictness = getStrictness(getOptionValue$1(zipReader, options, OPTION_STRICTNESS), getOptionValue$1(zipReader, options, OPTION_CHECK_AMBIGUITY));
4691
+ const strictness = getStrictness(options, zipReader.options);
4662
4692
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4663
4693
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
4664
4694
  const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
@@ -4880,6 +4910,7 @@
4880
4910
  index: indexFile,
4881
4911
  versionMadeBy,
4882
4912
  msDosCompatible,
4913
+ zip64: false,
4883
4914
  compressedSize: 0,
4884
4915
  uncompressedSize: 0,
4885
4916
  commentLength,
@@ -5090,9 +5121,12 @@
5090
5121
  extraFieldLength,
5091
5122
  filenameLength
5092
5123
  } = localDirectory;
5093
- const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
5124
+ const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5125
+ const entryStrictness = getStrictness(options, zipEntry.options);
5126
+ const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
5127
+ const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
5094
5128
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
5095
- if (checkAmbiguity && (filenameLength || extraFieldLength)) {
5129
+ if (checkLocalFilename && (filenameLength || extraFieldLength)) {
5096
5130
  const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
5097
5131
  rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
5098
5132
  localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
@@ -5101,17 +5135,26 @@
5101
5135
  await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
5102
5136
  EMPTY_UINT8_ARRAY;
5103
5137
  }
5138
+ if (checkLocalFilename) {
5139
+ localDirectory.rawFilename = rawLocalFilename;
5140
+ }
5104
5141
  readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
5105
- if (checkAmbiguity) {
5106
- checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename);
5142
+ if (checkLocalDirectory) {
5143
+ validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
5107
5144
  }
5108
- const { lastAccessDate, creationDate } = localDirectory;
5145
+ const { lastAccessDate, creationDate, uid, gid } = localDirectory;
5109
5146
  if (lastAccessDate) {
5110
5147
  fileEntry.lastAccessDate = lastAccessDate;
5111
5148
  }
5112
5149
  if (creationDate) {
5113
5150
  fileEntry.creationDate = creationDate;
5114
5151
  }
5152
+ if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
5153
+ fileEntry.uid = uid;
5154
+ }
5155
+ if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
5156
+ fileEntry.gid = gid;
5157
+ }
5115
5158
  const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
5116
5159
  const zipCrypto = encrypted && !extraFieldAES;
5117
5160
  if (!passThrough) {
@@ -5347,10 +5390,12 @@
5347
5390
  directory.extraFieldNTFS = extraFieldNTFS;
5348
5391
  }
5349
5392
  const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
5393
+ let unixIdsRead;
5350
5394
  if (extraFieldUnix) {
5351
- readExtraFieldUnix(extraFieldUnix, directory, false);
5395
+ unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
5352
5396
  directory.extraFieldUnix = extraFieldUnix;
5353
- } else {
5397
+ }
5398
+ if (!unixIdsRead) {
5354
5399
  const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
5355
5400
  if (extraFieldInfoZip) {
5356
5401
  readExtraFieldUnix(extraFieldInfoZip, directory, true);
@@ -5453,7 +5498,7 @@
5453
5498
  const creationDate = getDateNTFS(rawCreationDate);
5454
5499
  const extraFieldData = { lastModDate, lastAccessDate, creationDate };
5455
5500
  Object.assign(extraFieldNTFS, extraFieldData);
5456
- Object.assign(directory, extraFieldData);
5501
+ Object.assign(directory, extraFieldData, { rawLastAccessDate, rawCreationDate });
5457
5502
  }
5458
5503
  }
5459
5504
 
@@ -5497,6 +5542,7 @@
5497
5542
  if (gid !== UNDEFINED_VALUE) {
5498
5543
  directory.gid = gid;
5499
5544
  }
5545
+ return uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE;
5500
5546
  } catch {
5501
5547
  // ignored
5502
5548
  }
@@ -5569,26 +5615,25 @@
5569
5615
  }
5570
5616
  if (dataDescriptorLength) {
5571
5617
  const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
5572
- const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
5573
- getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5574
- if (dataDescriptorSignature) {
5575
- const readCrc32 = getUint32(getDataView(dataDescriptorArray), 4);
5576
- let readCompressedSize;
5577
- let readUncompressedSize;
5578
- if (extraFieldZip64) {
5579
- readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
5580
- readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
5581
- } else {
5582
- readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
5583
- readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
5584
- }
5585
- const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
5618
+ const dataDescriptorView = getDataView(dataDescriptorArray);
5619
+ let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
5620
+ getUint32(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
5621
+ if (signature) {
5622
+ const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
5623
+ const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
5586
5624
  if (matchCrc32 &&
5587
- readCompressedSize == compressedSize &&
5588
- readUncompressedSize == uncompressedSize) {
5625
+ signedDataDescriptor.compressedSize == compressedSize &&
5626
+ signedDataDescriptor.uncompressedSize == uncompressedSize) {
5589
5627
  dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
5628
+ } else {
5629
+ signature = false;
5590
5630
  }
5591
5631
  }
5632
+ if (dataDescriptorArray.length >= dataDescriptorLength) {
5633
+ const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
5634
+ localDataDescriptor.signature = signature;
5635
+ fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
5636
+ }
5592
5637
  }
5593
5638
  const range = {
5594
5639
  start: offset,
@@ -5605,6 +5650,20 @@
5605
5650
  readRanges.set(index, range);
5606
5651
  }
5607
5652
 
5653
+ function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
5654
+ const crc32 = getUint32(dataDescriptorView, offset);
5655
+ let compressedSize;
5656
+ let uncompressedSize;
5657
+ if (extraFieldZip64) {
5658
+ compressedSize = getBigUint64(dataDescriptorView, offset + 4);
5659
+ uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
5660
+ } else {
5661
+ compressedSize = getUint32(dataDescriptorView, offset + 4);
5662
+ uncompressedSize = getUint32(dataDescriptorView, offset + 8);
5663
+ }
5664
+ return { crc32, compressedSize, uncompressedSize };
5665
+ }
5666
+
5608
5667
  function getDiskOffset$1(reader, diskNumber) {
5609
5668
  return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
5610
5669
  }
@@ -5613,14 +5672,40 @@
5613
5672
  return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
5614
5673
  }
5615
5674
 
5616
- function getStrictness(strictness, checkAmbiguity) {
5617
- if (strictness === UNDEFINED_VALUE) {
5618
- return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
5675
+ function getStrictness(options, inheritedOptions) {
5676
+ return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
5677
+ }
5678
+
5679
+ function resolveStrictness(options, inheritedStrictness) {
5680
+ const strictness = options[OPTION_STRICTNESS];
5681
+ if (strictness !== UNDEFINED_VALUE) {
5682
+ if (!isStrictnessValue(strictness)) {
5683
+ throw new Error(ERR_INVALID_STRICTNESS);
5684
+ }
5685
+ return strictness;
5686
+ }
5687
+ const checkAmbiguity = options[OPTION_CHECK_AMBIGUITY];
5688
+ if (checkAmbiguity === UNDEFINED_VALUE) {
5689
+ return inheritedStrictness;
5690
+ }
5691
+ if (checkAmbiguity) {
5692
+ return STRICTNESS_STRICT;
5693
+ }
5694
+ return inheritedStrictness == STRICTNESS_TOLERANT ? STRICTNESS_TOLERANT : STRICTNESS_BALANCED;
5695
+ }
5696
+
5697
+ function getCheckLocalDirectory(checkLocalDirectory, strictness) {
5698
+ if (checkLocalDirectory === UNDEFINED_VALUE) {
5699
+ return strictness != STRICTNESS_TOLERANT;
5619
5700
  }
5620
- if (!isStrictnessValue(strictness)) {
5621
- throw new Error(ERR_INVALID_STRICTNESS);
5701
+ return Boolean(checkLocalDirectory);
5702
+ }
5703
+
5704
+ function getCheckLocalFilename(checkLocalFilename, strictness) {
5705
+ if (checkLocalFilename === UNDEFINED_VALUE) {
5706
+ return strictness == STRICTNESS_STRICT;
5622
5707
  }
5623
- return strictness;
5708
+ return Boolean(checkLocalFilename);
5624
5709
  }
5625
5710
 
5626
5711
  function getFilenameValidation(filenameValidation, strictness) {
@@ -5768,10 +5853,11 @@
5768
5853
  return UNDEFINED_VALUE;
5769
5854
  }
5770
5855
 
5771
- function checkLocalDirectory(zipEntry, localDirectory, rawLocalFilename) {
5856
+ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
5772
5857
  const { rawFilename } = zipEntry;
5773
- if (rawLocalFilename.length != rawFilename.length ||
5774
- rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte])) {
5858
+ if (checkLocalFilename &&
5859
+ (rawLocalFilename.length != rawFilename.length ||
5860
+ rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
5775
5861
  throwAmbiguousArchive("mismatched local file header (filename)");
5776
5862
  }
5777
5863
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
@@ -5889,6 +5975,7 @@
5889
5975
 
5890
5976
  const ERR_DUPLICATED_NAME = "File already exists";
5891
5977
  const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
5978
+ const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
5892
5979
  const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
5893
5980
  const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
5894
5981
  const ERR_INVALID_VERSION = "Version exceeds 65535";
@@ -5957,6 +6044,10 @@
5957
6044
  }
5958
6045
  reader = new GenericReader(reader);
5959
6046
  await initStream(reader);
6047
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
6048
+ reader = new BlobReader(await streamToBlob(reader.readable));
6049
+ await initStream(reader);
6050
+ }
5960
6051
  const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
5961
6052
  const zipReader$1 = new ZipReader(reader.readable);
5962
6053
  const entries = await zipReader$1.getEntries();
@@ -6105,6 +6196,9 @@
6105
6196
  const zipWriter = this;
6106
6197
  const { pendingAddFileCalls, writer } = this;
6107
6198
  const { writable } = writer;
6199
+ if (!(comment instanceof Uint8Array)) {
6200
+ throw new Error(ERR_INVALID_COMMENT_TYPE);
6201
+ }
6108
6202
  if (getLength(comment) > MAX_16_BITS) {
6109
6203
  throw new Error(ERR_INVALID_COMMENT);
6110
6204
  }
@@ -6201,8 +6295,6 @@
6201
6295
  const diskOffset = getDiskOffset(zipWriter.writer);
6202
6296
  const diskNumber = getDiskNumber(zipWriter.writer);
6203
6297
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
6204
- internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
6205
- externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
6206
6298
  signature: options[PROPERTY_NAME_SIGNATURE],
6207
6299
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
6208
6300
  offset: zipWriter.offset - diskOffset,
@@ -6216,14 +6308,20 @@
6216
6308
  zipWriter.files.delete(name);
6217
6309
  throw error;
6218
6310
  }
6219
- Object.assign(fileEntry, { name, comment, extraField });
6311
+ Object.assign(fileEntry, {
6312
+ name,
6313
+ comment,
6314
+ extraField,
6315
+ [PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
6316
+ [PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
6317
+ });
6220
6318
  return new Entry(fileEntry);
6221
6319
  }
6222
6320
 
6223
6321
  function resolveAttributes(zipWriter, name, options) {
6224
6322
  name = name.trim();
6225
6323
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6226
- let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
6324
+ let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
6227
6325
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
6228
6326
  const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
6229
6327
  const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
@@ -6257,7 +6355,7 @@
6257
6355
  const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
6258
6356
  if (hasUnixMetadata) {
6259
6357
  msDosCompatible = false;
6260
- versionMadeBy = (versionMadeBy & MAX_16_BITS) | (3 << 8);
6358
+ versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
6261
6359
  } else if (hasMsDosProvided) {
6262
6360
  msDosCompatible = true;
6263
6361
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
@@ -6297,11 +6395,10 @@
6297
6395
  externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
6298
6396
  }
6299
6397
  }
6300
- let unixExternalUpper;
6301
6398
  if (!msDosCompatible) {
6302
6399
  const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
6303
- unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
6304
- unixMode = unixMode === UNDEFINED_VALUE ? unixExternalUpper : (unixMode & MAX_16_BITS);
6400
+ const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
6401
+ unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
6305
6402
  if (setuid) {
6306
6403
  unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
6307
6404
  } else {
@@ -6330,17 +6427,20 @@
6330
6427
  if (hasMsDosProvided) {
6331
6428
  externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
6332
6429
  }
6430
+ const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
6431
+ const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
6333
6432
  return {
6334
6433
  name,
6335
6434
  resolvedOptions: {
6336
6435
  versionMadeBy,
6337
- msDosCompatible,
6436
+ msDosCompatible: Boolean(msDosCompatible),
6338
6437
  externalFileAttributes,
6339
6438
  unixExternalUpper,
6340
6439
  uid,
6341
6440
  gid,
6342
6441
  unixMode,
6343
6442
  unixExtraFieldType,
6443
+ symlink,
6344
6444
  setuid,
6345
6445
  setgid,
6346
6446
  sticky,
@@ -6573,6 +6673,9 @@
6573
6673
  if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
6574
6674
  throw new Error(ERR_UNDETERMINED_SIZE);
6575
6675
  }
6676
+ if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
6677
+ throw new Error(ERR_INVALID_COMMENT_TYPE);
6678
+ }
6576
6679
  const commentLength = getLength(comment);
6577
6680
  if (commentLength > MAX_16_BITS) {
6578
6681
  throw new Error(ERR_INVALID_COMMENT);
@@ -6854,6 +6957,7 @@
6854
6957
  uid,
6855
6958
  gid,
6856
6959
  unixMode,
6960
+ symlink,
6857
6961
  setuid,
6858
6962
  setgid,
6859
6963
  sticky,
@@ -6890,6 +6994,7 @@
6890
6994
  uid,
6891
6995
  gid,
6892
6996
  unixMode,
6997
+ symlink: Boolean(symlink),
6893
6998
  setuid,
6894
6999
  setgid,
6895
7000
  sticky,
@@ -6970,8 +7075,8 @@
6970
7075
  rawLastModDate,
6971
7076
  creationDate,
6972
7077
  lastAccessDate,
6973
- encrypted,
6974
- zipCrypto,
7078
+ encrypted: Boolean(encrypted),
7079
+ zipCrypto: Boolean(zipCrypto),
6975
7080
  size: metadataSize + compressedSize,
6976
7081
  compressionMethod,
6977
7082
  version,
@@ -10113,6 +10218,7 @@
10113
10218
  exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
10114
10219
  exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
10115
10220
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
10221
+ exports.ERR_INVALID_COMMENT_TYPE = ERR_INVALID_COMMENT_TYPE;
10116
10222
  exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
10117
10223
  exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
10118
10224
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;