@zip.js/zip.js 2.8.55 → 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.
@@ -141,6 +141,8 @@ export {
141
141
  checkFunctionOption,
142
142
  checkSignalOption,
143
143
  checkPasswordOption,
144
+ checkInteger,
145
+ checkIntegerOption,
144
146
  toNumber
145
147
  };
146
148
 
@@ -164,6 +166,18 @@ function checkPasswordOption(password, rawPassword) {
164
166
  }
165
167
  }
166
168
 
169
+ function checkInteger(value, maxValue, errorMessage) {
170
+ if (!Number.isInteger(value) || value < 0 || value > maxValue) {
171
+ throw new Error(errorMessage);
172
+ }
173
+ }
174
+
175
+ function checkIntegerOption(value, maxValue, errorMessage) {
176
+ if (value !== UNDEFINED_VALUE) {
177
+ checkInteger(value, maxValue, errorMessage);
178
+ }
179
+ }
180
+
167
181
  function toNumber(value) {
168
182
  return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
169
183
  }
@@ -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;
@@ -544,8 +546,15 @@ class ZipReader {
544
546
  yield entry;
545
547
  }
546
548
  let offsetAfterSignature = offset;
547
- const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
549
+ let digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
548
550
  (decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
551
+ if (!digitalSignature && !decryptedDirectory) {
552
+ const signatureRecordOffset = directoryDataOffset + offset;
553
+ const signatureRecordLength = Math.min(centralDirectoryEndOffset - signatureRecordOffset, 6 + MAX_16_BITS);
554
+ if (signatureRecordLength >= 6) {
555
+ digitalSignature = readDigitalSignature(await readUint8Array(reader, signatureRecordOffset, signatureRecordLength));
556
+ }
557
+ }
549
558
  if (digitalSignature) {
550
559
  zipReader.digitalSignature = digitalSignature;
551
560
  offsetAfterSignature = offset + 6 + digitalSignature.length;
@@ -658,6 +667,7 @@ export {
658
667
  ERR_INVALID_STRICTNESS,
659
668
  ERR_INVALID_FILENAME_VALIDATION,
660
669
  ERR_INVALID_MAX_APPENDED_DATA_SIZE,
670
+ ERR_UNSUPPORTED_UINT64,
661
671
  ERR_WORKER_STARTUP_TIMEOUT
662
672
  };
663
673
 
@@ -915,8 +925,8 @@ function getDirectoryEncryptionInfo(rawExtensibleData) {
915
925
  const hashDataLength = getUint16(extensibleDataView, 26);
916
926
  Object.assign(directoryEncryptionInfo, {
917
927
  compressionMethod: getUint16(extensibleDataView, 0),
918
- compressedSize: Number(getBigUint64(extensibleDataView, 2)),
919
- uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
928
+ compressedSize: getBigUint64(extensibleDataView, 2),
929
+ uncompressedSize: getBigUint64(extensibleDataView, 10),
920
930
  encryptionAlgorithm: getUint16(extensibleDataView, 18),
921
931
  bitLength: getUint16(extensibleDataView, 20),
922
932
  flags: getUint16(extensibleDataView, 22),
@@ -1551,5 +1561,9 @@ function getUint32(view, offset) {
1551
1561
  }
1552
1562
 
1553
1563
  function getBigUint64(view, offset) {
1554
- 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);
1555
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,
@@ -235,6 +235,8 @@ import {
235
235
  checkFunctionOption,
236
236
  checkSignalOption,
237
237
  checkPasswordOption,
238
+ checkInteger,
239
+ checkIntegerOption,
238
240
  toNumber
239
241
  } from "./options.js";
240
242
 
@@ -276,6 +278,8 @@ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
276
278
 
277
279
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
278
280
  const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
281
+ const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
282
+ const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
279
283
  const VENDOR_VERSION_AE_1 = 1;
280
284
  const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
281
285
  const UNIX_EXTRA_FIELD_TYPE = "unix";
@@ -322,16 +326,14 @@ class ZipWriter {
322
326
  await zipReader.close();
323
327
  await initStream(this.writer);
324
328
  const { directoryOffset } = zipReader;
325
- let splitZipSignatureLength = 0;
326
329
  if (this.addSplitZipSignature) {
327
330
  delete this.addSplitZipSignature;
328
331
  if (!await startsWithSplitZipSignature(reader)) {
329
332
  await writeData(this.writer, getSplitZipSignatureArray());
330
- splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
331
- this.offset += splitZipSignatureLength;
333
+ this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
332
334
  }
333
335
  }
334
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
336
+ const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
335
337
  this.filenames = new Set(entries.map(entry => entry.filename));
336
338
  this.fileEntries = new Map(entries.map(entry => {
337
339
  const {
@@ -344,7 +346,7 @@ class ZipWriter {
344
346
  encrypted,
345
347
  uncompressedSize,
346
348
  compressedSize,
347
- zip64
349
+ extraFieldZip64
348
350
  } = entry;
349
351
  let {
350
352
  compressionMethod,
@@ -361,13 +363,13 @@ class ZipWriter {
361
363
  rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
362
364
  rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
363
365
  rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
364
- rawExtraField = rawExtraField || EMPTY_UINT8_ARRAY;
366
+ rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
365
367
  if (entry.extraFieldAES) {
366
368
  compressionMethod = COMPRESSION_METHOD_AES;
367
369
  }
368
370
  const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
369
- const zip64UncompressedSize = zip64 && uncompressedSize >= MAX_32_BITS;
370
- 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;
371
373
  const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
372
374
  const {
373
375
  headerArray,
@@ -611,7 +613,8 @@ async function addFile(zipWriter, name, reader, options) {
611
613
  signature: options[PROPERTY_NAME_SIGNATURE],
612
614
  crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
613
615
  offset: zipWriter.offset - diskOffset,
614
- diskNumberStart: diskNumber
616
+ diskNumberStart: diskNumber,
617
+ [OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
615
618
  });
616
619
  const headerInfo = getHeaderInfo(options);
617
620
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -643,15 +646,9 @@ function resolveAttributes(zipWriter, name, options) {
643
646
  let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
644
647
  let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
645
648
  let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
646
- if (uid !== UNDEFINED_VALUE && (!Number.isInteger(uid) || uid < 0 || uid > MAX_32_BITS)) {
647
- throw new Error(ERR_INVALID_UID);
648
- }
649
- if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
650
- throw new Error(ERR_INVALID_GID);
651
- }
652
- if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
653
- throw new Error(ERR_INVALID_UNIX_MODE);
654
- }
649
+ checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
650
+ checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
651
+ checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
655
652
  if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
656
653
  throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
657
654
  }
@@ -673,9 +670,7 @@ function resolveAttributes(zipWriter, name, options) {
673
670
  msDosCompatible = true;
674
671
  versionMadeBy = (versionMadeBy & MAX_8_BITS);
675
672
  }
676
- if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
677
- throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
678
- }
673
+ checkIntegerOption(msdosAttributesRaw, MAX_8_BITS, ERR_INVALID_MSDOS_ATTRIBUTES);
679
674
  if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
680
675
  throw new Error(ERR_INVALID_MSDOS_DATA);
681
676
  }
@@ -815,9 +810,7 @@ function resolveMetadata(zipWriter, name, options) {
815
810
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
816
811
  }
817
812
  let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
818
- if (level !== UNDEFINED_VALUE && (!Number.isInteger(level) || level < 0 || level > MAX_LEVEL)) {
819
- throw new Error(ERR_INVALID_LEVEL);
820
- }
813
+ checkIntegerOption(level, MAX_LEVEL, ERR_INVALID_LEVEL);
821
814
  if (zipWriter.options[OPTION_USDZ]) {
822
815
  if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
823
816
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
@@ -895,9 +888,7 @@ function serializeExtraField(extraField) {
895
888
  let extraFieldSize = 0;
896
889
  let offset = 0;
897
890
  extraField.forEach((data, type) => {
898
- if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
899
- throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
900
- }
891
+ checkInteger(type, MAX_16_BITS, ERR_INVALID_EXTRAFIELD_TYPE);
901
892
  if (!(data instanceof Uint8Array)) {
902
893
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
903
894
  }
@@ -972,6 +963,10 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
972
963
  maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
973
964
  }
974
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
+ }
975
970
  const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
976
971
  const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
977
972
  if (zip64UncompressedSize || zip64CompressedSize) {
@@ -986,6 +981,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
986
981
  maximumCompressedSize,
987
982
  resolvedOptions: {
988
983
  dataDescriptor,
984
+ emptyEntry,
989
985
  zip64,
990
986
  zip64UncompressedSize,
991
987
  zip64CompressedSize,
@@ -1012,7 +1008,9 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
1012
1008
  const usdz = writerOptions[OPTION_USDZ];
1013
1009
  const files = new Map();
1014
1010
  let layoutDependsOnWriteOrder = Boolean(usdz);
1015
- let offset = 0;
1011
+ const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
1012
+ let offset = initialOffset;
1013
+ let minimumEntrySize = INFINITY_VALUE;
1016
1014
  for (const entry of entries) {
1017
1015
  let { name } = entry;
1018
1016
  const { size } = entry;
@@ -1036,7 +1034,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
1036
1034
  if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
1037
1035
  throw new Error(ERR_UNDETERMINED_SIZE);
1038
1036
  }
1039
- const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
1037
+ const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
1040
1038
  const headerInfo = getHeaderInfo(entryOptions);
1041
1039
  const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
1042
1040
  const entryInfo = {
@@ -1047,15 +1045,17 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
1047
1045
  appendExtraFieldUSDZ(entryInfo, offset);
1048
1046
  }
1049
1047
  const compressedSize = hasContent ? maximumCompressedSize : 0;
1050
- if (offset >= MAX_32_BITS) {
1051
- layoutDependsOnWriteOrder = true;
1052
- }
1053
1048
  files.set(name, Object.assign({}, entryOptions, headerInfo, {
1054
1049
  offset,
1055
1050
  diskNumberStart: 0,
1056
1051
  compressedSize
1057
1052
  }));
1058
- offset += entryInfo.metadataSize + compressedSize;
1053
+ const entrySize = entryInfo.metadataSize + compressedSize;
1054
+ minimumEntrySize = Math.min(minimumEntrySize, entrySize);
1055
+ offset += entrySize;
1056
+ }
1057
+ if (files.size && offset - minimumEntrySize >= MAX_32_BITS) {
1058
+ layoutDependsOnWriteOrder = true;
1059
1059
  }
1060
1060
  if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
1061
1061
  throw new Error(ERR_UNDETERMINED_SIZE);
@@ -1069,7 +1069,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
1069
1069
  zip64 = true;
1070
1070
  }
1071
1071
  }
1072
- return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
1072
+ return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
1073
1073
  }
1074
1074
 
1075
1075
  async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
@@ -1080,6 +1080,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
1080
1080
  const {
1081
1081
  keepOrder,
1082
1082
  dataDescriptor,
1083
+ emptyEntry,
1083
1084
  signal
1084
1085
  } = options;
1085
1086
  const {
@@ -1104,7 +1105,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
1104
1105
  lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
1105
1106
  requestLockCurrentFileEntry();
1106
1107
  }
1107
- if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
1108
+ if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || (!dataDescriptor && !emptyEntry)) {
1108
1109
  bufferedWrite = true;
1109
1110
  zipWriter.bufferedWrites++;
1110
1111
  if (options.createTempStream) {
@@ -1526,8 +1527,8 @@ function getHeaderInfo(options) {
1526
1527
  try {
1527
1528
  const { uid, gid, unixExtraFieldType } = options;
1528
1529
  if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
1529
- const uidBytes = packUnixId(uid);
1530
- const gidBytes = packUnixId(gid);
1530
+ const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
1531
+ const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
1531
1532
  const payloadLength = 3 + uidBytes.length + gidBytes.length;
1532
1533
  const extraFieldUnix = createRecordWriter(4 + payloadLength);
1533
1534
  extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
@@ -1566,12 +1567,13 @@ function getHeaderInfo(options) {
1566
1567
  if (passThrough && crc32 !== UNDEFINED_VALUE) {
1567
1568
  rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
1568
1569
  }
1569
- rawExtraFieldAES[9] = compressionMethod;
1570
+ setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
1570
1571
  compressionMethod = COMPRESSION_METHOD_AES;
1571
1572
  }
1572
1573
  const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
1573
1574
  const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
1574
- if (extraFieldLength > MAX_16_BITS) {
1575
+ const maximumUsdzExtraFieldLength = options[OPTION_USDZ] ? EXTRAFIELD_USDZ_MAX_LENGTH : 0;
1576
+ if (extraFieldLength + maximumUsdzExtraFieldLength > MAX_16_BITS) {
1575
1577
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
1576
1578
  }
1577
1579
  const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
@@ -1657,18 +1659,14 @@ function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
1657
1659
  }
1658
1660
 
1659
1661
  function packUnixId(id) {
1660
- if (id === UNDEFINED_VALUE) {
1661
- return EMPTY_UINT8_ARRAY;
1662
- } else {
1663
- const dataArray = new Uint8Array(4);
1664
- const dataView = getDataView(dataArray);
1665
- dataView.setUint32(0, id, true);
1666
- let length = 4;
1667
- while (length > 1 && dataArray[length - 1] === 0) {
1668
- length--;
1669
- }
1670
- return dataArray.subarray(0, length);
1671
- }
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);
1672
1670
  }
1673
1671
 
1674
1672
  function normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes) {
@@ -1972,7 +1970,11 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
1972
1970
  signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
1973
1971
  signatureRecord.writeUint16(signatureDataLength);
1974
1972
  signatureRecord.writeBytes(signatureData);
1975
- await writeData(zipWriter.writer, signatureRecord.array);
1973
+ const { writer } = zipWriter;
1974
+ if (exceedsAvailableSize(writer, getLength(signatureRecord.array))) {
1975
+ await writer.closeDisk();
1976
+ }
1977
+ await writeData(writer, signatureRecord.array);
1976
1978
  return 6 + signatureDataLength;
1977
1979
  }
1978
1980
  return 0;
@@ -2083,7 +2085,22 @@ async function startsWithSplitZipSignature(reader) {
2083
2085
  return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
2084
2086
  }
2085
2087
 
2086
- async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
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
+
2103
+ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
2087
2104
  const { writer } = zipWriter;
2088
2105
  const entryPositions = new Map();
2089
2106
  if (writer.closeDisk) {
@@ -2104,9 +2121,10 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZip
2104
2121
  }
2105
2122
  await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
2106
2123
  } else {
2124
+ const baseOffset = zipWriter.offset;
2107
2125
  await copyData(zipWriter, reader, 0, directoryOffset);
2108
2126
  entries.forEach(entry => entryPositions.set(entry, {
2109
- offset: splitZipSignatureLength + getSourceOffset(reader, entry),
2127
+ offset: baseOffset + getSourceOffset(reader, entry),
2110
2128
  diskNumberStart: 0
2111
2129
  }));
2112
2130
  }
@@ -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.55",
6
+ "version": "2.8.57",
7
7
  "type": "module",
8
8
  "keywords": [
9
9
  "zip",