@zip.js/zip.js 2.6.59 → 2.6.61

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
@@ -3311,12 +3311,9 @@
3311
3311
  const commentOffset = endOfDirectoryInfo.offset;
3312
3312
  const commentLength = getUint16(endOfDirectoryView, 20);
3313
3313
  const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
3314
- const lastDiskNumber = getUint16(endOfDirectoryView, 4);
3314
+ let lastDiskNumber = getUint16(endOfDirectoryView, 4);
3315
3315
  const expectedLastDiskNumber = reader.lastDiskNumber || 0;
3316
3316
  let diskNumber = getUint16(endOfDirectoryView, 6);
3317
- if (expectedLastDiskNumber != lastDiskNumber) {
3318
- throw new Error(ERR_SPLIT_ZIP_FILE);
3319
- }
3320
3317
  let filesLength = getUint16(endOfDirectoryView, 8);
3321
3318
  let prependedDataLength = 0;
3322
3319
  let startOffset = 0;
@@ -3340,8 +3337,11 @@
3340
3337
  if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
3341
3338
  throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
3342
3339
  }
3340
+ if (lastDiskNumber == MAX_16_BITS) {
3341
+ lastDiskNumber = getUint32(endOfDirectoryView, 16);
3342
+ }
3343
3343
  if (diskNumber == MAX_16_BITS) {
3344
- diskNumber = getUint32(endOfDirectoryView, 16);
3344
+ diskNumber = getUint32(endOfDirectoryView, 20);
3345
3345
  }
3346
3346
  if (filesLength == MAX_16_BITS) {
3347
3347
  filesLength = getBigUint64(endOfDirectoryView, 32);
@@ -3351,6 +3351,9 @@
3351
3351
  }
3352
3352
  directoryDataOffset -= directoryDataLength;
3353
3353
  }
3354
+ if (expectedLastDiskNumber != lastDiskNumber) {
3355
+ throw new Error(ERR_SPLIT_ZIP_FILE);
3356
+ }
3354
3357
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
3355
3358
  throw new Error(ERR_BAD_FORMAT);
3356
3359
  }
@@ -3847,7 +3850,6 @@
3847
3850
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
3848
3851
 
3849
3852
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
3850
- const EXTRAFIELD_LENGTH_ZIP64 = 28;
3851
3853
 
3852
3854
  let workers = 0;
3853
3855
  const pendingEntries = [];
@@ -3990,6 +3992,7 @@
3990
3992
  let maximumCompressedSize = 0;
3991
3993
  let maximumEntrySize = 0;
3992
3994
  let uncompressedSize = 0;
3995
+ const zip64Enabled = zip64 === true;
3993
3996
  if (reader) {
3994
3997
  reader = initReader(reader);
3995
3998
  await initStream(reader);
@@ -4005,10 +4008,12 @@
4005
4008
  }
4006
4009
  }
4007
4010
  const { diskOffset, diskNumber, maxSize } = zipWriter.writer;
