@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.
package/index-native.cjs CHANGED
@@ -77,6 +77,7 @@ const BITFLAG_LEVEL_MAX_MASK = 0b010;
77
77
  const BITFLAG_LEVEL_FAST_MASK = 0b100;
78
78
  const BITFLAG_LEVEL_SUPER_FAST_MASK = 0b110;
79
79
  const BITFLAG_DATA_DESCRIPTOR = 0b1000;
80
+ const BITFLAG_COMPRESSED_PATCHED_DATA = 0b100000;
80
81
  const BITFLAG_STRONG_ENCRYPTION = 0b1000000;
81
82
  const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
82
83
  const BITFLAG_MASKED_LOCAL_HEADERS = 0b10000000000000;
@@ -95,6 +96,7 @@ const FILE_ATTR_UNIX_SETUID_MASK = 0o4000;
95
96
  const FILE_ATTR_UNIX_SETGID_MASK = 0o2000;
96
97
  const FILE_ATTR_UNIX_STICKY_MASK = 0o1000;
97
98
 
99
+ const VERSION_STORE = 0x0A;
98
100
  const VERSION_DEFLATE = 0x14;
99
101
  const VERSION_ZIP64 = 0x2D;
100
102
  const VERSION_AES = 0x33;
@@ -193,6 +195,7 @@ const OPTION_OFFSET = "offset";
193
195
  const OPTION_USDZ = "usdz";
194
196
  const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
195
197
  const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
198
+ const OPTION_CENTRAL_EXTRA_FIELD = "centralExtraField";
196
199
  const OPTION_STRICTNESS = "strictness";
197
200
  const OPTION_FILENAME_VALIDATION = "filenameValidation";
198
201
  const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
@@ -405,7 +408,7 @@ function resetConfiguration() {
405
408
  Object.assign(config, DEFAULT_CONFIGURATION);
406
409
  }
407
410
 
408
- 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;
411
+ 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;
409
412
 
