@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/deno.json +1 -1
- package/dist/zip-core-external.js +458 -200
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +472 -199
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +481 -201
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +497 -193
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +481 -201
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +498 -202
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +499 -203
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +474 -201
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +474 -201
- package/dist/zip-native.min.js +1 -1
- package/dist/zip-web-worker-native.js +1 -1
- package/dist/zip-web-worker.js +1 -1
- package/dist/zip.js +475 -202
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +498 -202
- package/index-native.min.js +1 -1
- package/index.cjs +499 -203
- package/index.d.cts +297 -10
- package/index.d.ts +297 -10
- package/index.min.js +1 -1
- package/lib/core/constants.js +4 -0
- package/lib/core/options.js +2 -0
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-fs.js +27 -1
- package/lib/core/zip-reader.js +168 -38
- package/lib/core/zip-writer.js +290 -161
- package/lib/core/zlib-streams-inline.js +1 -1
- package/lib/zip-core-reader.js +16 -1
- package/package.json +1 -1
package/dist/zip-fs-native.js
CHANGED
|
@@ -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.
|
|
@@ -4730,6 +4733,21 @@
|
|
|
4730
4733
|
const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
|
|
4731
4734
|
const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
|
|
4732
4735
|
const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
|
|
4736
|
+
const WARNING_UNSORTED_CENTRAL_DIRECTORY = "unsorted central directory";
|
|
4737
|
+
const WARNING_UNKNOWN_VERSION = "unknown version needed to extract";
|
|
4738
|
+
const WARNING_COMPRESSED_PATCHED_DATA = "compressed patched data";
|
|
4739
|
+
const WARNING_MALFORMED_EXTRA_FIELD = "malformed extra field";
|
|
4740
|
+
const WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = "unknown zip64 extensible data";
|
|
4741
|
+
const WARNING_WRAPPED_ENTRIES_COUNT = "wrapped entries count";
|
|
4742
|
+
const WARNING_APPENDED_DATA = "appended data";
|
|
4743
|
+
const WARNING_PREPENDED_DATA = "prepended data";
|
|
4744
|
+
const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
|
|
4745
|
+
const WARNING_DUPLICATE_FILENAME = "duplicate filename";
|
|
4746
|
+
const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
|
|
4747
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
|
|
4748
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
|
|
4749
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
4750
|
+
const MAX_KNOWN_VERSION = 63;
|
|
4733
4751
|
const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
|
|
4734
4752
|
const CHARSET_UTF8 = "utf-8";
|
|
4735
4753
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
@@ -4780,6 +4798,7 @@
|
|
|
4780
4798
|
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
4781
4799
|
throw new Error(ERR_BAD_FORMAT);
|
|
4782
4800
|
}
|
|
4801
|
+
const warnings = zipReader.warnings = [];
|
|
4783
4802
|
const strictness = getStrictness(options, zipReader.options);
|
|
4784
4803
|
const checkAmbiguity = strictness == STRICTNESS_STRICT;
|
|
4785
4804
|
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
@@ -4803,8 +4822,12 @@
|
|
|
4803
4822
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
4804
4823
|
const commentLength = getUint16$1(endOfDirectoryView, 20);
|
|
4805
4824
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
4806
|
-
|
|
4807
|
-
|
|
4825
|
+
const appendedDataLength = reader.size - appendedDataOffset;
|
|
4826
|
+
if (appendedDataLength > maxAppendedDataSize) {
|
|
4827
|
+
throwAmbiguousArchive(WARNING_APPENDED_DATA);
|
|
4828
|
+
}
|
|
4829
|
+
if (appendedDataLength > 0) {
|
|
4830
|
+
addWarning(warnings, WARNING_APPENDED_DATA);
|
|
4808
4831
|
}
|
|
4809
4832
|
let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
|
|
4810
4833
|
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
@@ -4858,23 +4881,23 @@
|
|
|
4858
4881
|
}
|
|
4859
4882
|
if (lastDiskNumber == MAX_16_BITS) {
|
|
4860
4883
|
lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
|
|
4861
|
-
} else if (
|
|
4862
|
-
|
|
4884
|
+
} else if (lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
|
|
4885
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4863
4886
|
}
|
|
4864
4887
|
if (diskNumber == MAX_16_BITS) {
|
|
4865
4888
|
diskNumber = getUint32$1(endOfDirectoryView, 20);
|
|
4866
|
-
} else if (
|
|
4867
|
-
|
|
4889
|
+
} else if (diskNumber != getUint32$1(endOfDirectoryView, 20)) {
|
|
4890
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4868
4891
|
}
|
|
4869
4892
|
if (filesLength == MAX_16_BITS) {
|
|
4870
4893
|
filesLength = getBigUint64(endOfDirectoryView, 32);
|
|
4871
|
-
} else if (
|
|
4872
|
-
|
|
4894
|
+
} else if (filesLength != getBigUint64(endOfDirectoryView, 32)) {
|
|
4895
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4873
4896
|
}
|
|
4874
4897
|
if (directoryDataLength == MAX_32_BITS) {
|
|
4875
4898
|
directoryDataLength = getBigUint64(endOfDirectoryView, 40);
|
|
4876
|
-
} else if (
|
|
4877
|
-
|
|
4899
|
+
} else if (directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
|
|
4900
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4878
4901
|
}
|
|
4879
4902
|
directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
4880
4903
|
}
|
|
@@ -4943,11 +4966,23 @@
|
|
|
4943
4966
|
declaredDirectoryDataLength = directoryArray.length;
|
|
4944
4967
|
decryptedDirectory = true;
|
|
4945
4968
|
}
|
|
4969
|
+
if (directoryEncryptionInfo && !decryptedDirectory &&
|
|
4970
|
+
(directoryArray.length < 4 || getUint32$1(directoryView, 0) == CENTRAL_FILE_HEADER_SIGNATURE)) {
|
|
4971
|
+
addWarning(warnings, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA);
|
|
4972
|
+
}
|
|
4946
4973
|
startOffset = directoryDataOffset;
|
|
4947
4974
|
const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
|
|
4948
4975
|
const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
|
|
4949
|
-
const filenames =
|
|
4976
|
+
const filenames = new Set();
|
|
4950
4977
|
let duplicateFilename;
|
|
4978
|
+
let previousEntryPosition = -1;
|
|
4979
|
+
const recoverWrappedFilesLength = !checkAmbiguity && !zip64EndOfDirectory;
|
|
4980
|
+
if (!filesLength && recoverWrappedFilesLength) {
|
|
4981
|
+
filesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
4982
|
+
if (filesLength) {
|
|
4983
|
+
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
4984
|
+
}
|
|
4985
|
+
}
|
|
4951
4986
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4952
4987
|
const fileEntry = new ZipEntry$1(reader, zipReader.options);
|
|
4953
4988
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
@@ -5025,15 +5060,26 @@
|
|
|
5025
5060
|
filename,
|
|
5026
5061
|
comment
|
|
5027
5062
|
});
|
|
5028
|
-
readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)
|
|
5063
|
+
if (readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)) {
|
|
5064
|
+
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5065
|
+
}
|
|
5029
5066
|
fileEntry.offset += prependedDataLength;
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
}
|
|
5035
|
-
filenames.add(fileEntry.filename);
|
|
5067
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5068
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5069
|
+
if (entryPosition < previousEntryPosition) {
|
|
5070
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5036
5071
|
}
|
|
5072
|
+
previousEntryPosition = entryPosition;
|
|
5073
|
+
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5074
|
+
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5075
|
+
}
|
|
5076
|
+
if ((fileEntry.rawBitFlag & BITFLAG_COMPRESSED_PATCHED_DATA) == BITFLAG_COMPRESSED_PATCHED_DATA) {
|
|
5077
|
+
addWarning(warnings, WARNING_COMPRESSED_PATCHED_DATA, filename);
|
|
5078
|
+
}
|
|
5079
|
+
if (filenames.has(fileEntry.filename)) {
|
|
5080
|
+
duplicateFilename = true;
|
|
5081
|
+
}
|
|
5082
|
+
filenames.add(fileEntry.filename);
|
|
5037
5083
|
const unixExternalUpper = (fileEntry.externalFileAttributes >> 16) & MAX_16_BITS;
|
|
5038
5084
|
if (fileEntry.unixMode === UNDEFINED_VALUE && (unixExternalUpper & (FILE_ATTR_UNIX_DEFAULT_MASK | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_TYPE_DIR)) != 0) {
|
|
5039
5085
|
fileEntry.unixMode = unixExternalUpper;
|
|
@@ -5057,7 +5103,7 @@
|
|
|
5057
5103
|
internalFileAttribute: fileEntry.internalFileAttributes,
|
|
5058
5104
|
externalFileAttribute: fileEntry.externalFileAttributes,
|
|
5059
5105
|
executable,
|
|
5060
|
-
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) ||
|
|
5106
|
+
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE),
|
|
5061
5107
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5062
5108
|
});
|
|
5063
5109
|
const entry = new Entry(fileEntry);
|
|
@@ -5070,6 +5116,13 @@
|
|
|
5070
5116
|
return arrayBufferPromise;
|
|
5071
5117
|
};
|
|
5072
5118
|
offset = endOffset;
|
|
5119
|
+
if (indexFile == filesLength - 1 && recoverWrappedFilesLength) {
|
|
5120
|
+
const wrappedFilesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
5121
|
+
if (wrappedFilesLength) {
|
|
5122
|
+
filesLength += wrappedFilesLength;
|
|
5123
|
+
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5124
|
+
}
|
|
5125
|
+
}
|
|
5073
5126
|
const { onprogress } = options;
|
|
5074
5127
|
if (onprogress) {
|
|
5075
5128
|
try {
|
|
@@ -5094,18 +5147,22 @@
|
|
|
5094
5147
|
zipReader.digitalSignature = digitalSignature;
|
|
5095
5148
|
offsetAfterSignature = offset + 6 + digitalSignature.length;
|
|
5096
5149
|
}
|
|
5097
|
-
if (
|
|
5098
|
-
|
|
5150
|
+
if ((offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) ||
|
|
5151
|
+
(!decryptedDirectory && offset != directoryDataLength && offsetAfterSignature != directoryDataLength)) {
|
|
5152
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA);
|
|
5099
5153
|
}
|
|
5100
5154
|
if (duplicateFilename) {
|
|
5101
|
-
|
|
5155
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_DUPLICATE_FILENAME);
|
|
5102
5156
|
}
|
|
5103
5157
|
const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
|
|
5104
5158
|
const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
|
|
5105
5159
|
const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
|
|
5106
5160
|
startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
|
|
5107
5161
|
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
|
|
5108
|
-
throwAmbiguousArchive(
|
|
5162
|
+
throwAmbiguousArchive(WARNING_PREPENDED_DATA);
|
|
5163
|
+
}
|
|
5164
|
+
if (prependedDataLength || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
|
|
5165
|
+
addWarning(warnings, WARNING_PREPENDED_DATA);
|
|
5109
5166
|
}
|
|
5110
5167
|
if (extractPrependedData) {
|
|
5111
5168
|
zipReader.prependedData = startOffset > splitZipSignatureLength ?
|
|
@@ -5175,6 +5232,28 @@
|
|
|
5175
5232
|
}
|
|
5176
5233
|
}
|
|
5177
5234
|
|
|
5235
|
+
async function isZipFile(reader, options = {}) {
|
|
5236
|
+
reader = new GenericReader(reader);
|
|
5237
|
+
await initStream(reader);
|
|
5238
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
5239
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
5240
|
+
await initStream(reader);
|
|
5241
|
+
}
|
|
5242
|
+
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
5243
|
+
return false;
|
|
5244
|
+
}
|
|
5245
|
+
const strictness = getStrictness(options, {});
|
|
5246
|
+
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
5247
|
+
const maxAppendedDataSize = getMaxAppendedDataSize(options[OPTION_MAX_APPENDED_DATA_SIZE], strictness);
|
|
5248
|
+
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
5249
|
+
if (!endOfDirectoryInfo || (strictness == STRICTNESS_STRICT && endOfDirectoryReachingEndCount > 1)) {
|
|
5250
|
+
return false;
|
|
5251
|
+
}
|
|
5252
|
+
const commentLength = getUint16$1(getDataView(endOfDirectoryInfo), 20);
|
|
5253
|
+
const appendedDataOffset = endOfDirectoryInfo.offset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
5254
|
+
return reader.size - appendedDataOffset <= maxAppendedDataSize;
|
|
5255
|
+
}
|
|
5256
|
+
|
|
5178
5257
|
let ZipEntry$1 = class ZipEntry {
|
|
5179
5258
|
|
|
5180
5259
|
constructor(reader, options) {
|
|
@@ -5206,6 +5285,7 @@
|
|
|
5206
5285
|
dataDescriptor
|
|
5207
5286
|
} = bitFlag;
|
|
5208
5287
|
const localDirectory = fileEntry.localDirectory = {};
|
|
5288
|
+
const warnings = fileEntry.warnings = [];
|
|
5209
5289
|
const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
|
|
5210
5290
|
const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
|
|
5211
5291
|
const dataView = getDataView(dataArray);
|
|
@@ -5228,6 +5308,7 @@
|
|
|
5228
5308
|
extraFieldLength,
|
|
5229
5309
|
filenameLength
|
|
5230
5310
|
} = localDirectory;
|
|
5311
|
+
const dataOffset = localDirectory.dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
5231
5312
|
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5232
5313
|
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5233
5314
|
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
@@ -5245,10 +5326,10 @@
|
|
|
5245
5326
|
if (checkLocalFilename) {
|
|
5246
5327
|
localDirectory.rawFilename = rawLocalFilename;
|
|
5247
5328
|
}
|
|
5248
|
-
readCommonFooter(zipEntry, localDirectory, dataView, 4, true)
|
|
5249
|
-
|
|
5250
|
-
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
|
|
5329
|
+
if (readCommonFooter(zipEntry, localDirectory, dataView, 4, true)) {
|
|
5330
|
+
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD);
|
|
5251
5331
|
}
|
|
5332
|
+
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5252
5333
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5253
5334
|
if (lastAccessDate) {
|
|
5254
5335
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
@@ -5281,7 +5362,6 @@
|
|
|
5281
5362
|
throw new Error(ERR_ENCRYPTED);
|
|
5282
5363
|
}
|
|
5283
5364
|
}
|
|
5284
|
-
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
5285
5365
|
if (dataOffset + compressedSize > reader.size) {
|
|
5286
5366
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5287
5367
|
}
|
|
@@ -5401,6 +5481,16 @@
|
|
|
5401
5481
|
return false;
|
|
5402
5482
|
}
|
|
5403
5483
|
|
|
5484
|
+
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
5485
|
+
let wrappedFilesLength = 0;
|
|
5486
|
+
while (offset + CENTRAL_FILE_HEADER_LENGTH <= directoryArray.length && getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5487
|
+
offset += CENTRAL_FILE_HEADER_LENGTH +
|
|
5488
|
+
getUint16$1(directoryView, offset + 28) + getUint16$1(directoryView, offset + 30) + getUint16$1(directoryView, offset + 32);
|
|
5489
|
+
wrappedFilesLength++;
|
|
5490
|
+
}
|
|
5491
|
+
return wrappedFilesLength % (MAX_16_BITS + 1) ? 0 : wrappedFilesLength;
|
|
5492
|
+
}
|
|
5493
|
+
|
|
5404
5494
|
function readDigitalSignature(signatureRecordArray) {
|
|
5405
5495
|
if (signatureRecordArray.length >= 6) {
|
|
5406
5496
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5465,6 +5555,7 @@
|
|
|
5465
5555
|
const extraField = directory.extraField = new Map();
|
|
5466
5556
|
const rawExtraFieldView = getDataView(rawExtraField);
|
|
5467
5557
|
let offsetExtraField = 0;
|
|
5558
|
+
let malformedExtraField = false;
|
|
5468
5559
|
try {
|
|
5469
5560
|
while (offsetExtraField < rawExtraField.length) {
|
|
5470
5561
|
const type = getUint16$1(rawExtraFieldView, offsetExtraField);
|
|
@@ -5476,7 +5567,10 @@
|
|
|
5476
5567
|
offsetExtraField += 4 + size;
|
|
5477
5568
|
}
|
|
5478
5569
|
} catch {
|
|
5479
|
-
|
|
5570
|
+
malformedExtraField = true;
|
|
5571
|
+
}
|
|
5572
|
+
if (offsetExtraField > rawExtraField.length) {
|
|
5573
|
+
malformedExtraField = true;
|
|
5480
5574
|
}
|
|
5481
5575
|
const compressionMethod = getUint16$1(dataView, offset + 4);
|
|
5482
5576
|
Object.assign(directory, {
|
|
@@ -5544,6 +5638,7 @@
|
|
|
5544
5638
|
if (extraFieldUSDZ) {
|
|
5545
5639
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5546
5640
|
}
|
|
5641
|
+
return malformedExtraField;
|
|
5547
5642
|
}
|
|
5548
5643
|
|
|
5549
5644
|
function readExtraFieldZip64(extraFieldZip64, directory) {
|
|
@@ -5573,10 +5668,11 @@
|
|
|
5573
5668
|
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
5574
5669
|
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
5575
5670
|
const nameCrc32 = getUint32$1(extraFieldView, 1);
|
|
5671
|
+
const version = getUint8(extraFieldView, 0);
|
|
5576
5672
|
Object.assign(extraFieldUnicode, {
|
|
5577
|
-
version
|
|
5673
|
+
version,
|
|
5578
5674
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
5579
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5675
|
+
valid: version == 1 && !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5580
5676
|
});
|
|
5581
5677
|
if (extraFieldUnicode.valid) {
|
|
5582
5678
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -6004,27 +6100,46 @@
|
|
|
6004
6100
|
return UNDEFINED_VALUE;
|
|
6005
6101
|
}
|
|
6006
6102
|
|
|
6007
|
-
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
|
|
6103
|
+
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, warnings) {
|
|
6008
6104
|
const { rawFilename } = zipEntry;
|
|
6105
|
+
const reject = !warnings;
|
|
6009
6106
|
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6010
6107
|
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6011
6108
|
if (checkLocalFilename && !maskedLocalDirectory &&
|
|
6012
6109
|
(rawLocalFilename.length != rawFilename.length ||
|
|
6013
6110
|
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
6014
|
-
|
|
6111
|
+
reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
|
|
6015
6112
|
}
|
|
6016
6113
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
6017
|
-
|
|
6114
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
|
|
6018
6115
|
}
|
|
6019
6116
|
if (localDirectory.compressionMethod != zipEntry.compressionMethod) {
|
|
6020
|
-
|
|
6117
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD);
|
|
6021
6118
|
}
|
|
6022
6119
|
if (!localDirectory.bitFlag.dataDescriptor && !maskedLocalDirectory &&
|
|
6023
6120
|
(localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
|
|
6024
6121
|
(localDirectory.crc32 != zipEntry.crc32 ||
|
|
6025
6122
|
localDirectory.compressedSize != zipEntry.compressedSize ||
|
|
6026
6123
|
localDirectory.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6027
|
-
|
|
6124
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6125
|
+
}
|
|
6126
|
+
}
|
|
6127
|
+
|
|
6128
|
+
function reportAmbiguity(reject, warnings, reason) {
|
|
6129
|
+
if (reject) {
|
|
6130
|
+
throwAmbiguousArchive(reason);
|
|
6131
|
+
} else {
|
|
6132
|
+
addWarning(warnings, reason);
|
|
6133
|
+
}
|
|
6134
|
+
}
|
|
6135
|
+
|
|
6136
|
+
function addWarning(warnings, reason, filename) {
|
|
6137
|
+
if (!warnings.some(warning => warning.reason == reason)) {
|
|
6138
|
+
const warning = { reason };
|
|
6139
|
+
if (filename !== UNDEFINED_VALUE) {
|
|
6140
|
+
warning.filename = filename;
|
|
6141
|
+
}
|
|
6142
|
+
warnings.push(warning);
|
|
6028
6143
|
}
|
|
6029
6144
|
}
|
|
6030
6145
|
|
|
@@ -6045,7 +6160,8 @@
|
|
|
6045
6160
|
|
|
6046
6161
|
function getDate(timeRaw) {
|
|
6047
6162
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
6048
|
-
|
|
6163
|
+
const result = new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
6164
|
+
return result < MIN_DATE ? MIN_DATE : result;
|
|
6049
6165
|
}
|
|
6050
6166
|
|
|
6051
6167
|
function getDateNTFS(timeRaw) {
|
|
@@ -6100,8 +6216,23 @@
|
|
|
6100
6216
|
ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
|
|
6101
6217
|
ERR_UNSUPPORTED_UINT64: ERR_UNSUPPORTED_UINT64,
|
|
6102
6218
|
ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
|
|
6219
|
+
WARNING_APPENDED_DATA: WARNING_APPENDED_DATA,
|
|
6220
|
+
WARNING_COMPRESSED_PATCHED_DATA: WARNING_COMPRESSED_PATCHED_DATA,
|
|
6221
|
+
WARNING_DUPLICATE_FILENAME: WARNING_DUPLICATE_FILENAME,
|
|
6222
|
+
WARNING_MALFORMED_EXTRA_FIELD: WARNING_MALFORMED_EXTRA_FIELD,
|
|
6223
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
|
|
6224
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
|
|
6225
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
|
|
6226
|
+
WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
|
|
6227
|
+
WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
|
|
6228
|
+
WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
|
|
6229
|
+
WARNING_UNKNOWN_VERSION: WARNING_UNKNOWN_VERSION,
|
|
6230
|
+
WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA: WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA,
|
|
6231
|
+
WARNING_UNSORTED_CENTRAL_DIRECTORY: WARNING_UNSORTED_CENTRAL_DIRECTORY,
|
|
6232
|
+
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6103
6233
|
ZipReader: ZipReader,
|
|
6104
|
-
ZipReaderStream: ZipReaderStream
|
|
6234
|
+
ZipReaderStream: ZipReaderStream,
|
|
6235
|
+
isZipFile: isZipFile
|
|
6105
6236
|
});
|
|
6106
6237
|
|
|
6107
6238
|
/*
|
|
@@ -6198,153 +6329,151 @@
|
|
|
6198
6329
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
6199
6330
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
6200
6331
|
pendingAddFileCalls: new Set(),
|
|
6332
|
+
pendingErrors: [],
|
|
6201
6333
|
bufferedWrites: 0,
|
|
6202
6334
|
lastFileEntry: UNDEFINED_VALUE
|
|
6203
6335
|
});
|
|
6204
6336
|
}
|
|
6205
6337
|
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6209
|
-
}
|
|
6210
|
-
reader = new GenericReader(reader);
|
|
6211
|
-
await initStream(reader);
|
|
6212
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6213
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6214
|
-
await initStream(reader);
|
|
6215
|
-
}
|
|
6216
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6217
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6218
|
-
const entries = await zipReader$1.getEntries();
|
|
6219
|
-
await zipReader$1.close();
|
|
6220
|
-
await initStream(this.writer);
|
|
6221
|
-
const { directoryOffset } = zipReader$1;
|
|
6222
|
-
if (this.addSplitZipSignature) {
|
|
6223
|
-
delete this.addSplitZipSignature;
|
|
6224
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6225
|
-
await writeData(this.writer, getSplitZipSignatureArray());
|
|
6226
|
-
this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6227
|
-
}
|
|
6228
|
-
}
|
|
6229
|
-
const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
|
|
6230
|
-
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
6231
|
-
this.fileEntries = new Map(entries.map(entry => {
|
|
6232
|
-
const {
|
|
6233
|
-
version,
|
|
6234
|
-
rawLastModDate,
|
|
6235
|
-
lastAccessDate,
|
|
6236
|
-
creationDate,
|
|
6237
|
-
rawFilename,
|
|
6238
|
-
bitFlag,
|
|
6239
|
-
encrypted,
|
|
6240
|
-
uncompressedSize,
|
|
6241
|
-
compressedSize,
|
|
6242
|
-
extraFieldZip64
|
|
6243
|
-
} = entry;
|
|
6244
|
-
let {
|
|
6245
|
-
compressionMethod,
|
|
6246
|
-
rawExtraFieldZip64,
|
|
6247
|
-
rawExtraFieldAES,
|
|
6248
|
-
rawExtraFieldExtendedTimestamp,
|
|
6249
|
-
rawExtraFieldNTFS,
|
|
6250
|
-
rawExtraFieldUnix,
|
|
6251
|
-
rawExtraField,
|
|
6252
|
-
} = entry;
|
|
6253
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6254
|
-
rawExtraFieldZip64 = rawExtraFieldZip64 || EMPTY_UINT8_ARRAY;
|
|
6255
|
-
rawExtraFieldAES = rawExtraFieldAES || EMPTY_UINT8_ARRAY;
|
|
6256
|
-
rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
|
|
6257
|
-
rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
|
|
6258
|
-
rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
|
|
6259
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6260
|
-
if (entry.extraFieldAES) {
|
|
6261
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6262
|
-
}
|
|
6263
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
6264
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6265
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6266
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6267
|
-
const {
|
|
6268
|
-
headerArray,
|
|
6269
|
-
headerView
|
|
6270
|
-
} = getHeaderArrayData({
|
|
6271
|
-
version,
|
|
6272
|
-
bitFlag: bitFlagValue,
|
|
6273
|
-
compressionMethod,
|
|
6274
|
-
uncompressedSize,
|
|
6275
|
-
compressedSize,
|
|
6276
|
-
rawLastModDate,
|
|
6277
|
-
rawFilename,
|
|
6278
|
-
zip64CompressedSize,
|
|
6279
|
-
zip64UncompressedSize,
|
|
6280
|
-
extraFieldLength
|
|
6281
|
-
});
|
|
6282
|
-
const { crc32 } = entry;
|
|
6283
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6284
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6285
|
-
}
|
|
6286
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6287
|
-
Object.assign(entry, {
|
|
6288
|
-
zip64UncompressedSize,
|
|
6289
|
-
zip64CompressedSize,
|
|
6290
|
-
offset,
|
|
6291
|
-
diskNumberStart,
|
|
6292
|
-
zip64DiskNumberStart: false,
|
|
6293
|
-
rawExtraFieldZip64,
|
|
6294
|
-
rawExtraFieldAES,
|
|
6295
|
-
rawExtraFieldExtendedTimestamp,
|
|
6296
|
-
rawExtraFieldNTFS,
|
|
6297
|
-
rawExtraFieldUnix,
|
|
6298
|
-
rawExtraField,
|
|
6299
|
-
extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
|
|
6300
|
-
extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
|
|
6301
|
-
headerArray,
|
|
6302
|
-
headerView
|
|
6303
|
-
});
|
|
6304
|
-
return [entry.filename, entry];
|
|
6305
|
-
}));
|
|
6338
|
+
prependZip(reader) {
|
|
6339
|
+
return watchPromiseError(this, prependZipEntries(this, reader));
|
|
6306
6340
|
}
|
|
6307
6341
|
|
|
6308
|
-
|
|
6342
|
+
appendZip(reader) {
|
|
6343
|
+
return watchPromiseError(this, this.appendZipEntries(reader));
|
|
6344
|
+
}
|
|
6345
|
+
|
|
6346
|
+
async appendZipEntries(reader) {
|
|
6309
6347
|
const zipWriter = this;
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
workers++;
|
|
6314
|
-
} else {
|
|
6315
|
-
await new Promise(resolve => pendingEntries.push(resolve));
|
|
6348
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6349
|
+
while (pendingAddFileCalls.size) {
|
|
6350
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6316
6351
|
}
|
|
6317
|
-
let
|
|
6318
|
-
|
|
6352
|
+
let resolveAppendZip;
|
|
6353
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6354
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6355
|
+
const appendedFilenames = [];
|
|
6356
|
+
let releaseLockWriter;
|
|
6319
6357
|
try {
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
}
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6358
|
+
reader = new GenericReader(reader);
|
|
6359
|
+
await initStream(reader);
|
|
6360
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6361
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6362
|
+
await initStream(reader);
|
|
6363
|
+
}
|
|
6364
|
+
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6365
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6366
|
+
const entries = await zipReader$1.getEntries();
|
|
6367
|
+
await zipReader$1.close();
|
|
6368
|
+
await initStream(zipWriter.writer);
|
|
6369
|
+
const { directoryOffset } = zipReader$1;
|
|
6370
|
+
entries.forEach(({ filename }) => {
|
|
6371
|
+
if (filenames.has(filename)) {
|
|
6372
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6373
|
+
}
|
|
6374
|
+
filenames.add(filename);
|
|
6375
|
+
appendedFilenames.push(filename);
|
|
6376
|
+
});
|
|
6377
|
+
zipWriter.writerLocked = true;
|
|
6378
|
+
const { lockWriter } = zipWriter;
|
|
6379
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6380
|
+
zipWriter.writerLocked = false;
|
|
6381
|
+
resolve();
|
|
6382
|
+
});
|
|
6383
|
+
await lockWriter;
|
|
6384
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6385
|
+
delete zipWriter.addSplitZipSignature;
|
|
6386
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
6387
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6388
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6389
|
+
}
|
|
6335
6390
|
}
|
|
6391
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
|
|
6392
|
+
entries.forEach(entry => {
|
|
6393
|
+
const {
|
|
6394
|
+
version,
|
|
6395
|
+
rawLastModDate,
|
|
6396
|
+
rawFilename,
|
|
6397
|
+
bitFlag,
|
|
6398
|
+
encrypted,
|
|
6399
|
+
uncompressedSize,
|
|
6400
|
+
compressedSize,
|
|
6401
|
+
extraFieldZip64
|
|
6402
|
+
} = entry;
|
|
6403
|
+
let {
|
|
6404
|
+
compressionMethod,
|
|
6405
|
+
rawExtraField,
|
|
6406
|
+
} = entry;
|
|
6407
|
+
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6408
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6409
|
+
if (entry.extraFieldAES) {
|
|
6410
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6411
|
+
}
|
|
6412
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6413
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6414
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6415
|
+
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6416
|
+
const {
|
|
6417
|
+
headerArray,
|
|
6418
|
+
headerView
|
|
6419
|
+
} = getHeaderArrayData({
|
|
6420
|
+
version,
|
|
6421
|
+
bitFlag: bitFlagValue,
|
|
6422
|
+
compressionMethod,
|
|
6423
|
+
uncompressedSize,
|
|
6424
|
+
compressedSize,
|
|
6425
|
+
rawLastModDate,
|
|
6426
|
+
rawFilename,
|
|
6427
|
+
zip64CompressedSize,
|
|
6428
|
+
zip64UncompressedSize,
|
|
6429
|
+
extraFieldLength
|
|
6430
|
+
});
|
|
6431
|
+
const { crc32 } = entry;
|
|
6432
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6433
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6434
|
+
}
|
|
6435
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6436
|
+
Object.assign(entry, {
|
|
6437
|
+
zip64UncompressedSize,
|
|
6438
|
+
zip64CompressedSize,
|
|
6439
|
+
offset,
|
|
6440
|
+
diskNumberStart,
|
|
6441
|
+
zip64DiskNumberStart: false,
|
|
6442
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6443
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6444
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6445
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6446
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6447
|
+
rawExtraField,
|
|
6448
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6449
|
+
extendedTimestamp: false,
|
|
6450
|
+
headerArray,
|
|
6451
|
+
headerView
|
|
6452
|
+
});
|
|
6453
|
+
fileEntries.set(entry.filename, entry);
|
|
6454
|
+
});
|
|
6455
|
+
} catch (error) {
|
|
6456
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6336
6457
|
throw error;
|
|
6337
6458
|
} finally {
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
if (
|
|
6341
|
-
|
|
6342
|
-
} else {
|
|
6343
|
-
workers--;
|
|
6459
|
+
resolveAppendZip();
|
|
6460
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6461
|
+
if (releaseLockWriter) {
|
|
6462
|
+
releaseLockWriter();
|
|
6344
6463
|
}
|
|
6345
6464
|
}
|
|
6346
6465
|
}
|
|
6347
6466
|
|
|
6467
|
+
add(name = "", reader, options = {}) {
|
|
6468
|
+
const zipWriter = this;
|
|
6469
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
6470
|
+
const promiseAddFile = addFileEntry(zipWriter, name, reader, options);
|
|
6471
|
+
pendingAddFileCalls.add(promiseAddFile);
|
|
6472
|
+
const deletePendingAddFileCall = () => pendingAddFileCalls.delete(promiseAddFile);
|
|
6473
|
+
Promise.prototype.then.call(promiseAddFile, deletePendingAddFileCall, deletePendingAddFileCall);
|
|
6474
|
+
return watchPromiseError(zipWriter, promiseAddFile);
|
|
6475
|
+
}
|
|
6476
|
+
|
|
6348
6477
|
remove(entry) {
|
|
6349
6478
|
const { filenames, fileEntries } = this;
|
|
6350
6479
|
// deno-lint-ignore valid-typeof
|
|
@@ -6375,6 +6504,19 @@
|
|
|
6375
6504
|
while (pendingAddFileCalls.size) {
|
|
6376
6505
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6377
6506
|
}
|
|
6507
|
+
await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
|
|
6508
|
+
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
|
|
6509
|
+
if (unobservedWatchers.length) {
|
|
6510
|
+
const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
|
|
6511
|
+
unobservedWatchers.forEach(watcher => watcher.observed = true);
|
|
6512
|
+
const [error] = unobservedErrors;
|
|
6513
|
+
try {
|
|
6514
|
+
error.entryErrors = unobservedErrors;
|
|
6515
|
+
} catch {
|
|
6516
|
+
// ignored
|
|
6517
|
+
}
|
|
6518
|
+
throw error;
|
|
6519
|
+
}
|
|
6378
6520
|
await closeFile(zipWriter, comment, options);
|
|
6379
6521
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
6380
6522
|
if (!preventClose) {
|
|
@@ -6409,11 +6551,7 @@
|
|
|
6409
6551
|
try {
|
|
6410
6552
|
await zipWriter.close();
|
|
6411
6553
|
} catch (error) {
|
|
6412
|
-
|
|
6413
|
-
await zipWriter.writer.writable.abort(error);
|
|
6414
|
-
} catch {
|
|
6415
|
-
// ignored
|
|
6416
|
-
}
|
|
6554
|
+
await abortWritable(zipWriter, error);
|
|
6417
6555
|
}
|
|
6418
6556
|
}
|
|
6419
6557
|
}
|
|
@@ -6430,8 +6568,89 @@
|
|
|
6430
6568
|
}
|
|
6431
6569
|
|
|
6432
6570
|
async close(comment = UNDEFINED_VALUE, options = {}) {
|
|
6433
|
-
|
|
6434
|
-
|
|
6571
|
+
const { zipWriter } = this;
|
|
6572
|
+
const results = await Promise.allSettled(Array.from(this.pendingAddFileCalls));
|
|
6573
|
+
const entryErrors = results.filter(result => result.status == "rejected").map(result => result.reason);
|
|
6574
|
+
if (entryErrors.length) {
|
|
6575
|
+
const [error] = entryErrors;
|
|
6576
|
+
try {
|
|
6577
|
+
error.entryErrors = entryErrors;
|
|
6578
|
+
} catch {
|
|
6579
|
+
// ignored
|
|
6580
|
+
}
|
|
6581
|
+
await abortWritable(zipWriter, error);
|
|
6582
|
+
throw error;
|
|
6583
|
+
}
|
|
6584
|
+
try {
|
|
6585
|
+
return await zipWriter.close(comment, options);
|
|
6586
|
+
} catch (error) {
|
|
6587
|
+
await abortWritable(zipWriter, error);
|
|
6588
|
+
throw error;
|
|
6589
|
+
}
|
|
6590
|
+
}
|
|
6591
|
+
}
|
|
6592
|
+
|
|
6593
|
+
class WatchedPromise extends Promise {
|
|
6594
|
+
|
|
6595
|
+
then(onFulfilled, onRejected) {
|
|
6596
|
+
const { watcher } = this;
|
|
6597
|
+
if (watcher) {
|
|
6598
|
+
watcher.observed = true;
|
|
6599
|
+
}
|
|
6600
|
+
return super.then(onFulfilled, onRejected);
|
|
6601
|
+
}
|
|
6602
|
+
}
|
|
6603
|
+
|
|
6604
|
+
function watchPromiseError(zipWriter, promise) {
|
|
6605
|
+
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
6606
|
+
const watcher = {};
|
|
6607
|
+
watchedPromise.watcher = watcher;
|
|
6608
|
+
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
|
|
6609
|
+
zipWriter.pendingErrors.push(watcher);
|
|
6610
|
+
return watchedPromise;
|
|
6611
|
+
}
|
|
6612
|
+
|
|
6613
|
+
async function prependZipEntries(zipWriter, reader) {
|
|
6614
|
+
if (zipWriter.filenames.size) {
|
|
6615
|
+
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6616
|
+
}
|
|
6617
|
+
await zipWriter.appendZipEntries(reader);
|
|
6618
|
+
}
|
|
6619
|
+
|
|
6620
|
+
async function addFileEntry(zipWriter, name, reader, options) {
|
|
6621
|
+
options = Object.assign({}, options);
|
|
6622
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6623
|
+
name += DIRECTORY_SIGNATURE;
|
|
6624
|
+
}
|
|
6625
|
+
if (zipWriter.filenames.has(name)) {
|
|
6626
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6627
|
+
}
|
|
6628
|
+
zipWriter.filenames.add(name);
|
|
6629
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
6630
|
+
workers++;
|
|
6631
|
+
} else {
|
|
6632
|
+
await new Promise(resolve => pendingEntries.push(resolve));
|
|
6633
|
+
}
|
|
6634
|
+
try {
|
|
6635
|
+
return await addFile(zipWriter, name, reader, options);
|
|
6636
|
+
} catch (error) {
|
|
6637
|
+
zipWriter.filenames.delete(name);
|
|
6638
|
+
throw error;
|
|
6639
|
+
} finally {
|
|
6640
|
+
const pendingEntry = pendingEntries.shift();
|
|
6641
|
+
if (pendingEntry) {
|
|
6642
|
+
pendingEntry();
|
|
6643
|
+
} else {
|
|
6644
|
+
workers--;
|
|
6645
|
+
}
|
|
6646
|
+
}
|
|
6647
|
+
}
|
|
6648
|
+
|
|
6649
|
+
async function abortWritable(zipWriter, error) {
|
|
6650
|
+
try {
|
|
6651
|
+
await zipWriter.writer.writable.abort(error);
|
|
6652
|
+
} catch {
|
|
6653
|
+
// ignored
|
|
6435
6654
|
}
|
|
6436
6655
|
}
|
|
6437
6656
|
|
|
@@ -6490,7 +6709,6 @@
|
|
|
6490
6709
|
}
|
|
6491
6710
|
|
|
6492
6711
|
function resolveAttributes(zipWriter, name, options) {
|
|
6493
|
-
name = name.trim();
|
|
6494
6712
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
6495
6713
|
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
6496
6714
|
const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
|
|
@@ -6634,11 +6852,12 @@
|
|
|
6634
6852
|
if (getLength(rawComment) > MAX_16_BITS) {
|
|
6635
6853
|
throw new Error(ERR_INVALID_ENTRY_COMMENT);
|
|
6636
6854
|
}
|
|
6637
|
-
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION
|
|
6638
|
-
if (version > MAX_16_BITS) {
|
|
6855
|
+
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION);
|
|
6856
|
+
if (version !== UNDEFINED_VALUE && version > MAX_16_BITS) {
|
|
6639
6857
|
throw new Error(ERR_INVALID_VERSION);
|
|
6640
6858
|
}
|
|
6641
6859
|
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
6860
|
+
const rawLastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
|
|
6642
6861
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6643
6862
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6644
6863
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
@@ -6682,7 +6901,7 @@
|
|
|
6682
6901
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
6683
6902
|
dataDescriptor = false;
|
|
6684
6903
|
}
|
|
6685
|
-
if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
|
|
6904
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
|
|
6686
6905
|
dataDescriptor = true;
|
|
6687
6906
|
}
|
|
6688
6907
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -6694,6 +6913,7 @@
|
|
|
6694
6913
|
}
|
|
6695
6914
|
const rawExtraField = serializeExtraField(options[PROPERTY_NAME_EXTRA_FIELD]);
|
|
6696
6915
|
const rawLocalExtraField = serializeExtraField(options[OPTION_LOCAL_EXTRA_FIELD]);
|
|
6916
|
+
const rawCentralExtraField = serializeExtraField(options[OPTION_CENTRAL_EXTRA_FIELD]);
|
|
6697
6917
|
return {
|
|
6698
6918
|
comment,
|
|
6699
6919
|
resolvedOptions: {
|
|
@@ -6701,6 +6921,7 @@
|
|
|
6701
6921
|
rawComment,
|
|
6702
6922
|
version,
|
|
6703
6923
|
lastModDate,
|
|
6924
|
+
rawLastModDate,
|
|
6704
6925
|
lastAccessDate,
|
|
6705
6926
|
creationDate,
|
|
6706
6927
|
internalFileAttributes,
|
|
@@ -6728,7 +6949,8 @@
|
|
|
6728
6949
|
dataDescriptor,
|
|
6729
6950
|
zip64,
|
|
6730
6951
|
rawExtraField,
|
|
6731
|
-
rawLocalExtraField
|
|
6952
|
+
rawLocalExtraField,
|
|
6953
|
+
rawCentralExtraField
|
|
6732
6954
|
}
|
|
6733
6955
|
};
|
|
6734
6956
|
}
|
|
@@ -6870,7 +7092,6 @@
|
|
|
6870
7092
|
let { name } = entry;
|
|
6871
7093
|
const { size } = entry;
|
|
6872
7094
|
const options = Object.assign({}, entry.options);
|
|
6873
|
-
name = name.trim();
|
|
6874
7095
|
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6875
7096
|
name += DIRECTORY_SIGNATURE;
|
|
6876
7097
|
}
|
|
@@ -6976,10 +7197,8 @@
|
|
|
6976
7197
|
}
|
|
6977
7198
|
await initStream(fileWriter);
|
|
6978
7199
|
const diskOffset = getDiskOffset(writer);
|
|
6979
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6980
|
-
|
|
6981
|
-
await writeData(writer, getSplitZipSignatureArray());
|
|
6982
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
7200
|
+
if (zipWriter.addSplitZipSignature && !bufferedWrite) {
|
|
7201
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
6983
7202
|
}
|
|
6984
7203
|
if (usdz && !bufferedWrite) {
|
|
6985
7204
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -7006,6 +7225,9 @@
|
|
|
7006
7225
|
if (bufferedWrite) {
|
|
7007
7226
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
7008
7227
|
await requestLockWriter();
|
|
7228
|
+
if (zipWriter.addSplitZipSignature) {
|
|
7229
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
7230
|
+
}
|
|
7009
7231
|
writingBufferedEntryData = true;
|
|
7010
7232
|
writerSizeBeforeEntry = writer.size;
|
|
7011
7233
|
await skipDiskIfNeeded();
|
|
@@ -7125,6 +7347,7 @@
|
|
|
7125
7347
|
versionMadeBy,
|
|
7126
7348
|
rawComment,
|
|
7127
7349
|
rawExtraField,
|
|
7350
|
+
rawCentralExtraField,
|
|
7128
7351
|
useWebWorkers,
|
|
7129
7352
|
transferStreams,
|
|
7130
7353
|
onstart,
|
|
@@ -7168,6 +7391,7 @@
|
|
|
7168
7391
|
rawExtraFieldUnix,
|
|
7169
7392
|
rawExtraFieldAES,
|
|
7170
7393
|
rawExtraField,
|
|
7394
|
+
rawCentralExtraField,
|
|
7171
7395
|
extendedTimestamp,
|
|
7172
7396
|
msDosCompatible,
|
|
7173
7397
|
internalFileAttributes,
|
|
@@ -7277,6 +7501,7 @@
|
|
|
7277
7501
|
const {
|
|
7278
7502
|
rawFilename,
|
|
7279
7503
|
lastModDate,
|
|
7504
|
+
rawLastModDate: rawLastModDateOption,
|
|
7280
7505
|
lastAccessDate,
|
|
7281
7506
|
creationDate,
|
|
7282
7507
|
level,
|
|
@@ -7410,6 +7635,9 @@
|
|
|
7410
7635
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
7411
7636
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
7412
7637
|
}
|
|
7638
|
+
if (version === UNDEFINED_VALUE) {
|
|
7639
|
+
version = compressionMethod == COMPRESSION_METHOD_STORE && !directory && !encrypted ? VERSION_STORE : VERSION_DEFLATE;
|
|
7640
|
+
}
|
|
7413
7641
|
const { codecVersionNeeded } = options;
|
|
7414
7642
|
if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
|
|
7415
7643
|
version = version > codecVersionNeeded ? version : codecVersionNeeded;
|
|
@@ -7442,6 +7670,7 @@
|
|
|
7442
7670
|
compressionMethod,
|
|
7443
7671
|
uncompressedSize,
|
|
7444
7672
|
lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
|
|
7673
|
+
rawLastModDate: rawLastModDateOption,
|
|
7445
7674
|
rawFilename,
|
|
7446
7675
|
zip64CompressedSize,
|
|
7447
7676
|
zip64UncompressedSize,
|
|
@@ -7648,9 +7877,9 @@
|
|
|
7648
7877
|
|
|
7649
7878
|
async function closeFile(zipWriter, comment, options) {
|
|
7650
7879
|
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
7651
|
-
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7880
|
+
const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7652
7881
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
7653
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
7882
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
|
|
7654
7883
|
}
|
|
7655
7884
|
|
|
7656
7885
|
function createDirectoryRecords(files) {
|
|
@@ -7663,6 +7892,7 @@
|
|
|
7663
7892
|
rawExtraFieldNTFS,
|
|
7664
7893
|
rawExtraFieldUnix,
|
|
7665
7894
|
rawExtraField,
|
|
7895
|
+
rawCentralExtraField,
|
|
7666
7896
|
extendedTimestamp,
|
|
7667
7897
|
extraFieldExtendedTimestampFlag,
|
|
7668
7898
|
lastModDate,
|
|
@@ -7717,7 +7947,8 @@
|
|
|
7717
7947
|
rawExtraFieldNTFS,
|
|
7718
7948
|
rawExtraFieldUnix,
|
|
7719
7949
|
rawExtraFieldTimestamp,
|
|
7720
|
-
rawExtraField
|
|
7950
|
+
rawExtraField,
|
|
7951
|
+
rawCentralExtraField);
|
|
7721
7952
|
if (extraFieldLength > MAX_16_BITS) {
|
|
7722
7953
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
7723
7954
|
}
|
|
@@ -7734,6 +7965,7 @@
|
|
|
7734
7965
|
let directoryDiskOffset = 0;
|
|
7735
7966
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
7736
7967
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
7968
|
+
let directoryEndDiskEntriesLength = 0;
|
|
7737
7969
|
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
7738
7970
|
const {
|
|
7739
7971
|
offset: fileEntryOffset,
|
|
@@ -7744,6 +7976,7 @@
|
|
|
7744
7976
|
rawExtraFieldNTFS,
|
|
7745
7977
|
rawExtraFieldUnix,
|
|
7746
7978
|
rawExtraField,
|
|
7979
|
+
rawCentralExtraField,
|
|
7747
7980
|
rawComment,
|
|
7748
7981
|
versionMadeBy,
|
|
7749
7982
|
headerArray,
|
|
@@ -7758,11 +7991,12 @@
|
|
|
7758
7991
|
uncompressedSize,
|
|
7759
7992
|
compressedSize
|
|
7760
7993
|
} = fileEntry;
|
|
7761
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
7994
|
+
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawCentralExtraField);
|
|
7762
7995
|
const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
|
|
7763
7996
|
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
7764
7997
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
7765
7998
|
directoryDiskOffset = offset;
|
|
7999
|
+
directoryEndDiskEntriesLength = 0;
|
|
7766
8000
|
await writer.closeDisk();
|
|
7767
8001
|
}
|
|
7768
8002
|
if (indexFileEntry == 0) {
|
|
@@ -7795,9 +8029,11 @@
|
|
|
7795
8029
|
directoryRecord.writeBytes(rawExtraFieldNTFS);
|
|
7796
8030
|
directoryRecord.writeBytes(rawExtraFieldUnix);
|
|
7797
8031
|
directoryRecord.writeBytes(rawExtraField);
|
|
8032
|
+
directoryRecord.writeBytes(rawCentralExtraField);
|
|
7798
8033
|
directoryRecord.writeBytes(rawComment);
|
|
7799
8034
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
7800
8035
|
offset += directoryRecordLength;
|
|
8036
|
+
directoryEndDiskEntriesLength++;
|
|
7801
8037
|
if (options.onprogress) {
|
|
7802
8038
|
try {
|
|
7803
8039
|
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
@@ -7809,6 +8045,7 @@
|
|
|
7809
8045
|
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
7810
8046
|
return {
|
|
7811
8047
|
directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
|
|
8048
|
+
directoryEnd: { diskNumber: getDiskNumber(writer), entriesLength: directoryEndDiskEntriesLength },
|
|
7812
8049
|
directoryArray
|
|
7813
8050
|
};
|
|
7814
8051
|
}
|
|
@@ -7837,16 +8074,20 @@
|
|
|
7837
8074
|
|
|
7838
8075
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
7839
8076
|
const { writer } = zipWriter;
|
|
7840
|
-
const { directoryStart, signatureLength } = cdInfo;
|
|
8077
|
+
const { directoryStart, directoryEnd, signatureLength } = cdInfo;
|
|
7841
8078
|
let { directoryDataLength } = cdInfo;
|
|
7842
8079
|
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
7843
8080
|
let diskNumber = directoryStart.diskNumber;
|
|
7844
8081
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
8082
|
+
const commentLength = getLength(comment);
|
|
8083
|
+
if (commentLength > MAX_16_BITS) {
|
|
8084
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
8085
|
+
}
|
|
8086
|
+
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7845
8087
|
let lastDiskNumber = getDiskNumber(writer);
|
|
7846
|
-
if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
|
|
8088
|
+
if (exceedsAvailableSize(writer, (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH) + commentLength)) {
|
|
7847
8089
|
lastDiskNumber++;
|
|
7848
8090
|
}
|
|
7849
|
-
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7850
8091
|
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
7851
8092
|
if (zip64 === false) {
|
|
7852
8093
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
@@ -7854,15 +8095,12 @@
|
|
|
7854
8095
|
zip64 = true;
|
|
7855
8096
|
}
|
|
7856
8097
|
}
|
|
7857
|
-
const commentLength = getLength(comment);
|
|
7858
|
-
if (commentLength > MAX_16_BITS) {
|
|
7859
|
-
throw new Error(ERR_INVALID_COMMENT);
|
|
7860
|
-
}
|
|
7861
8098
|
const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
7862
8099
|
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
|
7863
8100
|
await writer.closeDisk();
|
|
7864
8101
|
}
|
|
7865
8102
|
lastDiskNumber = getDiskNumber(writer);
|
|
8103
|
+
let diskFileEntriesLength = lastDiskNumber == directoryEnd.diskNumber ? directoryEnd.entriesLength : 0;
|
|
7866
8104
|
if (zip64) {
|
|
7867
8105
|
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7868
8106
|
endOfdirectoryRecord.writeUint64(44);
|
|
@@ -7870,7 +8108,7 @@
|
|
|
7870
8108
|
endOfdirectoryRecord.writeUint16(45);
|
|
7871
8109
|
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7872
8110
|
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
7873
|
-
endOfdirectoryRecord.writeUint64(
|
|
8111
|
+
endOfdirectoryRecord.writeUint64(diskFileEntriesLength);
|
|
7874
8112
|
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7875
8113
|
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
7876
8114
|
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
@@ -7883,6 +8121,7 @@
|
|
|
7883
8121
|
lastDiskNumber = MAX_16_BITS;
|
|
7884
8122
|
diskNumber = MAX_16_BITS;
|
|
7885
8123
|
}
|
|
8124
|
+
diskFileEntriesLength = MAX_16_BITS;
|
|
7886
8125
|
fileEntriesLength = MAX_16_BITS;
|
|
7887
8126
|
directoryOffset = MAX_32_BITS;
|
|
7888
8127
|
directoryDataLength = MAX_32_BITS;
|
|
@@ -7890,7 +8129,7 @@
|
|
|
7890
8129
|
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7891
8130
|
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
7892
8131
|
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
7893
|
-
endOfdirectoryRecord.writeUint16(
|
|
8132
|
+
endOfdirectoryRecord.writeUint16(diskFileEntriesLength);
|
|
7894
8133
|
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7895
8134
|
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
7896
8135
|
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
@@ -7989,9 +8228,21 @@
|
|
|
7989
8228
|
async function copyData(zipWriter, reader, offset, size) {
|
|
7990
8229
|
if (size > 0) {
|
|
7991
8230
|
const { writer } = zipWriter;
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
8231
|
+
let copiedLength = 0;
|
|
8232
|
+
try {
|
|
8233
|
+
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8234
|
+
} catch (error) {
|
|
8235
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8236
|
+
try {
|
|
8237
|
+
error.corruptedEntry = true;
|
|
8238
|
+
} catch {
|
|
8239
|
+
// ignored
|
|
8240
|
+
}
|
|
8241
|
+
throw error;
|
|
8242
|
+
} finally {
|
|
8243
|
+
writer.size += copiedLength;
|
|
8244
|
+
zipWriter.offset += copiedLength;
|
|
8245
|
+
}
|
|
7995
8246
|
}
|
|
7996
8247
|
}
|
|
7997
8248
|
|
|
@@ -8016,6 +8267,12 @@
|
|
|
8016
8267
|
return signatureArray;
|
|
8017
8268
|
}
|
|
8018
8269
|
|
|
8270
|
+
async function writeSplitZipSignature(zipWriter, writer) {
|
|
8271
|
+
delete zipWriter.addSplitZipSignature;
|
|
8272
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
8273
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
8274
|
+
}
|
|
8275
|
+
|
|
8019
8276
|
async function writeData(writer, array) {
|
|
8020
8277
|
const { writable } = writer;
|
|
8021
8278
|
const streamWriter = writable.getWriter();
|
|
@@ -8765,6 +9022,7 @@
|
|
|
8765
9022
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
8766
9023
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
8767
9024
|
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
9025
|
+
const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
|
|
8768
9026
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
8769
9027
|
const ERR_ABORTED = "The operation was aborted";
|
|
8770
9028
|
const ABORT_ERROR_NAME = "AbortError";
|
|
@@ -9632,6 +9890,7 @@
|
|
|
9632
9890
|
versionMadeBy,
|
|
9633
9891
|
comment,
|
|
9634
9892
|
lastModDate,
|
|
9893
|
+
rawLastModDate,
|
|
9635
9894
|
creationDate,
|
|
9636
9895
|
lastAccessDate,
|
|
9637
9896
|
uncompressedSize,
|
|
@@ -9642,6 +9901,7 @@
|
|
|
9642
9901
|
extraFieldAES,
|
|
9643
9902
|
internalFileAttributes,
|
|
9644
9903
|
extraField,
|
|
9904
|
+
bitFlag,
|
|
9645
9905
|
uid,
|
|
9646
9906
|
gid
|
|
9647
9907
|
} = child.data;
|
|
@@ -9679,6 +9939,16 @@
|
|
|
9679
9939
|
encryptionStrength,
|
|
9680
9940
|
compressionMethod
|
|
9681
9941
|
};
|
|
9942
|
+
if (bitFlag) {
|
|
9943
|
+
passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
|
|
9944
|
+
}
|
|
9945
|
+
const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
|
|
9946
|
+
if (lastModDateOverride === UNDEFINED_VALUE) {
|
|
9947
|
+
passThroughOptions.rawLastModDate = rawLastModDate;
|
|
9948
|
+
} else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
|
|
9949
|
+
getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
|
|
9950
|
+
throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
|
|
9951
|
+
}
|
|
9682
9952
|
}
|
|
9683
9953
|
}
|
|
9684
9954
|
const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
|
|
@@ -9688,6 +9958,16 @@
|
|
|
9688
9958
|
return { name, entryOptions };
|
|
9689
9959
|
}
|
|
9690
9960
|
|
|
9961
|
+
function getDosTimeHighByte(lastModDate) {
|
|
9962
|
+
let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
9963
|
+
if (dosLastModDate < MIN_DATE) {
|
|
9964
|
+
dosLastModDate = MIN_DATE;
|
|
9965
|
+
} else if (dosLastModDate > MAX_DATE) {
|
|
9966
|
+
dosLastModDate = MAX_DATE;
|
|
9967
|
+
}
|
|
9968
|
+
return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
|
|
9969
|
+
}
|
|
9970
|
+
|
|
9691
9971
|
function getDeterminedSize(child, passThrough) {
|
|
9692
9972
|
const { reader } = child;
|
|
9693
9973
|
if (reader && reader.size !== UNDEFINED_VALUE) {
|
|
@@ -10119,7 +10399,7 @@
|
|
|
10119
10399
|
*/
|
|
10120
10400
|
|
|
10121
10401
|
|
|
10122
|
-
|
|
10402
|
+
c(setDefaultConfiguration);
|
|
10123
10403
|
|
|
10124
10404
|
exports.BlobReader = BlobReader;
|
|
10125
10405
|
exports.BlobWriter = BlobWriter;
|
|
@@ -10198,6 +10478,7 @@
|
|
|
10198
10478
|
exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
|
|
10199
10479
|
exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
|
|
10200
10480
|
exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
|
|
10481
|
+
exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
|
|
10201
10482
|
exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
|
|
10202
10483
|
exports.HttpRangeReader = HttpRangeReader;
|
|
10203
10484
|
exports.HttpReader = HttpReader;
|
|
@@ -10208,6 +10489,20 @@
|
|
|
10208
10489
|
exports.TextWriter = TextWriter;
|
|
10209
10490
|
exports.Uint8ArrayReader = Uint8ArrayReader;
|
|
10210
10491
|
exports.Uint8ArrayWriter = Uint8ArrayWriter;
|
|
10492
|
+
exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
|
|
10493
|
+
exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
|
|
10494
|
+
exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
|
|
10495
|
+
exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
|
|
10496
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
|
|
10497
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
|
|
10498
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
|
|
10499
|
+
exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
|
|
10500
|
+
exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
|
|
10501
|
+
exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;
|
|
10502
|
+
exports.WARNING_UNKNOWN_VERSION = WARNING_UNKNOWN_VERSION;
|
|
10503
|
+
exports.WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA;
|
|
10504
|
+
exports.WARNING_UNSORTED_CENTRAL_DIRECTORY = WARNING_UNSORTED_CENTRAL_DIRECTORY;
|
|
10505
|
+
exports.WARNING_WRAPPED_ENTRIES_COUNT = WARNING_WRAPPED_ENTRIES_COUNT;
|
|
10211
10506
|
exports.Writer = Writer;
|
|
10212
10507
|
exports.ZipDirectoryEntry = ZipDirectoryEntry;
|
|
10213
10508
|
exports.ZipEntry = ZipEntry;
|
|
@@ -10223,6 +10518,7 @@
|
|
|
10223
10518
|
exports.createSyncAccessHandleTempStream = createSyncAccessHandleTempStream;
|
|
10224
10519
|
exports.fs = fs;
|
|
10225
10520
|
exports.getMimeType = getMimeType;
|
|
10521
|
+
exports.isZipFile = isZipFile;
|
|
10226
10522
|
exports.registerCodec = registerCodec;
|
|
10227
10523
|
exports.resetConfiguration = resetConfiguration;
|
|
10228
10524
|
exports.terminateWorkers = terminateWorkers;
|