4008
- if (zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset >= MAX_32_BITS ||
4009
- uncompressedSize >= MAX_32_BITS ||
4010
- maximumCompressedSize >= MAX_32_BITS ||
4011
- diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) >= MAX_16_BITS) {
4011
+ const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
4012
+ const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
4013
+ const zip64Offset = zip64Enabled || zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset >= MAX_32_BITS;
4014
+ const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
4015
+ const zip64DiskNumberStart = (supportZip64SplitFile && zip64Enabled) || diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) >= MAX_16_BITS;
4016
+ if (zip64Offset || zip64UncompressedSize || zip64CompressedSize || zip64DiskNumberStart) {
4012
4017
  if (zip64 === false || !keepOrder) {
4013
4018
  throw new Error(ERR_UNSUPPORTED_FORMAT);
4014
4019
  } else {
@@ -4026,6 +4031,10 @@
4026
4031
  creationDate,
4027
4032
  rawExtraField,
4028
4033
  zip64,
4034
+ zip64UncompressedSize,
4035
+ zip64CompressedSize,
4036
+ zip64Offset,
4037
+ zip64DiskNumberStart,
4029
4038
  password,
4030
4039
  level,
4031
4040
  useWebWorkers,
@@ -4084,7 +4093,7 @@
4084
4093
  lockPreviousFileEntry = previousFileEntry && previousFileEntry.lock;
4085
4094
  requestLockCurrentFileEntry();
4086
4095
  }
4087
- if (options.bufferedWrite || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
4096
+ if (options.bufferedWrite || zipWriter.writerLocked || (zipWriter.bufferedWrites && keepOrder) || !dataDescriptor) {
4088
4097
  fileWriter = new BlobWriter();
4089
4098
  fileWriter.writable.size = 0;
4090
4099
  bufferedWrite = true;
@@ -4092,7 +4101,7 @@
4092
4101
  await initStream(writer);
4093
4102
  } else {
4094
4103
  fileWriter = writer;
4095
- requestLockWriter();
4104
+ await requestLockWriter();
4096
4105
  }
4097
4106
  await initStream(fileWriter);
4098
4107
  const { writable } = writer;
@@ -4123,7 +4132,7 @@
4123
4132
  await requestLockWriter();
4124
4133
  writingBufferedEntryData = true;
4125
4134
  if (!dataDescriptor) {
4126
- blob = await writeMissingHeaderInfo(fileEntry, blob, writable, options);
4135
+ blob = await writeExtraHeaderInfo(fileEntry, blob, writable, options);
4127
4136
  }
4128
4137
  await skipDiskIfNeeded(writable);
4129
4138
  fileEntry.diskNumberStart = writer.diskNumber;
@@ -4134,7 +4143,7 @@
4134
4143
  }
4135
4144
  fileEntry.offset = zipWriter.offset - diskOffset;
4136
4145
  if (fileEntry.zip64) {
4137
- setZip64OffsetInfo(fileEntry);
4146
+ setZip64ExtraInfo(fileEntry, options);
4138
4147
  } else if (fileEntry.offset >= MAX_32_BITS) {
4139
4148
  throw new Error(ERR_UNSUPPORTED_FORMAT);
4140
4149
  }
@@ -4172,7 +4181,7 @@
4172
4181
 
4173
4182
  async function requestLockWriter() {
4174
4183
  zipWriter.writerLocked = true;
4175
- const { lockWriter } = zipWriter;
4184
+ const { lockWriter } = zipWriter;
4176
4185
  zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
4177
4186
  zipWriter.writerLocked = false;
4178
4187
  resolve();
@@ -4214,6 +4223,10 @@
4214
4223
  password,
4215
4224
  level,
4216
4225
  zip64,
4226
+ zip64UncompressedSize,
4227
+ zip64CompressedSize,
4228
+ zip64Offset,
4229
+ zip64DiskNumberStart,
4217
4230
  zipCrypto,
4218
4231
  dataDescriptor,
4219
4232
  directory,
@@ -4286,7 +4299,25 @@
4286
4299
  } else {
4287
4300
  await writeData(writable, localHeaderArray);
4288
4301
  }
4289
- const rawExtraFieldZip64 = zip64 ? new Uint8Array(EXTRAFIELD_LENGTH_ZIP64 + 4) : new Uint8Array();
4302
+ let rawExtraFieldZip64;
4303
+ if (zip64) {
4304
+ let rawExtraFieldZip64Length = 4;
4305
+ if (zip64UncompressedSize) {
4306
+ rawExtraFieldZip64Length += 8;
4307
+ }
4308
+ if (zip64CompressedSize) {
4309
+ rawExtraFieldZip64Length += 8;
4310
+ }
4311
+ if (zip64Offset) {
4312
+ rawExtraFieldZip64Length += 8;
4313
+ }
4314
+ if (zip64DiskNumberStart) {
4315
+ rawExtraFieldZip64Length += 4;
4316
+ }
4317
+ rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length);
4318
+ } else {
4319
+ rawExtraFieldZip64 = new Uint8Array();
4320
+ }
4290
4321
  if (reader) {
4291
4322
  setEntryInfo({
4292
4323
  signature,
@@ -4301,6 +4332,7 @@
4301
4332
  await writeData(writable, dataDescriptorArray);
4302
4333
  }
4303
4334
  Object.assign(fileEntry, {
4335
+ uncompressedSize,
4304
4336
  compressedSize,
4305
4337
  lastModDate,
4306
4338
  rawLastModDate,
@@ -4312,7 +4344,11 @@
4312
4344
  version,
4313
4345
  headerArray,
4314
4346
  signature,
4315
- rawExtraFieldZip64
4347
+ rawExtraFieldZip64,
4348
+ zip64UncompressedSize,
4349
+ zip64CompressedSize,
4350
+ zip64Offset,
4351
+ zip64DiskNumberStart
4316
4352
  });
4317
4353
  return fileEntry;
4318
4354
  }
@@ -4489,6 +4525,8 @@
4489
4525
  } = dataDescriptorInfo;
