@zip.js/zip.js 2.8.56 → 2.8.57

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.
@@ -838,7 +838,7 @@ function keepsContentType(writer, data) {
838
838
  } else if (writer.constructor == BlobWriter) {
839
839
  return data.type == contentType;
840
840
  } else if (writer.constructor == Data64URIWriter) {
841
- return data.startsWith(writer.data);
841
+ return data.startsWith("data:" + (contentType || "") + ";base64,");
842
842
  } else {
843
843
  return true;
844
844
  }
@@ -194,6 +194,7 @@ const ERR_UNSAFE_FILENAME = "Unsafe filename";
194
194
  const ERR_INVALID_STRICTNESS = "Invalid strictness (must be 'strict', 'balanced' or 'tolerant')";
195
195
  const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
196
196
  const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
197
+ const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
197
198
  const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
198
199
  const CHARSET_UTF8 = "utf-8";
199
200
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
@@ -216,6 +217,7 @@ const ZIP64_EXTRACTION = {
216
217
  bytes: 8
217
218
  }
218
219
  };
220
+ const MAX_SAFE_UINT64 = BigInt(Number.MAX_SAFE_INTEGER);
219
221
  const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
220
222
  const MAX_DEFLATE_EXPANSION_RATIO = 1032;
221
223
  const CENTRAL_DIRECTORY_UNREACHABLE = 0;
