@zip.js/zip.js 2.8.57 → 2.8.59

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.
@@ -83,6 +83,7 @@
83
83
  const BITFLAG_LEVEL_FAST_MASK = 0b100;
84
84
  const BITFLAG_LEVEL_SUPER_FAST_MASK = 0b110;
85
85
  const BITFLAG_DATA_DESCRIPTOR = 0b1000;
86
+ const BITFLAG_COMPRESSED_PATCHED_DATA = 0b100000;
86
87
  const BITFLAG_STRONG_ENCRYPTION = 0b1000000;
87
88
  const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
88
89
  const BITFLAG_MASKED_LOCAL_HEADERS = 0b10000000000000;
@@ -101,6 +102,7 @@
101
102
  const FILE_ATTR_UNIX_SETGID_MASK = 0o2000;
102
103
  const FILE_ATTR_UNIX_STICKY_MASK = 0o1000;
103
104
 
105
+ const VERSION_STORE = 0x0A;
104
106
  const VERSION_DEFLATE = 0x14;
105
107
  const VERSION_ZIP64 = 0x2D;
106
108
  const VERSION_AES = 0x33;
@@ -199,6 +201,7 @@
199
201
  const OPTION_USDZ = "usdz";
200
202
  const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
201
203
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
204
+ const OPTION_CENTRAL_EXTRA_FIELD = "centralExtraField";
202
205
  const OPTION_STRICTNESS = "strictness";
203
206
  const OPTION_FILENAME_VALIDATION = "filenameValidation";
204
207
  const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
@@ -411,7 +414,7 @@
411
414
  Object.assign(config, DEFAULT_CONFIGURATION);
412
415
  }
413
416
 
414
- const n=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],r=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],e=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],f=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],t=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],o=new Uint8Array(288);o.fill(8,0,144),o.fill(9,144,256),o.fill(7,256,280),o.fill(8,280,288);const u=new Uint8Array(30).fill(5);function a(n){const r=new Uint16Array(16);for(const e of n)r[e]++;r[0]=0;const e=new Uint16Array(17);for(let n=1;n<=15;n++)e[n+1]=e[n]+r[n];const f=new Uint16Array(n.length);for(let r=0;r<n.length;r++)n[r]&&(f[e[n[r]]++]=r);return {o:r,symbols:f}}const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",p$1=(l=()=>(s=>{let p=0,l=0,U=0,K=new Uint8Array(1024),x=0,w=0;for(;!w;){w=i(1);const n=i(2);if(0==n)c();else if(1==n)j(a(o),a(u));else {if(2!=n)throw Error("invalid deflate block type");j(...y());}}return K.subarray(0,x);function b(){if(p>=s.length)throw Error("unexpected end of deflate data");return s[p++]}function i(n){for(;U<n;)l|=b()<<U,U+=8;const r=l&(1<<n)-1;return l>>>=n,U-=n,r}function c(){l=0,U=0;const n=b()|b()<<8;p+=2,V(x+n);for(let r=0;r<n;r++)K[x++]=b();}function j(t,o){let u=C(t);for(;256!=u;){if(u<256)V(x+1),K[x++]=u;else {const t=u-257,a=n[t]+i(r[t]),s=C(o),p=e[s]+i(f[s]);V(x+a);const l=x-p;for(let n=0;n<a;n++)K[x++]=K[l+n];}u=C(t);}}function y(){const n=i(5)+257,r=i(5)+1,e=i(4)+4,f=new Uint8Array(19);for(let n=0;n<e;n++)f[t[n]]=i(3);const o=a(f),u=new Uint8Array(n+r);let s=0;for(;s<u.length;){const n=C(o);if(n<16)u[s++]=n;else if(16==n){const n=u[s-1];let r=i(2)+3;for(;r--;)u[s++]=n;}else s+=17==n?i(3)+3:i(7)+11;}return [a(u.subarray(0,n)),a(u.subarray(n))]}function C(n){const{o:r,symbols:e}=n;let f=0,t=0,o=0;for(let n=1;n<=15;n++){f|=i(1);const u=r[n];if(f-t<u)return e[o+(f-t)];o+=u,t=t+u<<1,f<<=1;}throw Error("invalid huffman code")}function V(n){if(K.length<n){let r=2*K.length;for(;r<n;)r*=2;const e=new Uint8Array(r);e.set(K.subarray(0,x)),K=e;}}})((n=>{const r=(n=(n+"").replace(/[^A-Za-z0-9+/=]/g,"")).length,e=[];for(let f=0;f<r;f+=4){const r=s.indexOf(n[f])<<18|s.indexOf(n[f+1])<<12|(63&s.indexOf(n[f+2]))<<6|63&s.indexOf(n[f+3]);e.push(r>>16&255),"="!==n[f+2]&&e.push(r>>8&255),"="!==n[f+3]&&e.push(255&r);}return new Uint8Array(e)})("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")),n=>n({workerURI:n=>{const r="text/javascript";let e=l();if("string"==typeof e&&(e=(new TextEncoder).encode(e)),n){const n=new Blob([e],{type:r});return URL.createObjectURL(n)}return "data:"+r+";base64,"+(n=>{let r="";const e=n.length;let f=0;for(;f+2<e;f+=3){const e=n[f]<<16|n[f+1]<<8|n[f+2];r+=s[e>>18&63]+s[e>>12&63]+s[e>>6&63]+s[63&e];}const t=e-f;if(1===t){const e=n[f]<<16;r+=s[e>>18&63]+s[e>>12&63]+"==";}else if(2===t){const e=n[f]<<16|n[f+1]<<8;r+=s[e>>18&63]+s[e>>12&63]+s[e>>6&63]+"=";}return r})(e)}}));var l;
417
+ const o=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],r=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],e=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],t=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],n=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],w=new Uint8Array(288);w.fill(8,0,144),w.fill(9,144,256),w.fill(7,256,280),w.fill(8,280,288);const U=new Uint8Array(30).fill(5);function s(o){const r=new Uint16Array(16);for(const e of o)r[e]++;r[0]=0;const e=new Uint16Array(17);for(let o=1;o<=15;o++)e[o+1]=e[o]+r[o];const t=new Uint16Array(o.length);for(let r=0;r<o.length;r++)o[r]&&(t[e[o[r]]++]=r);return {o:r,symbols:t}}const x="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=(B=()=>function(x){let c=0,B=0,q=0,C=new Uint8Array(1024),f=0,h=0;for(;!h;){h=Y(1);const o=Y(2);if(0==o)g();else if(1==o)u(s(w),s(U));else {if(2!=o)throw new Error("invalid deflate block type");u(...z());}}return C.subarray(0,f);function i(){if(c>=x.length)throw new Error("unexpected end of deflate data");return x[c++]}function Y(o){for(;q<o;)B|=i()<<q,q+=8;const r=B&(1<<o)-1;return B>>>=o,q-=o,r}function g(){B=0,q=0;const o=i()|i()<<8;c+=2,O(f+o);for(let r=0;r<o;r++)C[f++]=i();}function u(n,w){let U=l(n);for(;256!=U;){if(U<256)O(f+1),C[f++]=U;else {const n=U-257,s=o[n]+Y(r[n]),x=l(w),c=e[x]+Y(t[x]);O(f+s);const B=f-c;for(let o=0;o<s;o++)C[f++]=C[B+o];}U=l(n);}}function z(){const o=Y(5)+257,r=Y(5)+1,e=Y(4)+4,t=new Uint8Array(19);for(let o=0;o<e;o++)t[n[o]]=Y(3);const w=s(t),U=new Uint8Array(o+r);let x=0;for(;x<U.length;){const o=l(w);if(o<16)U[x++]=o;else if(16==o){const o=U[x-1];let r=Y(2)+3;for(;r--;)U[x++]=o;}else x+=17==o?Y(3)+3:Y(7)+11;}return [s(U.subarray(0,o)),s(U.subarray(o))]}function l(o){const{o:r,symbols:e}=o;let t=0,n=0,w=0;for(let o=1;o<=15;o++){t|=Y(1);const U=r[o];if(t-n<U)return e[w+(t-n)];w+=U,n=n+U<<1,t<<=1;}throw new Error("invalid huffman code")}function O(o){if(C.length<o){let r=2*C.length;for(;r<o;)r*=2;const e=new Uint8Array(r);e.set(C.subarray(0,f)),C=e;}}}(function(o){const r=(o=String(o).replace(/[^A-Za-z0-9+/=]/g,"")).length,e=[];for(let t=0;t<r;t+=4){const r=x.indexOf(o[t])<<18|x.indexOf(o[t+1])<<12|(63&x.indexOf(o[t+2]))<<6|63&x.indexOf(o[t+3]);e.push(r>>16&255),"="!==o[t+2]&&e.push(r>>8&255),"="!==o[t+3]&&e.push(255&r);}return new Uint8Array(e)}("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")),o=>o({workerURI:o=>{const r="text/javascript";let e=B();if("string"==typeof e&&(e=(new TextEncoder).encode(e)),o){const o=new Blob([e],{type:r});return URL.createObjectURL(o)}return "data:"+r+";base64,"+function(o){let r="";const e=o.length;let t=0;for(;t+2<e;t+=3){const e=o[t]<<16|o[t+1]<<8|o[t+2];r+=x[e>>18&63]+x[e>>12&63]+x[e>>6&63]+x[63&e];}const n=e-t;if(1===n){const e=o[t]<<16;r+=x[e>>18&63]+x[e>>12&63]+"==";}else if(2===n){const e=o[t]<<16|o[t+1]<<8;r+=x[e>>18&63]+x[e>>12&63]+x[e>>6&63]+"=";}return r}(e)}}));var B;
415
418
 