410
413
  /*
411
414
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -4724,6 +4727,21 @@ const ERR_INVALID_STRICTNESS = "Invalid strictness (must be 'strict', 'balanced'
4724
4727
  const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
4725
4728
  const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
4726
4729
  const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
4730
+ const WARNING_UNSORTED_CENTRAL_DIRECTORY = "unsorted central directory";
4731
+ const WARNING_UNKNOWN_VERSION = "unknown version needed to extract";
4732
+ const WARNING_COMPRESSED_PATCHED_DATA = "compressed patched data";
4733
+ const WARNING_MALFORMED_EXTRA_FIELD = "malformed extra field";
4734
+ const WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = "unknown zip64 extensible data";
4735
+ const WARNING_WRAPPED_ENTRIES_COUNT = "wrapped entries count";
4736
+ const WARNING_APPENDED_DATA = "appended data";
4737
+ const WARNING_PREPENDED_DATA = "prepended data";
4738
+ const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
4739
+ const WARNING_DUPLICATE_FILENAME = "duplicate filename";
4740
+ const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
4741
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
4742
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
4743
+ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
4744
+ const MAX_KNOWN_VERSION = 63;
4727
4745
  const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
4728
4746
  const CHARSET_UTF8 = "utf-8";
4729
4747
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
@@ -4774,6 +4792,7 @@ class ZipReader {
4774
4792
  if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
4775
4793
  throw new Error(ERR_BAD_FORMAT);
4776
4794
  }
4795
+ const warnings = zipReader.warnings = [];
4777
4796
  const strictness = getStrictness(options, zipReader.options);
4778
4797
  const checkAmbiguity = strictness == STRICTNESS_STRICT;
4779
4798
  const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
@@ -4797,8 +4816,12 @@ class ZipReader {
4797
4816
  const commentOffset = endOfDirectoryInfo.offset;
4798
4817
  const commentLength = getUint16$1(endOfDirectoryView, 20);
4799
4818
  const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
4800
- if (reader.size - appendedDataOffset > maxAppendedDataSize) {
4801
- throwAmbiguousArchive("appended data");
4819
+ const appendedDataLength = reader.size - appendedDataOffset;
4820
+ if (appendedDataLength > maxAppendedDataSize) {
4821
+ throwAmbiguousArchive(WARNING_APPENDED_DATA);
4822
+ }
4823
+ if (appendedDataLength > 0) {
4824
+ addWarning(warnings, WARNING_APPENDED_DATA);
4802
4825
  }
4803
4826
  let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
4804
4827
  const expectedLastDiskNumber = reader.lastDiskNumber || 0;
@@ -4852,23 +4875,23 @@ class ZipReader {
4852
4875
  }
4853
4876
  if (lastDiskNumber == MAX_16_BITS) {
4854
4877
  lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
4855
- } else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
4856
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4878
+ } else if (lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
4879
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4857
4880
  }
4858
4881
  if (diskNumber == MAX_16_BITS) {
4859
4882
  diskNumber = getUint32$1(endOfDirectoryView, 20);
4860
- } else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
4861
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4883
+ } else if (diskNumber != getUint32$1(endOfDirectoryView, 20)) {
4884
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4862
4885
  }
4863
4886
  if (filesLength == MAX_16_BITS) {
4864
4887
  filesLength = getBigUint64(endOfDirectoryView, 32);
4865
- } else if (checkAmbiguity && filesLength != getBigUint64(endOfDirectoryView, 32)) {
4866
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4888
+ } else if (filesLength != getBigUint64(endOfDirectoryView, 32)) {
4889
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4867
4890
  }
4868
4891
  if (directoryDataLength == MAX_32_BITS) {
4869
4892
  directoryDataLength = getBigUint64(endOfDirectoryView, 40);
4870
- } else if (checkAmbiguity && directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
4871
- throwAmbiguousArchive("mismatched zip64 end of central directory record");
4893
+ } else if (directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
4894
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
4872
4895
  }
4873
4896
  directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4874
4897
  }
@@ -4937,11 +4960,23 @@ class ZipReader {
4937
4960
  declaredDirectoryDataLength = directoryArray.length;
4938
4961
  decryptedDirectory = true;
4939
4962
  }
4963
+ if (directoryEncryptionInfo && !decryptedDirectory &&
4964
+ (directoryArray.length < 4 || getUint32$1(directoryView, 0) == CENTRAL_FILE_HEADER_SIGNATURE)) {
4965
+ addWarning(warnings, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA);
4966
+ }
4940
4967
  startOffset = directoryDataOffset;
4941
4968
  const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
4942
4969
  const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
4943
- const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
4970
+ const filenames = new Set();
4944
4971
  let duplicateFilename;
4972
+ let previousEntryPosition = -1;
4973
+ const recoverWrappedFilesLength = !checkAmbiguity && !zip64EndOfDirectory;
4974
+ if (!filesLength && recoverWrappedFilesLength) {
4975
+ filesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
4976
+ if (filesLength) {
4977
+ addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
4978
+ }
4979
+ }
4945
4980
  for (let indexFile = 0; indexFile < filesLength; indexFile++) {
4946
4981
  const fileEntry = new ZipEntry$1(reader, zipReader.options);
4947
4982
  if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
@@ -5019,15 +5054,26 @@ class ZipReader {
5019
5054
  filename,
5020
5055
  comment
5021
5056
  });
5022
- readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
5057
+ if (readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)) {
5058
+ addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
5059
+ }
5023
5060
  fileEntry.offset += prependedDataLength;
5024
- startOffset = Math.min(getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset, startOffset);
5025
- if (checkAmbiguity) {
5026
- if (filenames.has(fileEntry.filename)) {
5027
- duplicateFilename = true;
5028
- }
5029
- filenames.add(fileEntry.filename);
5061
+ const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
5062
+ startOffset = Math.min(entryPosition, startOffset);
5063
+ if (entryPosition < previousEntryPosition) {
5064
+ addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
5030
5065
  }
5066
+ previousEntryPosition = entryPosition;
5067
+ if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
5068
+ addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
5069
+ }
5070
+ if ((fileEntry.rawBitFlag & BITFLAG_COMPRESSED_PATCHED_DATA) == BITFLAG_COMPRESSED_PATCHED_DATA) {
5071
+ addWarning(warnings, WARNING_COMPRESSED_PATCHED_DATA, filename);
5072
+ }
5073
+ if (filenames.has(fileEntry.filename)) {
5074
+ duplicateFilename = true;
5075
+ }
5076
+ filenames.add(fileEntry.filename);
5031
5077
  const unixExternalUpper = (fileEntry.externalFileAttributes >> 16) & MAX_16_BITS;
5032
5078
  if (fileEntry.unixMode === UNDEFINED_VALUE && (unixExternalUpper & (FILE_ATTR_UNIX_DEFAULT_MASK | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_TYPE_DIR)) != 0) {
5033
5079
  fileEntry.unixMode = unixExternalUpper;
@@ -5051,7 +5097,7 @@ class ZipReader {
5051
5097
  internalFileAttribute: fileEntry.internalFileAttributes,
5052
5098
  externalFileAttribute: fileEntry.externalFileAttributes,
5053
5099
  executable,
5054
- directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || (fileEntry.filename.endsWith(DIRECTORY_SIGNATURE) && !fileEntry.uncompressedSize),
5100
+ directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE),
5055
5101
  zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
5056
5102
  });
5057
5103
  const entry = new Entry(fileEntry);
@@ -5064,6 +5110,13 @@ class ZipReader {
5064
5110
  return arrayBufferPromise;
5065
5111
  };
5066
5112
  offset = endOffset;
5113
+ if (indexFile == filesLength - 1 && recoverWrappedFilesLength) {
5114
+ const wrappedFilesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
5115
+ if (wrappedFilesLength) {
5116
+ filesLength += wrappedFilesLength;
5117
+ addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
5118
+ }
5119
+ }
5067
5120
  const { onprogress } = options;
5068
5121
  if (onprogress) {
5069
5122
  try {
@@ -5088,18 +5141,22 @@ class ZipReader {
5088
5141
  zipReader.digitalSignature = digitalSignature;
5089
5142
  offsetAfterSignature = offset + 6 + digitalSignature.length;
5090
5143
  }
5091
- if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
5092
- throwAmbiguousArchive("trailing central directory data");
5144
+ if ((offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) ||
5145
+ (!decryptedDirectory && offset != directoryDataLength && offsetAfterSignature != directoryDataLength)) {
5146
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA);
5093
5147
  }
5094
5148
  if (duplicateFilename) {
5095
- throwAmbiguousArchive("duplicate filename");
5149
+ reportAmbiguity(checkAmbiguity, warnings, WARNING_DUPLICATE_FILENAME);
5096
5150
  }
5097
5151
  const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
5098
5152
  const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
5099
5153
  const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
5100
5154
  startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
5101
5155
  if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
5102
- throwAmbiguousArchive("prepended data");
5156
+ throwAmbiguousArchive(WARNING_PREPENDED_DATA);
5157
+ }
5158
+ if (prependedDataLength || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
5159
+ addWarning(warnings, WARNING_PREPENDED_DATA);
5103
5160
  }
5104
5161
  if (extractPrependedData) {
5105
5162
  zipReader.prependedData = startOffset > splitZipSignatureLength ?
@@ -5169,6 +5226,28 @@ class ZipReaderStream {
5169
5226
  }
5170
5227
  }
5171
5228
 
5229
+ async function isZipFile(reader, options = {}) {
5230
+ reader = new GenericReader(reader);
5231
+ await initStream(reader);
5232
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
5233
+ reader = new BlobReader(await streamToBlob(reader.readable));
5234
+ await initStream(reader);
5235
+ }
5236
+ if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
5237
+ return false;
5238
+ }
5239
+ const strictness = getStrictness(options, {});
5240
+ const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
5241
+ const maxAppendedDataSize = getMaxAppendedDataSize(options[OPTION_MAX_APPENDED_DATA_SIZE], strictness);
5242
+ const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
5243
+ if (!endOfDirectoryInfo || (strictness == STRICTNESS_STRICT && endOfDirectoryReachingEndCount > 1)) {
5244
+ return false;
5245
+ }
5246
+ const commentLength = getUint16$1(getDataView(endOfDirectoryInfo), 20);
5247
+ const appendedDataOffset = endOfDirectoryInfo.offset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
5248
+ return reader.size - appendedDataOffset <= maxAppendedDataSize;
5249
+ }
5250
+
5172
5251
  let ZipEntry$1 = class ZipEntry {
5173
5252
 
5174
5253
  constructor(reader, options) {
@@ -5200,6 +5279,7 @@ let ZipEntry$1 = class ZipEntry {
5200
5279
  dataDescriptor
5201
5280
  } = bitFlag;
5202
5281
  const localDirectory = fileEntry.localDirectory = {};
5282
+ const warnings = fileEntry.warnings = [];
5203
5283
  const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
5204
5284
  const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
5205
5285
  const dataView = getDataView(dataArray);
@@ -5222,6 +5302,7 @@ let ZipEntry$1 = class ZipEntry {
5222
5302
  extraFieldLength,
5223
5303
  filenameLength
5224
5304
  } = localDirectory;
5305
+ const dataOffset = localDirectory.dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
5225
5306
  const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
5226
5307
  const entryStrictness = getStrictness(options, zipEntry.options);
5227
5308
  const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
@@ -5239,10 +5320,10 @@ let ZipEntry$1 = class ZipEntry {
5239
5320
  if (checkLocalFilename) {
5240
5321
  localDirectory.rawFilename = rawLocalFilename;
5241
5322
  }
5242
- readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
5243
- if (checkLocalDirectory) {
5244
- validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
5323
+ if (readCommonFooter(zipEntry, localDirectory, dataView, 4, true)) {
5324
+ addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD);
5245
5325
  }
5326
+ validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
5246
5327
  const { lastAccessDate, creationDate, uid, gid } = localDirectory;
5247
5328
  if (lastAccessDate) {
5248
5329
  fileEntry.lastAccessDate = lastAccessDate;
@@ -5275,7 +5356,6 @@ let ZipEntry$1 = class ZipEntry {
5275
5356
  throw new Error(ERR_ENCRYPTED);
5276
5357
  }
5277
5358
  }
5278
- const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
5279
5359
  if (dataOffset + compressedSize > reader.size) {
5280
5360
  throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
5281
5361
  }
@@ -5395,6 +5475,16 @@ function detectEncryptedCentralDirectory(directoryView) {
5395
5475
  return false;
5396
5476
  }
5397
5477
 
5478
+ function getWrappedFilesLength(directoryView, directoryArray, offset) {
5479
+ let wrappedFilesLength = 0;
5480
+ while (offset + CENTRAL_FILE_HEADER_LENGTH <= directoryArray.length && getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE) {
5481
+ offset += CENTRAL_FILE_HEADER_LENGTH +
5482
+ getUint16$1(directoryView, offset + 28) + getUint16$1(directoryView, offset + 30) + getUint16$1(directoryView, offset + 32);
5483
+ wrappedFilesLength++;
5484
+ }
5485
+ return wrappedFilesLength % (MAX_16_BITS + 1) ? 0 : wrappedFilesLength;
5486
+ }
5487
+
5398
5488
  function readDigitalSignature(signatureRecordArray) {
5399
5489
  if (signatureRecordArray.length >= 6) {
5400
5490
  const signatureRecordView = getDataView(signatureRecordArray);
@@ -5459,6 +5549,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5459
5549
  const extraField = directory.extraField = new Map();
5460
5550
  const rawExtraFieldView = getDataView(rawExtraField);
5461
5551
  let offsetExtraField = 0;
5552
+ let malformedExtraField = false;
5462
5553
  try {
5463
5554
  while (offsetExtraField < rawExtraField.length) {
5464
5555
  const type = getUint16$1(rawExtraFieldView, offsetExtraField);
@@ -5470,7 +5561,10 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5470
5561
  offsetExtraField += 4 + size;
5471
5562
  }
5472
5563
  } catch {
5473
- // ignored
5564
+ malformedExtraField = true;
5565
+ }
5566
+ if (offsetExtraField > rawExtraField.length) {
5567
+ malformedExtraField = true;
5474
5568
  }
5475
5569
  const compressionMethod = getUint16$1(dataView, offset + 4);
5476
5570
  Object.assign(directory, {
@@ -5538,6 +5632,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
5538
5632
  if (extraFieldUSDZ) {
5539
5633
  directory.extraFieldUSDZ = extraFieldUSDZ;
5540
5634
  }
5635
+ return malformedExtraField;
5541
5636
  }
5542
5637
 
5543
5638
  function readExtraFieldZip64(extraFieldZip64, directory) {
@@ -5567,10 +5662,11 @@ function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName,
5567
5662
  const computedCrc32View = getDataView(new Uint8Array(4));
5568
5663
  computedCrc32View.setUint32(0, computedCrc32.get(), true);
5569
5664
  const nameCrc32 = getUint32$1(extraFieldView, 1);
5665
+ const version = getUint8(extraFieldView, 0);
5570
5666
  Object.assign(extraFieldUnicode, {
5571
- version: getUint8(extraFieldView, 0),
5667
+ version,
5572
5668
  [propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
5573
- valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
5669
+ valid: version == 1 && !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
5574
5670
  });
5575
5671
  if (extraFieldUnicode.valid) {
5576
5672
  directory[propertyName] = extraFieldUnicode[propertyName];
@@ -5998,27 +6094,46 @@ async function readSignature(reader, view, anchoredOffset, signatureOffset, size
5998
6094
  return UNDEFINED_VALUE;
5999
6095
  }
6000
6096
 
6001
- function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
6097
+ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, warnings) {
6002
6098
  const { rawFilename } = zipEntry;
6099
+ const reject = !warnings;
6003
6100
  const maskedLocalDirectory = zipEntry.decryptedDirectory &&
6004
6101
  (localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
6005
6102
  if (checkLocalFilename && !maskedLocalDirectory &&
6006
6103
  (rawLocalFilename.length != rawFilename.length ||
6007
6104
  rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
6008
- throwAmbiguousArchive("mismatched local file header (filename)");
6105
+ reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
6009
6106
  }
6010
6107
  if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
6011
- throwAmbiguousArchive("mismatched local file header (general purpose bit flag)");
6108
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
6012
6109
  }
6013
6110
  if (localDirectory.compressionMethod != zipEntry.compressionMethod) {
6014
- throwAmbiguousArchive("mismatched local file header (compression method)");
6111
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD);
6015
6112
  }
6016
6113
  if (!localDirectory.bitFlag.dataDescriptor && !maskedLocalDirectory &&
6017
6114
  (localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
6018
6115
  (localDirectory.crc32 != zipEntry.crc32 ||
6019
6116
  localDirectory.compressedSize != zipEntry.compressedSize ||
6020
6117
  localDirectory.uncompressedSize != zipEntry.uncompressedSize)) {
6021
- throwAmbiguousArchive("mismatched local file header (crc32 or sizes)");
6118
+ reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
6119
+ }
6120
+ }
6121
+
6122
+ function reportAmbiguity(reject, warnings, reason) {
6123
+ if (reject) {
6124
+ throwAmbiguousArchive(reason);
6125
+ } else {
6126
+ addWarning(warnings, reason);
6127
+ }
6128
+ }
6129
+
6130
+ function addWarning(warnings, reason, filename) {
6131
+ if (!warnings.some(warning => warning.reason == reason)) {
6132
+ const warning = { reason };
6133
+ if (filename !== UNDEFINED_VALUE) {
6134
+ warning.filename = filename;
6135
+ }
6136
+ warnings.push(warning);
6022
6137
  }
6023
6138
  }
6024
6139
 
@@ -6039,7 +6154,8 @@ function getFunctionOptionValue$1(zipReader, options, name) {
6039
6154
 
6040
6155
  function getDate(timeRaw) {
6041
6156
  const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
6042
- return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
6157
+ const result = new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
6158
+ return result < MIN_DATE ? MIN_DATE : result;
6043
6159
  }
6044
6160
 
6045
6161
  function getDateNTFS(timeRaw) {
@@ -6094,8 +6210,23 @@ var zipReader = /*#__PURE__*/Object.freeze({
6094
6210
  ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
6095
6211
  ERR_UNSUPPORTED_UINT64: ERR_UNSUPPORTED_UINT64,
6096
6212
  ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
6213
+ WARNING_APPENDED_DATA: WARNING_APPENDED_DATA,
6214
+ WARNING_COMPRESSED_PATCHED_DATA: WARNING_COMPRESSED_PATCHED_DATA,
6215
+ WARNING_DUPLICATE_FILENAME: WARNING_DUPLICATE_FILENAME,
6216
+ WARNING_MALFORMED_EXTRA_FIELD: WARNING_MALFORMED_EXTRA_FIELD,
6217
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
6218
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
6219
+ WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
6220
+ WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
6221
+ WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
6222
+ WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
6223
+ WARNING_UNKNOWN_VERSION: WARNING_UNKNOWN_VERSION,
6224
+ WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA: WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA,
6225
+ WARNING_UNSORTED_CENTRAL_DIRECTORY: WARNING_UNSORTED_CENTRAL_DIRECTORY,
6226
+ WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
6097
6227
  ZipReader: ZipReader,
6098
- ZipReaderStream: ZipReaderStream
6228
+ ZipReaderStream: ZipReaderStream,
6229
+ isZipFile: isZipFile
6099
6230
  });