4490
4526
  const {
4491
4527
  zip64,
4528
+ zip64UncompressedSize,
4529
+ zip64CompressedSize,
4492
4530
  zipCrypto,
4493
4531
  dataDescriptor
4494
4532
  } = options;
@@ -4501,11 +4539,17 @@
4501
4539
  if (zip64) {
4502
4540
  const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
4503
4541
  setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
4504
- setUint16(rawExtraFieldZip64View, 2, EXTRAFIELD_LENGTH_ZIP64);
4505
- setUint32(headerView, 14, MAX_32_BITS);
4506
- setBigUint64(rawExtraFieldZip64View, 12, BigInt(compressedSize));
4507
- setUint32(headerView, 18, MAX_32_BITS);
4508
- setBigUint64(rawExtraFieldZip64View, 4, BigInt(uncompressedSize));
4542
+ setUint16(rawExtraFieldZip64View, 2, rawExtraFieldZip64.length - 4);
4543
+ let rawExtraFieldZip64Offset = 4;
4544
+ if (zip64UncompressedSize) {
4545
+ setUint32(headerView, 18, MAX_32_BITS);
4546
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
4547
+ rawExtraFieldZip64Offset += 8;
4548
+ }
4549
+ if (zip64CompressedSize) {
4550
+ setUint32(headerView, 14, MAX_32_BITS);
4551
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
4552
+ }
4509
4553
  if (dataDescriptor) {
4510
4554
  setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
4511
4555
  setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
@@ -4520,7 +4564,7 @@
4520
4564
  }
4521
4565
  }
4522
4566
 
4523
- async function writeMissingHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
4567
+ async function writeExtraHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
4524
4568
  const arrayBuffer = await sliceAsArrayBuffer(entryData, 0, 26);
4525
4569
  const arrayBufferView = new DataView(arrayBuffer);
4526
4570
  if (!fileEntry.encrypted || zipCrypto) {
@@ -4537,11 +4581,24 @@
4537
4581
  return entryData.slice(arrayBuffer.byteLength);
4538
4582
  }
4539
4583
 