416
419
  /*
417
420
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -4710,6 +4713,21 @@
4710
4713
  const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
4711
4714
  const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
4712
4715
  const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
4716
+ const WARNING_UNSORTED_CENTRAL_DIRECTORY = "unsorted central directory";
4717
+ const WARNING_UNKNOWN_VERSION = "unknown version needed to extract";
4718
+ const WARNING_COMPRESSED_PATCHED_DATA = "compressed patched data";
4719
+ const WARNING_MALFORMED_EXTRA_FIELD = "malformed extra field";
4720
+ const WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = "unknown zip64 extensible data";
4721
+ const WARNING_WRAPPED_ENTRIES_COUNT = "wrapped entries count";
4722
+ const WARNING_APPENDED_DATA = "appended data";
4723
+ const WARNING_PREPENDED_DATA = "prepended data";
4724
+ const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4725
+ const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4726
+ const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
4727
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
4728
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
4729
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
4730
+ const MAX_KNOWN_VERSION = 63;
4713
4731
  const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
4714
4732
  const CHARSET_UTF8 = "utf-8";
4715
4733
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
@@ -4760,6 +4778,7 @@
4760
4778
  if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
4761
4779
  throw new Error(ERR_BAD_FORMAT);
4762
4780
  }
4781
+ const warnings = zipReader.warnings = [];
4763
4782
  const strictness = getStrictness(options, zipReader.options);
4764
4783
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4765
4784
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
@@ -4783,8 +4802,12 @@
4783
4802
  const commentOffset = endOfDirectoryInfo.offset;
4784
4803
  const commentLength = getUint16$1(endOfDirectoryView, 20);
4785
4804
  const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
4786
- if (reader.size - appendedDataOffset > maxAppendedDataSize) {
4787
- throwAmbiguousArchive("appended data");
4805
+ const appendedDataLength = reader.size - appendedDataOffset;
4806
+ if (appendedDataLength > maxAppendedDataSize) {
4807
+ throwAmbiguousArchive(WARNING_APPENDED_DATA);
4808
+ }
4809
+ if (appendedDataLength > 0) {
4810
+ addWarning(warnings, WARNING_APPENDED_DATA);
4788
4811
  }
4789
4812
  let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
4790
4813
  const expectedLastDiskNumber = reader.lastDiskNumber || 0;
@@ -4838,23 +4861,23 @@
4838
4861
  }
4839
4862
  if (lastDiskNumber == MAX_16_BITS) {
4840
4863
  lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
4841
- } else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
4842
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4864
+ } else if (lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
4865
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4843
4866
  }
4844
4867
  if (diskNumber == MAX_16_BITS) {
4845
4868
  diskNumber = getUint32$1(endOfDirectoryView, 20);
4846
- } else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
4847
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4869
+ } else if (diskNumber != getUint32$1(endOfDirectoryView, 20)) {
4870
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4848
4871
  }
4849
4872
  if (filesLength == MAX_16_BITS) {
4850
4873
  filesLength = getBigUint64(endOfDirectoryView, 32);
4851
- } else if (checkAmbiguity && filesLength != getBigUint64(endOfDirectoryView, 32)) {
4852
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4874
+ } else if (filesLength != getBigUint64(endOfDirectoryView, 32)) {
4875
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4853
4876
  }
4854
4877
  if (directoryDataLength == MAX_32_BITS) {
4855
4878
  directoryDataLength = getBigUint64(endOfDirectoryView, 40);
4856
- } else if (checkAmbiguity && directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
4857
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4879
+ } else if (directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
4880
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4858
4881
  }
4859
4882
  directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4860
4883
  }
@@ -4923,11 +4946,23 @@
4923
4946
  declaredDirectoryDataLength = directoryArray.length;
4924
4947
  decryptedDirectory = true;
4925
4948
  }
4949
+ if (directoryEncryptionInfo && !decryptedDirectory &&
4950
+ (directoryArray.length < 4 || getUint32$1(directoryView, 0) == CENTRAL_FILE_HEADER_SIGNATURE)) {
4951
+ addWarning(warnings, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA);
4952
+ }
4926
4953
  startOffset = directoryDataOffset;
4927
4954
  const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
4928
4955
  const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
4929
- const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
4956
+ const filenames = new Set();
4930
4957
  let duplicateFilename;
4958
+ let previousEntryPosition = -1;
4959
+ const recoverWrappedFilesLength = !checkAmbiguity && !zip64EndOfDirectory;
4960
+ if (!filesLength && recoverWrappedFilesLength) {
4961
+ filesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
4962
+ if (filesLength) {
4963
+ addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
4964
+ }
4965
+ }
4931
4966
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4932
4967
  const fileEntry = new ZipEntry(reader, zipReader.options);
4933
4968
  if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
@@ -5005,15 +5040,26 @@
5005
5040
  filename,
5006
5041
  comment
5007
5042
  });
5008
- readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
5043
+ if (readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)) {
5044
+ addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
5045
+ }
5009
5046
  fileEntry.offset += prependedDataLength;
5010
- startOffset = Math.min(getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset, startOffset);
5011
- if (checkAmbiguity) {
5012
- if (filenames.has(fileEntry.filename)) {
5013
- duplicateFilename = true;
5014
- }
5015
- filenames.add(fileEntry.filename);
5047
+ const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
5048
+ startOffset = Math.min(entryPosition, startOffset);
5049
+ if (entryPosition < previousEntryPosition) {
5050
+ addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
5051
+ }
5052
+ previousEntryPosition = entryPosition;
5053
+ if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
5054
+ addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
5055
+ }
5056
+ if ((fileEntry.rawBitFlag & BITFLAG_COMPRESSED_PATCHED_DATA) == BITFLAG_COMPRESSED_PATCHED_DATA) {
5057
+ addWarning(warnings, WARNING_COMPRESSED_PATCHED_DATA, filename);
5016
5058
  }
5059
+ if (filenames.has(fileEntry.filename)) {
5060
+ duplicateFilename = true;
5061
+ }
5062
+ filenames.add(fileEntry.filename);
5017
5063
  const unixExternalUpper = (fileEntry.externalFileAttributes >> 16) & MAX_16_BITS;
5018
5064
  if (fileEntry.unixMode === UNDEFINED_VALUE && (unixExternalUpper & (FILE_ATTR_UNIX_DEFAULT_MASK | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_TYPE_DIR)) != 0) {
5019
5065
  fileEntry.unixMode = unixExternalUpper;
@@ -5037,7 +5083,7 @@
5037
5083
  internalFileAttribute: fileEntry.internalFileAttributes,
5038
5084
  externalFileAttribute: fileEntry.externalFileAttributes,
5039
5085
  executable,
5040
- directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || (fileEntry.filename.endsWith(DIRECTORY_SIGNATURE) && !fileEntry.uncompressedSize),
5086
+ directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE),
5041
5087
  zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
5042
5088
  });
5043
5089
  const entry = new Entry(fileEntry);
@@ -5050,6 +5096,13 @@
5050
5096
  return arrayBufferPromise;
5051
5097
  };
5052
5098
  offset = endOffset;
5099
+ if (indexFile == filesLength - 1 && recoverWrappedFilesLength) {
5100
+ const wrappedFilesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
5101
+ if (wrappedFilesLength) {
5102
+ filesLength += wrappedFilesLength;
5103
+ addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
5104
+ }
5105
+ }
5053
5106
  const { onprogress } = options;
5054
5107
  if (onprogress) {
5055
5108
  try {
@@ -5074,18 +5127,22 @@
5074
5127
  zipReader.digitalSignature = digitalSignature;
5075
5128
  offsetAfterSignature = offset + 6 + digitalSignature.length;
5076
5129
  }
5077
- if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
5078
- throwAmbiguousArchive("trailing central directory data");
5130
+ if ((offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) ||
5131
+ (!decryptedDirectory && offset != directoryDataLength && offsetAfterSignature != directoryDataLength)) {
5132
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA);
5079
5133
  }
5080
5134
  if (duplicateFilename) {
5081
- throwAmbiguousArchive("duplicate filename");
5135
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_DUPLICATE_FILENAME);
5082
5136
  }
5083
5137
  const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
5084
5138
  const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
5085
5139
  const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
5086
5140
  startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
5087
5141
  if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
5088
- throwAmbiguousArchive("prepended data");
5142
+ throwAmbiguousArchive(WARNING_PREPENDED_DATA);
5143
+ }
5144
+ if (prependedDataLength || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
5145
+ addWarning(warnings, WARNING_PREPENDED_DATA);
5089
5146
  }
5090
5147
  if (extractPrependedData) {
5091
5148
  zipReader.prependedData = startOffset > splitZipSignatureLength ?
@@ -5155,6 +5212,28 @@
5155
5212
  }
5156
5213
  }
5157
5214
 
5215
+ async function isZipFile(reader, options = {}) {
5216
+ reader = new GenericReader(reader);
5217
+ await initStream(reader);
5218
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
5219
+ reader = new BlobReader(await streamToBlob(reader.readable));
5220
+ await initStream(reader);
5221
+ }
5222
+ if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
5223
+ return false;
5224
+ }
5225
+ const strictness = getStrictness(options, {});
5226
+ const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
5227
+ const maxAppendedDataSize = getMaxAppendedDataSize(options[OPTION_MAX_APPENDED_DATA_SIZE], strictness);
5228
+ const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
5229
+ if (!endOfDirectoryInfo || (strictness == STRICTNESS_STRICT && endOfDirectoryReachingEndCount > 1)) {
5230
+ return false;
5231
+ }
5232
+ const commentLength = getUint16$1(getDataView(endOfDirectoryInfo), 20);
5233
+ const appendedDataOffset = endOfDirectoryInfo.offset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
5234
+ return reader.size - appendedDataOffset <= maxAppendedDataSize;
5235
+ }
5236
+
5158
5237
  class ZipEntry {
5159
5238
 
5160
5239
  constructor(reader, options) {
@@ -5186,6 +5265,7 @@
5186
5265
  dataDescriptor
5187
5266
  } = bitFlag;
5188
5267
  const localDirectory = fileEntry.localDirectory = {};
5268
+ const warnings = fileEntry.warnings = [];
5189
5269
  const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
5190
5270
  const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
5191
5271
  const dataView = getDataView(dataArray);
@@ -5208,6 +5288,7 @@
5208
5288
  extraFieldLength,
5209
5289
  filenameLength
5210
5290
  } = localDirectory;
5291
+ const dataOffset = localDirectory.dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
5211
5292
  const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5212
5293
  const entryStrictness = getStrictness(options, zipEntry.options);
5213
5294
  const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
@@ -5225,10 +5306,10 @@
5225
5306
  if (checkLocalFilename) {
5226
5307
  localDirectory.rawFilename = rawLocalFilename;
5227
5308
  }
5228
- readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
5229
- if (checkLocalDirectory) {
5230
- validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
5309
+ if (readCommonFooter(zipEntry, localDirectory, dataView, 4, true)) {
5310
+ addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD);
5231
5311
  }
5312
+ validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
5232
5313
  const { lastAccessDate, creationDate, uid, gid } = localDirectory;
5233
5314
  if (lastAccessDate) {
5234
5315
  fileEntry.lastAccessDate = lastAccessDate;
@@ -5261,7 +5342,6 @@
5261
5342
  throw new Error(ERR_ENCRYPTED);
5262
5343
  }
5263
5344
  }
5264
- const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
5265
5345
  if (dataOffset + compressedSize > reader.size) {
5266
5346
  throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
5267
5347
  }
@@ -5381,6 +5461,16 @@
5381
5461
  return false;
5382
5462
  }
5383
5463
 
5464
+ function getWrappedFilesLength(directoryView, directoryArray, offset) {
5465
+ let wrappedFilesLength = 0;
5466
+ while (offset + CENTRAL_FILE_HEADER_LENGTH <= directoryArray.length && getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE) {
5467
+ offset += CENTRAL_FILE_HEADER_LENGTH +
5468
+ getUint16$1(directoryView, offset + 28) + getUint16$1(directoryView, offset + 30) + getUint16$1(directoryView, offset + 32);
5469
+ wrappedFilesLength++;
5470
+ }
5471
+ return wrappedFilesLength % (MAX_16_BITS + 1) ? 0 : wrappedFilesLength;
5472
+ }
5473
+
5384
5474
  function readDigitalSignature(signatureRecordArray) {
5385
5475
  if (signatureRecordArray.length >= 6) {
5386
5476
  const signatureRecordView = getDataView(signatureRecordArray);
@@ -5445,6 +5535,7 @@
5445
5535
  const extraField = directory.extraField = new Map();
5446
5536
  const rawExtraFieldView = getDataView(rawExtraField);
5447
5537
  let offsetExtraField = 0;
5538
+ let malformedExtraField = false;
5448
5539
  try {
5449
5540
  while (offsetExtraField < rawExtraField.length) {
5450
5541
  const type = getUint16$1(rawExtraFieldView, offsetExtraField);
@@ -5456,7 +5547,10 @@
5456
5547
  offsetExtraField += 4 + size;
5457
5548
  }
5458
5549
  } catch {
5459
- // ignored
5550
+ malformedExtraField = true;
5551
+ }
5552
+ if (offsetExtraField > rawExtraField.length) {
5553
+ malformedExtraField = true;
5460
5554
  }
5461
5555
  const compressionMethod = getUint16$1(dataView, offset + 4);
5462
5556
  Object.assign(directory, {
@@ -5524,6 +5618,7 @@
5524
5618
  if (extraFieldUSDZ) {
5525
5619
  directory.extraFieldUSDZ = extraFieldUSDZ;
5526
5620
  }
5621
+ return malformedExtraField;
5527
5622
  }
5528
5623
 
5529
5624
  function readExtraFieldZip64(extraFieldZip64, directory) {
@@ -5553,10 +5648,11 @@
5553
5648
  const computedCrc32View = getDataView(new Uint8Array(4));
5554
5649
  computedCrc32View.setUint32(0, computedCrc32.get(), true);
5555
5650
  const nameCrc32 = getUint32$1(extraFieldView, 1);
5651
+ const version = getUint8(extraFieldView, 0);
5556
5652
  Object.assign(extraFieldUnicode, {
5557
- version: getUint8(extraFieldView, 0),
5653
+ version,
5558
5654
  [propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
5559
- valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
5655
+ valid: version == 1 && !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
5560
5656
  });
5561
5657
  if (extraFieldUnicode.valid) {
5562
5658
  directory[propertyName] = extraFieldUnicode[propertyName];
@@ -5984,27 +6080,46 @@
5984
6080
  return UNDEFINED_VALUE;
5985
6081
  }
5986
6082
 
5987
- function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
6083
+ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, warnings) {
5988
6084
  const { rawFilename } = zipEntry;
6085
+ const reject = !warnings;
5989
6086
  const maskedLocalDirectory = zipEntry.decryptedDirectory &&
5990
6087
  (localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
5991
6088
  if (checkLocalFilename && !maskedLocalDirectory &&
5992
6089
  (rawLocalFilename.length != rawFilename.length ||
5993
6090
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
5994
- throwAmbiguousArchive("mismatched local file header (filename)");
6091
+ reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
5995
6092
  }
5996
6093
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
5997
- throwAmbiguousArchive("mismatched local file header (general purpose bit flag)");
6094
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
5998
6095
  }
5999
6096
  if (localDirectory.compressionMethod != zipEntry.compressionMethod) {
6000
- throwAmbiguousArchive("mismatched local file header (compression method)");
6097
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD);
6001
6098
  }
6002
6099
  if (!localDirectory.bitFlag.dataDescriptor && !maskedLocalDirectory &&
6003
6100
  (localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
6004
6101
  (localDirectory.crc32 != zipEntry.crc32 ||
6005
6102
  localDirectory.compressedSize != zipEntry.compressedSize ||
6006
6103
  localDirectory.uncompressedSize != zipEntry.uncompressedSize)) {
6007
- throwAmbiguousArchive("mismatched local file header (crc32 or sizes)");
6104
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
6105
+ }
6106
+ }
6107
+
6108
+ function reportAmbiguity(reject, warnings, reason) {
6109
+ if (reject) {
6110
+ throwAmbiguousArchive(reason);
6111
+ } else {
6112
+ addWarning(warnings, reason);
6113
+ }
6114
+ }
6115
+
6116
+ function addWarning(warnings, reason, filename) {
6117
+ if (!warnings.some(warning => warning.reason == reason)) {
6118
+ const warning = { reason };
6119
+ if (filename !== UNDEFINED_VALUE) {
6120
+ warning.filename = filename;
6121
+ }
6122
+ warnings.push(warning);
6008
6123
  }
6009
6124
  }
6010
6125
 
@@ -6025,7 +6140,8 @@
6025
6140
 
6026
6141
  function getDate(timeRaw) {
6027
6142
  const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
6028
- return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
6143
+ const result = new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
6144
+ return result < MIN_DATE ? MIN_DATE : result;
6029
6145
  }
6030
6146
 
6031
6147
  function getDateNTFS(timeRaw) {
@@ -6080,8 +6196,23 @@
6080
6196
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
6081
6197
  ERR_UNSUPPORTED_UINT64: ERR_UNSUPPORTED_UINT64,
6082
6198
  ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
6199
+ WARNING_APPENDED_DATA: WARNING_APPENDED_DATA,
6200
+ WARNING_COMPRESSED_PATCHED_DATA: WARNING_COMPRESSED_PATCHED_DATA,
6201
+ WARNING_DUPLICATE_FILENAME: WARNING_DUPLICATE_FILENAME,
6202
+ WARNING_MALFORMED_EXTRA_FIELD: WARNING_MALFORMED_EXTRA_FIELD,
6203
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6204
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6205
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
6206
+ WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
6207
+ WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
6208
+ WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
6209
+ WARNING_UNKNOWN_VERSION: WARNING_UNKNOWN_VERSION,
6210
+ WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA: WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA,
6211
+ WARNING_UNSORTED_CENTRAL_DIRECTORY: WARNING_UNSORTED_CENTRAL_DIRECTORY,
6212
+ WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
6083
6213
  ZipReader: ZipReader,
6084
- ZipReaderStream: ZipReaderStream
6214
+ ZipReaderStream: ZipReaderStream,
6215
+ isZipFile: isZipFile
6085
6216
  });
6086
6217
 
6087
6218
  /*
@@ -6178,153 +6309,151 @@
6178
6309
  offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
6179
6310
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
6180
6311
  pendingAddFileCalls: new Set(),
6312
+ pendingErrors: [],
6181
6313
  bufferedWrites: 0,
6182
6314
  lastFileEntry: UNDEFINED_VALUE
6183
6315
  });
6184
6316
  }
6185
6317
 
6186
- async prependZip(reader) {
6187
- if (this.filenames.size) {
6188
- throw new Error(ERR_ZIP_NOT_EMPTY);
6189
- }
6190
- reader = new GenericReader(reader);
6191
- await initStream(reader);
6192
- if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
6193
- reader = new BlobReader(await streamToBlob(reader.readable));
6194
- await initStream(reader);
6195
- }
6196
- const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
6197
- const zipReader$1 = new ZipReader(reader);
6198
- const entries = await zipReader$1.getEntries();
6199
- await zipReader$1.close();
6200
- await initStream(this.writer);
6201
- const { directoryOffset } = zipReader$1;
6202
- if (this.addSplitZipSignature) {
6203
- delete this.addSplitZipSignature;
6204
- if (!await startsWithSplitZipSignature(reader)) {
6205
- await writeData(this.writer, getSplitZipSignatureArray());
6206
- this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6207
- }
6208
- }
6209
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
6210
- this.filenames = new Set(entries.map(entry => entry.filename));
6211
- this.fileEntries = new Map(entries.map(entry => {
6212
- const {
6213
- version,
6214
- rawLastModDate,
6215
- lastAccessDate,
6216
- creationDate,
6217
- rawFilename,
6218
- bitFlag,
6219
- encrypted,
6220
- uncompressedSize,
6221
- compressedSize,
6222
- extraFieldZip64
6223
- } = entry;
6224
- let {
6225
- compressionMethod,
6226
- rawExtraFieldZip64,
6227
- rawExtraFieldAES,
6228
- rawExtraFieldExtendedTimestamp,
6229
- rawExtraFieldNTFS,
6230
- rawExtraFieldUnix,
6231
- rawExtraField,
6232
- } = entry;
6233
- const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
6234
- rawExtraFieldZip64 = rawExtraFieldZip64 || EMPTY_UINT8_ARRAY;
6235
- rawExtraFieldAES = rawExtraFieldAES || EMPTY_UINT8_ARRAY;
6236
- rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
6237
- rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
6238
- rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
6239
- rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
6240
- if (entry.extraFieldAES) {
6241
- compressionMethod = COMPRESSION_METHOD_AES;
6242
- }
6243
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
6244
- const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
6245
- const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
6246
- const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
6247
- const {
6248
- headerArray,
6249
- headerView
6250
- } = getHeaderArrayData({
6251
- version,
6252
- bitFlag: bitFlagValue,
6253
- compressionMethod,
6254
- uncompressedSize,
6255
- compressedSize,
6256
- rawLastModDate,
6257
- rawFilename,
6258
- zip64CompressedSize,
6259
- zip64UncompressedSize,
6260
- extraFieldLength
6261
- });
6262
- const { crc32 } = entry;
6263
- if (crc32 !== UNDEFINED_VALUE) {
6264
- setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
6265
- }
6266
- const { offset, diskNumberStart } = entryPositions.get(entry);
6267
- Object.assign(entry, {
6268
- zip64UncompressedSize,
6269
- zip64CompressedSize,
6270
- offset,
6271
- diskNumberStart,
6272
- zip64DiskNumberStart: false,
6273
- rawExtraFieldZip64,
6274
- rawExtraFieldAES,
6275
- rawExtraFieldExtendedTimestamp,
6276
- rawExtraFieldNTFS,
6277
- rawExtraFieldUnix,
6278
- rawExtraField,
6279
- extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
6280
- extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
6281
- headerArray,
6282
- headerView
6283
- });
6284
- return [entry.filename, entry];
6285
- }));
6318
+ prependZip(reader) {
6319
+ return watchPromiseError(this, prependZipEntries(this, reader));
6320
+ }
6321
+
6322
+ appendZip(reader) {
6323
+ return watchPromiseError(this, this.appendZipEntries(reader));
6286
6324
  }
6287
6325
 
6288
- async add(name = "", reader, options = {}) {
6326
+ async appendZipEntries(reader) {
6289
6327
  const zipWriter = this;
6290
- options = Object.assign({}, options);
6291
- const { pendingAddFileCalls } = zipWriter;
6292
- if (workers < getConfiguration().maxWorkers) {
6293
- workers++;
6294
- } else {
6295
- await new Promise(resolve => pendingEntries.push(resolve));
6328
+ const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
6329
+ while (pendingAddFileCalls.size) {
6330
+ await Promise.allSettled(Array.from(pendingAddFileCalls));
6296
6331
  }
6297
- let promiseAddFile;
6298
- let nameAdded;
6332
+ let resolveAppendZip;
6333
+ const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
6334
+ pendingAddFileCalls.add(promiseAppendZip);
6335
+ const appendedFilenames = [];
6336
+ let releaseLockWriter;
6299
6337
  try {
6300
- name = name.trim();
6301
- if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6302
- name += DIRECTORY_SIGNATURE;
6303
- }
6304
- if (zipWriter.filenames.has(name)) {
6305
- throw new Error(ERR_DUPLICATED_NAME);
6306
- }
6307
- zipWriter.filenames.add(name);
6308
- nameAdded = true;
6309
- promiseAddFile = addFile(zipWriter, name, reader, options);
6310
- pendingAddFileCalls.add(promiseAddFile);
6311
- return await promiseAddFile;
6312
- } catch (error) {
6313
- if (nameAdded) {
6314
- zipWriter.filenames.delete(name);
6338
+ reader = new GenericReader(reader);
6339
+ await initStream(reader);
6340
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
6341
+ reader = new BlobReader(await streamToBlob(reader.readable));
6342
+ await initStream(reader);
6343
+ }
6344
+ const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
6345
+ const zipReader$1 = new ZipReader(reader);
6346
+ const entries = await zipReader$1.getEntries();
6347
+ await zipReader$1.close();
6348
+ await initStream(zipWriter.writer);
6349
+ const { directoryOffset } = zipReader$1;
6350
+ entries.forEach(({ filename }) => {
6351
+ if (filenames.has(filename)) {
6352
+ throw new Error(ERR_DUPLICATED_NAME);
6353
+ }
6354
+ filenames.add(filename);
6355
+ appendedFilenames.push(filename);
6356
+ });
6357
+ zipWriter.writerLocked = true;
6358
+ const { lockWriter } = zipWriter;
6359
+ zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
6360
+ zipWriter.writerLocked = false;
6361
+ resolve();
6362
+ });
6363
+ await lockWriter;
6364
+ if (zipWriter.addSplitZipSignature) {
6365
+ delete zipWriter.addSplitZipSignature;
6366
+ if (!await startsWithSplitZipSignature(reader)) {
6367
+ await writeData(zipWriter.writer, getSplitZipSignatureArray());
6368
+ zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6369
+ }
6315
6370
  }
6371
+ const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
6372
+ entries.forEach(entry => {
6373
+ const {
6374
+ version,
6375
+ rawLastModDate,
6376
+ rawFilename,
6377
+ bitFlag,
6378
+ encrypted,
6379
+ uncompressedSize,
6380
+ compressedSize,
6381
+ extraFieldZip64
6382
+ } = entry;
6383
+ let {
6384
+ compressionMethod,
6385
+ rawExtraField,
6386
+ } = entry;
6387
+ const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
6388
+ rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
6389
+ if (entry.extraFieldAES) {
6390
+ compressionMethod = COMPRESSION_METHOD_AES;
6391
+ }
6392
+ const extraFieldLength = getLength(rawExtraField);
6393
+ const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
6394
+ const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
6395
+ const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
6396
+ const {
6397
+ headerArray,
6398
+ headerView
6399
+ } = getHeaderArrayData({
6400
+ version,
6401
+ bitFlag: bitFlagValue,
6402
+ compressionMethod,
6403
+ uncompressedSize,
6404
+ compressedSize,
6405
+ rawLastModDate,
6406
+ rawFilename,
6407
+ zip64CompressedSize,
6408
+ zip64UncompressedSize,
6409
+ extraFieldLength
6410
+ });
6411
+ const { crc32 } = entry;
6412
+ if (crc32 !== UNDEFINED_VALUE) {
6413
+ setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
6414
+ }
6415
+ const { offset, diskNumberStart } = entryPositions.get(entry);
6416
+ Object.assign(entry, {
6417
+ zip64UncompressedSize,
6418
+ zip64CompressedSize,
6419
+ offset,
6420
+ diskNumberStart,
6421
+ zip64DiskNumberStart: false,
6422
+ rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
6423
+ rawExtraFieldAES: EMPTY_UINT8_ARRAY,
6424
+ rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
6425
+ rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
6426
+ rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
6427
+ rawExtraField,
6428
+ rawCentralExtraField: EMPTY_UINT8_ARRAY,
6429
+ extendedTimestamp: false,
6430
+ headerArray,
6431
+ headerView
6432
+ });
6433
+ fileEntries.set(entry.filename, entry);
6434
+ });
6435
+ } catch (error) {
6436
+ appendedFilenames.forEach(filename => filenames.delete(filename));
6316
6437
  throw error;
6317
6438
  } finally {
6318
- pendingAddFileCalls.delete(promiseAddFile);
6319
- const pendingEntry = pendingEntries.shift();
6320
- if (pendingEntry) {
6321
- pendingEntry();
6322
- } else {
6323
- workers--;
6439
+ resolveAppendZip();
6440
+ pendingAddFileCalls.delete(promiseAppendZip);
6441
+ if (releaseLockWriter) {
6442
+ releaseLockWriter();
6324
6443
  }
6325
6444
  }
6326
6445
  }
6327
6446
 
6447
+ add(name = "", reader, options = {}) {
6448
+ const zipWriter = this;
6449
+ const { pendingAddFileCalls } = zipWriter;
6450
+ const promiseAddFile = addFileEntry(zipWriter, name, reader, options);
6451
+ pendingAddFileCalls.add(promiseAddFile);
6452
+ const deletePendingAddFileCall = () => pendingAddFileCalls.delete(promiseAddFile);
6453
+ Promise.prototype.then.call(promiseAddFile, deletePendingAddFileCall, deletePendingAddFileCall);
6454
+ return watchPromiseError(zipWriter, promiseAddFile);
6455
+ }
6456
+
6328
6457
  remove(entry) {
6329
6458
  const { filenames, fileEntries } = this;
6330
6459
  // deno-lint-ignore valid-typeof
@@ -6355,6 +6484,19 @@
6355
6484
  while (pendingAddFileCalls.size) {
6356
6485
  await Promise.allSettled(Array.from(pendingAddFileCalls));
6357
6486
  }
6487
+ await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
6488
+ const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
6489
+ if (unobservedWatchers.length) {
6490
+ const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
6491
+ unobservedWatchers.forEach(watcher => watcher.observed = true);
6492
+ const [error] = unobservedErrors;
6493
+ try {
6494
+ error.entryErrors = unobservedErrors;
6495
+ } catch {
6496
+ // ignored
6497
+ }
6498
+ throw error;
6499
+ }
6358
6500
  await closeFile(zipWriter, comment, options);
6359
6501
  const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
6360
6502
  if (!preventClose) {
@@ -6389,11 +6531,7 @@
6389
6531
  try {
6390
6532
  await zipWriter.close();
6391
6533
  } catch (error) {
6392
- try {
6393
- await zipWriter.writer.writable.abort(error);
6394
- } catch {
6395
- // ignored
6396
- }
6534
+ await abortWritable(zipWriter, error);
6397
6535
  }
6398
6536
  }
6399
6537
  }
@@ -6410,8 +6548,89 @@
6410
6548
  }
6411
6549
 
6412
6550
  async close(comment = UNDEFINED_VALUE, options = {}) {
6413
- await Promise.all(Array.from(this.pendingAddFileCalls));
6414
- return this.zipWriter.close(comment, options);
6551
+ const { zipWriter } = this;
6552
+ const results = await Promise.allSettled(Array.from(this.pendingAddFileCalls));
6553
+ const entryErrors = results.filter(result => result.status == "rejected").map(result => result.reason);
6554
+ if (entryErrors.length) {
6555
+ const [error] = entryErrors;
6556
+ try {
6557
+ error.entryErrors = entryErrors;
6558
+ } catch {
6559
+ // ignored
6560
+ }
6561
+ await abortWritable(zipWriter, error);
6562
+ throw error;
6563
+ }
6564
+ try {
6565
+ return await zipWriter.close(comment, options);
6566
+ } catch (error) {
6567
+ await abortWritable(zipWriter, error);
6568
+ throw error;
6569
+ }
6570
+ }
6571
+ }
6572
+
6573
+ class WatchedPromise extends Promise {
6574
+
6575
+ then(onFulfilled, onRejected) {
6576
+ const { watcher } = this;
6577
+ if (watcher) {
6578
+ watcher.observed = true;
6579
+ }
6580
+ return super.then(onFulfilled, onRejected);
6581
+ }
6582
+ }
6583
+
6584
+ function watchPromiseError(zipWriter, promise) {
6585
+ const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
6586
+ const watcher = {};
6587
+ watchedPromise.watcher = watcher;
6588
+ watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
6589
+ zipWriter.pendingErrors.push(watcher);
6590
+ return watchedPromise;
6591
+ }
6592
+
6593
+ async function prependZipEntries(zipWriter, reader) {
6594
+ if (zipWriter.filenames.size) {
6595
+ throw new Error(ERR_ZIP_NOT_EMPTY);
6596
+ }
6597
+ await zipWriter.appendZipEntries(reader);
6598
+ }
6599
+
6600
+ async function addFileEntry(zipWriter, name, reader, options) {
6601
+ options = Object.assign({}, options);
6602
+ if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6603
+ name += DIRECTORY_SIGNATURE;
6604
+ }
6605
+ if (zipWriter.filenames.has(name)) {
6606
+ throw new Error(ERR_DUPLICATED_NAME);
6607
+ }
6608
+ zipWriter.filenames.add(name);
6609
+ if (workers < getConfiguration().maxWorkers) {
6610
+ workers++;
6611
+ } else {
6612
+ await new Promise(resolve => pendingEntries.push(resolve));
6613
+ }
6614
+ try {
6615
+ return await addFile(zipWriter, name, reader, options);
6616
+ } catch (error) {
6617
+ zipWriter.filenames.delete(name);
6618
+ throw error;
6619
+ } finally {
6620
+ const pendingEntry = pendingEntries.shift();
6621
+ if (pendingEntry) {
6622
+ pendingEntry();
6623
+ } else {
6624
+ workers--;
6625
+ }
6626
+ }
6627
+ }
6628
+
6629
+ async function abortWritable(zipWriter, error) {
6630
+ try {
6631
+ await zipWriter.writer.writable.abort(error);
6632
+ } catch {
6633
+ // ignored
6415
6634
  }
6416
6635
  }
6417
6636
 
@@ -6470,7 +6689,6 @@
6470
6689
  }
6471
6690
 
6472
6691
  function resolveAttributes(zipWriter, name, options) {
6473
- name = name.trim();
6474
6692
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6475
6693
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
6476
6694
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
@@ -6614,11 +6832,12 @@
6614
6832
  if (getLength(rawComment) > MAX_16_BITS) {
6615
6833
  throw new Error(ERR_INVALID_ENTRY_COMMENT);
6616
6834
  }
6617
- const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION, VERSION_DEFLATE);
6618
- if (version > MAX_16_BITS) {
6835
+ const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION);
6836
+ if (version !== UNDEFINED_VALUE && version > MAX_16_BITS) {
6619
6837
  throw new Error(ERR_INVALID_VERSION);
6620
6838
  }
6621
6839
  const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
6840
+ const rawLastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
6622
6841
  const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6623
6842
  const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6624
6843
  const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
@@ -6662,7 +6881,7 @@
6662
6881
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
6663
6882
  dataDescriptor = false;
6664
6883
  }
6665
- if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
6884
+ if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
6666
6885
  dataDescriptor = true;
6667
6886
  }
6668
6887
  if (level !== UNDEFINED_VALUE && level != 6) {
@@ -6674,6 +6893,7 @@
6674
6893
  }
6675
6894
  const rawExtraField = serializeExtraField(options[PROPERTY_NAME_EXTRA_FIELD]);
6676
6895
  const rawLocalExtraField = serializeExtraField(options[OPTION_LOCAL_EXTRA_FIELD]);
6896
+ const rawCentralExtraField = serializeExtraField(options[OPTION_CENTRAL_EXTRA_FIELD]);
6677
6897
  return {
6678
6898
  comment,
6679
6899
  resolvedOptions: {
@@ -6681,6 +6901,7 @@
6681
6901
  rawComment,
6682
6902
  version,
6683
6903
  lastModDate,
6904
+ rawLastModDate,
6684
6905
  lastAccessDate,
6685
6906
  creationDate,
6686
6907
  internalFileAttributes,
@@ -6708,7 +6929,8 @@
6708
6929
  dataDescriptor,
6709
6930
  zip64,
6710
6931
  rawExtraField,
6711
- rawLocalExtraField
6932
+ rawLocalExtraField,
6933
+ rawCentralExtraField
6712
6934
  }
6713
6935
  };
6714
6936
  }
@@ -6877,10 +7099,8 @@
6877
7099
  }
6878
7100
  await initStream(fileWriter);
6879
7101
  const diskOffset = getDiskOffset(writer);
6880
- if (zipWriter.addSplitZipSignature) {
6881
- delete zipWriter.addSplitZipSignature;
6882
- await writeData(writer, getSplitZipSignatureArray());
6883
- zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
7102
+ if (zipWriter.addSplitZipSignature && !bufferedWrite) {
7103
+ await writeSplitZipSignature(zipWriter, writer);
6884
7104
  }
6885
7105
  if (usdz && !bufferedWrite) {
6886
7106
  appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
@@ -6907,6 +7127,9 @@
6907
7127
  if (bufferedWrite) {
6908
7128
  await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
6909
7129
  await requestLockWriter();
7130
+ if (zipWriter.addSplitZipSignature) {
7131
+ await writeSplitZipSignature(zipWriter, writer);
7132
+ }
6910
7133
  writingBufferedEntryData = true;
6911
7134
  writerSizeBeforeEntry = writer.size;
6912
7135
  await skipDiskIfNeeded();
@@ -7026,6 +7249,7 @@
7026
7249
  versionMadeBy,
7027
7250
  rawComment,
7028
7251
  rawExtraField,
7252
+ rawCentralExtraField,
7029
7253
  useWebWorkers,
7030
7254
  transferStreams,
7031
7255
  onstart,
@@ -7069,6 +7293,7 @@
7069
7293
  rawExtraFieldUnix,
7070
7294
  rawExtraFieldAES,
7071
7295
  rawExtraField,
7296
+ rawCentralExtraField,
7072
7297
  extendedTimestamp,
7073
7298
  msDosCompatible,
7074
7299
  internalFileAttributes,
@@ -7178,6 +7403,7 @@
7178
7403
  const {
7179
7404
  rawFilename,
7180
7405
  lastModDate,
7406
+ rawLastModDate: rawLastModDateOption,
7181
7407
  lastAccessDate,
7182
7408
  creationDate,
7183
7409
  level,
@@ -7311,6 +7537,9 @@
7311
7537
  if (compressionMethod === UNDEFINED_VALUE) {
7312
7538
  compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
7313
7539
  }
7540
+ if (version === UNDEFINED_VALUE) {
7541
+ version = compressionMethod == COMPRESSION_METHOD_STORE && !directory && !encrypted ? VERSION_STORE : VERSION_DEFLATE;
7542
+ }
7314
7543
  const { codecVersionNeeded } = options;
7315
7544
  if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
7316
7545
  version = version > codecVersionNeeded ? version : codecVersionNeeded;
@@ -7343,6 +7572,7 @@
7343
7572
  compressionMethod,
7344
7573
  uncompressedSize,
7345
7574
  lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
7575
+ rawLastModDate: rawLastModDateOption,
7346
7576
  rawFilename,
7347
7577
  zip64CompressedSize,
7348
7578
  zip64UncompressedSize,
@@ -7549,9 +7779,9 @@
7549
7779
 
7550
7780
  async function closeFile(zipWriter, comment, options) {
7551
7781
  const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
7552
- const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7782
+ const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7553
7783
  const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
7554
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
7784
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
7555
7785
  }
7556
7786
 
7557
7787
  function createDirectoryRecords(files) {
@@ -7564,6 +7794,7 @@
7564
7794
  rawExtraFieldNTFS,
7565
7795
  rawExtraFieldUnix,
7566
7796
  rawExtraField,
7797
+ rawCentralExtraField,
7567
7798
  extendedTimestamp,
7568
7799
  extraFieldExtendedTimestampFlag,
7569
7800
  lastModDate,
@@ -7618,7 +7849,8 @@
7618
7849
  rawExtraFieldNTFS,
7619
7850
  rawExtraFieldUnix,
7620
7851
  rawExtraFieldTimestamp,
7621
- rawExtraField);
7852
+ rawExtraField,
7853
+ rawCentralExtraField);
7622
7854
  if (extraFieldLength > MAX_16_BITS) {
7623
7855
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
7624
7856
  }
@@ -7635,6 +7867,7 @@
7635
7867
  let directoryDiskOffset = 0;
7636
7868
  let directoryStartDiskNumber = getDiskNumber(writer);
7637
7869
  let directoryStartDiskOffset = getDiskOffset(writer);
7870
+ let directoryEndDiskEntriesLength = 0;
7638
7871
  for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
7639
7872
  const {
7640
7873
  offset: fileEntryOffset,
@@ -7645,6 +7878,7 @@
7645
7878
  rawExtraFieldNTFS,
7646
7879
  rawExtraFieldUnix,
7647
7880
  rawExtraField,
7881
+ rawCentralExtraField,
7648
7882
  rawComment,
7649
7883
  versionMadeBy,
7650
7884
  headerArray,
@@ -7659,11 +7893,12 @@
7659
7893
  uncompressedSize,
7660
7894
  compressedSize
7661
7895
  } = fileEntry;
7662
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
7896
+ const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawCentralExtraField);
7663
7897
  const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
7664
7898
  if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
7665
7899
  await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
7666
7900
  directoryDiskOffset = offset;
7901
+ directoryEndDiskEntriesLength = 0;
7667
7902
  await writer.closeDisk();
7668
7903
  }
7669
7904
  if (indexFileEntry == 0) {
@@ -7696,9 +7931,11 @@
7696
7931
  directoryRecord.writeBytes(rawExtraFieldNTFS);
7697
7932
  directoryRecord.writeBytes(rawExtraFieldUnix);
7698
7933
  directoryRecord.writeBytes(rawExtraField);
7934
+ directoryRecord.writeBytes(rawCentralExtraField);
7699
7935
  directoryRecord.writeBytes(rawComment);
7700
7936
  arraySet(directoryArray, directoryRecord.array, offset);
7701
7937
  offset += directoryRecordLength;
7938
+ directoryEndDiskEntriesLength++;
7702
7939
  if (options.onprogress) {
7703
7940
  try {
7704
7941
  await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
@@ -7710,6 +7947,7 @@
7710
7947
  await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
7711
7948
  return {
7712
7949
  directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
7950
+ directoryEnd: { diskNumber: getDiskNumber(writer), entriesLength: directoryEndDiskEntriesLength },
7713
7951
  directoryArray
7714
7952
  };
7715
7953
  }
@@ -7738,16 +7976,20 @@
7738
7976
 
7739
7977
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7740
7978
  const { writer } = zipWriter;
7741
- const { directoryStart, signatureLength } = cdInfo;
7979
+ const { directoryStart, directoryEnd, signatureLength } = cdInfo;
7742
7980
  let { directoryDataLength } = cdInfo;
7743
7981
  let fileEntriesLength = zipWriter.fileEntries.size;
7744
7982
  let diskNumber = directoryStart.diskNumber;
7745
7983
  let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
7984
+ const commentLength = getLength(comment);
7985
+ if (commentLength > MAX_16_BITS) {
7986
+ throw new Error(ERR_INVALID_COMMENT);
7987
+ }
7988
+ let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
7746
7989
  let lastDiskNumber = getDiskNumber(writer);
7747
- if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
7990
+ if (exceedsAvailableSize(writer, (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH) + commentLength)) {
7748
7991
  lastDiskNumber++;
7749
7992
  }
7750
- let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
7751
7993
  if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
7752
7994
  if (zip64 === false) {
7753
7995
  throw new Error(ERR_UNSUPPORTED_FORMAT);
@@ -7755,15 +7997,12 @@
7755
7997
  zip64 = true;
7756
7998
  }
7757
7999
  }
7758
- const commentLength = getLength(comment);
7759
- if (commentLength > MAX_16_BITS) {
7760
- throw new Error(ERR_INVALID_COMMENT);
7761
- }
7762
8000
  const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
7763
8001
  if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
7764
8002
  await writer.closeDisk();
7765
8003
  }
7766
8004
  lastDiskNumber = getDiskNumber(writer);
8005
+ let diskFileEntriesLength = lastDiskNumber == directoryEnd.diskNumber ? directoryEnd.entriesLength : 0;
7767
8006
  if (zip64) {
7768
8007
  endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
7769
8008
  endOfdirectoryRecord.writeUint64(44);
@@ -7771,7 +8010,7 @@
7771
8010
  endOfdirectoryRecord.writeUint16(45);
7772
8011
  endOfdirectoryRecord.writeUint32(lastDiskNumber);
7773
8012
  endOfdirectoryRecord.writeUint32(diskNumber);
7774
- endOfdirectoryRecord.writeUint64(fileEntriesLength);
8013
+ endOfdirectoryRecord.writeUint64(diskFileEntriesLength);
7775
8014
  endOfdirectoryRecord.writeUint64(fileEntriesLength);
7776
8015
  endOfdirectoryRecord.writeUint64(directoryDataLength);
7777
8016
  endOfdirectoryRecord.writeUint64(directoryOffset);
@@ -7784,6 +8023,7 @@
7784
8023
  lastDiskNumber = MAX_16_BITS;
7785
8024
  diskNumber = MAX_16_BITS;
7786
8025
  }
8026
+ diskFileEntriesLength = MAX_16_BITS;
7787
8027
  fileEntriesLength = MAX_16_BITS;
7788
8028
  directoryOffset = MAX_32_BITS;
7789
8029
  directoryDataLength = MAX_32_BITS;
@@ -7791,7 +8031,7 @@
7791
8031
  endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
7792
8032
  endOfdirectoryRecord.writeUint16(lastDiskNumber);
7793
8033
  endOfdirectoryRecord.writeUint16(diskNumber);
7794
- endOfdirectoryRecord.writeUint16(fileEntriesLength);
8034
+ endOfdirectoryRecord.writeUint16(diskFileEntriesLength);
7795
8035
  endOfdirectoryRecord.writeUint16(fileEntriesLength);
7796
8036
  endOfdirectoryRecord.writeUint32(directoryDataLength);
7797
8037
  endOfdirectoryRecord.writeUint32(directoryOffset);
@@ -7890,9 +8130,21 @@
7890
8130
  async function copyData(zipWriter, reader, offset, size) {
7891
8131
  if (size > 0) {
7892
8132
  const { writer } = zipWriter;
7893
- await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
7894
- writer.size += size;
7895
- zipWriter.offset += size;
8133
+ let copiedLength = 0;
8134
+ try {
8135
+ await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
8136
+ } catch (error) {
8137
+ zipWriter.hasCorruptedEntries = true;
8138
+ try {
8139
+ error.corruptedEntry = true;
8140
+ } catch {
8141
+ // ignored
8142
+ }
8143
+ throw error;
8144
+ } finally {
8145
+ writer.size += copiedLength;
8146
+ zipWriter.offset += copiedLength;
8147
+ }
7896
8148
  }
7897
8149
  }
7898
8150
 
@@ -7917,6 +8169,12 @@
7917
8169
  return signatureArray;
7918
8170
  }
7919
8171
 
8172
+ async function writeSplitZipSignature(zipWriter, writer) {
8173
+ delete zipWriter.addSplitZipSignature;
8174
+ await writeData(writer, getSplitZipSignatureArray());
8175
+ zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
8176
+ }
8177
+
7920
8178
  async function writeData(writer, array) {
7921
8179
  const { writable } = writer;
7922
8180
  const streamWriter = writable.getWriter();
@@ -8662,7 +8920,7 @@
8662
8920
  */