6100
6231
 
6101
6232
  /*
@@ -6192,153 +6323,151 @@ class ZipWriter {
6192
6323
  offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
6193
6324
  initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
6194
6325
  pendingAddFileCalls: new Set(),
6326
+ pendingErrors: [],
6195
6327
  bufferedWrites: 0,
6196
6328
  lastFileEntry: UNDEFINED_VALUE
6197
6329
  });
6198
6330
  }
6199
6331
 
6200
- async prependZip(reader) {
6201
- if (this.filenames.size) {
6202
- throw new Error(ERR_ZIP_NOT_EMPTY);
6203
- }
6204
- reader = new GenericReader(reader);
6205
- await initStream(reader);
6206
- if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
6207
- reader = new BlobReader(await streamToBlob(reader.readable));
6208
- await initStream(reader);
6209
- }
6210
- const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
6211
- const zipReader$1 = new ZipReader(reader);
6212
- const entries = await zipReader$1.getEntries();
6213
- await zipReader$1.close();
6214
- await initStream(this.writer);
6215
- const { directoryOffset } = zipReader$1;
6216
- if (this.addSplitZipSignature) {
6217
- delete this.addSplitZipSignature;
6218
- if (!await startsWithSplitZipSignature(reader)) {
6219
- await writeData(this.writer, getSplitZipSignatureArray());
6220
- this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6221
- }
6222
- }
6223
- const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
6224
- this.filenames = new Set(entries.map(entry => entry.filename));
6225
- this.fileEntries = new Map(entries.map(entry => {
6226
- const {
6227
- version,
6228
- rawLastModDate,
6229
- lastAccessDate,
6230
- creationDate,
6231
- rawFilename,
6232
- bitFlag,
6233
- encrypted,
6234
- uncompressedSize,
6235
- compressedSize,
6236
- extraFieldZip64
6237
- } = entry;
6238
- let {
6239
- compressionMethod,
6240
- rawExtraFieldZip64,
6241
- rawExtraFieldAES,
6242
- rawExtraFieldExtendedTimestamp,
6243
- rawExtraFieldNTFS,
6244
- rawExtraFieldUnix,
6245
- rawExtraField,
6246
- } = entry;
6247
- const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
6248
- rawExtraFieldZip64 = rawExtraFieldZip64 || EMPTY_UINT8_ARRAY;
6249
- rawExtraFieldAES = rawExtraFieldAES || EMPTY_UINT8_ARRAY;
6250
- rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
6251
- rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
6252
- rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
6253
- rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
6254
- if (entry.extraFieldAES) {
6255
- compressionMethod = COMPRESSION_METHOD_AES;
6256
- }
6257
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
6258
- const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
6259
- const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
6260
- const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
6261
- const {
6262
- headerArray,
6263
- headerView
6264
- } = getHeaderArrayData({
6265
- version,
6266
- bitFlag: bitFlagValue,
6267
- compressionMethod,
6268
- uncompressedSize,
6269
- compressedSize,
6270
- rawLastModDate,
6271
- rawFilename,
6272
- zip64CompressedSize,
6273
- zip64UncompressedSize,
6274
- extraFieldLength
6275
- });
6276
- const { crc32 } = entry;
6277
- if (crc32 !== UNDEFINED_VALUE) {
6278
- setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
6279
- }
6280
- const { offset, diskNumberStart } = entryPositions.get(entry);
6281
- Object.assign(entry, {
6282
- zip64UncompressedSize,
6283
- zip64CompressedSize,
6284
- offset,
6285
- diskNumberStart,
6286
- zip64DiskNumberStart: false,
6287
- rawExtraFieldZip64,
6288
- rawExtraFieldAES,
6289
- rawExtraFieldExtendedTimestamp,
6290
- rawExtraFieldNTFS,
6291
- rawExtraFieldUnix,
6292
- rawExtraField,
6293
- extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
6294
- extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
6295
- headerArray,
6296
- headerView
6297
- });
6298
- return [entry.filename, entry];
6299
- }));
6332
+ prependZip(reader) {
6333
+ return watchPromiseError(this, prependZipEntries(this, reader));
6300
6334
  }
6301
6335
 
6302
- async add(name = "", reader, options = {}) {
6336
+ appendZip(reader) {
6337
+ return watchPromiseError(this, this.appendZipEntries(reader));
6338
+ }
6339
+
6340
+ async appendZipEntries(reader) {
6303
6341
  const zipWriter = this;
6304
- options = Object.assign({}, options);
6305
- const { pendingAddFileCalls } = zipWriter;
6306
- if (workers < getConfiguration().maxWorkers) {
6307
- workers++;
6308
- } else {
6309
- await new Promise(resolve => pendingEntries.push(resolve));
6342
+ const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
6343
+ while (pendingAddFileCalls.size) {
6344
+ await Promise.allSettled(Array.from(pendingAddFileCalls));
6310
6345
  }
6311
- let promiseAddFile;
6312
- let nameAdded;
6346
+ let resolveAppendZip;
6347
+ const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
6348
+ pendingAddFileCalls.add(promiseAppendZip);
6349
+ const appendedFilenames = [];
6350
+ let releaseLockWriter;
6313
6351
  try {
6314
- name = name.trim();
6315
- if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6316
- name += DIRECTORY_SIGNATURE;
6317
- }
6318
- if (zipWriter.filenames.has(name)) {
6319
- throw new Error(ERR_DUPLICATED_NAME);
6320
- }
6321
- zipWriter.filenames.add(name);
6322
- nameAdded = true;
6323
- promiseAddFile = addFile(zipWriter, name, reader, options);
6324
- pendingAddFileCalls.add(promiseAddFile);
6325
- return await promiseAddFile;
6326
- } catch (error) {
6327
- if (nameAdded) {
6328
- zipWriter.filenames.delete(name);
6352
+ reader = new GenericReader(reader);
6353
+ await initStream(reader);
6354
+ if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
6355
+ reader = new BlobReader(await streamToBlob(reader.readable));
6356
+ await initStream(reader);
6357
+ }
6358
+ const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
6359
+ const zipReader$1 = new ZipReader(reader);
6360
+ const entries = await zipReader$1.getEntries();
6361
+ await zipReader$1.close();
6362
+ await initStream(zipWriter.writer);
6363
+ const { directoryOffset } = zipReader$1;
6364
+ entries.forEach(({ filename }) => {
6365
+ if (filenames.has(filename)) {
6366
+ throw new Error(ERR_DUPLICATED_NAME);
6367
+ }
6368
+ filenames.add(filename);
6369
+ appendedFilenames.push(filename);
6370
+ });
6371
+ zipWriter.writerLocked = true;
6372
+ const { lockWriter } = zipWriter;
6373
+ zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
6374
+ zipWriter.writerLocked = false;
6375
+ resolve();
6376
+ });
6377
+ await lockWriter;
6378
+ if (zipWriter.addSplitZipSignature) {
6379
+ delete zipWriter.addSplitZipSignature;
6380
+ if (!await startsWithSplitZipSignature(reader)) {
6381
+ await writeData(zipWriter.writer, getSplitZipSignatureArray());
6382
+ zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
6383
+ }
6329
6384
  }
6385
+ const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
6386
+ entries.forEach(entry => {
6387
+ const {
6388
+ version,
6389
+ rawLastModDate,
6390
+ rawFilename,
6391
+ bitFlag,
6392
+ encrypted,
6393
+ uncompressedSize,
6394
+ compressedSize,
6395
+ extraFieldZip64
6396
+ } = entry;
6397
+ let {
6398
+ compressionMethod,
6399
+ rawExtraField,
6400
+ } = entry;
6401
+ const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
6402
+ rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
6403
+ if (entry.extraFieldAES) {
6404
+ compressionMethod = COMPRESSION_METHOD_AES;
6405
+ }
6406
+ const extraFieldLength = getLength(rawExtraField);
6407
+ const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
6408
+ const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
6409
+ const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
6410
+ const {
6411
+ headerArray,
6412
+ headerView
6413
+ } = getHeaderArrayData({
6414
+ version,
6415
+ bitFlag: bitFlagValue,
6416
+ compressionMethod,
6417
+ uncompressedSize,
6418
+ compressedSize,
6419
+ rawLastModDate,
6420
+ rawFilename,
6421
+ zip64CompressedSize,
6422
+ zip64UncompressedSize,
6423
+ extraFieldLength
6424
+ });
6425
+ const { crc32 } = entry;
6426
+ if (crc32 !== UNDEFINED_VALUE) {
6427
+ setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
6428
+ }
6429
+ const { offset, diskNumberStart } = entryPositions.get(entry);
6430
+ Object.assign(entry, {
6431
+ zip64UncompressedSize,
6432
+ zip64CompressedSize,
6433
+ offset,
6434
+ diskNumberStart,
6435
+ zip64DiskNumberStart: false,
6436
+ rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
6437
+ rawExtraFieldAES: EMPTY_UINT8_ARRAY,
6438
+ rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
6439
+ rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
6440
+ rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
6441
+ rawExtraField,
6442
+ rawCentralExtraField: EMPTY_UINT8_ARRAY,
6443
+ extendedTimestamp: false,
6444
+ headerArray,
6445
+ headerView
6446
+ });
6447
+ fileEntries.set(entry.filename, entry);
6448
+ });
6449
+ } catch (error) {
6450
+ appendedFilenames.forEach(filename => filenames.delete(filename));
6330
6451
  throw error;
6331
6452
  } finally {
6332
- pendingAddFileCalls.delete(promiseAddFile);
6333
- const pendingEntry = pendingEntries.shift();
6334
- if (pendingEntry) {
6335
- pendingEntry();
6336
- } else {
6337
- workers--;
6453
+ resolveAppendZip();
6454
+ pendingAddFileCalls.delete(promiseAppendZip);
6455
+ if (releaseLockWriter) {
6456
+ releaseLockWriter();
6338
6457
  }
6339
6458
  }
6340
6459
  }
6341
6460
 
6461
+ add(name = "", reader, options = {}) {
6462
+ const zipWriter = this;
6463
+ const { pendingAddFileCalls } = zipWriter;
6464
+ const promiseAddFile = addFileEntry(zipWriter, name, reader, options);
6465
+ pendingAddFileCalls.add(promiseAddFile);
6466
+ const deletePendingAddFileCall = () => pendingAddFileCalls.delete(promiseAddFile);
6467
+ Promise.prototype.then.call(promiseAddFile, deletePendingAddFileCall, deletePendingAddFileCall);
6468
+ return watchPromiseError(zipWriter, promiseAddFile);
6469
+ }
6470
+
6342
6471
  remove(entry) {
6343
6472
  const { filenames, fileEntries } = this;
6344
6473
  // deno-lint-ignore valid-typeof
@@ -6369,6 +6498,19 @@ class ZipWriter {
6369
6498
  while (pendingAddFileCalls.size) {
6370
6499
  await Promise.allSettled(Array.from(pendingAddFileCalls));
6371
6500
  }
6501
+ await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
6502
+ const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
6503
+ if (unobservedWatchers.length) {
6504
+ const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
6505
+ unobservedWatchers.forEach(watcher => watcher.observed = true);
6506
+ const [error] = unobservedErrors;
6507
+ try {
6508
+ error.entryErrors = unobservedErrors;
6509
+ } catch {
6510
+ // ignored
6511
+ }
6512
+ throw error;
6513
+ }
6372
6514
  await closeFile(zipWriter, comment, options);
6373
6515
  const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
6374
6516
  if (!preventClose) {
@@ -6403,11 +6545,7 @@ class ZipWriterStream {
6403
6545
  try {
6404
6546
  await zipWriter.close();
6405
6547
  } catch (error) {
6406
- try {
6407
- await zipWriter.writer.writable.abort(error);
6408
- } catch {
6409
- // ignored
6410
- }
6548
+ await abortWritable(zipWriter, error);
6411
6549
  }
6412
6550
  }
6413
6551
  }
@@ -6424,8 +6562,89 @@ class ZipWriterStream {
6424
6562
  }
6425
6563
 
6426
6564
  async close(comment = UNDEFINED_VALUE, options = {}) {
6427
- await Promise.all(Array.from(this.pendingAddFileCalls));
6428
- return this.zipWriter.close(comment, options);
6565
+ const { zipWriter } = this;
6566
+ const results = await Promise.allSettled(Array.from(this.pendingAddFileCalls));
6567
+ const entryErrors = results.filter(result => result.status == "rejected").map(result => result.reason);
6568
+ if (entryErrors.length) {
6569
+ const [error] = entryErrors;
6570
+ try {
6571
+ error.entryErrors = entryErrors;
6572
+ } catch {
6573
+ // ignored
6574
+ }
6575
+ await abortWritable(zipWriter, error);
6576
+ throw error;
6577
+ }
6578
+ try {
6579
+ return await zipWriter.close(comment, options);
6580
+ } catch (error) {
6581
+ await abortWritable(zipWriter, error);
6582
+ throw error;
6583
+ }
6584
+ }
6585
+ }
6586
+
6587
+ class WatchedPromise extends Promise {
6588
+
6589
+ then(onFulfilled, onRejected) {
6590
+ const { watcher } = this;
6591
+ if (watcher) {
6592
+ watcher.observed = true;
6593
+ }
6594
+ return super.then(onFulfilled, onRejected);
6595
+ }
6596
+ }
6597
+
6598
+ function watchPromiseError(zipWriter, promise) {
6599
+ const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
6600
+ const watcher = {};
6601
+ watchedPromise.watcher = watcher;
6602
+ watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
6603
+ zipWriter.pendingErrors.push(watcher);
6604
+ return watchedPromise;
6605
+ }
6606
+
6607
+ async function prependZipEntries(zipWriter, reader) {
6608
+ if (zipWriter.filenames.size) {
6609
+ throw new Error(ERR_ZIP_NOT_EMPTY);
6610
+ }
6611
+ await zipWriter.appendZipEntries(reader);
6612
+ }
6613
+
6614
+ async function addFileEntry(zipWriter, name, reader, options) {
6615
+ options = Object.assign({}, options);
6616
+ if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6617
+ name += DIRECTORY_SIGNATURE;
6618
+ }
6619
+ if (zipWriter.filenames.has(name)) {
6620
+ throw new Error(ERR_DUPLICATED_NAME);
6621
+ }
6622
+ zipWriter.filenames.add(name);
6623
+ if (workers < getConfiguration().maxWorkers) {
6624
+ workers++;
6625
+ } else {
6626
+ await new Promise(resolve => pendingEntries.push(resolve));
6627
+ }
6628
+ try {
6629
+ return await addFile(zipWriter, name, reader, options);
6630
+ } catch (error) {
6631
+ zipWriter.filenames.delete(name);
6632
+ throw error;
6633
+ } finally {
6634
+ const pendingEntry = pendingEntries.shift();
6635
+ if (pendingEntry) {
6636
+ pendingEntry();
6637
+ } else {
6638
+ workers--;
6639
+ }
6640
+ }
6641
+ }
6642
+
6643
+ async function abortWritable(zipWriter, error) {
6644
+ try {
6645
+ await zipWriter.writer.writable.abort(error);
6646
+ } catch {
6647
+ // ignored
6429
6648
  }
6430
6649
  }
6431
6650
 
@@ -6484,7 +6703,6 @@ async function addFile(zipWriter, name, reader, options) {
6484
6703
  }
6485
6704
 
6486
6705
  function resolveAttributes(zipWriter, name, options) {
6487
- name = name.trim();
6488
6706
  let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
6489
6707
  let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
6490
6708
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
@@ -6628,11 +6846,12 @@ function resolveMetadata(zipWriter, name, options) {
6628
6846
  if (getLength(rawComment) > MAX_16_BITS) {
6629
6847
  throw new Error(ERR_INVALID_ENTRY_COMMENT);
6630
6848
  }
6631
- const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION, VERSION_DEFLATE);
6632
- if (version > MAX_16_BITS) {
6849
+ const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION);
6850
+ if (version !== UNDEFINED_VALUE && version > MAX_16_BITS) {
6633
6851
  throw new Error(ERR_INVALID_VERSION);
6634
6852
  }
6635
6853
  const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
6854
+ const rawLastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
6636
6855
  const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
6637
6856
  const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
6638
6857
  const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
@@ -6676,7 +6895,7 @@ function resolveMetadata(zipWriter, name, options) {
6676
6895
  if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
6677
6896
  dataDescriptor = false;
6678
6897
  }
6679
- if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
6898
+ if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
6680
6899
  dataDescriptor = true;
6681
6900
  }
6682
6901
  if (level !== UNDEFINED_VALUE && level != 6) {
@@ -6688,6 +6907,7 @@ function resolveMetadata(zipWriter, name, options) {
6688
6907
  }
6689
6908
  const rawExtraField = serializeExtraField(options[PROPERTY_NAME_EXTRA_FIELD]);
6690
6909
  const rawLocalExtraField = serializeExtraField(options[OPTION_LOCAL_EXTRA_FIELD]);
6910
+ const rawCentralExtraField = serializeExtraField(options[OPTION_CENTRAL_EXTRA_FIELD]);
6691
6911
  return {
6692
6912
  comment,
6693
6913
  resolvedOptions: {
@@ -6695,6 +6915,7 @@ function resolveMetadata(zipWriter, name, options) {
6695
6915
  rawComment,
6696
6916
  version,
6697
6917
  lastModDate,
6918
+ rawLastModDate,
6698
6919
  lastAccessDate,
6699
6920
  creationDate,
6700
6921
  internalFileAttributes,
@@ -6722,7 +6943,8 @@ function resolveMetadata(zipWriter, name, options) {
6722
6943
  dataDescriptor,
6723
6944
  zip64,
6724
6945
  rawExtraField,
6725
- rawLocalExtraField
6946
+ rawLocalExtraField,
6947
+ rawCentralExtraField
6726
6948
  }
6727
6949
  };
6728
6950
  }
@@ -6864,7 +7086,6 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
6864
7086
  let { name } = entry;
6865
7087
  const { size } = entry;
6866
7088
  const options = Object.assign({}, entry.options);
6867
- name = name.trim();
6868
7089
  if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
6869
7090
  name += DIRECTORY_SIGNATURE;
6870
7091
  }
@@ -6970,10 +7191,8 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
6970
7191
  }
6971
7192
  await initStream(fileWriter);
6972
7193
  const diskOffset = getDiskOffset(writer);
6973
- if (zipWriter.addSplitZipSignature) {
6974
- delete zipWriter.addSplitZipSignature;
6975
- await writeData(writer, getSplitZipSignatureArray());
6976
- zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
7194
+ if (zipWriter.addSplitZipSignature && !bufferedWrite) {
7195
+ await writeSplitZipSignature(zipWriter, writer);
6977
7196
  }
6978
7197
  if (usdz && !bufferedWrite) {
6979
7198
  appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
@@ -7000,6 +7219,9 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
7000
7219
  if (bufferedWrite) {
7001
7220
  await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
7002
7221
  await requestLockWriter();
7222
+ if (zipWriter.addSplitZipSignature) {
7223
+ await writeSplitZipSignature(zipWriter, writer);
7224
+ }
7003
7225
  writingBufferedEntryData = true;
7004
7226
  writerSizeBeforeEntry = writer.size;
7005
7227
  await skipDiskIfNeeded();
@@ -7119,6 +7341,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7119
7341
  versionMadeBy,
7120
7342
  rawComment,
7121
7343
  rawExtraField,
7344
+ rawCentralExtraField,
7122
7345
  useWebWorkers,
7123
7346
  transferStreams,
7124
7347
  onstart,
@@ -7162,6 +7385,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7162
7385
  rawExtraFieldUnix,
7163
7386
  rawExtraFieldAES,
7164
7387
  rawExtraField,
7388
+ rawCentralExtraField,
7165
7389
  extendedTimestamp,
7166
7390
  msDosCompatible,
7167
7391
  internalFileAttributes,
@@ -7271,6 +7495,7 @@ function getHeaderInfo(options) {
7271
7495
  const {
7272
7496
  rawFilename,
7273
7497
  lastModDate,
7498
+ rawLastModDate: rawLastModDateOption,
7274
7499
  lastAccessDate,
7275
7500
  creationDate,
7276
7501
  level,
@@ -7404,6 +7629,9 @@ function getHeaderInfo(options) {
7404
7629
  if (compressionMethod === UNDEFINED_VALUE) {
7405
7630
  compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
7406
7631
  }
7632
+ if (version === UNDEFINED_VALUE) {
7633
+ version = compressionMethod == COMPRESSION_METHOD_STORE && !directory && !encrypted ? VERSION_STORE : VERSION_DEFLATE;
7634
+ }
7407
7635
  const { codecVersionNeeded } = options;
7408
7636
  if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
7409
7637
  version = version > codecVersionNeeded ? version : codecVersionNeeded;
@@ -7436,6 +7664,7 @@ function getHeaderInfo(options) {
7436
7664
  compressionMethod,
7437
7665
  uncompressedSize,
7438
7666
  lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
7667
+ rawLastModDate: rawLastModDateOption,
7439
7668
  rawFilename,
7440
7669
  zip64CompressedSize,
7441
7670
  zip64UncompressedSize,
@@ -7642,9 +7871,9 @@ function updateLocalHeader({
7642
7871
 
7643
7872
  async function closeFile(zipWriter, comment, options) {
7644
7873
  const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
7645
- const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7874
+ const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
7646
7875
  const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
7647
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
7876
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
7648
7877
  }
7649
7878
 
7650
7879
  function createDirectoryRecords(files) {
@@ -7657,6 +7886,7 @@ function createDirectoryRecords(files) {
7657
7886
  rawExtraFieldNTFS,
7658
7887
  rawExtraFieldUnix,
7659
7888
  rawExtraField,
7889
+ rawCentralExtraField,
7660
7890
  extendedTimestamp,
7661
7891
  extraFieldExtendedTimestampFlag,
7662
7892
  lastModDate,
@@ -7711,7 +7941,8 @@ function createDirectoryRecords(files) {
7711
7941
  rawExtraFieldNTFS,
7712
7942
  rawExtraFieldUnix,
7713
7943
  rawExtraFieldTimestamp,
7714
- rawExtraField);
7944
+ rawExtraField,
7945
+ rawCentralExtraField);
7715
7946
  if (extraFieldLength > MAX_16_BITS) {
7716
7947
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
7717
7948
  }
@@ -7728,6 +7959,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
7728
7959
  let directoryDiskOffset = 0;
7729
7960
  let directoryStartDiskNumber = getDiskNumber(writer);
7730
7961
  let directoryStartDiskOffset = getDiskOffset(writer);
7962
+ let directoryEndDiskEntriesLength = 0;
7731
7963
  for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
7732
7964
  const {
7733
7965
  offset: fileEntryOffset,
@@ -7738,6 +7970,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
7738
7970
  rawExtraFieldNTFS,
7739
7971
  rawExtraFieldUnix,
7740
7972
  rawExtraField,
7973
+ rawCentralExtraField,
7741
7974
  rawComment,
7742
7975
  versionMadeBy,
7743
7976
  headerArray,
@@ -7752,11 +7985,12 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
7752
7985
  uncompressedSize,
7753
7986
  compressedSize
7754
7987
  } = fileEntry;
7755
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
7988
+ const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawCentralExtraField);
7756
7989
  const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
7757
7990
  if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
7758
7991
  await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
7759
7992
  directoryDiskOffset = offset;
7993
+ directoryEndDiskEntriesLength = 0;
7760
7994
  await writer.closeDisk();
7761
7995
  }
7762
7996
  if (indexFileEntry == 0) {
@@ -7789,9 +8023,11 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
7789
8023
  directoryRecord.writeBytes(rawExtraFieldNTFS);
7790
8024
  directoryRecord.writeBytes(rawExtraFieldUnix);
7791
8025
  directoryRecord.writeBytes(rawExtraField);
8026
+ directoryRecord.writeBytes(rawCentralExtraField);
7792
8027
  directoryRecord.writeBytes(rawComment);
7793
8028
  arraySet(directoryArray, directoryRecord.array, offset);
7794
8029
  offset += directoryRecordLength;
8030
+ directoryEndDiskEntriesLength++;
7795
8031
  if (options.onprogress) {
7796
8032
  try {
7797
8033
  await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
@@ -7803,6 +8039,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
7803
8039
  await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
7804
8040
  return {
7805
8041
  directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
8042
+ directoryEnd: { diskNumber: getDiskNumber(writer), entriesLength: directoryEndDiskEntriesLength },
7806
8043
  directoryArray
7807
8044
  };
7808
8045
  }
@@ -7831,16 +8068,20 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
7831
8068
 
7832
8069
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7833
8070
  const { writer } = zipWriter;
7834
- const { directoryStart, signatureLength } = cdInfo;
8071
+ const { directoryStart, directoryEnd, signatureLength } = cdInfo;
7835
8072
  let { directoryDataLength } = cdInfo;
7836
8073
  let fileEntriesLength = zipWriter.fileEntries.size;
7837
8074
  let diskNumber = directoryStart.diskNumber;
7838
8075
  let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
8076
+ const commentLength = getLength(comment);
8077
+ if (commentLength > MAX_16_BITS) {
8078
+ throw new Error(ERR_INVALID_COMMENT);
8079
+ }
8080
+ let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
7839
8081
  let lastDiskNumber = getDiskNumber(writer);
7840
- if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
8082
+ if (exceedsAvailableSize(writer, (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH) + commentLength)) {
7841
8083
  lastDiskNumber++;
7842
8084
  }
7843
- let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
7844
8085
  if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
7845
8086
  if (zip64 === false) {
7846
8087
  throw new Error(ERR_UNSUPPORTED_FORMAT);
@@ -7848,15 +8089,12 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7848
8089
  zip64 = true;
7849
8090
  }
7850
8091
  }
7851
- const commentLength = getLength(comment);
7852
- if (commentLength > MAX_16_BITS) {
7853
- throw new Error(ERR_INVALID_COMMENT);
7854
- }
7855
8092
  const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
7856
8093
  if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
7857
8094
  await writer.closeDisk();
7858
8095
  }
7859
8096
  lastDiskNumber = getDiskNumber(writer);
8097
+ let diskFileEntriesLength = lastDiskNumber == directoryEnd.diskNumber ? directoryEnd.entriesLength : 0;
7860
8098
  if (zip64) {
7861
8099
  endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
7862
8100
  endOfdirectoryRecord.writeUint64(44);
@@ -7864,7 +8102,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7864
8102
  endOfdirectoryRecord.writeUint16(45);
7865
8103
  endOfdirectoryRecord.writeUint32(lastDiskNumber);
7866
8104
  endOfdirectoryRecord.writeUint32(diskNumber);
7867
- endOfdirectoryRecord.writeUint64(fileEntriesLength);
8105
+ endOfdirectoryRecord.writeUint64(diskFileEntriesLength);
7868
8106
  endOfdirectoryRecord.writeUint64(fileEntriesLength);
7869
8107
  endOfdirectoryRecord.writeUint64(directoryDataLength);
7870
8108
  endOfdirectoryRecord.writeUint64(directoryOffset);
@@ -7877,6 +8115,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7877
8115
  lastDiskNumber = MAX_16_BITS;
7878
8116
  diskNumber = MAX_16_BITS;
7879
8117
  }
8118
+ diskFileEntriesLength = MAX_16_BITS;
7880
8119
  fileEntriesLength = MAX_16_BITS;
7881
8120
  directoryOffset = MAX_32_BITS;
7882
8121
  directoryDataLength = MAX_32_BITS;
@@ -7884,7 +8123,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
7884
8123
  endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
7885
8124
  endOfdirectoryRecord.writeUint16(lastDiskNumber);
7886
8125
  endOfdirectoryRecord.writeUint16(diskNumber);
7887
- endOfdirectoryRecord.writeUint16(fileEntriesLength);
8126
+ endOfdirectoryRecord.writeUint16(diskFileEntriesLength);
7888
8127
  endOfdirectoryRecord.writeUint16(fileEntriesLength);
7889
8128
  endOfdirectoryRecord.writeUint32(directoryDataLength);
7890
8129
  endOfdirectoryRecord.writeUint32(directoryOffset);
@@ -7983,9 +8222,21 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
7983
8222
  async function copyData(zipWriter, reader, offset, size) {
7984
8223
  if (size > 0) {
7985
8224
  const { writer } = zipWriter;
7986
- await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
7987
- writer.size += size;
7988
- zipWriter.offset += size;
8225
+ let copiedLength = 0;
8226
+ try {
8227
+ await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
8228
+ } catch (error) {
8229
+ zipWriter.hasCorruptedEntries = true;
8230
+ try {
8231
+ error.corruptedEntry = true;
8232
+ } catch {
8233
+ // ignored
8234
+ }
8235
+ throw error;
8236
+ } finally {
8237
+ writer.size += copiedLength;
8238
+ zipWriter.offset += copiedLength;
8239
+ }
7989
8240
  }
7990
8241
  }
7991
8242
 
@@ -8010,6 +8261,12 @@ function getSplitZipSignatureArray() {
8010
8261
  return signatureArray;
8011
8262
  }
8012
8263
 
8264
+ async function writeSplitZipSignature(zipWriter, writer) {
8265
+ delete zipWriter.addSplitZipSignature;
8266
+ await writeData(writer, getSplitZipSignatureArray());
8267
+ zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
8268
+ }
8269
+
8013
8270
  async function writeData(writer, array) {
8014
8271
  const { writable } = writer;
8015
8272
  const streamWriter = writable.getWriter();
@@ -8759,6 +9016,7 @@ const ERR_ENTRY_EXISTS = "Entry filename already exists";
8759
9016
  const ERR_READABLE_CONSUMED = "Readable stream already consumed";
8760
9017
  const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
8761
9018
  const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
9019
+ const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
8762
9020
  const ERR_ABORT_EXPORT = "zipjs-abort-export";
8763
9021
  const ERR_ABORTED = "The operation was aborted";
8764
9022
  const ABORT_ERROR_NAME = "AbortError";
@@ -9626,6 +9884,7 @@ function getChildEntryOptions(child, selectedEntry, options) {
9626
9884
  versionMadeBy,
9627
9885
  comment,
9628
9886
  lastModDate,
9887
+ rawLastModDate,
9629
9888
  creationDate,
9630
9889
  lastAccessDate,
9631
9890
  uncompressedSize,
@@ -9636,6 +9895,7 @@ function getChildEntryOptions(child, selectedEntry, options) {
9636
9895
  extraFieldAES,
9637
9896
  internalFileAttributes,
9638
9897
  extraField,
9898
+ bitFlag,
9639
9899
  uid,
9640
9900
  gid
9641
9901
  } = child.data;
@@ -9673,6 +9933,16 @@ function getChildEntryOptions(child, selectedEntry, options) {
9673
9933
  encryptionStrength,
9674
9934
  compressionMethod
9675
9935
  };
9936
+ if (bitFlag) {
9937
+ passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
9938
+ }
9939
+ const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
9940
+ if (lastModDateOverride === UNDEFINED_VALUE) {
9941
+ passThroughOptions.rawLastModDate = rawLastModDate;
9942
+ } else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
9943
+ getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
9944
+ throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
9945
+ }
9676
9946
  }
9677
9947
  }
9678
9948
  const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
@@ -9682,6 +9952,16 @@ function getChildEntryOptions(child, selectedEntry, options) {
9682
9952
  return { name, entryOptions };
9683
9953
  }
9684
9954
 
9955
+ function getDosTimeHighByte(lastModDate) {
9956
+ let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
9957
+ if (dosLastModDate < MIN_DATE) {
9958
+ dosLastModDate = MIN_DATE;
9959
+ } else if (dosLastModDate > MAX_DATE) {
9960
+ dosLastModDate = MAX_DATE;
9961
+ }
9962
+ return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
9963
+ }
9964
+
9685
9965
  function getDeterminedSize(child, passThrough) {
9686
9966
  const { reader } = child;
9687
9967
  if (reader && reader.size !== UNDEFINED_VALUE) {
@@ -10113,7 +10393,7 @@ function decodeMimeTypes(data) {
10113
10393
  */
