@zip.js/zip.js 2.11.2 → 2.11.3

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.
@@ -26,6 +26,6 @@
26
26
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
  */
28
28
 
29
- const VERSION = "2.11.2";
29
+ const VERSION = "2.11.3";
30
30
 
31
31
  export { VERSION };
@@ -587,12 +587,14 @@ class ZipDirectoryEntry extends ZipEntry {
587
587
  if (options.bufferedWrite === UNDEFINED_VALUE) {
588
588
  options.bufferedWrite = true;
589
589
  }
590
- const entries = zipEntry.getChildren({ recursive: true }).filter(child => !isImplicitDirectory(child)).map(child => {
590
+ const children = zipEntry.getChildren({ recursive: true });
591
+ const entries = children.filter(child => !isImplicitDirectory(child)).map(child => {
591
592
  const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
592
593
  return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
593
594
  });
594
595
  const writeOrderGuaranteed = !options.bufferedWrite ||
595
- (entries.every(entry => entry.options.keepOrder !== false) && zipEntry.children.every(child => !child.children.length));
596
+ (entries.every(entry => entry.options.keepOrder !== false) &&
597
+ children.every(child => isImplicitDirectory(child) || !child.children.length));
596
598
  return getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
597
599
  }
598
600
 
@@ -254,6 +254,7 @@ const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
254
254
  const ERR_INVALID_VERSION = "Version exceeds 65535";
255
255
  const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
256
256
  const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
257
+ const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
257
258
  const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
258
259
  const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
259
260
  const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
@@ -268,6 +269,7 @@ const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
268
269
  const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
269
270
  const ERR_UNDETERMINED_SIZE = "Undetermined size";
270
271
  const ERR_UNDEFINED_READER = "Undefined reader";
272
+ const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
271
273
  const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
272
274
  const ERR_INVALID_UID = "Invalid uid (must be integer 0..2^32-1)";
273
275
  const ERR_INVALID_GID = "Invalid gid (must be integer 0..2^32-1)";
@@ -299,6 +301,9 @@ class ZipWriter {
299
301
  const addSplitZipSignature =
300
302
  availableSize > 0 && availableSize !== INFINITY_VALUE &&
301
303
  maxSize > 0 && maxSize !== INFINITY_VALUE;
304
+ if (addSplitZipSignature && options[OPTION_USDZ]) {
305
+ throw new Error(ERR_UNSUPPORTED_SPLIT_USDZ);
306
+ }
302
307
  Object.assign(this, {
303
308
  writer,
304
309
  addSplitZipSignature,
@@ -414,6 +419,7 @@ class ZipWriter {
414
419
  }
415
420
  const { offset, diskNumberStart } = entryPositions.get(entry);
416
421
  Object.assign(entry, {
422
+ zip64Enabled: true,
417
423
  zip64UncompressedSize,
418
424
  zip64CompressedSize,
419
425
  offset,
@@ -663,12 +669,14 @@ export {
663
669
  ERR_INVALID_EXTRAFIELD_DATA,
664
670
  ERR_INVALID_ENCRYPTION_STRENGTH,
665
671
  ERR_UNSUPPORTED_ENCRYPTION_USDZ,
672
+ ERR_UNSUPPORTED_SPLIT_USDZ,
666
673
  ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH,
667
674
  ERR_UNSUPPORTED_FORMAT,
668
675
  ERR_UNDEFINED_UNCOMPRESSED_SIZE,
669
676
  ERR_UNDEFINED_COMPRESSION_METHOD,
670
677
  ERR_UNDETERMINED_SIZE,
671
678
  ERR_UNDEFINED_READER,
679
+ ERR_INVALID_READER,
672
680
  ERR_ZIP_NOT_EMPTY,
673
681
  ERR_INVALID_SIGNATURE_DATA,
674
682
  ERR_INVALID_UID,
@@ -1027,6 +1035,9 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
1027
1035
  if (reader) {
1028
1036
  reader = new GenericReader(reader);
1029
1037
  await initStream(reader);
1038
+ if (!reader.readable && !reader.readUint8Array) {
1039
+ throw new Error(ERR_INVALID_READER);
1040
+ }
1030
1041
  ({ size: contentSize } = reader);
1031
1042
  }
1032
1043
  return Object.assign({ reader }, resolveEntrySizes(zipWriter, Boolean(reader), contentSize, metadata, options));
@@ -1037,6 +1048,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
1037
1048
  let { dataDescriptor, zip64, level, compressionMethod } = metadata;
1038
1049
  let maximumCompressedSize = 0;
1039
1050
  let uncompressedSize = 0;
1051
+ let unknownSize = false;
1040
1052
  if (passThrough && hasContent) {
1041
1053
  uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
1042
1054
  if (uncompressedSize === UNDEFINED_VALUE) {
@@ -1062,8 +1074,8 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
1062
1074
  if (contentSize === UNDEFINED_VALUE) {
1063
1075
  dataDescriptor = true;
1064
1076
  if (zip64 || zip64 === UNDEFINED_VALUE) {
1065
- zip64 = true;
1066
- uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
1077
+ zip64 = unknownSize = true;
1078
+ maximumCompressedSize = MAX_32_BITS + 1;
1067
1079
  }
1068
1080
  } else {
1069
1081
  options.uncompressedSize = uncompressedSize = contentSize;
@@ -1078,7 +1090,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
1078
1090
  if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
1079
1091
  dataDescriptor = false;
1080
1092
  }
1081
- const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
1093
+ const zip64UncompressedSize = zip64Enabled || unknownSize || uncompressedSize >= MAX_32_BITS;
1082
1094
  const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
1083
1095
  if (zip64UncompressedSize || zip64CompressedSize) {
1084
1096
  if (zip64 === false) {
@@ -1094,6 +1106,8 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
1094
1106
  dataDescriptor,
1095
1107
  emptyEntry,
1096
1108
  zip64,
1109
+ zip64Enabled,
1110
+ unknownSize,
1097
1111
  zip64UncompressedSize,
1098
1112
  zip64CompressedSize,
1099
1113
  uncompressedSize,
@@ -1167,7 +1181,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
1167
1181
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
1168
1182
  throw new Error(ERR_UNDETERMINED_SIZE);
1169
1183
  }
1170
- const directoryDataLength = createDirectoryRecords(files);
1184
+ const { directoryDataLength, zip64Entries } = createDirectoryRecords(files);
1171
1185
  let zip64 = getOptionValue(zipWriter, writerOptions, PROPERTY_NAME_ZIP64);
1172
1186
  if (offset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || files.size >= MAX_16_BITS) {
1173
1187
  if (zip64 === false) {
@@ -1175,6 +1189,8 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
1175
1189
  } else {
1176
1190
  zip64 = true;
1177
1191
  }
1192
+ } else if (zip64 === UNDEFINED_VALUE && zip64Entries) {
1193
+ zip64 = true;
1178
1194
  }
1179
1195
  return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
1180
1196
  }
@@ -1367,6 +1383,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
1367
1383
  rawPassword,
1368
1384
  level,
1369
1385
  zip64,
1386
+ zip64Enabled,
1370
1387
  zip64UncompressedSize,
1371
1388
  zip64CompressedSize,
1372
1389
  zipCrypto,
@@ -1407,6 +1424,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
1407
1424
  lockFileEntry,
1408
1425
  versionMadeBy,
1409
1426
  zip64,
1427
+ zip64Enabled,
1410
1428
  directory: Boolean(directory),
1411
1429
  executable: Boolean(executable),
1412
1430
  filenameUTF8: true,
@@ -1550,13 +1568,14 @@ function getHeaderInfo(options) {
1550
1568
  zip64UncompressedSize,
1551
1569
  zip64CompressedSize,
1552
1570
  uncompressedSize,
1571
+ unknownSize,
1553
1572
  crc32
1554
1573
  } = options;
1555
1574
  let { version, compressionMethod } = options;
1556
1575
  const compressed = !directory && isCompressed(compressionMethod, level);
1557
1576
  let rawLocalExtraFieldZip64;
1558
1577
  const uncompressedFile = passThrough || !compressed;
1559
- const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || uncompressedFile));
1578
+ const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
1560
1579
  const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
1561
1580
  if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
1562
1581
  const length = 4 + 16;
@@ -1690,6 +1709,10 @@ function getHeaderInfo(options) {
1690
1709
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
1691
1710
  }
1692
1711
  const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
1712
+ const clampedLastModDate = dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate;
1713
+ const storedLastModDate = getLength(rawExtraFieldExtendedTimestamp) ?
1714
+ new Date(getTimeUnix(lastModDate) * 1000) :
1715
+ getLength(rawExtraFieldNTFS) ? lastModDate : clampedLastModDate;
1693
1716
  const {
1694
1717
  headerArray,
1695
1718
  headerView,
@@ -1699,7 +1722,7 @@ function getHeaderInfo(options) {
1699
1722
  bitFlag: getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod),
1700
1723
  compressionMethod,
1701
1724
  uncompressedSize,
1702
- lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
1725
+ lastModDate: clampedLastModDate,
1703
1726
  rawLastModDate: rawLastModDateOption,
1704
1727
  rawFilename,
1705
1728
  zip64CompressedSize,
@@ -1734,7 +1757,7 @@ function getHeaderInfo(options) {
1734
1757
  localHeaderView,
1735
1758
  headerArray,
1736
1759
  headerView,
1737
- lastModDate,
1760
+ lastModDate: storedLastModDate,
1738
1761
  rawLastModDate,
1739
1762
  encrypted,
1740
1763
  compressed,
@@ -1906,14 +1929,15 @@ function updateLocalHeader({
1906
1929
 
1907
1930
 
1908
1931
  async function closeFile(zipWriter, comment, options) {
1909
- const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
1932
+ const { directoryDataLength, zip64Entries } = createDirectoryRecords(zipWriter.fileEntries);
1910
1933
  const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
1911
1934
  const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
1912
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
1935
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength, zip64Entries });
1913
1936
  }
1914
1937
 
1915
1938
  function createDirectoryRecords(files) {
1916
1939
  let directoryDataLength = 0;
1940
+ let zip64Entries = false;
1917
1941
  for (const [, fileEntry] of files) {
1918
1942
  const {
1919
1943
  rawFilename,
@@ -1926,11 +1950,20 @@ function createDirectoryRecords(files) {
1926
1950
  extendedTimestamp,
1927
1951
  extraFieldExtendedTimestampFlag,
1928
1952
  lastModDate,
1929
- zip64UncompressedSize,
1930
- zip64CompressedSize,
1953
+ zip64Enabled,
1931
1954
  uncompressedSize,
1932
1955
  compressedSize
1933
1956
  } = fileEntry;
1957
+ let { zip64UncompressedSize, zip64CompressedSize } = fileEntry;
1958
+ if (!zip64Enabled) {
1959
+ if (zip64UncompressedSize && uncompressedSize < MAX_32_BITS) {
1960
+ zip64UncompressedSize = fileEntry.zip64UncompressedSize = false;
1961
+ }
1962
+ if (zip64CompressedSize && compressedSize < MAX_32_BITS) {
1963
+ zip64CompressedSize = fileEntry.zip64CompressedSize = false;
1964
+ }
1965
+ }
1966
+ zip64Entries = zip64Entries || zip64UncompressedSize || zip64CompressedSize;
1934
1967
  const zip64Offset = fileEntry.offset >= MAX_32_BITS;
1935
1968
  const zip64DiskNumberStart = fileEntry.diskNumberStart >= MAX_16_BITS;
1936
1969
  let rawExtraFieldZip64;
@@ -1984,7 +2017,7 @@ function createDirectoryRecords(files) {
1984
2017
  }
1985
2018
  directoryDataLength += CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
1986
2019
  }
1987
- return directoryDataLength;
2020
+ return { directoryDataLength, zip64Entries };
1988
2021
  }
1989
2022
 
1990
2023
  async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
@@ -2104,7 +2137,7 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
2104
2137
 
2105
2138
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
2106
2139
  const { writer } = zipWriter;
2107
- const { directoryStart, directoryEnd, signatureLength } = cdInfo;
2140
+ const { directoryStart, directoryEnd, signatureLength, zip64Entries } = cdInfo;
2108
2141
  let { directoryDataLength } = cdInfo;
2109
2142
  let fileEntriesLength = zipWriter.fileEntries.size;
2110
2143
  let diskNumber = directoryStart.diskNumber;
@@ -2124,6 +2157,8 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
2124
2157
  } else {
2125
2158
  zip64 = true;
2126
2159
  }
2160
+ } else if (zip64 === UNDEFINED_VALUE && zip64Entries) {
2161
+ zip64 = true;
2127
2162
  }
2128
2163
  const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
2129
2164
  if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
@@ -45,12 +45,14 @@ export {
45
45
  ERR_INVALID_EXTRAFIELD_DATA,
46
46
  ERR_INVALID_ENCRYPTION_STRENGTH,
47
47
  ERR_UNSUPPORTED_ENCRYPTION_USDZ,
48
+ ERR_UNSUPPORTED_SPLIT_USDZ,
48
49
  ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH,
49
50
  ERR_UNSUPPORTED_FORMAT,
50
51
  ERR_UNDEFINED_UNCOMPRESSED_SIZE,
51
52
  ERR_UNDEFINED_COMPRESSION_METHOD,
52
53
  ERR_UNDETERMINED_SIZE,
53
54
  ERR_UNDEFINED_READER,
55
+ ERR_INVALID_READER,
54
56
  ERR_ZIP_NOT_EMPTY,
55
57
  ERR_INVALID_SIGNATURE_DATA,
56
58
  ERR_INVALID_UID,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "A JavaScript library to zip and unzip files in the browser, Deno and Node.js",
4
4
  "author": "Gildas Lormeau",
5
5
  "license": "BSD-3-Clause",
6
- "version": "2.11.2",
6
+ "version": "2.11.3",
7
7
  "type": "module",
8
8
  "keywords": [
9
9
  "zip",