8663
8921
 
8664
8922
 
8665
- p$1(setDefaultConfiguration);
8923
+ c(setDefaultConfiguration);
8666
8924
 
8667
8925
  exports.BlobReader = BlobReader;
8668
8926
  exports.BlobWriter = BlobWriter;
@@ -8746,6 +9004,20 @@
8746
9004
  exports.TextWriter = TextWriter;
8747
9005
  exports.Uint8ArrayReader = Uint8ArrayReader;
8748
9006
  exports.Uint8ArrayWriter = Uint8ArrayWriter;
9007
+ exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
9008
+ exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
9009
+ exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
9010
+ exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
9011
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
9012
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
9013
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
9014
+ exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
9015
+ exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
9016
+ exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;
9017
+ exports.WARNING_UNKNOWN_VERSION = WARNING_UNKNOWN_VERSION;
9018
+ exports.WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA;
9019
+ exports.WARNING_UNSORTED_CENTRAL_DIRECTORY = WARNING_UNSORTED_CENTRAL_DIRECTORY;
9020
+ exports.WARNING_WRAPPED_ENTRIES_COUNT = WARNING_WRAPPED_ENTRIES_COUNT;
8749
9021
  exports.Writer = Writer;
8750
9022
  exports.ZipReader = ZipReader;
8751
9023
  exports.ZipReaderStream = ZipReaderStream;
@@ -8756,6 +9028,7 @@
8756
9028
  exports.createOPFSTempStream = createOPFSTempStream;
8757
9029
  exports.createSyncAccessHandleTempStream = createSyncAccessHandleTempStream;
8758
9030
  exports.getMimeType = getMimeType;
9031
+ exports.isZipFile = isZipFile;
8759
9032
  exports.registerCodec = registerCodec;
8760
9033
  exports.resetConfiguration = resetConfiguration;
8761
9034
  exports.terminateWorkers = terminateWorkers;