10114
10394
 
10115
10395
 
10116
- p$1(setDefaultConfiguration);
10396
+ c(setDefaultConfiguration);
10117
10397
 
10118
10398
  exports.BlobReader = BlobReader;
10119
10399
  exports.BlobWriter = BlobWriter;
@@ -10192,6 +10472,7 @@ exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
10192
10472
  exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
10193
10473
  exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
10194
10474
  exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
10475
+ exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
10195
10476
  exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
10196
10477
  exports.HttpRangeReader = HttpRangeReader;
10197
10478
  exports.HttpReader = HttpReader;
@@ -10202,6 +10483,20 @@ exports.TextReader = TextReader;
10202
10483
  exports.TextWriter = TextWriter;
10203
10484
  exports.Uint8ArrayReader = Uint8ArrayReader;
10204
10485
  exports.Uint8ArrayWriter = Uint8ArrayWriter;
10486
+ exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
10487
+ exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
10488
+ exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
10489
+ exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
10490
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
10491
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
10492
+ exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
10493
+ exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
10494
+ exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
10495
+ exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;
10496
+ exports.WARNING_UNKNOWN_VERSION = WARNING_UNKNOWN_VERSION;
10497
+ exports.WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA;
10498
+ exports.WARNING_UNSORTED_CENTRAL_DIRECTORY = WARNING_UNSORTED_CENTRAL_DIRECTORY;
10499
+ exports.WARNING_WRAPPED_ENTRIES_COUNT = WARNING_WRAPPED_ENTRIES_COUNT;
10205
10500
  exports.Writer = Writer;
10206
10501
  exports.ZipDirectoryEntry = ZipDirectoryEntry;
10207
10502
  exports.ZipEntry = ZipEntry;
@@ -10217,6 +10512,7 @@ exports.createOPFSTempStream = createOPFSTempStream;
10217
10512
  exports.createSyncAccessHandleTempStream = createSyncAccessHandleTempStream;
10218
10513
  exports.fs = fs;
10219
10514
  exports.getMimeType = getMimeType;
10515
+ exports.isZipFile = isZipFile;
10220
10516
  exports.registerCodec = registerCodec;
10221
10517
  exports.resetConfiguration = resetConfiguration;
10222
10518
  exports.terminateWorkers = terminateWorkers;