@@ -311,7 +313,7 @@ class ZipReader {
311
313
  zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
312
314
  if (zip64EndOfDirectoryVersion2) {
313
315
  const extensibleDataLength = Math.min(
314
- Number(getBigUint64(endOfDirectoryView, 4)) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
316
+ getBigUint64(endOfDirectoryView, 4) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
315
317
  reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
316
318
  if (extensibleDataLength > 0) {
317
319
  zip64EndOfDirectoryLength += extensibleDataLength;
@@ -665,6 +667,7 @@ export {
665
667
  ERR_INVALID_STRICTNESS,
666
668
  ERR_INVALID_FILENAME_VALIDATION,
667
669
  ERR_INVALID_MAX_APPENDED_DATA_SIZE,
670
+ ERR_UNSUPPORTED_UINT64,
668
671
  ERR_WORKER_STARTUP_TIMEOUT
669
672
  };
670
673
 
@@ -922,8 +925,8 @@ function getDirectoryEncryptionInfo(rawExtensibleData) {
922
925
  const hashDataLength = getUint16(extensibleDataView, 26);
923
926
  Object.assign(directoryEncryptionInfo, {
924
927
  compressionMethod: getUint16(extensibleDataView, 0),
925
- compressedSize: Number(getBigUint64(extensibleDataView, 2)),
926
- uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
928
+ compressedSize: getBigUint64(extensibleDataView, 2),
929
+ uncompressedSize: getBigUint64(extensibleDataView, 10),
927
930
  encryptionAlgorithm: getUint16(extensibleDataView, 18),
928
931
  bitLength: getUint16(extensibleDataView, 20),
929
932
  flags: getUint16(extensibleDataView, 22),
@@ -1558,5 +1561,9 @@ function getUint32(view, offset) {
1558
1561
  }
1559
1562
 
1560
1563
  function getBigUint64(view, offset) {
1561
- return Number(view.getBigUint64(offset, true));
1564
+ const value = view.getBigUint64(offset, true);
1565
+ if (value > MAX_SAFE_UINT64) {
1566
+ throw new Error(ERR_UNSUPPORTED_UINT64);
1567
+ }
1568
+ return Number(value);
1562
1569
  }
@@ -170,7 +170,7 @@ import {
170
170
  ownsWritable
171
171
  } from "./io.js";
172
172
  import { encodeText } from "./util/encode-text.js";
173
- import { getDataView } from "./util/array.js";
173
+ import { concat, getDataView } from "./util/array.js";
174
174
  import { toCompatibleReadable, streamToBlob } from "./util/compatible-streams.js";
175
175
  import {
176
176
  PROPERTY_NAME_LAST_MODIFICATION_DATE,
@@ -346,7 +346,7 @@ class ZipWriter {
346
346
  encrypted,
347
347
  uncompressedSize,
348
348
  compressedSize,
349
- zip64
349
+ extraFieldZip64
350
350
  } = entry;
351
351
  let {
352
352
  compressionMethod,
@@ -363,13 +363,13 @@ class ZipWriter {
363
363
  rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
364
364
  rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
365
365
  rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
366
- rawExtraField = rawExtraField || EMPTY_UINT8_ARRAY;
366
+ rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
367
367
  if (entry.extraFieldAES) {
368
368
  compressionMethod = COMPRESSION_METHOD_AES;
369
369
  }
370
370
  const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
371
- const zip64UncompressedSize = zip64 && uncompressedSize >= MAX_32_BITS;
372
- const zip64CompressedSize = zip64 && compressedSize >= MAX_32_BITS;
371
+ const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
372
+ const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
373
373
  const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
374
374
  const {
375
375
  headerArray,
@@ -963,6 +963,10 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
963
963
  maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
964
964
  }
965
965
  }
966
+ const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
967
+ if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
968
+ dataDescriptor = false;
969
+ }
966
970
  const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
967
971
  const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
968
972
  if (zip64UncompressedSize || zip64CompressedSize) {
@@ -977,6 +981,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
977
981
  maximumCompressedSize,
978
982
  resolvedOptions: {
979
983
  dataDescriptor,
984
+ emptyEntry,
980
985
  zip64,
981
986
  zip64UncompressedSize,
982
987
  zip64CompressedSize,
@@ -1075,6 +1080,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
1075
1080
  const {
1076
1081
  keepOrder,
1077
1082
  dataDescriptor,
1083
+ emptyEntry,
1078
1084
  signal
1079
1085
  } = options;
1080
1086
  const {
@@ -1099,7 +1105,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
1099
1105
  lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
1100
1106
  requestLockCurrentFileEntry();
1101
1107
  }
1102
- if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
1108
+ if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || (!dataDescriptor && !emptyEntry)) {
1103
1109
  bufferedWrite = true;
1104
1110
  zipWriter.bufferedWrites++;
1105
1111
  if (options.createTempStream) {
@@ -1521,8 +1527,8 @@ function getHeaderInfo(options) {
1521
1527
  try {
1522
1528
  const { uid, gid, unixExtraFieldType } = options;
1523
1529
  if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
1524
- const uidBytes = packUnixId(uid);
1525
- const gidBytes = packUnixId(gid);
1530
+ const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
1531
+ const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
1526
1532
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
1527
1533
  const extraFieldUnix = createRecordWriter(4 + payloadLength);
1528
1534
  extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
@@ -1653,18 +1659,14 @@ function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
1653
1659
  }
1654
1660
 
1655
1661
  function packUnixId(id) {
1656
- if (id === UNDEFINED_VALUE) {
1657
- return EMPTY_UINT8_ARRAY;
1658
- } else {
1659
- const dataArray = new Uint8Array(4);
1660
- const dataView = getDataView(dataArray);
1661
- dataView.setUint32(0, id, true);
1662
- let length = 4;
1663
- while (length > 1 && dataArray[length - 1] === 0) {
1664
- length--;
1665
- }
1666
- return dataArray.subarray(0, length);
1667
- }
1662
+ const dataArray = new Uint8Array(4);
1663
+ const dataView = getDataView(dataArray);
1664
+ dataView.setUint32(0, id, true);
1665
+ let length = 4;
1666
+ while (length > 1 && dataArray[length - 1] === 0) {
1667
+ length--;
1668
+ }
1669
+ return dataArray.subarray(0, length);
1668
1670
  }
1669
1671
 
1670
1672
  function normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes) {
@@ -2083,6 +2085,21 @@ async function startsWithSplitZipSignature(reader) {
2083
2085
  return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
2084
2086
  }
2085
2087
 
2088
+ function removeExtraFieldZip64(rawExtraField) {
2089
+ const rawExtraFieldView = getDataView(rawExtraField);
2090
+ let offsetExtraField = 0;
2091
+ while (offsetExtraField + 4 <= getLength(rawExtraField)) {
2092
+ const size = 4 + getUint16(rawExtraFieldView, offsetExtraField + 2);
2093
+ if (getUint16(rawExtraFieldView, offsetExtraField) == EXTRAFIELD_TYPE_ZIP64) {
2094
+ return removeExtraFieldZip64(concat(
2095
+ rawExtraField.subarray(0, offsetExtraField),
2096
+ rawExtraField.subarray(Math.min(offsetExtraField + size, getLength(rawExtraField)))));
2097
+ }
2098
+ offsetExtraField += size;
2099
+ }
2100
+ return rawExtraField;
2101
+ }
2102
+
2086
2103
  async function copyZipData(zipWriter, reader, entries, directoryOffset) {
2087
2104
  const { writer } = zipWriter;
2088
2105
  const entryPositions = new Map();
@@ -55,5 +55,6 @@ export {
55
55
  ERR_INVALID_STRICTNESS,
56
56
  ERR_INVALID_FILENAME_VALIDATION,
57
57
  ERR_INVALID_MAX_APPENDED_DATA_SIZE,
58
+ ERR_UNSUPPORTED_UINT64,
58
59
  ERR_WORKER_STARTUP_TIMEOUT
59
60
  } from "./core/zip-reader.js";
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.8.56",
6
+ "version": "2.8.57",
7
7
  "type": "module",
8
8
  "keywords": [
9
9
  "zip",