4540
- function setZip64OffsetInfo(fileEntry) {
4584
+ function setZip64ExtraInfo(fileEntry, options) {
4541
4585
  const { rawExtraFieldZip64, offset, diskNumberStart } = fileEntry;
4586
+ const { zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart } = options;
4542
4587
  const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
4543
- setBigUint64(rawExtraFieldZip64View, 20, BigInt(offset));
4544
- setUint32(rawExtraFieldZip64View, 28, diskNumberStart);
4588
+ let rawExtraFieldZip64Offset = 4;
4589
+ if (zip64UncompressedSize) {
4590
+ rawExtraFieldZip64Offset += 8;
4591
+ }
4592
+ if (zip64CompressedSize) {
4593
+ rawExtraFieldZip64Offset += 8;
4594
+ }
4595
+ if (zip64Offset) {
4596
+ setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
4597
+ rawExtraFieldZip64Offset += 8;
4598
+ }
4599
+ if (zip64DiskNumberStart) {
4600
+ setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
4601
+ }
4545
4602
  }
4546
4603
 
4547
4604
  async function closeFile(zipWriter, comment, options) {
@@ -4588,12 +4645,18 @@
4588
4645
  headerArray,
4589
4646
  directory,
4590
4647
  zip64,
4648
+ zip64UncompressedSize,
4649
+ zip64CompressedSize,
4650
+ zip64DiskNumberStart,
4651
+ zip64Offset,
4591
4652
  msDosCompatible,
4592
4653
  internalFileAttribute,
4593
4654
  externalFileAttribute,
4594
4655
  extendedTimestamp,
4595
4656
  lastModDate,
4596
- diskNumberStart
4657
+ diskNumberStart,
4658
+ uncompressedSize,
4659
+ compressedSize
4597
4660
  } = fileEntry;
4598
4661
  let rawExtraFieldExtendedTimestamp;
4599
4662
  if (extendedTimestamp) {
@@ -4609,17 +4672,24 @@
4609
4672
  const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
4610
4673
  setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
4611
4674
  setUint16(directoryView, offset + 4, versionMadeBy);
4675
+ const headerView = getDataView(headerArray);
4676
+ if (!zip64UncompressedSize) {
4677
+ setUint32(headerView, 18, uncompressedSize);
4678
+ }
4679
+ if (!zip64CompressedSize) {
4680
+ setUint32(headerView, 14, compressedSize);
4681
+ }
4612
4682
  arraySet(directoryArray, headerArray, offset + 6);
4613
4683
  setUint16(directoryView, offset + 30, extraFieldLength);
4614
4684
  setUint16(directoryView, offset + 32, getLength(rawComment));
4615
- setUint16(directoryView, offset + 34, zip64 ? MAX_16_BITS : diskNumberStart);
4685
+ setUint16(directoryView, offset + 34, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
4616
4686
  setUint16(directoryView, offset + 36, internalFileAttribute);
4617
4687
  if (externalFileAttribute) {
4618
4688
  setUint32(directoryView, offset + 38, externalFileAttribute);
4619
4689
  } else if (directory && msDosCompatible) {
4620
4690
  setUint8(directoryView, offset + 38, FILE_ATTR_MSDOS_DIR_MASK);
4621
4691
  }
4622
- setUint32(directoryView, offset + 42, zip64 ? MAX_32_BITS : fileEntryOffset);
4692
+ setUint32(directoryView, offset + 42, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
4623
4693
  arraySet(directoryArray, rawFilename, offset + 46);
4624
4694
  arraySet(directoryArray, rawExtraFieldZip64, offset + 46 + getLength(rawFilename));
4625
4695
  arraySet(directoryArray, rawExtraFieldAES, offset + 46 + getLength(rawFilename, rawExtraFieldZip64));
@@ -4673,7 +4743,11 @@
4673
4743
  setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
4674
4744
  setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength));
4675
4745
  setUint32(endOfdirectoryView, 72, lastDiskNumber + 1);
4676
- diskNumber = MAX_16_BITS;
4746
+ const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
4747
+ if (supportZip64SplitFile) {
4748
+ lastDiskNumber = MAX_16_BITS;
4749
+ diskNumber = MAX_16_BITS;
4750
+ }
4677
4751
  filesLength = MAX_16_BITS;
4678
4752
  directoryOffset = MAX_32_BITS;
4679
4753
  directoryDataLength = MAX_32_BITS;