@zip.js/zip.js 2.8.52 → 2.8.54
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/README.md +1 -1
- package/deno.json +2 -1
- package/dist/zip-core-external.js +839 -528
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +847 -527
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +880 -557
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +829 -538
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +880 -557
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +895 -558
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +894 -557
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +849 -529
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +849 -529
- 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 +848 -528
- package/dist/zip.min.js +1 -1
- package/eslint.config.mjs +2 -1
- package/index-native.cjs +895 -558
- package/index-native.min.js +1 -1
- package/index.cjs +894 -557
- package/index.d.cts +672 -78
- package/index.d.ts +672 -78
- package/index.min.js +1 -1
- package/lib/core/codec-worker-web.js +13 -4
- package/lib/core/configuration.js +62 -21
- package/lib/core/constants.js +16 -1
- package/lib/core/io.js +44 -29
- package/lib/core/options.js +46 -2
- package/lib/core/streams/aes-crypto-stream.js +12 -12
- package/lib/core/util/decode-text.js +11 -2
- package/lib/core/web-worker-base.js +3 -2
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-entry.js +8 -0
- package/lib/core/zip-fs.js +38 -27
- package/lib/core/zip-reader.js +149 -60
- package/lib/core/zip-writer.js +329 -189
- package/lib/zip-core-base.js +6 -1
- package/lib/zip-core-reader.js +1 -0
- package/lib/zip-core-writer.js +5 -0
- package/package.json +11 -3
package/index-native.cjs
CHANGED
|
@@ -39,6 +39,7 @@ const COMPRESSION_METHOD_AES = 0x63;
|
|
|
39
39
|
|
|
40
40
|
const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
|
|
41
41
|
const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
|
|
42
|
+
const TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE = 0x30304b50;
|
|
42
43
|
const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
|
|
43
44
|
const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
|
|
44
45
|
const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
|
|
@@ -55,6 +56,7 @@ const ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH = END_OF_CENTRAL_DIR_LENGTH + ZIP64_
|
|
|
55
56
|
const DATA_DESCRIPTOR_RECORD_LENGTH = 12;
|
|
56
57
|
const DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH = 20;
|
|
57
58
|
const DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH = 4;
|
|
59
|
+
const SPLIT_ZIP_FILE_SIGNATURE_LENGTH = 4;
|
|
58
60
|
|
|
59
61
|
const EXTRAFIELD_TYPE_ZIP64 = 0x0001;
|
|
60
62
|
const EXTRAFIELD_TYPE_AES = 0x9901;
|
|
@@ -96,6 +98,9 @@ const VERSION_DEFLATE = 0x14;
|
|
|
96
98
|
const VERSION_ZIP64 = 0x2D;
|
|
97
99
|
const VERSION_AES = 0x33;
|
|
98
100
|
|
|
101
|
+
const VERSION_MADE_BY_MSDOS = 0x0014;
|
|
102
|
+
const VERSION_MADE_BY_UNIX = 0x0300;
|
|
103
|
+
|
|
99
104
|
const DIRECTORY_SIGNATURE = "/";
|
|
100
105
|
|
|
101
106
|
const HEADER_SIZE = 30;
|
|
@@ -103,6 +108,8 @@ const HEADER_OFFSET_VERSION = 0;
|
|
|
103
108
|
const HEADER_OFFSET_SIGNATURE = 10;
|
|
104
109
|
const HEADER_OFFSET_COMPRESSED_SIZE = 14;
|
|
105
110
|
const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18;
|
|
111
|
+
const HEADER_OFFSET_FILENAME_LENGTH = 22;
|
|
112
|
+
const HEADER_OFFSET_EXTRAFIELD_LENGTH = 24;
|
|
106
113
|
const LOCAL_HEADER_COMMON_OFFSET = 4;
|
|
107
114
|
|
|
108
115
|
const MAX_DATE = new Date(2107, 11, 31, 23, 59, 58);
|
|
@@ -115,9 +122,116 @@ const FUNCTION_TYPE = "function";
|
|
|
115
122
|
const OBJECT_TYPE = "object";
|
|
116
123
|
const STRING_TYPE = "string";
|
|
117
124
|
const NUMBER_TYPE = "number";
|
|
125
|
+
const BOOLEAN_TYPE = "boolean";
|
|
118
126
|
|
|
119
127
|
const EMPTY_UINT8_ARRAY = new Uint8Array();
|
|
120
128
|
|
|
129
|
+
/*
|
|
130
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
131
|
+
|
|
132
|
+
Redistribution and use in source and binary forms, with or without
|
|
133
|
+
modification, are permitted provided that the following conditions are met:
|
|
134
|
+
|
|
135
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
136
|
+
this list of conditions and the following disclaimer.
|
|
137
|
+
|
|
138
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
139
|
+
notice, this list of conditions and the following disclaimer in
|
|
140
|
+
the documentation and/or other materials provided with the distribution.
|
|
141
|
+
|
|
142
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
143
|
+
derived from this software without specific prior written permission.
|
|
144
|
+
|
|
145
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
146
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
147
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
148
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
149
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
150
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
151
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
152
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
153
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
154
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
155
|
+
*/
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
const OPTION_FILENAME_ENCODING = "filenameEncoding";
|
|
159
|
+
const OPTION_COMMENT_ENCODING = "commentEncoding";
|
|
160
|
+
const OPTION_DECODE_TEXT = "decodeText";
|
|
161
|
+
const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
|
|
162
|
+
const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
|
|
163
|
+
const OPTION_PASSWORD = "password";
|
|
164
|
+
const OPTION_RAW_PASSWORD = "rawPassword";
|
|
165
|
+
const OPTION_PASS_THROUGH = "passThrough";
|
|
166
|
+
const OPTION_SIGNAL = "signal";
|
|
167
|
+
const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
|
|
168
|
+
const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
|
|
169
|
+
const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
|
|
170
|
+
const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
|
|
171
|
+
const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
|
|
172
|
+
const OPTION_CHECK_SIGNATURE = "checkSignature";
|
|
173
|
+
const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
174
|
+
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
175
|
+
const OPTION_USE_WEB_WORKERS = "useWebWorkers";
|
|
176
|
+
const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
|
|
177
|
+
const OPTION_TRANSFER_STREAMS = "transferStreams";
|
|
178
|
+
const OPTION_PREVENT_CLOSE = "preventClose";
|
|
179
|
+
const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
|
|
180
|
+
const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
|
|
181
|
+
const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
|
|
182
|
+
const OPTION_KEEP_ORDER = "keepOrder";
|
|
183
|
+
const OPTION_LEVEL = "level";
|
|
184
|
+
const OPTION_BUFFERED_WRITE = "bufferedWrite";
|
|
185
|
+
const OPTION_CREATE_TEMP_STREAM = "createTempStream";
|
|
186
|
+
const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
|
|
187
|
+
const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
|
|
188
|
+
const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
|
|
189
|
+
const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
|
|
190
|
+
const OPTION_ENCODE_TEXT = "encodeText";
|
|
191
|
+
const OPTION_OFFSET = "offset";
|
|
192
|
+
const OPTION_USDZ = "usdz";
|
|
193
|
+
const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
|
|
194
|
+
const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
|
|
195
|
+
const OPTION_STRICTNESS = "strictness";
|
|
196
|
+
const OPTION_FILENAME_VALIDATION = "filenameValidation";
|
|
197
|
+
const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
|
|
198
|
+
const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
|
|
199
|
+
const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
|
|
200
|
+
const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
|
|
201
|
+
const TEXT_TYPE_FILENAME = "filename";
|
|
202
|
+
const TEXT_TYPE_COMMENT = "comment";
|
|
203
|
+
const STRICTNESS_STRICT = "strict";
|
|
204
|
+
const STRICTNESS_BALANCED = "balanced";
|
|
205
|
+
const STRICTNESS_TOLERANT = "tolerant";
|
|
206
|
+
|
|
207
|
+
const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
|
|
208
|
+
const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
|
|
209
|
+
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
210
|
+
|
|
211
|
+
function checkFunctionOption(value) {
|
|
212
|
+
if (value && typeof value != FUNCTION_TYPE) {
|
|
213
|
+
throw new Error(ERR_INVALID_FUNCTION_OPTION);
|
|
214
|
+
}
|
|
215
|
+
return value;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function checkSignalOption(signal) {
|
|
219
|
+
if (signal && (typeof signal.addEventListener != FUNCTION_TYPE || typeof signal.aborted != BOOLEAN_TYPE)) {
|
|
220
|
+
throw new Error(ERR_INVALID_SIGNAL);
|
|
221
|
+
}
|
|
222
|
+
return signal || UNDEFINED_VALUE;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function checkPasswordOption(password, rawPassword) {
|
|
226
|
+
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
227
|
+
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function toNumber(value) {
|
|
232
|
+
return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
|
|
233
|
+
}
|
|
234
|
+
|
|
121
235
|
/*
|
|
122
236
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
123
237
|
|
|
@@ -147,7 +261,10 @@ const EMPTY_UINT8_ARRAY = new Uint8Array();
|
|
|
147
261
|
*/
|
|
148
262
|
|
|
149
263
|
|
|
264
|
+
const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
|
|
150
265
|
const MINIMUM_CHUNK_SIZE = 64;
|
|
266
|
+
const MINIMUM_PROPERTY_VALUE = 1;
|
|
267
|
+
const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
|
|
151
268
|
let maxWorkers = 2;
|
|
152
269
|
try {
|
|
153
270
|
if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
|
|
@@ -159,7 +276,7 @@ try {
|
|
|
159
276
|
const DEFAULT_CONFIGURATION = {
|
|
160
277
|
workerURI: "./core/web-worker-wasm.js",
|
|
161
278
|
wasmURI: "./core/streams/zlib-wasm/zlib-streams.wasm",
|
|
162
|
-
chunkSize:
|
|
279
|
+
chunkSize: DEFAULT_CHUNK_SIZE$1,
|
|
163
280
|
maxWorkers,
|
|
164
281
|
terminateWorkerTimeout: 5000,
|
|
165
282
|
workerStarvationTimeout: 5000,
|
|
@@ -171,24 +288,38 @@ const DEFAULT_CONFIGURATION = {
|
|
|
171
288
|
DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
172
289
|
};
|
|
173
290
|
|
|
174
|
-
const
|
|
291
|
+
const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
|
|
292
|
+
|
|
293
|
+
const STRING_PROPERTY_NAMES = [
|
|
175
294
|
"baseURI",
|
|
176
295
|
"wasmURI",
|
|
177
|
-
"workerURI"
|
|
178
|
-
|
|
296
|
+
"workerURI"
|
|
297
|
+
];
|
|
298
|
+
const BOOLEAN_PROPERTY_NAMES = [
|
|
299
|
+
"useCompressionStream",
|
|
300
|
+
"useWebWorkers",
|
|
301
|
+
"transferStreams"
|
|
302
|
+
];
|
|
303
|
+
const NUMBER_PROPERTY_NAMES = [
|
|
179
304
|
"chunkSize",
|
|
180
|
-
|
|
305
|
+
PROPERTY_NAME_MAX_WORKERS,
|
|
181
306
|
"terminateWorkerTimeout",
|
|
182
307
|
"workerStarvationTimeout",
|
|
183
|
-
"workerStartupTimeout"
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
"
|
|
308
|
+
"workerStartupTimeout"
|
|
309
|
+
];
|
|
310
|
+
const FUNCTION_PROPERTY_NAMES = [
|
|
311
|
+
"createWorker",
|
|
187
312
|
"CompressionStream",
|
|
188
313
|
"DecompressionStream",
|
|
189
314
|
"CompressionStreamFallback",
|
|
190
315
|
"DecompressionStreamFallback"
|
|
191
316
|
];
|
|
317
|
+
const CONFIGURABLE_PROPERTY_NAMES = [
|
|
318
|
+
...STRING_PROPERTY_NAMES,
|
|
319
|
+
...BOOLEAN_PROPERTY_NAMES,
|
|
320
|
+
...NUMBER_PROPERTY_NAMES,
|
|
321
|
+
...FUNCTION_PROPERTY_NAMES
|
|
322
|
+
];
|
|
192
323
|
|
|
193
324
|
const config = { ...DEFAULT_CONFIGURATION };
|
|
194
325
|
|
|
@@ -197,20 +328,43 @@ function getConfiguration() {
|
|
|
197
328
|
}
|
|
198
329
|
|
|
199
330
|
function getChunkSize(config) {
|
|
200
|
-
return
|
|
331
|
+
return normalizeChunkSize(config.chunkSize);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function normalizeChunkSize(chunkSize) {
|
|
335
|
+
chunkSize = toNumber(chunkSize);
|
|
336
|
+
return Number.isInteger(chunkSize) && chunkSize >= MINIMUM_PROPERTY_VALUE ? Math.max(chunkSize, MINIMUM_CHUNK_SIZE) : DEFAULT_CHUNK_SIZE$1;
|
|
201
337
|
}
|
|
202
338
|
|
|
203
339
|
function configure(configuration) {
|
|
204
|
-
|
|
340
|
+
Object.assign(config, checkConfiguration(normalizeConfiguration(configuration)));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function checkConfiguration(configuration) {
|
|
344
|
+
const checkedConfiguration = {};
|
|
205
345
|
for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
|
|
206
346
|
const propertyValue = configuration[propertyName];
|
|
207
347
|
if (propertyValue !== UNDEFINED_VALUE) {
|
|
208
|
-
|
|
348
|
+
checkedConfiguration[propertyName] = checkPropertyValue(propertyName, propertyValue);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return checkedConfiguration;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function checkPropertyValue(propertyName, propertyValue) {
|
|
355
|
+
if (NUMBER_PROPERTY_NAMES.includes(propertyName)) {
|
|
356
|
+
propertyValue = toNumber(propertyValue);
|
|
357
|
+
if (propertyName == PROPERTY_NAME_MAX_WORKERS && (!Number.isInteger(propertyValue) || propertyValue < MINIMUM_PROPERTY_VALUE)) {
|
|
358
|
+
throw new Error(ERR_INVALID_MAX_WORKERS);
|
|
209
359
|
}
|
|
360
|
+
} else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
|
|
361
|
+
checkFunctionOption(propertyValue);
|
|
210
362
|
}
|
|
363
|
+
return propertyValue;
|
|
211
364
|
}
|
|
212
365
|
|
|
213
366
|
function normalizeConfiguration(configuration) {
|
|
367
|
+
configuration = configuration || {};
|
|
214
368
|
const { CompressionStreamZlib, DecompressionStreamZlib } = configuration;
|
|
215
369
|
if (CompressionStreamZlib === UNDEFINED_VALUE && DecompressionStreamZlib === UNDEFINED_VALUE) {
|
|
216
370
|
return configuration;
|
|
@@ -226,14 +380,9 @@ function normalizeConfiguration(configuration) {
|
|
|
226
380
|
}
|
|
227
381
|
|
|
228
382
|
function setDefaultConfiguration(configuration) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (propertyValue !== UNDEFINED_VALUE) {
|
|
233
|
-
DEFAULT_CONFIGURATION[propertyName] = propertyValue;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
configure(configuration);
|
|
383
|
+
const checkedConfiguration = checkConfiguration(normalizeConfiguration(configuration));
|
|
384
|
+
Object.assign(DEFAULT_CONFIGURATION, checkedConfiguration);
|
|
385
|
+
Object.assign(config, checkedConfiguration);
|
|
237
386
|
}
|
|
238
387
|
|
|
239
388
|
function resetConfiguration() {
|
|
@@ -243,7 +392,7 @@ function resetConfiguration() {
|
|
|
243
392
|
Object.assign(config, DEFAULT_CONFIGURATION);
|
|
244
393
|
}
|
|
245
394
|
|
|
246
|
-
const r=[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],t=[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],f=[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],n=[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],c=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],e=new Uint8Array(288);e.fill(8,0,144),e.fill(9,144,256),e.fill(7,256,280),e.fill(8,280,288);const j$1=new Uint8Array(30).fill(5);function z$1(r){const t=new Uint16Array(16);for(const f of r)t[f]++;t[0]=0;const f=new Uint16Array(17);for(let r=1;15>=r;r++)f[r+1]=f[r]+t[r];const n=new Uint16Array(r.length);for(let t=0;t<r.length;t++)r[t]&&(n[f[r[t]]++]=t);return {j:t,symbols:n}}const W$1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",p$1=(s=()=>(W=>{let p=0,s=0,o=0,Y=new Uint8Array(1024),l=0,B=0;for(;!B;){B=u(1);const r=u(2);if(0==r)T();else if(1==r)w(z$1(e),z$1(j$1));else {if(2!=r)throw Error("invalid deflate block type");w(...K());}}return Y.subarray(0,l);function S(){if(p>=W.length)throw Error("unexpected end of deflate data");return W[p++]}function u(r){for(;r>o;)s|=S()<<o,o+=8;const t=s&(1<<r)-1;return s>>>=r,o-=r,t}function T(){s=0,o=0;const r=S()|S()<<8;p+=2,D(l+r);for(let t=0;r>t;t++)Y[l++]=S();}function w(c,e){let j=q(c);for(;256!=j;){if(256>j)D(l+1),Y[l++]=j;else {const c=j-257,z=r[c]+u(t[c]),W=q(e),p=f[W]+u(n[W]);D(l+z);const s=l-p;for(let r=0;z>r;r++)Y[l++]=Y[s+r];}j=q(c);}}function K(){const r=u(5)+257,t=u(5)+1,f=u(4)+4,n=new Uint8Array(19);for(let r=0;f>r;r++)n[c[r]]=u(3);const e=z$1(n),j=new Uint8Array(r+t);let W=0;for(;W<j.length;){const r=q(e);if(16>r)j[W++]=r;else if(16==r){const r=j[W-1];let t=u(2)+3;for(;t--;)j[W++]=r;}else W+=17==r?u(3)+3:u(7)+11;}return [z$1(j.subarray(0,r)),z$1(j.subarray(r))]}function q(r){const{j:t,symbols:f}=r;let n=0,c=0,e=0;for(let r=1;15>=r;r++){n|=u(1);const j=t[r];if(j>n-c)return f[e+(n-c)];e+=j,c=c+j<<1,n<<=1;}throw Error("invalid huffman code")}function D(r){if(Y.length<r){let t=2*Y.length;for(;r>t;)t*=2;const f=new Uint8Array(t);f.set(Y.subarray(0,l)),Y=f;}}})((r=>{const t=(r=(r+"").replace(/[^A-Za-z0-9+/=]/g,"")).length,f=[];for(let n=0;t>n;n+=4){const t=W$1.indexOf(r[n])<<18|W$1.indexOf(r[n+1])<<12|(63&W$1.indexOf(r[n+2]))<<6|63&W$1.indexOf(r[n+3]);f.push(t>>16&255),"="!==r[n+2]&&f.push(t>>8&255),"="!==r[n+3]&&f.push(255&t);}return new Uint8Array(f)})("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")),r=>r({workerURI:r=>{const t="text/javascript";let f=s();if("string"==typeof f&&(f=(new TextEncoder).encode(f)),r){const r=new Blob([f],{type:t});return URL.createObjectURL(r)}return "data:"+t+";base64,"+(r=>{let t="";const f=r.length;let n=0;for(;f>n+2;n+=3){const f=r[n]<<16|r[n+1]<<8|r[n+2];t+=W$1[f>>18&63]+W$1[f>>12&63]+W$1[f>>6&63]+W$1[63&f];}const c=f-n;if(1===c){const f=r[n]<<16;t+=W$1[f>>18&63]+W$1[f>>12&63]+"==";}else if(2===c){const f=r[n]<<16|r[n+1]<<8;t+=W$1[f>>18&63]+W$1[f>>12&63]+W$1[f>>6&63]+"=";}return t})(f)}}));var s;
|
|
395
|
+
const t=[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],n=[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],r=[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],e=[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],o=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],s=new Uint8Array(288);s.fill(8,0,144),s.fill(9,144,256),s.fill(7,256,280),s.fill(8,280,288);const Z$1=new Uint8Array(30).fill(5);function f(t){const n=new Uint16Array(16);for(const r of t)n[r]++;n[0]=0;const r=new Uint16Array(17);for(let t=1;15>=t;t++)r[t+1]=r[t]+n[t];const e=new Uint16Array(t.length);for(let n=0;n<t.length;n++)t[n]&&(e[r[t[n]]++]=n);return {o:n,symbols:e}}const P="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=(w=()=>(P=>{let a=0,w=0,b=0,l=new Uint8Array(1024),z=0,i=0;for(;!i;){i=c(1);const t=c(2);if(0==t)x();else if(1==t)h(f(s),f(Z$1));else {if(2!=t)throw Error("invalid deflate block type");h(...K());}}return l.subarray(0,z);function U(){if(a>=P.length)throw Error("unexpected end of deflate data");return P[a++]}function c(t){for(;t>b;)w|=U()<<b,b+=8;const n=w&(1<<t)-1;return w>>>=t,b-=t,n}function x(){w=0,b=0;const t=U()|U()<<8;a+=2,u(z+t);for(let n=0;t>n;n++)l[z++]=U();}function h(o,s){let Z=j(o);for(;256!=Z;){if(256>Z)u(z+1),l[z++]=Z;else {const o=Z-257,f=t[o]+c(n[o]),P=j(s),a=r[P]+c(e[P]);u(z+f);const w=z-a;for(let t=0;f>t;t++)l[z++]=l[w+t];}Z=j(o);}}function K(){const t=c(5)+257,n=c(5)+1,r=c(4)+4,e=new Uint8Array(19);for(let t=0;r>t;t++)e[o[t]]=c(3);const s=f(e),Z=new Uint8Array(t+n);let P=0;for(;P<Z.length;){const t=j(s);if(16>t)Z[P++]=t;else if(16==t){const t=Z[P-1];let n=c(2)+3;for(;n--;)Z[P++]=t;}else P+=17==t?c(3)+3:c(7)+11;}return [f(Z.subarray(0,t)),f(Z.subarray(t))]}function j(t){const{o:n,symbols:r}=t;let e=0,o=0,s=0;for(let t=1;15>=t;t++){e|=c(1);const Z=n[t];if(Z>e-o)return r[s+(e-o)];s+=Z,o=o+Z<<1,e<<=1;}throw Error("invalid huffman code")}function u(t){if(l.length<t){let n=2*l.length;for(;t>n;)n*=2;const r=new Uint8Array(n);r.set(l.subarray(0,z)),l=r;}}})((t=>{const n=(t=(t+"").replace(/[^A-Za-z0-9+/=]/g,"")).length,r=[];for(let e=0;n>e;e+=4){const n=P.indexOf(t[e])<<18|P.indexOf(t[e+1])<<12|(63&P.indexOf(t[e+2]))<<6|63&P.indexOf(t[e+3]);r.push(n>>16&255),"="!==t[e+2]&&r.push(n>>8&255),"="!==t[e+3]&&r.push(255&n);}return new Uint8Array(r)})("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")),t=>t({workerURI:t=>{const n="text/javascript";let r=w();if("string"==typeof r&&(r=(new TextEncoder).encode(r)),t){const t=new Blob([r],{type:n});return URL.createObjectURL(t)}return "data:"+n+";base64,"+(t=>{let n="";const r=t.length;let e=0;for(;r>e+2;e+=3){const r=t[e]<<16|t[e+1]<<8|t[e+2];n+=P[r>>18&63]+P[r>>12&63]+P[r>>6&63]+P[63&r];}const o=r-e;if(1===o){const r=t[e]<<16;n+=P[r>>18&63]+P[r>>12&63]+"==";}else if(2===o){const r=t[e]<<16|t[e+1]<<8;n+=P[r>>18&63]+P[r>>12&63]+P[r>>6&63]+"=";}return n})(r)}}));var w;
|
|
247
396
|
|
|
248
397
|
/*
|
|
249
398
|
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
@@ -1391,13 +1540,13 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1391
1540
|
const {
|
|
1392
1541
|
ctr,
|
|
1393
1542
|
hmac,
|
|
1394
|
-
|
|
1543
|
+
pendingInput,
|
|
1395
1544
|
ready
|
|
1396
1545
|
} = this;
|
|
1397
1546
|
if (hmac && ctr) {
|
|
1398
1547
|
await ready;
|
|
1399
|
-
const chunkToDecrypt = subarray(
|
|
1400
|
-
const originalAuthenticationCode = subarray(
|
|
1548
|
+
const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1549
|
+
const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1401
1550
|
let decryptedChunkArray = EMPTY_UINT8_ARRAY;
|
|
1402
1551
|
if (chunkToDecrypt.length) {
|
|
1403
1552
|
const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
|
|
@@ -1406,7 +1555,7 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1406
1555
|
decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
|
|
1407
1556
|
}
|
|
1408
1557
|
const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1409
|
-
let invalidAuthenticationCode =
|
|
1558
|
+
let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
|
|
1410
1559
|
for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
|
|
1411
1560
|
invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
|
|
1412
1561
|
}
|
|
@@ -1450,14 +1599,14 @@ class AESEncryptionStream extends TransformStream {
|
|
|
1450
1599
|
const {
|
|
1451
1600
|
ctr,
|
|
1452
1601
|
hmac,
|
|
1453
|
-
|
|
1602
|
+
pendingInput,
|
|
1454
1603
|
ready
|
|
1455
1604
|
} = this;
|
|
1456
1605
|
if (hmac && ctr) {
|
|
1457
1606
|
await ready;
|
|
1458
1607
|
let encryptedChunkArray = EMPTY_UINT8_ARRAY;
|
|
1459
|
-
if (
|
|
1460
|
-
const encryptedChunk = ctr.update(toBits(codecBytes,
|
|
1608
|
+
if (pendingInput.length) {
|
|
1609
|
+
const encryptedChunk = ctr.update(toBits(codecBytes, pendingInput));
|
|
1461
1610
|
hmac.update(encryptedChunk);
|
|
1462
1611
|
encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
|
|
1463
1612
|
}
|
|
@@ -1474,7 +1623,7 @@ function initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength) {
|
|
|
1474
1623
|
ready: new Promise(resolve => aesCrypto.resolveReady = resolve),
|
|
1475
1624
|
password: encodePassword(password, rawPassword),
|
|
1476
1625
|
strength: encryptionStrength - 1,
|
|
1477
|
-
|
|
1626
|
+
pendingInput: EMPTY_UINT8_ARRAY
|
|
1478
1627
|
});
|
|
1479
1628
|
}
|
|
1480
1629
|
|
|
@@ -1482,10 +1631,10 @@ function append(aesCrypto, input, output, paddingStart, paddingEnd, verifyAuthen
|
|
|
1482
1631
|
const {
|
|
1483
1632
|
ctr,
|
|
1484
1633
|
hmac,
|
|
1485
|
-
|
|
1634
|
+
pendingInput
|
|
1486
1635
|
} = aesCrypto;
|
|
1487
|
-
if (
|
|
1488
|
-
input = concat(
|
|
1636
|
+
if (pendingInput.length) {
|
|
1637
|
+
input = concat(pendingInput, input);
|
|
1489
1638
|
}
|
|
1490
1639
|
const inputLength = input.length - paddingEnd;
|
|
1491
1640
|
output = expand(output, paddingStart + (inputLength - (inputLength % BLOCK_LENGTH)));
|
|
@@ -1501,7 +1650,7 @@ function append(aesCrypto, input, output, paddingStart, paddingEnd, verifyAuthen
|
|
|
1501
1650
|
}
|
|
1502
1651
|
output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
|
|
1503
1652
|
}
|
|
1504
|
-
aesCrypto.
|
|
1653
|
+
aesCrypto.pendingInput = subarray(input, offset);
|
|
1505
1654
|
return output;
|
|
1506
1655
|
}
|
|
1507
1656
|
|
|
@@ -2752,6 +2901,7 @@ function createWebWorkerInterface(workerData, config) {
|
|
|
2752
2901
|
worker,
|
|
2753
2902
|
workerAlive: false,
|
|
2754
2903
|
terminated: false,
|
|
2904
|
+
startupError: null,
|
|
2755
2905
|
interface: {
|
|
2756
2906
|
run: async () => {
|
|
2757
2907
|
try {
|
|
@@ -2779,6 +2929,13 @@ function createWebWorkerInterface(workerData, config) {
|
|
|
2779
2929
|
}
|
|
2780
2930
|
|
|
2781
2931
|
async function runWebWorker(workerData, config) {
|
|
2932
|
+
if (!workerData.worker) {
|
|
2933
|
+
const { startupError } = workerData;
|
|
2934
|
+
workerData.startupError = null;
|
|
2935
|
+
const error = startupError || new Error(ERR_WORKER_STARTUP_TIMEOUT);
|
|
2936
|
+
error.workerStartupFailed = true;
|
|
2937
|
+
throw error;
|
|
2938
|
+
}
|
|
2782
2939
|
let resolveResult, rejectResult;
|
|
2783
2940
|
const result = new Promise((resolve, reject) => {
|
|
2784
2941
|
resolveResult = resolve;
|
|
@@ -2992,11 +3149,12 @@ function onWorkerError(event, workerData) {
|
|
|
2992
3149
|
if (!workerAlive) {
|
|
2993
3150
|
workerData.worker = null;
|
|
2994
3151
|
}
|
|
3152
|
+
let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
|
|
3153
|
+
if (!workerAlive) {
|
|
3154
|
+
error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
|
|
3155
|
+
workerData.startupError = error;
|
|
3156
|
+
}
|
|
2995
3157
|
if (rejectResult) {
|
|
2996
|
-
let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
|
|
2997
|
-
if (!workerAlive) {
|
|
2998
|
-
error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
|
|
2999
|
-
}
|
|
3000
3158
|
rejectResult(error);
|
|
3001
3159
|
if (writer) {
|
|
3002
3160
|
writer.releaseLock();
|
|
@@ -3265,6 +3423,96 @@ async function terminateWorkers() {
|
|
|
3265
3423
|
resetWebWorkerSupport();
|
|
3266
3424
|
}
|
|
3267
3425
|
|
|
3426
|
+
/*
|
|
3427
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3428
|
+
|
|
3429
|
+
Redistribution and use in source and binary forms, with or without
|
|
3430
|
+
modification, are permitted provided that the following conditions are met:
|
|
3431
|
+
|
|
3432
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
3433
|
+
this list of conditions and the following disclaimer.
|
|
3434
|
+
|
|
3435
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
3436
|
+
notice, this list of conditions and the following disclaimer in
|
|
3437
|
+
the documentation and/or other materials provided with the distribution.
|
|
3438
|
+
|
|
3439
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
3440
|
+
derived from this software without specific prior written permission.
|
|
3441
|
+
|
|
3442
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
3443
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
3444
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
3445
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
3446
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
3447
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
3448
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
3449
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
3450
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
3451
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3452
|
+
*/
|
|
3453
|
+
|
|
3454
|
+
/* global TextDecoder */
|
|
3455
|
+
|
|
3456
|
+
const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
|
|
3457
|
+
const VALID_CP437 = CP437.length == 256;
|
|
3458
|
+
|
|
3459
|
+
function decodeCP437(stringValue) {
|
|
3460
|
+
if (VALID_CP437) {
|
|
3461
|
+
let result = "";
|
|
3462
|
+
for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
|
|
3463
|
+
result += CP437[stringValue[indexCharacter]];
|
|
3464
|
+
}
|
|
3465
|
+
return result;
|
|
3466
|
+
} else {
|
|
3467
|
+
return new TextDecoder().decode(stringValue);
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3470
|
+
|
|
3471
|
+
/*
|
|
3472
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3473
|
+
|
|
3474
|
+
Redistribution and use in source and binary forms, with or without
|
|
3475
|
+
modification, are permitted provided that the following conditions are met:
|
|
3476
|
+
|
|
3477
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
3478
|
+
this list of conditions and the following disclaimer.
|
|
3479
|
+
|
|
3480
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
3481
|
+
notice, this list of conditions and the following disclaimer in
|
|
3482
|
+
the documentation and/or other materials provided with the distribution.
|
|
3483
|
+
|
|
3484
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
3485
|
+
derived from this software without specific prior written permission.
|
|
3486
|
+
|
|
3487
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
3488
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
3489
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
3490
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
3491
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
3492
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
3493
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
3494
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
3495
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
3496
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3497
|
+
*/
|
|
3498
|
+
|
|
3499
|
+
|
|
3500
|
+
function decodeText(value, encoding) {
|
|
3501
|
+
return decode(value, encoding, true);
|
|
3502
|
+
}
|
|
3503
|
+
|
|
3504
|
+
function decodeTextRemovingBOM(value, encoding) {
|
|
3505
|
+
return decode(value, encoding, false);
|
|
3506
|
+
}
|
|
3507
|
+
|
|
3508
|
+
function decode(value, encoding, ignoreBOM) {
|
|
3509
|
+
if (encoding && encoding.trim().toLowerCase() == "cp437") {
|
|
3510
|
+
return decodeCP437(value);
|
|
3511
|
+
} else {
|
|
3512
|
+
return new TextDecoder(encoding, { ignoreBOM }).decode(value);
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
|
|
3268
3516
|
/*
|
|
3269
3517
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
3270
3518
|
|
|
@@ -3337,6 +3585,7 @@ class Reader extends Stream {
|
|
|
3337
3585
|
createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
|
|
3338
3586
|
const reader = this;
|
|
3339
3587
|
let chunkOffset = 0;
|
|
3588
|
+
chunkSize = normalizeChunkSize(chunkSize);
|
|
3340
3589
|
return new ReadableStream({
|
|
3341
3590
|
async pull(controller) {
|
|
3342
3591
|
const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
|
|
@@ -3344,7 +3593,7 @@ class Reader extends Stream {
|
|
|
3344
3593
|
if (data.length) {
|
|
3345
3594
|
controller.enqueue(data);
|
|
3346
3595
|
}
|
|
3347
|
-
if ((chunkOffset + chunkSize >= size) || (
|
|
3596
|
+
if ((chunkOffset + chunkSize >= size) || (!data.length && dataSize)) {
|
|
3348
3597
|
controller.close();
|
|
3349
3598
|
} else {
|
|
3350
3599
|
chunkOffset += chunkSize;
|
|
@@ -3424,31 +3673,31 @@ class Data64URIWriter extends Writer {
|
|
|
3424
3673
|
Object.assign(this, {
|
|
3425
3674
|
contentType,
|
|
3426
3675
|
data: "data:" + (contentType || "") + ";base64,",
|
|
3427
|
-
|
|
3676
|
+
pendingCharacters: ""
|
|
3428
3677
|
});
|
|
3429
3678
|
}
|
|
3430
3679
|
|
|
3431
3680
|
writeUint8Array(array) {
|
|
3432
3681
|
const writer = this;
|
|
3433
3682
|
let indexArray;
|
|
3434
|
-
let dataString = writer.
|
|
3435
|
-
const delta = writer.
|
|
3436
|
-
writer.
|
|
3683
|
+
let dataString = writer.pendingCharacters;
|
|
3684
|
+
const delta = writer.pendingCharacters.length;
|
|
3685
|
+
writer.pendingCharacters = "";
|
|
3437
3686
|
for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
|
|
3438
3687
|
dataString += String.fromCharCode(array[indexArray]);
|
|
3439
3688
|
}
|
|
3440
3689
|
for (; indexArray < array.length; indexArray++) {
|
|
3441
|
-
writer.
|
|
3690
|
+
writer.pendingCharacters += String.fromCharCode(array[indexArray]);
|
|
3442
3691
|
}
|
|
3443
3692
|
if (dataString.length > 2) {
|
|
3444
3693
|
writer.data += btoa(dataString);
|
|
3445
3694
|
} else {
|
|
3446
|
-
writer.
|
|
3695
|
+
writer.pendingCharacters = dataString + writer.pendingCharacters;
|
|
3447
3696
|
}
|
|
3448
3697
|
}
|
|
3449
3698
|
|
|
3450
3699
|
getData() {
|
|
3451
|
-
return this.data + btoa(this.
|
|
3700
|
+
return this.data + btoa(this.pendingCharacters);
|
|
3452
3701
|
}
|
|
3453
3702
|
}
|
|
3454
3703
|
|
|
@@ -3478,7 +3727,7 @@ class BlobReader extends Reader {
|
|
|
3478
3727
|
constructor(blob) {
|
|
3479
3728
|
super();
|
|
3480
3729
|
Object.assign(this, {
|
|
3481
|
-
blob,
|
|
3730
|
+
sourceBlob: blob,
|
|
3482
3731
|
size: blob.size
|
|
3483
3732
|
});
|
|
3484
3733
|
if (!blobSliceProbe) {
|
|
@@ -3488,13 +3737,13 @@ class BlobReader extends Reader {
|
|
|
3488
3737
|
|
|
3489
3738
|
createReadable(options) {
|
|
3490
3739
|
const reader = this;
|
|
3491
|
-
const {
|
|
3740
|
+
const { sourceBlob, size } = reader;
|
|
3492
3741
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
3493
3742
|
if (!offset && readSize >= size) {
|
|
3494
|
-
return toCompatibleReadable(
|
|
3743
|
+
return toCompatibleReadable(sourceBlob.stream());
|
|
3495
3744
|
}
|
|
3496
3745
|
if (blobSliceReliable) {
|
|
3497
|
-
return toCompatibleReadable(
|
|
3746
|
+
return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
|
|
3498
3747
|
}
|
|
3499
3748
|
return super.createReadable(options);
|
|
3500
3749
|
}
|
|
@@ -3503,7 +3752,7 @@ class BlobReader extends Reader {
|
|
|
3503
3752
|
const reader = this;
|
|
3504
3753
|
const offsetEnd = offset + length;
|
|
3505
3754
|
const readsWholeBlob = !offset && offsetEnd >= reader.size;
|
|
3506
|
-
const blob = readsWholeBlob ? reader.
|
|
3755
|
+
const blob = readsWholeBlob ? reader.sourceBlob : reader.sourceBlob.slice(offset, offsetEnd);
|
|
3507
3756
|
let arrayBuffer = await blob.arrayBuffer();
|
|
3508
3757
|
const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
|
|
3509
3758
|
if (sliceIgnoredByBuggyImplementation) {
|
|
@@ -3525,12 +3774,12 @@ class BlobWriter extends Stream {
|
|
|
3525
3774
|
}
|
|
3526
3775
|
});
|
|
3527
3776
|
writer.contentType = contentType;
|
|
3528
|
-
writer.
|
|
3529
|
-
writer.
|
|
3777
|
+
writer.blobPromise = streamToBlob(transformStream.readable, contentType);
|
|
3778
|
+
writer.blobPromise.catch(() => { });
|
|
3530
3779
|
}
|
|
3531
3780
|
|
|
3532
3781
|
getData() {
|
|
3533
|
-
return this.
|
|
3782
|
+
return this.blobPromise;
|
|
3534
3783
|
}
|
|
3535
3784
|
}
|
|
3536
3785
|
|
|
@@ -3564,7 +3813,7 @@ function getTextSize(text) {
|
|
|
3564
3813
|
class TextWriter extends BlobWriter {
|
|
3565
3814
|
|
|
3566
3815
|
constructor(encoding) {
|
|
3567
|
-
super(
|
|
3816
|
+
super();
|
|
3568
3817
|
Object.assign(this, {
|
|
3569
3818
|
encoding,
|
|
3570
3819
|
utf8: !encoding || encoding.toLowerCase() == "utf-8"
|
|
@@ -3580,14 +3829,7 @@ class TextWriter extends BlobWriter {
|
|
|
3580
3829
|
if (blob.text && utf8) {
|
|
3581
3830
|
return blob.text();
|
|
3582
3831
|
} else {
|
|
3583
|
-
|
|
3584
|
-
return new Promise((resolve, reject) => {
|
|
3585
|
-
Object.assign(reader, {
|
|
3586
|
-
onload: ({ target }) => resolve(target.result),
|
|
3587
|
-
onerror: () => reject(reader.error)
|
|
3588
|
-
});
|
|
3589
|
-
reader.readAsText(blob, encoding);
|
|
3590
|
-
});
|
|
3832
|
+
return decodeTextRemovingBOM(new Uint8Array(await blob.arrayBuffer()), encoding);
|
|
3591
3833
|
}
|
|
3592
3834
|
}
|
|
3593
3835
|
}
|
|
@@ -4045,9 +4287,8 @@ class SplitDataReader extends Reader {
|
|
|
4045
4287
|
|
|
4046
4288
|
async init() {
|
|
4047
4289
|
const reader = this;
|
|
4048
|
-
const { readers } = reader;
|
|
4049
4290
|
reader.lastDiskNumber = 0;
|
|
4050
|
-
await Promise.all(readers.map(
|
|
4291
|
+
const readers = reader.readers = await Promise.all(reader.readers.map(initDiskReader));
|
|
4051
4292
|
reader.diskOffsets = readers.map(diskReader => {
|
|
4052
4293
|
const diskOffset = reader.size;
|
|
4053
4294
|
reader.size += diskReader.size;
|
|
@@ -4242,89 +4483,27 @@ async function initStream(stream, initSize) {
|
|
|
4242
4483
|
}
|
|
4243
4484
|
}
|
|
4244
4485
|
|
|
4245
|
-
function
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
Redistribution and use in source and binary forms, with or without
|
|
4253
|
-
modification, are permitted provided that the following conditions are met:
|
|
4254
|
-
|
|
4255
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
4256
|
-
this list of conditions and the following disclaimer.
|
|
4257
|
-
|
|
4258
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
4259
|
-
notice, this list of conditions and the following disclaimer in
|
|
4260
|
-
the documentation and/or other materials provided with the distribution.
|
|
4261
|
-
|
|
4262
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
4263
|
-
derived from this software without specific prior written permission.
|
|
4264
|
-
|
|
4265
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4266
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4267
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4268
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4269
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4270
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4271
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4272
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4273
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4274
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4275
|
-
*/
|
|
4276
|
-
|
|
4277
|
-
/* global TextDecoder */
|
|
4278
|
-
|
|
4279
|
-
const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
|
|
4280
|
-
const VALID_CP437 = CP437.length == 256;
|
|
4281
|
-
|
|
4282
|
-
function decodeCP437(stringValue) {
|
|
4283
|
-
if (VALID_CP437) {
|
|
4284
|
-
let result = "";
|
|
4285
|
-
for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
|
|
4286
|
-
result += CP437[stringValue[indexCharacter]];
|
|
4287
|
-
}
|
|
4288
|
-
return result;
|
|
4289
|
-
} else {
|
|
4290
|
-
return new TextDecoder().decode(stringValue);
|
|
4486
|
+
async function initDiskReader(diskReader) {
|
|
4487
|
+
diskReader = new GenericReader(diskReader);
|
|
4488
|
+
await initStream(diskReader);
|
|
4489
|
+
if (diskReader.size === UNDEFINED_VALUE || !diskReader.readUint8Array) {
|
|
4490
|
+
diskReader = new BlobReader(await streamToBlob(diskReader.readable));
|
|
4491
|
+
await initStream(diskReader);
|
|
4291
4492
|
}
|
|
4493
|
+
return diskReader;
|
|
4292
4494
|
}
|
|
4293
4495
|
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
Redistribution and use in source and binary forms, with or without
|
|
4298
|
-
modification, are permitted provided that the following conditions are met:
|
|
4299
|
-
|
|
4300
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
4301
|
-
this list of conditions and the following disclaimer.
|
|
4302
|
-
|
|
4303
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
4304
|
-
notice, this list of conditions and the following disclaimer in
|
|
4305
|
-
the documentation and/or other materials provided with the distribution.
|
|
4306
|
-
|
|
4307
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
4308
|
-
derived from this software without specific prior written permission.
|
|
4309
|
-
|
|
4310
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4311
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4312
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4313
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4314
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4315
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4316
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4317
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4318
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4319
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4320
|
-
*/
|
|
4321
|
-
|
|
4496
|
+
function readUint8Array(reader, offset, size) {
|
|
4497
|
+
return reader.readUint8Array(offset, size);
|
|
4498
|
+
}
|
|
4322
4499
|
|
|
4323
|
-
function
|
|
4324
|
-
if (
|
|
4325
|
-
return
|
|
4500
|
+
function createReadable(reader, options) {
|
|
4501
|
+
if (reader.createReadable) {
|
|
4502
|
+
return reader.createReadable(options);
|
|
4503
|
+
} else if (reader.readUint8Array) {
|
|
4504
|
+
return Reader.prototype.createReadable.call(reader, options);
|
|
4326
4505
|
} else {
|
|
4327
|
-
return
|
|
4506
|
+
return reader.readable;
|
|
4328
4507
|
}
|
|
4329
4508
|
}
|
|
4330
4509
|
|
|
@@ -4400,6 +4579,10 @@ const PROPERTY_NAME_SETUID = "setuid";
|
|
|
4400
4579
|
const PROPERTY_NAME_SETGID = "setgid";
|
|
4401
4580
|
const PROPERTY_NAME_STICKY = "sticky";
|
|
4402
4581
|
const PROPERTY_NAME_BITFLAG = "bitFlag";
|
|
4582
|
+
const PROPERTY_NAME_RAW_BITFLAG = "rawBitFlag";
|
|
4583
|
+
const PROPERTY_NAME_FILENAME_LENGTH = "filenameLength";
|
|
4584
|
+
const PROPERTY_NAME_EXTRA_FIELD_LENGTH = "extraFieldLength";
|
|
4585
|
+
const PROPERTY_NAME_UNIX_EXTERNAL_UPPER = "unixExternalUpper";
|
|
4403
4586
|
const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
|
|
4404
4587
|
const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
|
|
4405
4588
|
const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
|
|
@@ -4452,10 +4635,14 @@ const PROPERTY_NAMES = [
|
|
|
4452
4635
|
PROPERTY_NAME_UID,
|
|
4453
4636
|
PROPERTY_NAME_GID,
|
|
4454
4637
|
PROPERTY_NAME_UNIX_MODE,
|
|
4638
|
+
PROPERTY_NAME_UNIX_EXTERNAL_UPPER,
|
|
4455
4639
|
PROPERTY_NAME_SETUID,
|
|
4456
4640
|
PROPERTY_NAME_SETGID,
|
|
4457
4641
|
PROPERTY_NAME_STICKY,
|
|
4458
4642
|
PROPERTY_NAME_BITFLAG,
|
|
4643
|
+
PROPERTY_NAME_RAW_BITFLAG,
|
|
4644
|
+
PROPERTY_NAME_FILENAME_LENGTH,
|
|
4645
|
+
PROPERTY_NAME_EXTRA_FIELD_LENGTH,
|
|
4459
4646
|
PROPERTY_NAME_FILENAME_UTF8,
|
|
4460
4647
|
PROPERTY_NAME_COMMENT_UTF8,
|
|
4461
4648
|
PROPERTY_NAME_RAW_EXTRA_FIELD,
|
|
@@ -4476,82 +4663,6 @@ class Entry {
|
|
|
4476
4663
|
|
|
4477
4664
|
}
|
|
4478
4665
|
|
|
4479
|
-
/*
|
|
4480
|
-
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
4481
|
-
|
|
4482
|
-
Redistribution and use in source and binary forms, with or without
|
|
4483
|
-
modification, are permitted provided that the following conditions are met:
|
|
4484
|
-
|
|
4485
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
4486
|
-
this list of conditions and the following disclaimer.
|
|
4487
|
-
|
|
4488
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
4489
|
-
notice, this list of conditions and the following disclaimer in
|
|
4490
|
-
the documentation and/or other materials provided with the distribution.
|
|
4491
|
-
|
|
4492
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
4493
|
-
derived from this software without specific prior written permission.
|
|
4494
|
-
|
|
4495
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4496
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4497
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4498
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4499
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4500
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4501
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4502
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4503
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4504
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4505
|
-
*/
|
|
4506
|
-
|
|
4507
|
-
const OPTION_FILENAME_ENCODING = "filenameEncoding";
|
|
4508
|
-
const OPTION_COMMENT_ENCODING = "commentEncoding";
|
|
4509
|
-
const OPTION_DECODE_TEXT = "decodeText";
|
|
4510
|
-
const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
|
|
4511
|
-
const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
|
|
4512
|
-
const OPTION_PASSWORD = "password";
|
|
4513
|
-
const OPTION_RAW_PASSWORD = "rawPassword";
|
|
4514
|
-
const OPTION_PASS_THROUGH = "passThrough";
|
|
4515
|
-
const OPTION_SIGNAL = "signal";
|
|
4516
|
-
const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
|
|
4517
|
-
const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
|
|
4518
|
-
const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
|
|
4519
|
-
const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
|
|
4520
|
-
const OPTION_CHECK_SIGNATURE = "checkSignature";
|
|
4521
|
-
const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
4522
|
-
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
4523
|
-
const OPTION_USE_WEB_WORKERS = "useWebWorkers";
|
|
4524
|
-
const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
|
|
4525
|
-
const OPTION_TRANSFER_STREAMS = "transferStreams";
|
|
4526
|
-
const OPTION_PREVENT_CLOSE = "preventClose";
|
|
4527
|
-
const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
|
|
4528
|
-
const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
|
|
4529
|
-
const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
|
|
4530
|
-
const OPTION_KEEP_ORDER = "keepOrder";
|
|
4531
|
-
const OPTION_LEVEL = "level";
|
|
4532
|
-
const OPTION_BUFFERED_WRITE = "bufferedWrite";
|
|
4533
|
-
const OPTION_CREATE_TEMP_STREAM = "createTempStream";
|
|
4534
|
-
const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
|
|
4535
|
-
const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
|
|
4536
|
-
const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
|
|
4537
|
-
const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
|
|
4538
|
-
const OPTION_ENCODE_TEXT = "encodeText";
|
|
4539
|
-
const OPTION_OFFSET = "offset";
|
|
4540
|
-
const OPTION_USDZ = "usdz";
|
|
4541
|
-
const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
|
|
4542
|
-
const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
|
|
4543
|
-
const OPTION_STRICTNESS = "strictness";
|
|
4544
|
-
const OPTION_FILENAME_VALIDATION = "filenameValidation";
|
|
4545
|
-
const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
|
|
4546
|
-
const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
|
|
4547
|
-
const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
|
|
4548
|
-
const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
|
|
4549
|
-
const TEXT_TYPE_FILENAME = "filename";
|
|
4550
|
-
const TEXT_TYPE_COMMENT = "comment";
|
|
4551
|
-
const STRICTNESS_STRICT = "strict";
|
|
4552
|
-
const STRICTNESS_BALANCED = "balanced";
|
|
4553
|
-
const STRICTNESS_TOLERANT = "tolerant";
|
|
4554
|
-
|
|
4555
4666
|
/*
|
|
4556
4667
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4557
4668
|
|
|
@@ -4592,6 +4703,7 @@ const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
|
4592
4703
|
const ERR_UNSUPPORTED_COMPRESSION$1 = "Compression method not supported";
|
|
4593
4704
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4594
4705
|
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4706
|
+
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4595
4707
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4596
4708
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
4597
4709
|
const ERR_UNSAFE_FILENAME = "Unsafe filename";
|
|
@@ -4612,7 +4724,7 @@ const ZIP64_PROPERTIES = [
|
|
|
4612
4724
|
];
|
|
4613
4725
|
const ZIP64_EXTRACTION = {
|
|
4614
4726
|
[MAX_16_BITS]: {
|
|
4615
|
-
getValue: getUint32,
|
|
4727
|
+
getValue: getUint32$1,
|
|
4616
4728
|
bytes: 4
|
|
4617
4729
|
},
|
|
4618
4730
|
[MAX_32_BITS]: {
|
|
@@ -4621,6 +4733,7 @@ const ZIP64_EXTRACTION = {
|
|
|
4621
4733
|
}
|
|
4622
4734
|
};
|
|
4623
4735
|
const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
|
|
4736
|
+
const MAX_DEFLATE_EXPANSION_RATIO = 1032;
|
|
4624
4737
|
const CENTRAL_DIRECTORY_UNREACHABLE = 0;
|
|
4625
4738
|
const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
|
|
4626
4739
|
const CENTRAL_DIRECTORY_REACHABLE = 2;
|
|
@@ -4631,7 +4744,6 @@ class ZipReader {
|
|
|
4631
4744
|
Object.assign(this, {
|
|
4632
4745
|
reader: new GenericReader(reader),
|
|
4633
4746
|
options,
|
|
4634
|
-
config: getConfiguration(),
|
|
4635
4747
|
readRanges: new Map()
|
|
4636
4748
|
});
|
|
4637
4749
|
}
|
|
@@ -4639,7 +4751,6 @@ class ZipReader {
|
|
|
4639
4751
|
async* getEntriesGenerator(options = {}) {
|
|
4640
4752
|
const zipReader = this;
|
|
4641
4753
|
let { reader } = zipReader;
|
|
4642
|
-
const { config } = zipReader;
|
|
4643
4754
|
await initStream(reader);
|
|
4644
4755
|
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
4645
4756
|
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
@@ -4648,7 +4759,7 @@ class ZipReader {
|
|
|
4648
4759
|
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
4649
4760
|
throw new Error(ERR_BAD_FORMAT);
|
|
4650
4761
|
}
|
|
4651
|
-
const strictness = getStrictness(
|
|
4762
|
+
const strictness = getStrictness(options, zipReader.options);
|
|
4652
4763
|
const checkAmbiguity = strictness == STRICTNESS_STRICT;
|
|
4653
4764
|
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
4654
4765
|
const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
|
|
@@ -4656,9 +4767,7 @@ class ZipReader {
|
|
|
4656
4767
|
const normalizeFilename = getOptionValue$1(zipReader, options, OPTION_NORMALIZE_FILENAME);
|
|
4657
4768
|
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
4658
4769
|
if (!endOfDirectoryInfo) {
|
|
4659
|
-
|
|
4660
|
-
const signatureView = getDataView(signatureArray);
|
|
4661
|
-
if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
|
|
4770
|
+
if (await startsWithSplitZipSignature$1(reader)) {
|
|
4662
4771
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4663
4772
|
} else {
|
|
4664
4773
|
throw new Error(ERR_EOCDR_NOT_FOUND);
|
|
@@ -4668,18 +4777,18 @@ class ZipReader {
|
|
|
4668
4777
|
throwAmbiguousArchive("multiple end of central directory records");
|
|
4669
4778
|
}
|
|
4670
4779
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
4671
|
-
let directoryDataLength = getUint32(endOfDirectoryView, 12);
|
|
4672
|
-
let directoryDataOffset = getUint32(endOfDirectoryView, 16);
|
|
4780
|
+
let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
|
|
4781
|
+
let directoryDataOffset = getUint32$1(endOfDirectoryView, 16);
|
|
4673
4782
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
4674
|
-
const commentLength = getUint16(endOfDirectoryView, 20);
|
|
4783
|
+
const commentLength = getUint16$1(endOfDirectoryView, 20);
|
|
4675
4784
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
4676
4785
|
if (reader.size - appendedDataOffset > maxAppendedDataSize) {
|
|
4677
4786
|
throwAmbiguousArchive("appended data");
|
|
4678
4787
|
}
|
|
4679
|
-
let lastDiskNumber = getUint16(endOfDirectoryView, 4);
|
|
4788
|
+
let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
|
|
4680
4789
|
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
4681
|
-
let diskNumber = getUint16(endOfDirectoryView, 6);
|
|
4682
|
-
let filesLength = getUint16(endOfDirectoryView, 10);
|
|
4790
|
+
let diskNumber = getUint16$1(endOfDirectoryView, 6);
|
|
4791
|
+
let filesLength = getUint16$1(endOfDirectoryView, 10);
|
|
4683
4792
|
let prependedDataLength = 0;
|
|
4684
4793
|
let startOffset;
|
|
4685
4794
|
let zip64EndOfDirectory;
|
|
@@ -4695,12 +4804,12 @@ class ZipReader {
|
|
|
4695
4804
|
EMPTY_UINT8_ARRAY;
|
|
4696
4805
|
const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
|
|
4697
4806
|
if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
|
|
4698
|
-
getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
4699
|
-
directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4807
|
+
getUint32$1(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
4808
|
+
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4700
4809
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4701
4810
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4702
4811
|
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4703
|
-
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
4812
|
+
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
4704
4813
|
directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
|
|
4705
4814
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4706
4815
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
@@ -4710,7 +4819,7 @@ class ZipReader {
|
|
|
4710
4819
|
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4711
4820
|
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4712
4821
|
}
|
|
4713
|
-
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4822
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4714
4823
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
4715
4824
|
}
|
|
4716
4825
|
zip64EndOfDirectory = true;
|
|
@@ -4725,13 +4834,13 @@ class ZipReader {
|
|
|
4725
4834
|
}
|
|
4726
4835
|
}
|
|
4727
4836
|
if (lastDiskNumber == MAX_16_BITS) {
|
|
4728
|
-
lastDiskNumber = getUint32(endOfDirectoryView, 16);
|
|
4729
|
-
} else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
|
|
4837
|
+
lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
|
|
4838
|
+
} else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
|
|
4730
4839
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
4731
4840
|
}
|
|
4732
4841
|
if (diskNumber == MAX_16_BITS) {
|
|
4733
|
-
diskNumber = getUint32(endOfDirectoryView, 20);
|
|
4734
|
-
} else if (checkAmbiguity && diskNumber != getUint32(endOfDirectoryView, 20)) {
|
|
4842
|
+
diskNumber = getUint32$1(endOfDirectoryView, 20);
|
|
4843
|
+
} else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
|
|
4735
4844
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
4736
4845
|
}
|
|
4737
4846
|
if (filesLength == MAX_16_BITS) {
|
|
@@ -4769,11 +4878,11 @@ class ZipReader {
|
|
|
4769
4878
|
}
|
|
4770
4879
|
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4771
4880
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4772
|
-
const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4881
|
+
const storedPointsAtDirectory = getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4773
4882
|
let reconcile = !storedPointsAtDirectory;
|
|
4774
4883
|
if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4775
4884
|
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
|
|
4776
|
-
reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4885
|
+
reconcile = getUint32$1(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4777
4886
|
}
|
|
4778
4887
|
if (reconcile) {
|
|
4779
4888
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -4797,10 +4906,10 @@ class ZipReader {
|
|
|
4797
4906
|
}
|
|
4798
4907
|
zipReader.directoryOffset = directoryDataOffset;
|
|
4799
4908
|
zipReader.directoryLength = declaredDirectoryDataLength;
|
|
4800
|
-
const decryptCentralDirectory =
|
|
4909
|
+
const decryptCentralDirectory = getFunctionOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
|
|
4801
4910
|
let decryptedDirectory;
|
|
4802
4911
|
if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
|
|
4803
|
-
getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
|
|
4912
|
+
getUint32$1(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
|
|
4804
4913
|
(zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4805
4914
|
directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
|
|
4806
4915
|
directoryView = getDataView(directoryArray);
|
|
@@ -4813,8 +4922,8 @@ class ZipReader {
|
|
|
4813
4922
|
const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
|
|
4814
4923
|
let duplicateFilename;
|
|
4815
4924
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4816
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
4817
|
-
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4925
|
+
const fileEntry = new ZipEntry$1(reader, zipReader.options);
|
|
4926
|
+
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4818
4927
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4819
4928
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
4820
4929
|
}
|
|
@@ -4825,16 +4934,16 @@ class ZipReader {
|
|
|
4825
4934
|
const filenameOffset = offset + CENTRAL_FILE_HEADER_LENGTH;
|
|
4826
4935
|
const extraFieldOffset = filenameOffset + fileEntry.filenameLength;
|
|
4827
4936
|
const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
|
|
4828
|
-
const versionMadeBy = getUint16(directoryView, offset + 4);
|
|
4937
|
+
const versionMadeBy = getUint16$1(directoryView, offset + 4);
|
|
4829
4938
|
const msDosCompatible = versionMadeBy >> 8 == 0;
|
|
4830
4939
|
const unixCompatible = versionMadeBy >> 8 == 3;
|
|
4831
4940
|
const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
|
|
4832
|
-
const commentLength = getUint16(directoryView, offset + 32);
|
|
4941
|
+
const commentLength = getUint16$1(directoryView, offset + 32);
|
|
4833
4942
|
const endOffset = commentOffset + commentLength;
|
|
4834
4943
|
const rawComment = directoryArray.subarray(commentOffset, endOffset);
|
|
4835
4944
|
const filenameUTF8 = languageEncodingFlag;
|
|
4836
4945
|
const commentUTF8 = languageEncodingFlag;
|
|
4837
|
-
const externalFileAttributes = getUint32(directoryView, offset + 38);
|
|
4946
|
+
const externalFileAttributes = getUint32$1(directoryView, offset + 38);
|
|
4838
4947
|
const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
|
|
4839
4948
|
const msdosAttributes = {
|
|
4840
4949
|
readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
|
|
@@ -4843,8 +4952,8 @@ class ZipReader {
|
|
|
4843
4952
|
directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
|
|
4844
4953
|
archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
|
|
4845
4954
|
};
|
|
4846
|
-
const offsetFileEntry = getUint32(directoryView, offset + 42);
|
|
4847
|
-
const decode =
|
|
4955
|
+
const offsetFileEntry = getUint32$1(directoryView, offset + 42);
|
|
4956
|
+
const decode = getFunctionOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
|
|
4848
4957
|
const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
|
|
4849
4958
|
const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
|
|
4850
4959
|
let filename = decode(rawFilename, rawFilenameEncoding, TEXT_TYPE_FILENAME);
|
|
@@ -4870,12 +4979,13 @@ class ZipReader {
|
|
|
4870
4979
|
index: indexFile,
|
|
4871
4980
|
versionMadeBy,
|
|
4872
4981
|
msDosCompatible,
|
|
4982
|
+
zip64: false,
|
|
4873
4983
|
compressedSize: 0,
|
|
4874
4984
|
uncompressedSize: 0,
|
|
4875
4985
|
commentLength,
|
|
4876
4986
|
offset: offsetFileEntry,
|
|
4877
|
-
diskNumberStart: getUint16(directoryView, offset + 34),
|
|
4878
|
-
internalFileAttributes: getUint16(directoryView, offset + 36),
|
|
4987
|
+
diskNumberStart: getUint16$1(directoryView, offset + 34),
|
|
4988
|
+
internalFileAttributes: getUint16$1(directoryView, offset + 36),
|
|
4879
4989
|
externalFileAttributes,
|
|
4880
4990
|
msdosAttributesRaw,
|
|
4881
4991
|
msdosAttributes,
|
|
@@ -4943,8 +5053,8 @@ class ZipReader {
|
|
|
4943
5053
|
yield entry;
|
|
4944
5054
|
}
|
|
4945
5055
|
let offsetAfterSignature = offset;
|
|
4946
|
-
if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
4947
|
-
const signatureDataLength = getUint16(directoryView, offset + 4);
|
|
5056
|
+
if (offset + 6 <= directoryArray.length && getUint32$1(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
5057
|
+
const signatureDataLength = getUint16$1(directoryView, offset + 4);
|
|
4948
5058
|
if (offset + 6 + signatureDataLength <= directoryArray.length) {
|
|
4949
5059
|
zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
|
|
4950
5060
|
offsetAfterSignature = offset + 6 + signatureDataLength;
|
|
@@ -4956,13 +5066,17 @@ class ZipReader {
|
|
|
4956
5066
|
if (duplicateFilename) {
|
|
4957
5067
|
throwAmbiguousArchive("duplicate filename");
|
|
4958
5068
|
}
|
|
4959
|
-
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > 0))) {
|
|
4960
|
-
throwAmbiguousArchive("prepended data");
|
|
4961
|
-
}
|
|
4962
5069
|
const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
|
|
4963
5070
|
const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
|
|
5071
|
+
const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
|
|
5072
|
+
startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
|
|
5073
|
+
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
|
|
5074
|
+
throwAmbiguousArchive("prepended data");
|
|
5075
|
+
}
|
|
4964
5076
|
if (extractPrependedData) {
|
|
4965
|
-
zipReader.prependedData = startOffset >
|
|
5077
|
+
zipReader.prependedData = startOffset > splitZipSignatureLength ?
|
|
5078
|
+
await readUint8Array(reader, splitZipSignatureLength, startOffset - splitZipSignatureLength) :
|
|
5079
|
+
EMPTY_UINT8_ARRAY;
|
|
4966
5080
|
}
|
|
4967
5081
|
zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : EMPTY_UINT8_ARRAY;
|
|
4968
5082
|
if (extractAppendedData) {
|
|
@@ -5029,16 +5143,16 @@ class ZipReaderStream {
|
|
|
5029
5143
|
|
|
5030
5144
|
let ZipEntry$1 = class ZipEntry {
|
|
5031
5145
|
|
|
5032
|
-
constructor(reader,
|
|
5146
|
+
constructor(reader, options) {
|
|
5033
5147
|
Object.assign(this, {
|
|
5034
5148
|
reader,
|
|
5035
|
-
config,
|
|
5036
5149
|
options
|
|
5037
5150
|
});
|
|
5038
5151
|
}
|
|
5039
5152
|
|
|
5040
5153
|
async getData(writer, fileEntry, readRanges, options = {}) {
|
|
5041
5154
|
const zipEntry = this;
|
|
5155
|
+
const config = getConfiguration();
|
|
5042
5156
|
const {
|
|
5043
5157
|
reader,
|
|
5044
5158
|
index,
|
|
@@ -5047,7 +5161,6 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5047
5161
|
extraFieldAES,
|
|
5048
5162
|
extraFieldZip64,
|
|
5049
5163
|
compressionMethod,
|
|
5050
|
-
config,
|
|
5051
5164
|
bitFlag,
|
|
5052
5165
|
rawBitFlag,
|
|
5053
5166
|
crc32,
|
|
@@ -5065,6 +5178,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5065
5178
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
5066
5179
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
5067
5180
|
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
5181
|
+
checkPasswordOption(password, rawPassword);
|
|
5068
5182
|
password = password && password.length && password;
|
|
5069
5183
|
rawPassword = rawPassword && rawPassword.length && rawPassword;
|
|
5070
5184
|
if (extraFieldAES) {
|
|
@@ -5072,7 +5186,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5072
5186
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
|
|
5073
5187
|
}
|
|
5074
5188
|
}
|
|
5075
|
-
if (dataArray.length < HEADER_SIZE || getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
5189
|
+
if (dataArray.length < HEADER_SIZE || getUint32$1(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
5076
5190
|
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
5077
5191
|
}
|
|
5078
5192
|
readCommonHeader(localDirectory, dataView, 4);
|
|
@@ -5080,9 +5194,12 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5080
5194
|
extraFieldLength,
|
|
5081
5195
|
filenameLength
|
|
5082
5196
|
} = localDirectory;
|
|
5083
|
-
const
|
|
5197
|
+
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5198
|
+
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5199
|
+
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
5200
|
+
const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
|
|
5084
5201
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
5085
|
-
if (
|
|
5202
|
+
if (checkLocalFilename && (filenameLength || extraFieldLength)) {
|
|
5086
5203
|
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
5087
5204
|
rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
|
|
5088
5205
|
localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
|
|
@@ -5091,17 +5208,26 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5091
5208
|
await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
|
|
5092
5209
|
EMPTY_UINT8_ARRAY;
|
|
5093
5210
|
}
|
|
5211
|
+
if (checkLocalFilename) {
|
|
5212
|
+
localDirectory.rawFilename = rawLocalFilename;
|
|
5213
|
+
}
|
|
5094
5214
|
readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
|
|
5095
|
-
if (
|
|
5096
|
-
|
|
5215
|
+
if (checkLocalDirectory) {
|
|
5216
|
+
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
|
|
5097
5217
|
}
|
|
5098
|
-
const { lastAccessDate, creationDate } = localDirectory;
|
|
5218
|
+
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5099
5219
|
if (lastAccessDate) {
|
|
5100
5220
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5101
5221
|
}
|
|
5102
5222
|
if (creationDate) {
|
|
5103
5223
|
fileEntry.creationDate = creationDate;
|
|
5104
5224
|
}
|
|
5225
|
+
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
5226
|
+
fileEntry.uid = uid;
|
|
5227
|
+
}
|
|
5228
|
+
if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
|
|
5229
|
+
fileEntry.gid = gid;
|
|
5230
|
+
}
|
|
5105
5231
|
const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
|
|
5106
5232
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
5107
5233
|
if (!passThrough) {
|
|
@@ -5122,9 +5248,12 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5122
5248
|
}
|
|
5123
5249
|
}
|
|
5124
5250
|
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
5251
|
+
if (dataOffset + compressedSize > reader.size) {
|
|
5252
|
+
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5253
|
+
}
|
|
5125
5254
|
const size = compressedSize;
|
|
5126
5255
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5127
|
-
const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
|
|
5256
|
+
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5128
5257
|
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5129
5258
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
5130
5259
|
const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
|
|
@@ -5132,6 +5261,8 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5132
5261
|
checkOverlappingEntry = true;
|
|
5133
5262
|
}
|
|
5134
5263
|
const { onstart, onprogress, onend } = options;
|
|
5264
|
+
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
|
|
5265
|
+
const outputSize = passThrough ? compressedSize : uncompressedSize;
|
|
5135
5266
|
const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
|
|
5136
5267
|
let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5137
5268
|
if (deflate64) {
|
|
@@ -5152,9 +5283,9 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5152
5283
|
checkCrc32,
|
|
5153
5284
|
checkAuthenticationCode: getOptionValue$1(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
|
|
5154
5285
|
passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((crc32 >>> 24) & MAX_8_BITS)),
|
|
5155
|
-
outputSize
|
|
5286
|
+
outputSize,
|
|
5156
5287
|
crc32,
|
|
5157
|
-
compressed
|
|
5288
|
+
compressed,
|
|
5158
5289
|
encrypted,
|
|
5159
5290
|
useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
|
|
5160
5291
|
useCompressionStream,
|
|
@@ -5191,11 +5322,11 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5191
5322
|
writer = new WritableStream();
|
|
5192
5323
|
}
|
|
5193
5324
|
writer = new GenericWriter(writer);
|
|
5194
|
-
await initStream(writer,
|
|
5325
|
+
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5195
5326
|
({ writable } = writer);
|
|
5196
|
-
const { outputSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5197
|
-
writer.size +=
|
|
5198
|
-
if (
|
|
5327
|
+
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5328
|
+
writer.size += writtenSize;
|
|
5329
|
+
if (writtenSize != outputSize) {
|
|
5199
5330
|
throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
5200
5331
|
}
|
|
5201
5332
|
}
|
|
@@ -5229,7 +5360,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5229
5360
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5230
5361
|
const maxOffset = Math.min(directoryView.byteLength, 1024) - 3;
|
|
5231
5362
|
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5232
|
-
if (getUint32(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5363
|
+
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5233
5364
|
return true;
|
|
5234
5365
|
}
|
|
5235
5366
|
}
|
|
@@ -5240,15 +5371,15 @@ function getDirectoryEncryptionInfo(rawExtensibleData) {
|
|
|
5240
5371
|
const directoryEncryptionInfo = { rawExtensibleData };
|
|
5241
5372
|
if (rawExtensibleData.length >= 28) {
|
|
5242
5373
|
const extensibleDataView = getDataView(rawExtensibleData);
|
|
5243
|
-
const hashDataLength = getUint16(extensibleDataView, 26);
|
|
5374
|
+
const hashDataLength = getUint16$1(extensibleDataView, 26);
|
|
5244
5375
|
Object.assign(directoryEncryptionInfo, {
|
|
5245
|
-
compressionMethod: getUint16(extensibleDataView, 0),
|
|
5376
|
+
compressionMethod: getUint16$1(extensibleDataView, 0),
|
|
5246
5377
|
compressedSize: Number(getBigUint64(extensibleDataView, 2)),
|
|
5247
5378
|
uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
|
|
5248
|
-
encryptionAlgorithm: getUint16(extensibleDataView, 18),
|
|
5249
|
-
bitLength: getUint16(extensibleDataView, 20),
|
|
5250
|
-
flags: getUint16(extensibleDataView, 22),
|
|
5251
|
-
hashAlgorithm: getUint16(extensibleDataView, 24),
|
|
5379
|
+
encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
|
|
5380
|
+
bitLength: getUint16$1(extensibleDataView, 20),
|
|
5381
|
+
flags: getUint16$1(extensibleDataView, 22),
|
|
5382
|
+
hashAlgorithm: getUint16$1(extensibleDataView, 24),
|
|
5252
5383
|
hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
|
|
5253
5384
|
});
|
|
5254
5385
|
}
|
|
@@ -5256,12 +5387,12 @@ function getDirectoryEncryptionInfo(rawExtensibleData) {
|
|
|
5256
5387
|
}
|
|
5257
5388
|
|
|
5258
5389
|
function readCommonHeader(directory, dataView, offset) {
|
|
5259
|
-
const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
|
|
5390
|
+
const rawBitFlag = directory.rawBitFlag = getUint16$1(dataView, offset + 2);
|
|
5260
5391
|
const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
|
|
5261
|
-
const rawLastModDate = getUint32(dataView, offset + 6);
|
|
5392
|
+
const rawLastModDate = getUint32$1(dataView, offset + 6);
|
|
5262
5393
|
Object.assign(directory, {
|
|
5263
5394
|
encrypted,
|
|
5264
|
-
version: getUint16(dataView, offset),
|
|
5395
|
+
version: getUint16$1(dataView, offset),
|
|
5265
5396
|
bitFlag: {
|
|
5266
5397
|
level: (rawBitFlag & BITFLAG_LEVEL) >> 1,
|
|
5267
5398
|
dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR,
|
|
@@ -5269,8 +5400,8 @@ function readCommonHeader(directory, dataView, offset) {
|
|
|
5269
5400
|
},
|
|
5270
5401
|
rawLastModDate,
|
|
5271
5402
|
lastModDate: getDate(rawLastModDate),
|
|
5272
|
-
filenameLength: getUint16(dataView, offset + 22),
|
|
5273
|
-
extraFieldLength: getUint16(dataView, offset + 24)
|
|
5403
|
+
filenameLength: getUint16$1(dataView, offset + 22),
|
|
5404
|
+
extraFieldLength: getUint16$1(dataView, offset + 24)
|
|
5274
5405
|
});
|
|
5275
5406
|
}
|
|
5276
5407
|
|
|
@@ -5281,8 +5412,8 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5281
5412
|
let offsetExtraField = 0;
|
|
5282
5413
|
try {
|
|
5283
5414
|
while (offsetExtraField < rawExtraField.length) {
|
|
5284
|
-
const type = getUint16(rawExtraFieldView, offsetExtraField);
|
|
5285
|
-
const size = getUint16(rawExtraFieldView, offsetExtraField + 2);
|
|
5415
|
+
const type = getUint16$1(rawExtraFieldView, offsetExtraField);
|
|
5416
|
+
const size = getUint16$1(rawExtraFieldView, offsetExtraField + 2);
|
|
5286
5417
|
extraField.set(type, {
|
|
5287
5418
|
type,
|
|
5288
5419
|
data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size)
|
|
@@ -5292,12 +5423,12 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5292
5423
|
} catch {
|
|
5293
5424
|
// ignored
|
|
5294
5425
|
}
|
|
5295
|
-
const compressionMethod = getUint16(dataView, offset + 4);
|
|
5426
|
+
const compressionMethod = getUint16$1(dataView, offset + 4);
|
|
5296
5427
|
Object.assign(directory, {
|
|
5297
|
-
signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5298
|
-
crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5299
|
-
compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
|
|
5300
|
-
uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5428
|
+
signature: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5429
|
+
crc32: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5430
|
+
compressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
|
|
5431
|
+
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5301
5432
|
});
|
|
5302
5433
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5303
5434
|
if (extraFieldZip64) {
|
|
@@ -5337,10 +5468,12 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5337
5468
|
directory.extraFieldNTFS = extraFieldNTFS;
|
|
5338
5469
|
}
|
|
5339
5470
|
const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
|
|
5471
|
+
let unixIdsRead;
|
|
5340
5472
|
if (extraFieldUnix) {
|
|
5341
|
-
readExtraFieldUnix(extraFieldUnix, directory, false);
|
|
5473
|
+
unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
|
|
5342
5474
|
directory.extraFieldUnix = extraFieldUnix;
|
|
5343
|
-
}
|
|
5475
|
+
}
|
|
5476
|
+
if (!unixIdsRead) {
|
|
5344
5477
|
const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
|
|
5345
5478
|
if (extraFieldInfoZip) {
|
|
5346
5479
|
readExtraFieldUnix(extraFieldInfoZip, directory, true);
|
|
@@ -5384,11 +5517,11 @@ function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName,
|
|
|
5384
5517
|
computedCrc32.append(fileEntry[rawPropertyName]);
|
|
5385
5518
|
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
5386
5519
|
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
5387
|
-
const nameCrc32 = getUint32(extraFieldView, 1);
|
|
5520
|
+
const nameCrc32 = getUint32$1(extraFieldView, 1);
|
|
5388
5521
|
Object.assign(extraFieldUnicode, {
|
|
5389
5522
|
version: getUint8(extraFieldView, 0),
|
|
5390
5523
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
5391
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32(computedCrc32View, 0)
|
|
5524
|
+
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5392
5525
|
});
|
|
5393
5526
|
if (extraFieldUnicode.valid) {
|
|
5394
5527
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -5404,7 +5537,7 @@ function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
|
|
|
5404
5537
|
vendorId: getUint8(extraFieldView, 2),
|
|
5405
5538
|
strength,
|
|
5406
5539
|
originalCompressionMethod: compressionMethod,
|
|
5407
|
-
compressionMethod: getUint16(extraFieldView, 5)
|
|
5540
|
+
compressionMethod: getUint16$1(extraFieldView, 5)
|
|
5408
5541
|
});
|
|
5409
5542
|
directory.compressionMethod = extraFieldAES.compressionMethod;
|
|
5410
5543
|
if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1$1) {
|
|
@@ -5418,8 +5551,8 @@ function readExtraFieldNTFS(extraFieldNTFS, directory) {
|
|
|
5418
5551
|
let tag1Data;
|
|
5419
5552
|
try {
|
|
5420
5553
|
while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) {
|
|
5421
|
-
const tagValue = getUint16(extraFieldView, offsetExtraField);
|
|
5422
|
-
const attributeSize = getUint16(extraFieldView, offsetExtraField + 2);
|
|
5554
|
+
const tagValue = getUint16$1(extraFieldView, offsetExtraField);
|
|
5555
|
+
const attributeSize = getUint16$1(extraFieldView, offsetExtraField + 2);
|
|
5423
5556
|
if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) {
|
|
5424
5557
|
tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize);
|
|
5425
5558
|
}
|
|
@@ -5443,7 +5576,7 @@ function readExtraFieldNTFS(extraFieldNTFS, directory) {
|
|
|
5443
5576
|
const creationDate = getDateNTFS(rawCreationDate);
|
|
5444
5577
|
const extraFieldData = { lastModDate, lastAccessDate, creationDate };
|
|
5445
5578
|
Object.assign(extraFieldNTFS, extraFieldData);
|
|
5446
|
-
Object.assign(directory, extraFieldData);
|
|
5579
|
+
Object.assign(directory, extraFieldData, { rawLastAccessDate, rawCreationDate });
|
|
5447
5580
|
}
|
|
5448
5581
|
}
|
|
5449
5582
|
|
|
@@ -5452,12 +5585,12 @@ function readExtraFieldUnixDates(extraField, directory) {
|
|
|
5452
5585
|
return;
|
|
5453
5586
|
}
|
|
5454
5587
|
const extraFieldView = getDataView(extraField.data);
|
|
5455
|
-
const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
|
|
5456
|
-
const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
|
|
5588
|
+
const lastAccessDate = new Date((getUint32$1(extraFieldView, 0) | 0) * 1000);
|
|
5589
|
+
const lastModDate = new Date((getUint32$1(extraFieldView, 4) | 0) * 1000);
|
|
5457
5590
|
const extraFieldData = { lastAccessDate, lastModDate };
|
|
5458
5591
|
if (extraField.data.length >= 12) {
|
|
5459
|
-
extraFieldData.uid = getUint16(extraFieldView, 8);
|
|
5460
|
-
extraFieldData.gid = getUint16(extraFieldView, 10);
|
|
5592
|
+
extraFieldData.uid = getUint16$1(extraFieldView, 8);
|
|
5593
|
+
extraFieldData.gid = getUint16$1(extraFieldView, 10);
|
|
5461
5594
|
}
|
|
5462
5595
|
Object.assign(extraField, extraFieldData);
|
|
5463
5596
|
Object.assign(directory, extraFieldData);
|
|
@@ -5477,8 +5610,8 @@ function readExtraFieldUnix(extraField, directory, isInfoZip) {
|
|
|
5477
5610
|
gid = unpackUnixId(extraField.data.subarray(offset, offset + gidSize));
|
|
5478
5611
|
Object.assign(extraField, { version, uid, gid });
|
|
5479
5612
|
} else if (extraField.data.length >= 4) {
|
|
5480
|
-
uid = getUint16(view, 0);
|
|
5481
|
-
gid = getUint16(view, 2);
|
|
5613
|
+
uid = getUint16$1(view, 0);
|
|
5614
|
+
gid = getUint16$1(view, 2);
|
|
5482
5615
|
Object.assign(extraField, { uid, gid });
|
|
5483
5616
|
}
|
|
5484
5617
|
if (uid !== UNDEFINED_VALUE) {
|
|
@@ -5487,6 +5620,7 @@ function readExtraFieldUnix(extraField, directory, isInfoZip) {
|
|
|
5487
5620
|
if (gid !== UNDEFINED_VALUE) {
|
|
5488
5621
|
directory.gid = gid;
|
|
5489
5622
|
}
|
|
5623
|
+
return uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE;
|
|
5490
5624
|
} catch {
|
|
5491
5625
|
// ignored
|
|
5492
5626
|
}
|
|
@@ -5527,7 +5661,7 @@ function readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory,
|
|
|
5527
5661
|
let offset = 1;
|
|
5528
5662
|
timeProperties.forEach((propertyName, indexProperty) => {
|
|
5529
5663
|
if (extraFieldExtendedTimestamp.data.length >= offset + 4) {
|
|
5530
|
-
const time = getUint32(extraFieldView, offset);
|
|
5664
|
+
const time = getUint32$1(extraFieldView, offset);
|
|
5531
5665
|
directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date((time | 0) * 1000);
|
|
5532
5666
|
const rawPropertyName = timeRawProperties[indexProperty];
|
|
5533
5667
|
extraFieldExtendedTimestamp[rawPropertyName] = time;
|
|
@@ -5559,26 +5693,25 @@ async function detectOverlappingEntry({
|
|
|
5559
5693
|
}
|
|
5560
5694
|
if (dataDescriptorLength) {
|
|
5561
5695
|
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
|
|
5562
|
-
const
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
if (extraFieldZip64) {
|
|
5569
|
-
readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
|
|
5570
|
-
readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
|
|
5571
|
-
} else {
|
|
5572
|
-
readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
|
|
5573
|
-
readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
|
|
5574
|
-
}
|
|
5575
|
-
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
|
|
5696
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
5697
|
+
let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
5698
|
+
getUint32$1(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
5699
|
+
if (signature) {
|
|
5700
|
+
const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
|
|
5701
|
+
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
|
|
5576
5702
|
if (matchCrc32 &&
|
|
5577
|
-
|
|
5578
|
-
|
|
5703
|
+
signedDataDescriptor.compressedSize == compressedSize &&
|
|
5704
|
+
signedDataDescriptor.uncompressedSize == uncompressedSize) {
|
|
5579
5705
|
dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
5706
|
+
} else {
|
|
5707
|
+
signature = false;
|
|
5580
5708
|
}
|
|
5581
5709
|
}
|
|
5710
|
+
if (dataDescriptorArray.length >= dataDescriptorLength) {
|
|
5711
|
+
const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
|
|
5712
|
+
localDataDescriptor.signature = signature;
|
|
5713
|
+
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
5714
|
+
}
|
|
5582
5715
|
}
|
|
5583
5716
|
const range = {
|
|
5584
5717
|
start: offset,
|
|
@@ -5595,22 +5728,80 @@ async function detectOverlappingEntry({
|
|
|
5595
5728
|
readRanges.set(index, range);
|
|
5596
5729
|
}
|
|
5597
5730
|
|
|
5731
|
+
function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
|
|
5732
|
+
const crc32 = getUint32$1(dataDescriptorView, offset);
|
|
5733
|
+
let compressedSize;
|
|
5734
|
+
let uncompressedSize;
|
|
5735
|
+
if (extraFieldZip64) {
|
|
5736
|
+
compressedSize = getBigUint64(dataDescriptorView, offset + 4);
|
|
5737
|
+
uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
|
|
5738
|
+
} else {
|
|
5739
|
+
compressedSize = getUint32$1(dataDescriptorView, offset + 4);
|
|
5740
|
+
uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
|
|
5741
|
+
}
|
|
5742
|
+
return { crc32, compressedSize, uncompressedSize };
|
|
5743
|
+
}
|
|
5744
|
+
|
|
5598
5745
|
function getDiskOffset$1(reader, diskNumber) {
|
|
5599
5746
|
return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
|
|
5600
5747
|
}
|
|
5601
5748
|
|
|
5749
|
+
async function startsWithSplitZipSignature$1(reader) {
|
|
5750
|
+
return await getFirstSignature(reader) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
5751
|
+
}
|
|
5752
|
+
|
|
5753
|
+
async function startsWithSplitZipMarker(reader) {
|
|
5754
|
+
const signature = await getFirstSignature(reader);
|
|
5755
|
+
return signature == SPLIT_ZIP_FILE_SIGNATURE || signature == TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE;
|
|
5756
|
+
}
|
|
5757
|
+
|
|
5758
|
+
async function getFirstSignature(reader) {
|
|
5759
|
+
const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
5760
|
+
return getUint32$1(getDataView(signatureArray));
|
|
5761
|
+
}
|
|
5762
|
+
|
|
5602
5763
|
function isStrictnessValue(value) {
|
|
5603
5764
|
return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
|
|
5604
5765
|
}
|
|
5605
5766
|
|
|
5606
|
-
function
|
|
5607
|
-
|
|
5608
|
-
|
|
5767
|
+
function getDecodableOutputSize(outputSize, compressedSize, compressed) {
|
|
5768
|
+
return Math.min(outputSize, compressed ? compressedSize * MAX_DEFLATE_EXPANSION_RATIO : compressedSize);
|
|
5769
|
+
}
|
|
5770
|
+
|
|
5771
|
+
function getStrictness(options, inheritedOptions) {
|
|
5772
|
+
return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
|
|
5773
|
+
}
|
|
5774
|
+
|
|
5775
|
+
function resolveStrictness(options, inheritedStrictness) {
|
|
5776
|
+
const strictness = options[OPTION_STRICTNESS];
|
|
5777
|
+
if (strictness !== UNDEFINED_VALUE) {
|
|
5778
|
+
if (!isStrictnessValue(strictness)) {
|
|
5779
|
+
throw new Error(ERR_INVALID_STRICTNESS);
|
|
5780
|
+
}
|
|
5781
|
+
return strictness;
|
|
5782
|
+
}
|
|
5783
|
+
const checkAmbiguity = options[OPTION_CHECK_AMBIGUITY];
|
|
5784
|
+
if (checkAmbiguity === UNDEFINED_VALUE) {
|
|
5785
|
+
return inheritedStrictness;
|
|
5609
5786
|
}
|
|
5610
|
-
if (
|
|
5611
|
-
|
|
5787
|
+
if (checkAmbiguity) {
|
|
5788
|
+
return STRICTNESS_STRICT;
|
|
5612
5789
|
}
|
|
5613
|
-
return
|
|
5790
|
+
return inheritedStrictness == STRICTNESS_TOLERANT ? STRICTNESS_TOLERANT : STRICTNESS_BALANCED;
|
|
5791
|
+
}
|
|
5792
|
+
|
|
5793
|
+
function getCheckLocalDirectory(checkLocalDirectory, strictness) {
|
|
5794
|
+
if (checkLocalDirectory === UNDEFINED_VALUE) {
|
|
5795
|
+
return strictness != STRICTNESS_TOLERANT;
|
|
5796
|
+
}
|
|
5797
|
+
return Boolean(checkLocalDirectory);
|
|
5798
|
+
}
|
|
5799
|
+
|
|
5800
|
+
function getCheckLocalFilename(checkLocalFilename, strictness) {
|
|
5801
|
+
if (checkLocalFilename === UNDEFINED_VALUE) {
|
|
5802
|
+
return strictness == STRICTNESS_STRICT;
|
|
5803
|
+
}
|
|
5804
|
+
return Boolean(checkLocalFilename);
|
|
5614
5805
|
}
|
|
5615
5806
|
|
|
5616
5807
|
function getFilenameValidation(filenameValidation, strictness) {
|
|
@@ -5639,7 +5830,7 @@ function isUnsafeFilename(filename, filenameValidation) {
|
|
|
5639
5830
|
|
|
5640
5831
|
function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
|
|
5641
5832
|
if (maxAppendedDataSize !== UNDEFINED_VALUE) {
|
|
5642
|
-
const size = toNumber
|
|
5833
|
+
const size = toNumber(maxAppendedDataSize);
|
|
5643
5834
|
if (typeof size != NUMBER_TYPE || Number.isNaN(size) || size < 0) {
|
|
5644
5835
|
throw new Error(ERR_INVALID_MAX_APPENDED_DATA_SIZE);
|
|
5645
5836
|
}
|
|
@@ -5662,7 +5853,7 @@ async function findEndOfCentralDirectory(reader, rejectAmbiguous, maxAppendedDat
|
|
|
5662
5853
|
let plausibleEndOfDirectoryInfo;
|
|
5663
5854
|
let endOfDirectoryReachingEndCount = 0;
|
|
5664
5855
|
for await (const [anchoredView, anchoredOffset, anchoredArray, indexByte, offset] of scanEndOfCentralDirectory(reader, anchoredLength)) {
|
|
5665
|
-
const commentLength = getUint16(anchoredView, indexByte + 20);
|
|
5856
|
+
const commentLength = getUint16$1(anchoredView, indexByte + 20);
|
|
5666
5857
|
if (offset + END_OF_CENTRAL_DIR_LENGTH + commentLength == size) {
|
|
5667
5858
|
const reachability = await getCentralDirectoryReachability(reader, anchoredView, anchoredOffset, indexByte, offset, size, remoteProbeBudget);
|
|
5668
5859
|
if (reachability == CENTRAL_DIRECTORY_REACHABLE) {
|
|
@@ -5713,7 +5904,7 @@ async function* scanEndOfCentralDirectory(reader, scanLength) {
|
|
|
5713
5904
|
const scanArray = await readUint8Array(reader, scanOffset, scanLength);
|
|
5714
5905
|
const scanView = getDataView(scanArray);
|
|
5715
5906
|
for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5716
|
-
if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
5907
|
+
if (getUint32$1(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
5717
5908
|
yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
|
|
5718
5909
|
}
|
|
5719
5910
|
}
|
|
@@ -5724,9 +5915,9 @@ function getEndOfCentralDirectoryInfo(scanArray, indexByte, offset) {
|
|
|
5724
5915
|
}
|
|
5725
5916
|
|
|
5726
5917
|
async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
|
|
5727
|
-
const filesLength = getUint16(view, indexByte + 10);
|
|
5728
|
-
const directoryDataLength = getUint32(view, indexByte + 12);
|
|
5729
|
-
const directoryDataOffset = getUint32(view, indexByte + 16);
|
|
5918
|
+
const filesLength = getUint16$1(view, indexByte + 10);
|
|
5919
|
+
const directoryDataLength = getUint32$1(view, indexByte + 12);
|
|
5920
|
+
const directoryDataOffset = getUint32$1(view, indexByte + 16);
|
|
5730
5921
|
if (filesLength == MAX_16_BITS || directoryDataLength == MAX_32_BITS || directoryDataOffset == MAX_32_BITS) {
|
|
5731
5922
|
const locatorSignature = await readSignature(reader, view, anchoredOffset, offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, size, remoteProbeBudget);
|
|
5732
5923
|
return locatorSignature == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE ? CENTRAL_DIRECTORY_REACHABLE : CENTRAL_DIRECTORY_UNREACHABLE;
|
|
@@ -5734,7 +5925,7 @@ async function getCentralDirectoryReachability(reader, view, anchoredOffset, ind
|
|
|
5734
5925
|
if (!filesLength && !directoryDataLength) {
|
|
5735
5926
|
return CENTRAL_DIRECTORY_PLAUSIBLE;
|
|
5736
5927
|
}
|
|
5737
|
-
const directoryDiskNumber = getUint16(view, indexByte + 6);
|
|
5928
|
+
const directoryDiskNumber = getUint16$1(view, indexByte + 6);
|
|
5738
5929
|
for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
|
|
5739
5930
|
if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5740
5931
|
return CENTRAL_DIRECTORY_REACHABLE;
|
|
@@ -5748,20 +5939,21 @@ async function readSignature(reader, view, anchoredOffset, signatureOffset, size
|
|
|
5748
5939
|
return UNDEFINED_VALUE;
|
|
5749
5940
|
}
|
|
5750
5941
|
if (signatureOffset >= anchoredOffset) {
|
|
5751
|
-
return getUint32(view, signatureOffset - anchoredOffset);
|
|
5942
|
+
return getUint32$1(view, signatureOffset - anchoredOffset);
|
|
5752
5943
|
}
|
|
5753
5944
|
if (remoteProbeBudget.count > 0) {
|
|
5754
5945
|
remoteProbeBudget.count--;
|
|
5755
5946
|
const signatureArray = await readUint8Array(reader, signatureOffset, 4);
|
|
5756
|
-
return getUint32(getDataView(signatureArray), 0);
|
|
5947
|
+
return getUint32$1(getDataView(signatureArray), 0);
|
|
5757
5948
|
}
|
|
5758
5949
|
return UNDEFINED_VALUE;
|
|
5759
5950
|
}
|
|
5760
5951
|
|
|
5761
|
-
function
|
|
5952
|
+
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
|
|
5762
5953
|
const { rawFilename } = zipEntry;
|
|
5763
|
-
if (
|
|
5764
|
-
rawLocalFilename.
|
|
5954
|
+
if (checkLocalFilename &&
|
|
5955
|
+
(rawLocalFilename.length != rawFilename.length ||
|
|
5956
|
+
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
5765
5957
|
throwAmbiguousArchive("mismatched local file header (filename)");
|
|
5766
5958
|
}
|
|
5767
5959
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
@@ -5789,10 +5981,11 @@ function getOptionValue$1(zipReader, options, name) {
|
|
|
5789
5981
|
return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
|
|
5790
5982
|
}
|
|
5791
5983
|
|
|
5792
|
-
function
|
|
5793
|
-
return
|
|
5984
|
+
function getFunctionOptionValue$1(zipReader, options, name) {
|
|
5985
|
+
return checkFunctionOption(getOptionValue$1(zipReader, options, name));
|
|
5794
5986
|
}
|
|
5795
5987
|
|
|
5988
|
+
|
|
5796
5989
|
function getDate(timeRaw) {
|
|
5797
5990
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
5798
5991
|
return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
@@ -5806,11 +5999,11 @@ function getUint8(view, offset) {
|
|
|
5806
5999
|
return view.getUint8(offset);
|
|
5807
6000
|
}
|
|
5808
6001
|
|
|
5809
|
-
function getUint16(view, offset) {
|
|
6002
|
+
function getUint16$1(view, offset) {
|
|
5810
6003
|
return view.getUint16(offset, true);
|
|
5811
6004
|
}
|
|
5812
6005
|
|
|
5813
|
-
function getUint32(view, offset) {
|
|
6006
|
+
function getUint32$1(view, offset) {
|
|
5814
6007
|
return view.getUint32(offset, true);
|
|
5815
6008
|
}
|
|
5816
6009
|
|
|
@@ -5825,6 +6018,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
5825
6018
|
ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
|
|
5826
6019
|
ERR_ENCRYPTED: ERR_ENCRYPTED,
|
|
5827
6020
|
ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
|
|
6021
|
+
ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
|
|
5828
6022
|
ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
|
|
5829
6023
|
ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
|
|
5830
6024
|
ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
@@ -5879,13 +6073,18 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
5879
6073
|
|
|
5880
6074
|
const ERR_DUPLICATED_NAME = "File already exists";
|
|
5881
6075
|
const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
|
|
6076
|
+
const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
|
|
5882
6077
|
const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
|
|
6078
|
+
const ERR_INVALID_ENTRY_COMMENT_TYPE = "Invalid file entry comment (must be a string)";
|
|
6079
|
+
const ERR_INVALID_DATE = "Invalid date (must be a valid Date instance)";
|
|
5883
6080
|
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
5884
6081
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
5885
6082
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
5886
6083
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
5887
6084
|
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
5888
|
-
const
|
|
6085
|
+
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
6086
|
+
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
6087
|
+
const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
|
|
5889
6088
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
5890
6089
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
5891
6090
|
const MIN_UNIX_TIME = -2147483648;
|
|
@@ -5905,7 +6104,6 @@ const ERR_INVALID_UNIX_ID_SIZE = "uid/gid must be 0..65535 for unixExtraFieldTyp
|
|
|
5905
6104
|
const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
|
|
5906
6105
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
5907
6106
|
const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
|
|
5908
|
-
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
5909
6107
|
const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
5910
6108
|
|
|
5911
6109
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
@@ -5930,8 +6128,7 @@ class ZipWriter {
|
|
|
5930
6128
|
writer,
|
|
5931
6129
|
addSplitZipSignature,
|
|
5932
6130
|
options,
|
|
5933
|
-
|
|
5934
|
-
files: new Map(),
|
|
6131
|
+
fileEntries: new Map(),
|
|
5935
6132
|
filenames: new Set(),
|
|
5936
6133
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
5937
6134
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
@@ -5947,15 +6144,28 @@ class ZipWriter {
|
|
|
5947
6144
|
}
|
|
5948
6145
|
reader = new GenericReader(reader);
|
|
5949
6146
|
await initStream(reader);
|
|
6147
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6148
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6149
|
+
await initStream(reader);
|
|
6150
|
+
}
|
|
5950
6151
|
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5951
|
-
const zipReader$1 = new ZipReader(reader
|
|
6152
|
+
const zipReader$1 = new ZipReader(reader);
|
|
5952
6153
|
const entries = await zipReader$1.getEntries();
|
|
5953
6154
|
await zipReader$1.close();
|
|
5954
6155
|
await initStream(this.writer);
|
|
5955
|
-
|
|
5956
|
-
|
|
6156
|
+
const { directoryOffset } = zipReader$1;
|
|
6157
|
+
let splitZipSignatureLength = 0;
|
|
6158
|
+
if (this.addSplitZipSignature) {
|
|
6159
|
+
delete this.addSplitZipSignature;
|
|
6160
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
6161
|
+
await writeData(this.writer, getSplitZipSignatureArray());
|
|
6162
|
+
splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6163
|
+
this.offset += splitZipSignatureLength;
|
|
6164
|
+
}
|
|
6165
|
+
}
|
|
6166
|
+
const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
|
|
5957
6167
|
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
5958
|
-
this.
|
|
6168
|
+
this.fileEntries = new Map(entries.map(entry => {
|
|
5959
6169
|
const {
|
|
5960
6170
|
version,
|
|
5961
6171
|
rawLastModDate,
|
|
@@ -6010,11 +6220,12 @@ class ZipWriter {
|
|
|
6010
6220
|
if (crc32 !== UNDEFINED_VALUE) {
|
|
6011
6221
|
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6012
6222
|
}
|
|
6223
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6013
6224
|
Object.assign(entry, {
|
|
6014
6225
|
zip64UncompressedSize,
|
|
6015
6226
|
zip64CompressedSize,
|
|
6016
|
-
|
|
6017
|
-
diskNumberStart
|
|
6227
|
+
offset,
|
|
6228
|
+
diskNumberStart,
|
|
6018
6229
|
zip64DiskNumberStart: false,
|
|
6019
6230
|
rawExtraFieldZip64,
|
|
6020
6231
|
rawExtraFieldAES,
|
|
@@ -6034,11 +6245,8 @@ class ZipWriter {
|
|
|
6034
6245
|
async add(name = "", reader, options = {}) {
|
|
6035
6246
|
const zipWriter = this;
|
|
6036
6247
|
options = Object.assign({}, options);
|
|
6037
|
-
const {
|
|
6038
|
-
|
|
6039
|
-
config
|
|
6040
|
-
} = zipWriter;
|
|
6041
|
-
if (workers < config.maxWorkers) {
|
|
6248
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
6249
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
6042
6250
|
workers++;
|
|
6043
6251
|
} else {
|
|
6044
6252
|
await new Promise(resolve => pendingEntries.push(resolve));
|
|
@@ -6075,16 +6283,16 @@ class ZipWriter {
|
|
|
6075
6283
|
}
|
|
6076
6284
|
|
|
6077
6285
|
remove(entry) {
|
|
6078
|
-
const { filenames,
|
|
6286
|
+
const { filenames, fileEntries } = this;
|
|
6079
6287
|
// deno-lint-ignore valid-typeof
|
|
6080
6288
|
if (typeof entry == STRING_TYPE) {
|
|
6081
|
-
entry =
|
|
6289
|
+
entry = fileEntries.get(entry);
|
|
6082
6290
|
}
|
|
6083
6291
|
if (entry && entry.filename !== UNDEFINED_VALUE) {
|
|
6084
6292
|
const { filename } = entry;
|
|
6085
|
-
if (filenames.has(filename) &&
|
|
6293
|
+
if (filenames.has(filename) && fileEntries.has(filename)) {
|
|
6086
6294
|
filenames.delete(filename);
|
|
6087
|
-
|
|
6295
|
+
fileEntries.delete(filename);
|
|
6088
6296
|
return true;
|
|
6089
6297
|
}
|
|
6090
6298
|
}
|
|
@@ -6095,6 +6303,9 @@ class ZipWriter {
|
|
|
6095
6303
|
const zipWriter = this;
|
|
6096
6304
|
const { pendingAddFileCalls, writer } = this;
|
|
6097
6305
|
const { writable } = writer;
|
|
6306
|
+
if (!(comment instanceof Uint8Array)) {
|
|
6307
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
6308
|
+
}
|
|
6098
6309
|
if (getLength(comment) > MAX_16_BITS) {
|
|
6099
6310
|
throw new Error(ERR_INVALID_COMMENT);
|
|
6100
6311
|
}
|
|
@@ -6178,12 +6389,12 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
6178
6389
|
const metadataInfo = resolveMetadata(zipWriter, name, options);
|
|
6179
6390
|
const { comment } = metadataInfo;
|
|
6180
6391
|
const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
|
|
6181
|
-
zipWriter.
|
|
6392
|
+
zipWriter.fileEntries.set(name, UNDEFINED_VALUE);
|
|
6182
6393
|
let fileEntry;
|
|
6183
6394
|
try {
|
|
6184
6395
|
const { resolvedOptions } = metadataInfo;
|
|
6185
6396
|
if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
|
|
6186
|
-
!resolvedOptions.passThrough && !(await supportsDeflate(
|
|
6397
|
+
!resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
|
|
6187
6398
|
resolvedOptions.level = 0;
|
|
6188
6399
|
}
|
|
6189
6400
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
@@ -6191,8 +6402,6 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
6191
6402
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
6192
6403
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
6193
6404
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
6194
|
-
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
6195
|
-
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
6196
6405
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
6197
6406
|
crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
|
|
6198
6407
|
offset: zipWriter.offset - diskOffset,
|
|
@@ -6203,17 +6412,23 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
6203
6412
|
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
6204
6413
|
fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
|
|
6205
6414
|
} catch (error) {
|
|
6206
|
-
zipWriter.
|
|
6415
|
+
zipWriter.fileEntries.delete(name);
|
|
6207
6416
|
throw error;
|
|
6208
6417
|
}
|
|
6209
|
-
Object.assign(fileEntry, {
|
|
6418
|
+
Object.assign(fileEntry, {
|
|
6419
|
+
name,
|
|
6420
|
+
comment,
|
|
6421
|
+
extraField,
|
|
6422
|
+
[PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
|
|
6423
|
+
[PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
|
|
6424
|
+
});
|
|
6210
6425
|
return new Entry(fileEntry);
|
|
6211
6426
|
}
|
|
6212
6427
|
|
|
6213
6428
|
function resolveAttributes(zipWriter, name, options) {
|
|
6214
6429
|
name = name.trim();
|
|
6215
6430
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
6216
|
-
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ?
|
|
6431
|
+
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
6217
6432
|
const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
|
|
6218
6433
|
const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
|
|
6219
6434
|
const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
|
|
@@ -6241,21 +6456,21 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
6241
6456
|
if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
6242
6457
|
unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
|
|
6243
6458
|
}
|
|
6244
|
-
let msdosAttributesRaw =
|
|
6459
|
+
let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
|
|
6245
6460
|
let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
|
|
6246
|
-
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
|
|
6461
|
+
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType || executable;
|
|
6247
6462
|
const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
|
|
6248
6463
|
if (hasUnixMetadata) {
|
|
6249
6464
|
msDosCompatible = false;
|
|
6250
|
-
versionMadeBy = (versionMadeBy &
|
|
6465
|
+
versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
|
|
6251
6466
|
} else if (hasMsDosProvided) {
|
|
6252
6467
|
msDosCompatible = true;
|
|
6253
6468
|
versionMadeBy = (versionMadeBy & MAX_8_BITS);
|
|
6254
6469
|
}
|
|
6255
|
-
if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
6470
|
+
if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
6256
6471
|
throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
|
|
6257
6472
|
}
|
|
6258
|
-
if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
|
|
6473
|
+
if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
|
|
6259
6474
|
throw new Error(ERR_INVALID_MSDOS_DATA);
|
|
6260
6475
|
}
|
|
6261
6476
|
if (versionMadeBy > MAX_16_BITS) {
|
|
@@ -6287,11 +6502,10 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
6287
6502
|
externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
|
|
6288
6503
|
}
|
|
6289
6504
|
}
|
|
6290
|
-
let unixExternalUpper;
|
|
6291
6505
|
if (!msDosCompatible) {
|
|
6292
6506
|
const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
|
|
6293
|
-
|
|
6294
|
-
unixMode = unixMode === UNDEFINED_VALUE ?
|
|
6507
|
+
const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
6508
|
+
unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
|
|
6295
6509
|
if (setuid) {
|
|
6296
6510
|
unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
|
|
6297
6511
|
} else {
|
|
@@ -6320,17 +6534,20 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
6320
6534
|
if (hasMsDosProvided) {
|
|
6321
6535
|
externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
|
|
6322
6536
|
}
|
|
6537
|
+
const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
6538
|
+
const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
|
|
6323
6539
|
return {
|
|
6324
6540
|
name,
|
|
6325
6541
|
resolvedOptions: {
|
|
6326
6542
|
versionMadeBy,
|
|
6327
|
-
msDosCompatible,
|
|
6543
|
+
msDosCompatible: Boolean(msDosCompatible),
|
|
6328
6544
|
externalFileAttributes,
|
|
6329
6545
|
unixExternalUpper,
|
|
6330
6546
|
uid,
|
|
6331
6547
|
gid,
|
|
6332
6548
|
unixMode,
|
|
6333
6549
|
unixExtraFieldType,
|
|
6550
|
+
symlink,
|
|
6334
6551
|
setuid,
|
|
6335
6552
|
setgid,
|
|
6336
6553
|
sticky,
|
|
@@ -6341,7 +6558,7 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
6341
6558
|
}
|
|
6342
6559
|
|
|
6343
6560
|
function resolveMetadata(zipWriter, name, options) {
|
|
6344
|
-
const encode =
|
|
6561
|
+
const encode = getFunctionOptionValue(zipWriter, options, OPTION_ENCODE_TEXT) || encodeText;
|
|
6345
6562
|
let rawFilename = encode(name, TEXT_TYPE_FILENAME);
|
|
6346
6563
|
if (rawFilename === UNDEFINED_VALUE) {
|
|
6347
6564
|
rawFilename = encodeText(name);
|
|
@@ -6350,6 +6567,10 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
6350
6567
|
throw new Error(ERR_INVALID_ENTRY_NAME);
|
|
6351
6568
|
}
|
|
6352
6569
|
const comment = options[PROPERTY_NAME_COMMENT] || "";
|
|
6570
|
+
// deno-lint-ignore valid-typeof
|
|
6571
|
+
if (typeof comment != STRING_TYPE) {
|
|
6572
|
+
throw new Error(ERR_INVALID_ENTRY_COMMENT_TYPE);
|
|
6573
|
+
}
|
|
6353
6574
|
let rawComment = encode(comment, TEXT_TYPE_COMMENT);
|
|
6354
6575
|
if (rawComment === UNDEFINED_VALUE) {
|
|
6355
6576
|
rawComment = encodeText(comment);
|
|
@@ -6361,16 +6582,14 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
6361
6582
|
if (version > MAX_16_BITS) {
|
|
6362
6583
|
throw new Error(ERR_INVALID_VERSION);
|
|
6363
6584
|
}
|
|
6364
|
-
const lastModDate =
|
|
6365
|
-
const lastAccessDate =
|
|
6366
|
-
const creationDate =
|
|
6585
|
+
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
6586
|
+
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6587
|
+
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6367
6588
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
6368
6589
|
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
6369
6590
|
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
6370
6591
|
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
6371
|
-
|
|
6372
|
-
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
6373
|
-
}
|
|
6592
|
+
checkPasswordOption(password, rawPassword);
|
|
6374
6593
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
6375
6594
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
6376
6595
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
@@ -6379,9 +6598,9 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
6379
6598
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
6380
6599
|
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
6381
6600
|
const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
|
|
6382
|
-
const createTempStream =
|
|
6601
|
+
const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
6383
6602
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
6384
|
-
const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
|
|
6603
|
+
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
6385
6604
|
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
|
|
6386
6605
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
6387
6606
|
const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
@@ -6461,18 +6680,26 @@ function serializeExtraField(extraField) {
|
|
|
6461
6680
|
if (!extraField) {
|
|
6462
6681
|
return EMPTY_UINT8_ARRAY;
|
|
6463
6682
|
}
|
|
6683
|
+
if (!(extraField instanceof Map)) {
|
|
6684
|
+
throw new Error(ERR_INVALID_EXTRAFIELD);
|
|
6685
|
+
}
|
|
6464
6686
|
let extraFieldSize = 0;
|
|
6465
6687
|
let offset = 0;
|
|
6466
|
-
extraField.forEach(data => extraFieldSize += 4 + getLength(data));
|
|
6467
|
-
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
6468
|
-
const rawExtraFieldView = getDataView(rawExtraField);
|
|
6469
6688
|
extraField.forEach((data, type) => {
|
|
6470
|
-
if (type > MAX_16_BITS) {
|
|
6689
|
+
if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
|
|
6471
6690
|
throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
|
|
6472
6691
|
}
|
|
6692
|
+
if (!(data instanceof Uint8Array)) {
|
|
6693
|
+
throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
|
|
6694
|
+
}
|
|
6473
6695
|
if (getLength(data) > MAX_16_BITS) {
|
|
6474
6696
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
6475
6697
|
}
|
|
6698
|
+
extraFieldSize += 4 + getLength(data);
|
|
6699
|
+
});
|
|
6700
|
+
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
6701
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
6702
|
+
extraField.forEach((data, type) => {
|
|
6476
6703
|
setUint16(rawExtraFieldView, offset, type);
|
|
6477
6704
|
setUint16(rawExtraFieldView, offset + 2, getLength(data));
|
|
6478
6705
|
arraySet(rawExtraField, data, offset + 4);
|
|
@@ -6559,10 +6786,13 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
6559
6786
|
}
|
|
6560
6787
|
|
|
6561
6788
|
async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
|
|
6562
|
-
const zipWriter = { options: writerOptions
|
|
6563
|
-
if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
|
|
6789
|
+
const zipWriter = { options: writerOptions };
|
|
6790
|
+
if (checkFunctionOption(writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY])) {
|
|
6564
6791
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
6565
6792
|
}
|
|
6793
|
+
if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
|
|
6794
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
6795
|
+
}
|
|
6566
6796
|
const commentLength = getLength(comment);
|
|
6567
6797
|
if (commentLength > MAX_16_BITS) {
|
|
6568
6798
|
throw new Error(ERR_INVALID_COMMENT);
|
|
@@ -6583,7 +6813,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
6583
6813
|
({ name } = attributesInfo);
|
|
6584
6814
|
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
6585
6815
|
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
6586
|
-
!metadata.passThrough && !(await supportsDeflate(
|
|
6816
|
+
!metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
|
|
6587
6817
|
metadata.level = 0;
|
|
6588
6818
|
}
|
|
6589
6819
|
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
@@ -6632,7 +6862,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
6632
6862
|
|
|
6633
6863
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
6634
6864
|
const {
|
|
6635
|
-
|
|
6865
|
+
fileEntries,
|
|
6636
6866
|
writer
|
|
6637
6867
|
} = zipWriter;
|
|
6638
6868
|
const {
|
|
@@ -6654,12 +6884,12 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
6654
6884
|
let writerSizeBeforeEntry;
|
|
6655
6885
|
let flushedBufferedSize = 0;
|
|
6656
6886
|
let fileWriter;
|
|
6657
|
-
|
|
6887
|
+
fileEntries.set(name, fileEntry);
|
|
6658
6888
|
zipWriter.lastFileEntry = fileEntry;
|
|
6659
6889
|
try {
|
|
6660
6890
|
let lockPreviousFileEntry;
|
|
6661
6891
|
if (keepOrder) {
|
|
6662
|
-
lockPreviousFileEntry = previousFileEntry && previousFileEntry.
|
|
6892
|
+
lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
|
|
6663
6893
|
requestLockCurrentFileEntry();
|
|
6664
6894
|
}
|
|
6665
6895
|
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
|
|
@@ -6680,11 +6910,8 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
6680
6910
|
const diskOffset = getDiskOffset(writer);
|
|
6681
6911
|
if (zipWriter.addSplitZipSignature) {
|
|
6682
6912
|
delete zipWriter.addSplitZipSignature;
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
6686
|
-
await writeData(writer, signatureArray);
|
|
6687
|
-
zipWriter.offset += 4;
|
|
6913
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
6914
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6688
6915
|
}
|
|
6689
6916
|
if (usdz && !bufferedWrite) {
|
|
6690
6917
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -6702,11 +6929,11 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
6702
6929
|
writerSizeBeforeEntry = writer.size;
|
|
6703
6930
|
await writeData(fileWriter, localHeaderArray);
|
|
6704
6931
|
}
|
|
6705
|
-
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo,
|
|
6932
|
+
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, getConfiguration(), options);
|
|
6706
6933
|
if (!bufferedWrite) {
|
|
6707
6934
|
writingEntryData = false;
|
|
6708
6935
|
}
|
|
6709
|
-
|
|
6936
|
+
fileEntries.set(name, fileEntry);
|
|
6710
6937
|
fileEntry.filename = name;
|
|
6711
6938
|
if (bufferedWrite) {
|
|
6712
6939
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
@@ -6747,7 +6974,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
6747
6974
|
zipWriter.offset += flushedBufferedSize;
|
|
6748
6975
|
}
|
|
6749
6976
|
}
|
|
6750
|
-
|
|
6977
|
+
fileEntries.delete(name);
|
|
6751
6978
|
throw error;
|
|
6752
6979
|
} finally {
|
|
6753
6980
|
if (bufferedWrite) {
|
|
@@ -6769,7 +6996,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
6769
6996
|
}
|
|
6770
6997
|
|
|
6771
6998
|
function requestLockCurrentFileEntry() {
|
|
6772
|
-
fileEntry.
|
|
6999
|
+
fileEntry.lockFileEntry = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
|
|
6773
7000
|
}
|
|
6774
7001
|
|
|
6775
7002
|
async function requestLockWriter() {
|
|
@@ -6789,7 +7016,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
6789
7016
|
}
|
|
6790
7017
|
}
|
|
6791
7018
|
|
|
6792
|
-
async function createFileEntry(reader, writer, { diskNumberStart,
|
|
7019
|
+
async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry }, entryInfo, config, options) {
|
|
6793
7020
|
const {
|
|
6794
7021
|
headerInfo,
|
|
6795
7022
|
dataDescriptorInfo,
|
|
@@ -6844,6 +7071,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
6844
7071
|
uid,
|
|
6845
7072
|
gid,
|
|
6846
7073
|
unixMode,
|
|
7074
|
+
symlink,
|
|
6847
7075
|
setuid,
|
|
6848
7076
|
setgid,
|
|
6849
7077
|
sticky,
|
|
@@ -6856,7 +7084,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
6856
7084
|
codecURI
|
|
6857
7085
|
} = options;
|
|
6858
7086
|
const fileEntry = {
|
|
6859
|
-
|
|
7087
|
+
lockFileEntry,
|
|
6860
7088
|
versionMadeBy,
|
|
6861
7089
|
zip64,
|
|
6862
7090
|
directory: Boolean(directory),
|
|
@@ -6880,6 +7108,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
6880
7108
|
uid,
|
|
6881
7109
|
gid,
|
|
6882
7110
|
unixMode,
|
|
7111
|
+
symlink: Boolean(symlink),
|
|
6883
7112
|
setuid,
|
|
6884
7113
|
setgid,
|
|
6885
7114
|
sticky,
|
|
@@ -6897,7 +7126,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
6897
7126
|
}
|
|
6898
7127
|
const { writable } = writer;
|
|
6899
7128
|
if (reader) {
|
|
6900
|
-
const readable = toCompatibleReadable(
|
|
7129
|
+
const readable = toCompatibleReadable(createReadable(reader));
|
|
6901
7130
|
const size = reader.size;
|
|
6902
7131
|
const workerOptions = {
|
|
6903
7132
|
options: {
|
|
@@ -6960,8 +7189,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
6960
7189
|
rawLastModDate,
|
|
6961
7190
|
creationDate,
|
|
6962
7191
|
lastAccessDate,
|
|
6963
|
-
encrypted,
|
|
6964
|
-
zipCrypto,
|
|
7192
|
+
encrypted: Boolean(encrypted),
|
|
7193
|
+
zipCrypto: Boolean(zipCrypto),
|
|
6965
7194
|
size: metadataSize + compressedSize,
|
|
6966
7195
|
compressionMethod,
|
|
6967
7196
|
version,
|
|
@@ -7009,14 +7238,14 @@ function getHeaderInfo(options) {
|
|
|
7009
7238
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
7010
7239
|
const length = 4 + 16;
|
|
7011
7240
|
const extraFieldZip64 = createRecordWriter(length);
|
|
7012
|
-
extraFieldZip64.
|
|
7013
|
-
extraFieldZip64.
|
|
7241
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
7242
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
7014
7243
|
rawLocalExtraFieldZip64 = extraFieldZip64.array;
|
|
7015
7244
|
if (zip64ExtraFieldComplete) {
|
|
7016
|
-
extraFieldZip64.
|
|
7245
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
7017
7246
|
if (uncompressedFile) {
|
|
7018
7247
|
const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
7019
|
-
extraFieldZip64.
|
|
7248
|
+
extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
|
|
7020
7249
|
}
|
|
7021
7250
|
}
|
|
7022
7251
|
} else {
|
|
@@ -7025,8 +7254,8 @@ function getHeaderInfo(options) {
|
|
|
7025
7254
|
let rawExtraFieldAES;
|
|
7026
7255
|
if (encrypted && !zipCrypto) {
|
|
7027
7256
|
const extraFieldAES = createRecordWriter(getLength(EXTRAFIELD_DATA_AES) + 2);
|
|
7028
|
-
extraFieldAES.
|
|
7029
|
-
extraFieldAES.
|
|
7257
|
+
extraFieldAES.writeUint16(EXTRAFIELD_TYPE_AES);
|
|
7258
|
+
extraFieldAES.writeBytes(EXTRAFIELD_DATA_AES);
|
|
7030
7259
|
rawExtraFieldAES = extraFieldAES.array;
|
|
7031
7260
|
rawExtraFieldAES[8] = encryptionStrength;
|
|
7032
7261
|
} else {
|
|
@@ -7042,15 +7271,15 @@ function getHeaderInfo(options) {
|
|
|
7042
7271
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
7043
7272
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
7044
7273
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
7045
|
-
extraFieldTimestamp.
|
|
7046
|
-
extraFieldTimestamp.
|
|
7047
|
-
extraFieldTimestamp.
|
|
7048
|
-
extraFieldTimestamp.
|
|
7274
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7275
|
+
extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
|
|
7276
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7277
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
7049
7278
|
if (lastAccessDate) {
|
|
7050
|
-
extraFieldTimestamp.
|
|
7279
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(lastAccessDate)));
|
|
7051
7280
|
}
|
|
7052
7281
|
if (creationDate) {
|
|
7053
|
-
extraFieldTimestamp.
|
|
7282
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(creationDate)));
|
|
7054
7283
|
}
|
|
7055
7284
|
rawExtraFieldExtendedTimestamp = extraFieldTimestamp.array;
|
|
7056
7285
|
} else {
|
|
@@ -7063,14 +7292,14 @@ function getHeaderInfo(options) {
|
|
|
7063
7292
|
try {
|
|
7064
7293
|
const lastModTimeNTFS = getTimeNTFS(lastModDate);
|
|
7065
7294
|
const extraFieldNTFS = createRecordWriter(36);
|
|
7066
|
-
extraFieldNTFS.
|
|
7067
|
-
extraFieldNTFS.
|
|
7295
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS);
|
|
7296
|
+
extraFieldNTFS.writeUint16(32);
|
|
7068
7297
|
extraFieldNTFS.skip(4);
|
|
7069
|
-
extraFieldNTFS.
|
|
7070
|
-
extraFieldNTFS.
|
|
7071
|
-
extraFieldNTFS.
|
|
7072
|
-
extraFieldNTFS.
|
|
7073
|
-
extraFieldNTFS.
|
|
7298
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS_TAG1);
|
|
7299
|
+
extraFieldNTFS.writeUint16(24);
|
|
7300
|
+
extraFieldNTFS.writeUint64(lastModTimeNTFS);
|
|
7301
|
+
extraFieldNTFS.writeUint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
|
|
7302
|
+
extraFieldNTFS.writeUint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
|
|
7074
7303
|
rawExtraFieldNTFS = extraFieldNTFS.array;
|
|
7075
7304
|
} catch {
|
|
7076
7305
|
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
@@ -7089,20 +7318,20 @@ function getHeaderInfo(options) {
|
|
|
7089
7318
|
const gidBytes = packUnixId(gid);
|
|
7090
7319
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
7091
7320
|
const extraFieldUnix = createRecordWriter(4 + payloadLength);
|
|
7092
|
-
extraFieldUnix.
|
|
7093
|
-
extraFieldUnix.
|
|
7094
|
-
extraFieldUnix.
|
|
7095
|
-
extraFieldUnix.
|
|
7096
|
-
extraFieldUnix.
|
|
7097
|
-
extraFieldUnix.
|
|
7098
|
-
extraFieldUnix.
|
|
7321
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
|
|
7322
|
+
extraFieldUnix.writeUint16(payloadLength);
|
|
7323
|
+
extraFieldUnix.writeUint8(1);
|
|
7324
|
+
extraFieldUnix.writeUint8(uidBytes.length);
|
|
7325
|
+
extraFieldUnix.writeBytes(uidBytes);
|
|
7326
|
+
extraFieldUnix.writeUint8(gidBytes.length);
|
|
7327
|
+
extraFieldUnix.writeBytes(gidBytes);
|
|
7099
7328
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
7100
7329
|
} else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
7101
7330
|
const extraFieldUnix = createRecordWriter(8);
|
|
7102
|
-
extraFieldUnix.
|
|
7103
|
-
extraFieldUnix.
|
|
7104
|
-
extraFieldUnix.
|
|
7105
|
-
extraFieldUnix.
|
|
7331
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
|
|
7332
|
+
extraFieldUnix.writeUint16(4);
|
|
7333
|
+
extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
|
|
7334
|
+
extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
|
|
7106
7335
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
7107
7336
|
} else {
|
|
7108
7337
|
rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
|
|
@@ -7152,18 +7381,18 @@ function getHeaderInfo(options) {
|
|
|
7152
7381
|
const localHeader = createRecordWriter(HEADER_SIZE + getLength(rawFilename) + extraFieldLength);
|
|
7153
7382
|
const localHeaderArray = localHeader.array;
|
|
7154
7383
|
const localHeaderView = getDataView(localHeaderArray);
|
|
7155
|
-
localHeader.
|
|
7156
|
-
localHeader.
|
|
7157
|
-
localHeader.
|
|
7384
|
+
localHeader.writeUint32(LOCAL_FILE_HEADER_SIGNATURE);
|
|
7385
|
+
localHeader.writeBytes(headerArray);
|
|
7386
|
+
localHeader.writeBytes(rawFilename);
|
|
7158
7387
|
if (writeLocalExtraFieldZip64) {
|
|
7159
|
-
localHeader.
|
|
7160
|
-
}
|
|
7161
|
-
localHeader.
|
|
7162
|
-
localHeader.
|
|
7163
|
-
localHeader.
|
|
7164
|
-
localHeader.
|
|
7165
|
-
localHeader.
|
|
7166
|
-
localHeader.
|
|
7388
|
+
localHeader.writeBytes(rawLocalExtraFieldZip64);
|
|
7389
|
+
}
|
|
7390
|
+
localHeader.writeBytes(rawExtraFieldAES);
|
|
7391
|
+
localHeader.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
7392
|
+
localHeader.writeBytes(rawExtraFieldNTFS);
|
|
7393
|
+
localHeader.writeBytes(rawExtraFieldUnix);
|
|
7394
|
+
localHeader.writeBytes(rawExtraField);
|
|
7395
|
+
localHeader.writeBytes(rawLocalExtraField);
|
|
7167
7396
|
if (dataDescriptor) {
|
|
7168
7397
|
if (!zip64CompressedSize) {
|
|
7169
7398
|
setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, 0);
|
|
@@ -7353,7 +7582,7 @@ function updateLocalHeader({
|
|
|
7353
7582
|
|
|
7354
7583
|
|
|
7355
7584
|
async function closeFile(zipWriter, comment, options) {
|
|
7356
|
-
const directoryDataLength = createDirectoryRecords(zipWriter.
|
|
7585
|
+
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
7357
7586
|
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7358
7587
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
7359
7588
|
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
@@ -7383,19 +7612,19 @@ function createDirectoryRecords(files) {
|
|
|
7383
7612
|
if (zip64Offset || zip64DiskNumberStart || zip64UncompressedSize || zip64CompressedSize) {
|
|
7384
7613
|
const length = 4 + (zip64UncompressedSize ? 8 : 0) + (zip64CompressedSize ? 8 : 0) + (zip64Offset ? 8 : 0) + (zip64DiskNumberStart ? 4 : 0);
|
|
7385
7614
|
const extraFieldZip64 = createRecordWriter(length);
|
|
7386
|
-
extraFieldZip64.
|
|
7387
|
-
extraFieldZip64.
|
|
7615
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
7616
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
7388
7617
|
if (zip64UncompressedSize) {
|
|
7389
|
-
extraFieldZip64.
|
|
7618
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
7390
7619
|
}
|
|
7391
7620
|
if (zip64CompressedSize) {
|
|
7392
|
-
extraFieldZip64.
|
|
7621
|
+
extraFieldZip64.writeUint64(compressedSize);
|
|
7393
7622
|
}
|
|
7394
7623
|
if (zip64Offset) {
|
|
7395
|
-
extraFieldZip64.
|
|
7624
|
+
extraFieldZip64.writeUint64(fileEntry.offset);
|
|
7396
7625
|
}
|
|
7397
7626
|
if (zip64DiskNumberStart) {
|
|
7398
|
-
extraFieldZip64.
|
|
7627
|
+
extraFieldZip64.writeUint32(fileEntry.diskNumberStart);
|
|
7399
7628
|
}
|
|
7400
7629
|
rawExtraFieldZip64 = extraFieldZip64.array;
|
|
7401
7630
|
} else {
|
|
@@ -7408,10 +7637,10 @@ function createDirectoryRecords(files) {
|
|
|
7408
7637
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
7409
7638
|
if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
|
|
7410
7639
|
const extraFieldTimestamp = createRecordWriter(9);
|
|
7411
|
-
extraFieldTimestamp.
|
|
7412
|
-
extraFieldTimestamp.
|
|
7413
|
-
extraFieldTimestamp.
|
|
7414
|
-
extraFieldTimestamp.
|
|
7640
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7641
|
+
extraFieldTimestamp.writeUint16(5);
|
|
7642
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7643
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
7415
7644
|
rawExtraFieldTimestamp = extraFieldTimestamp.array;
|
|
7416
7645
|
} else {
|
|
7417
7646
|
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
@@ -7433,14 +7662,14 @@ function createDirectoryRecords(files) {
|
|
|
7433
7662
|
}
|
|
7434
7663
|
|
|
7435
7664
|
async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
7436
|
-
const {
|
|
7665
|
+
const { fileEntries, writer } = zipWriter;
|
|
7437
7666
|
const directoryArray = new Uint8Array(directoryDataLength);
|
|
7438
7667
|
await initStream(writer);
|
|
7439
7668
|
let offset = 0;
|
|
7440
7669
|
let directoryDiskOffset = 0;
|
|
7441
7670
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
7442
7671
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
7443
|
-
for (const [indexFileEntry, fileEntry] of Array.from(
|
|
7672
|
+
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
7444
7673
|
const {
|
|
7445
7674
|
offset: fileEntryOffset,
|
|
7446
7675
|
rawFilename,
|
|
@@ -7485,28 +7714,28 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
7485
7714
|
setUint16(headerView, HEADER_OFFSET_VERSION, VERSION_ZIP64);
|
|
7486
7715
|
}
|
|
7487
7716
|
const directoryRecord = createRecordWriter(directoryRecordLength);
|
|
7488
|
-
directoryRecord.
|
|
7489
|
-
directoryRecord.
|
|
7490
|
-
directoryRecord.
|
|
7491
|
-
directoryRecord.
|
|
7492
|
-
directoryRecord.
|
|
7493
|
-
directoryRecord.
|
|
7494
|
-
directoryRecord.
|
|
7495
|
-
directoryRecord.
|
|
7496
|
-
directoryRecord.
|
|
7497
|
-
directoryRecord.
|
|
7498
|
-
directoryRecord.
|
|
7499
|
-
directoryRecord.
|
|
7500
|
-
directoryRecord.
|
|
7501
|
-
directoryRecord.
|
|
7502
|
-
directoryRecord.
|
|
7503
|
-
directoryRecord.
|
|
7504
|
-
directoryRecord.
|
|
7717
|
+
directoryRecord.writeUint32(CENTRAL_FILE_HEADER_SIGNATURE);
|
|
7718
|
+
directoryRecord.writeUint16(versionMadeBy);
|
|
7719
|
+
directoryRecord.writeBytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
|
|
7720
|
+
directoryRecord.writeUint16(extraFieldLength);
|
|
7721
|
+
directoryRecord.writeUint16(getLength(rawComment));
|
|
7722
|
+
directoryRecord.writeUint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
|
|
7723
|
+
directoryRecord.writeUint16(internalFileAttributes);
|
|
7724
|
+
directoryRecord.writeUint32(externalFileAttributes);
|
|
7725
|
+
directoryRecord.writeUint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
|
|
7726
|
+
directoryRecord.writeBytes(rawFilename);
|
|
7727
|
+
directoryRecord.writeBytes(rawExtraFieldZip64);
|
|
7728
|
+
directoryRecord.writeBytes(rawExtraFieldAES);
|
|
7729
|
+
directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
7730
|
+
directoryRecord.writeBytes(rawExtraFieldNTFS);
|
|
7731
|
+
directoryRecord.writeBytes(rawExtraFieldUnix);
|
|
7732
|
+
directoryRecord.writeBytes(rawExtraField);
|
|
7733
|
+
directoryRecord.writeBytes(rawComment);
|
|
7505
7734
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
7506
7735
|
offset += directoryRecordLength;
|
|
7507
7736
|
if (options.onprogress) {
|
|
7508
7737
|
try {
|
|
7509
|
-
await options.onprogress(indexFileEntry + 1,
|
|
7738
|
+
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
7510
7739
|
} catch {
|
|
7511
7740
|
// ignored
|
|
7512
7741
|
}
|
|
@@ -7520,7 +7749,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
7520
7749
|
}
|
|
7521
7750
|
|
|
7522
7751
|
async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
7523
|
-
const signCentralDirectory =
|
|
7752
|
+
const signCentralDirectory = getFunctionOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
|
|
7524
7753
|
if (signCentralDirectory) {
|
|
7525
7754
|
const signatureData = await signCentralDirectory(directoryArray);
|
|
7526
7755
|
const signatureDataLength = getLength(signatureData);
|
|
@@ -7528,9 +7757,9 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
|
7528
7757
|
throw new Error(ERR_INVALID_SIGNATURE_DATA);
|
|
7529
7758
|
}
|
|
7530
7759
|
const signatureRecord = createRecordWriter(6 + signatureDataLength);
|
|
7531
|
-
signatureRecord.
|
|
7532
|
-
signatureRecord.
|
|
7533
|
-
signatureRecord.
|
|
7760
|
+
signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
|
|
7761
|
+
signatureRecord.writeUint16(signatureDataLength);
|
|
7762
|
+
signatureRecord.writeBytes(signatureData);
|
|
7534
7763
|
await writeData(zipWriter.writer, signatureRecord.array);
|
|
7535
7764
|
return 6 + signatureDataLength;
|
|
7536
7765
|
}
|
|
@@ -7541,7 +7770,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
7541
7770
|
const { writer } = zipWriter;
|
|
7542
7771
|
const { directoryStart, signatureLength } = cdInfo;
|
|
7543
7772
|
let { directoryDataLength } = cdInfo;
|
|
7544
|
-
let
|
|
7773
|
+
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
7545
7774
|
let diskNumber = directoryStart.diskNumber;
|
|
7546
7775
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
7547
7776
|
let lastDiskNumber = getDiskNumber(writer);
|
|
@@ -7549,7 +7778,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
7549
7778
|
lastDiskNumber++;
|
|
7550
7779
|
}
|
|
7551
7780
|
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7552
|
-
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS ||
|
|
7781
|
+
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
7553
7782
|
if (zip64 === false) {
|
|
7554
7783
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
7555
7784
|
} else {
|
|
@@ -7566,37 +7795,37 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
7566
7795
|
}
|
|
7567
7796
|
lastDiskNumber = getDiskNumber(writer);
|
|
7568
7797
|
if (zip64) {
|
|
7569
|
-
endOfdirectoryRecord.
|
|
7570
|
-
endOfdirectoryRecord.
|
|
7571
|
-
endOfdirectoryRecord.
|
|
7572
|
-
endOfdirectoryRecord.
|
|
7573
|
-
endOfdirectoryRecord.
|
|
7574
|
-
endOfdirectoryRecord.
|
|
7575
|
-
endOfdirectoryRecord.
|
|
7576
|
-
endOfdirectoryRecord.
|
|
7577
|
-
endOfdirectoryRecord.
|
|
7578
|
-
endOfdirectoryRecord.
|
|
7579
|
-
endOfdirectoryRecord.
|
|
7580
|
-
endOfdirectoryRecord.
|
|
7581
|
-
endOfdirectoryRecord.
|
|
7582
|
-
endOfdirectoryRecord.
|
|
7798
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7799
|
+
endOfdirectoryRecord.writeUint64(44);
|
|
7800
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
7801
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
7802
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7803
|
+
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
7804
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7805
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7806
|
+
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
7807
|
+
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
7808
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
7809
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7810
|
+
endOfdirectoryRecord.writeUint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
|
|
7811
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber + 1);
|
|
7583
7812
|
const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
|
|
7584
7813
|
if (supportZip64SplitFile) {
|
|
7585
7814
|
lastDiskNumber = MAX_16_BITS;
|
|
7586
7815
|
diskNumber = MAX_16_BITS;
|
|
7587
7816
|
}
|
|
7588
|
-
|
|
7817
|
+
fileEntriesLength = MAX_16_BITS;
|
|
7589
7818
|
directoryOffset = MAX_32_BITS;
|
|
7590
7819
|
directoryDataLength = MAX_32_BITS;
|
|
7591
7820
|
}
|
|
7592
|
-
endOfdirectoryRecord.
|
|
7593
|
-
endOfdirectoryRecord.
|
|
7594
|
-
endOfdirectoryRecord.
|
|
7595
|
-
endOfdirectoryRecord.
|
|
7596
|
-
endOfdirectoryRecord.
|
|
7597
|
-
endOfdirectoryRecord.
|
|
7598
|
-
endOfdirectoryRecord.
|
|
7599
|
-
endOfdirectoryRecord.
|
|
7821
|
+
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7822
|
+
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
7823
|
+
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
7824
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7825
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7826
|
+
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
7827
|
+
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
7828
|
+
endOfdirectoryRecord.writeUint16(commentLength);
|
|
7600
7829
|
await writeData(writer, endOfdirectoryRecord.array);
|
|
7601
7830
|
if (commentLength) {
|
|
7602
7831
|
await writeData(writer, comment);
|
|
@@ -7609,11 +7838,11 @@ function createRecordWriter(length) {
|
|
|
7609
7838
|
let offset = 0;
|
|
7610
7839
|
return {
|
|
7611
7840
|
array,
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7841
|
+
writeUint8: value => { setUint8(view, offset, value); offset += 1; },
|
|
7842
|
+
writeUint16: value => { setUint16(view, offset, value); offset += 2; },
|
|
7843
|
+
writeUint32: value => { setUint32(view, offset, value); offset += 4; },
|
|
7844
|
+
writeUint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
|
|
7845
|
+
writeBytes: value => { arraySet(array, value, offset); offset += getLength(value); },
|
|
7617
7846
|
skip: count => offset += count
|
|
7618
7847
|
};
|
|
7619
7848
|
}
|
|
@@ -7637,6 +7866,71 @@ function getSegmentOffset(zipWriter, { diskNumber = 0, diskOffset = 0 }) {
|
|
|
7637
7866
|
return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
|
|
7638
7867
|
}
|
|
7639
7868
|
|
|
7869
|
+
async function startsWithSplitZipSignature(reader) {
|
|
7870
|
+
const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
7871
|
+
return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
7872
|
+
}
|
|
7873
|
+
|
|
7874
|
+
async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
|
|
7875
|
+
const { writer } = zipWriter;
|
|
7876
|
+
const entryPositions = new Map();
|
|
7877
|
+
if (writer.closeDisk) {
|
|
7878
|
+
const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
|
|
7879
|
+
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
7880
|
+
let copiedLength = 0;
|
|
7881
|
+
for (const entry of sortedEntries) {
|
|
7882
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
7883
|
+
await copyData(zipWriter, reader, copiedLength, sourceOffset - copiedLength);
|
|
7884
|
+
if (exceedsAvailableSize(writer, await getLocalHeaderLength(reader, sourceOffset))) {
|
|
7885
|
+
await writer.closeDisk();
|
|
7886
|
+
}
|
|
7887
|
+
entryPositions.set(entry, {
|
|
7888
|
+
offset: getSegmentOffset(zipWriter, writer),
|
|
7889
|
+
diskNumberStart: getDiskNumber(writer)
|
|
7890
|
+
});
|
|
7891
|
+
copiedLength = sourceOffset;
|
|
7892
|
+
}
|
|
7893
|
+
await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
|
|
7894
|
+
} else {
|
|
7895
|
+
await copyData(zipWriter, reader, 0, directoryOffset);
|
|
7896
|
+
entries.forEach(entry => entryPositions.set(entry, {
|
|
7897
|
+
offset: splitZipSignatureLength + getSourceOffset(reader, entry),
|
|
7898
|
+
diskNumberStart: 0
|
|
7899
|
+
}));
|
|
7900
|
+
}
|
|
7901
|
+
return entryPositions;
|
|
7902
|
+
}
|
|
7903
|
+
|
|
7904
|
+
async function copyData(zipWriter, reader, offset, size) {
|
|
7905
|
+
if (size > 0) {
|
|
7906
|
+
const { writer } = zipWriter;
|
|
7907
|
+
await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
|
|
7908
|
+
writer.size += size;
|
|
7909
|
+
zipWriter.offset += size;
|
|
7910
|
+
}
|
|
7911
|
+
}
|
|
7912
|
+
|
|
7913
|
+
async function getLocalHeaderLength(reader, offset) {
|
|
7914
|
+
const headerArray = await readUint8Array(reader, offset, HEADER_SIZE);
|
|
7915
|
+
if (getLength(headerArray) < HEADER_SIZE) {
|
|
7916
|
+
return HEADER_SIZE;
|
|
7917
|
+
}
|
|
7918
|
+
const headerView = getDataView(headerArray);
|
|
7919
|
+
return HEADER_SIZE +
|
|
7920
|
+
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
7921
|
+
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
7922
|
+
}
|
|
7923
|
+
|
|
7924
|
+
function getSourceOffset(reader, { offset, diskNumberStart }) {
|
|
7925
|
+
return offset + (reader.getDiskOffset ? reader.getDiskOffset(diskNumberStart) : 0);
|
|
7926
|
+
}
|
|
7927
|
+
|
|
7928
|
+
function getSplitZipSignatureArray() {
|
|
7929
|
+
const signatureArray = new Uint8Array(SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
7930
|
+
setUint32(getDataView(signatureArray), 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
7931
|
+
return signatureArray;
|
|
7932
|
+
}
|
|
7933
|
+
|
|
7640
7934
|
async function writeData(writer, array) {
|
|
7641
7935
|
const { writable } = writer;
|
|
7642
7936
|
const streamWriter = writable.getWriter();
|
|
@@ -7688,6 +7982,21 @@ function getOptionValue(zipWriter, options, name, defaultValue) {
|
|
|
7688
7982
|
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
7689
7983
|
}
|
|
7690
7984
|
|
|
7985
|
+
function getDateOptionValue(zipWriter, options, name, defaultValue) {
|
|
7986
|
+
const date = getOptionValue(zipWriter, options, name, defaultValue);
|
|
7987
|
+
if (date === null) {
|
|
7988
|
+
return defaultValue;
|
|
7989
|
+
}
|
|
7990
|
+
if (date !== UNDEFINED_VALUE && (typeof date.getTime != FUNCTION_TYPE || Number.isNaN(date.getTime()))) {
|
|
7991
|
+
throw new Error(ERR_INVALID_DATE);
|
|
7992
|
+
}
|
|
7993
|
+
return date;
|
|
7994
|
+
}
|
|
7995
|
+
|
|
7996
|
+
function getFunctionOptionValue(zipWriter, options, name) {
|
|
7997
|
+
return checkFunctionOption(getOptionValue(zipWriter, options, name));
|
|
7998
|
+
}
|
|
7999
|
+
|
|
7691
8000
|
function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
|
|
7692
8001
|
const value = getAliasedValue(options, name, deprecatedName);
|
|
7693
8002
|
const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
|
|
@@ -7702,9 +8011,6 @@ function getNumberOptionValue(zipWriter, options, name, defaultValue) {
|
|
|
7702
8011
|
return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
|
|
7703
8012
|
}
|
|
7704
8013
|
|
|
7705
|
-
function toNumber(value) {
|
|
7706
|
-
return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
|
|
7707
|
-
}
|
|
7708
8014
|
|
|
7709
8015
|
function getMaximumCompressedSize(uncompressedSize) {
|
|
7710
8016
|
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
@@ -7716,6 +8022,14 @@ function isCompressed(compressionMethod, level) {
|
|
|
7716
8022
|
: compressionMethod !== COMPRESSION_METHOD_STORE;
|
|
7717
8023
|
}
|
|
7718
8024
|
|
|
8025
|
+
function getUint16(view, offset) {
|
|
8026
|
+
return view.getUint16(offset, true);
|
|
8027
|
+
}
|
|
8028
|
+
|
|
8029
|
+
function getUint32(view, offset) {
|
|
8030
|
+
return view.getUint32(offset, true);
|
|
8031
|
+
}
|
|
8032
|
+
|
|
7719
8033
|
function setUint8(view, offset, value) {
|
|
7720
8034
|
view.setUint8(offset, value);
|
|
7721
8035
|
}
|
|
@@ -7759,9 +8073,9 @@ function getHeaderArrayData({
|
|
|
7759
8073
|
const headerRecord = createRecordWriter(HEADER_SIZE - 4);
|
|
7760
8074
|
const headerArray = headerRecord.array;
|
|
7761
8075
|
const headerView = getDataView(headerArray);
|
|
7762
|
-
headerRecord.
|
|
7763
|
-
headerRecord.
|
|
7764
|
-
headerRecord.
|
|
8076
|
+
headerRecord.writeUint16(version);
|
|
8077
|
+
headerRecord.writeUint16(bitFlag);
|
|
8078
|
+
headerRecord.writeUint16(compressionMethod);
|
|
7765
8079
|
if (rawLastModDate === UNDEFINED_VALUE) {
|
|
7766
8080
|
const dateArray = new Uint32Array(1);
|
|
7767
8081
|
const dateView = getDataView(dateArray);
|
|
@@ -7769,20 +8083,20 @@ function getHeaderArrayData({
|
|
|
7769
8083
|
setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
|
|
7770
8084
|
rawLastModDate = dateArray[0];
|
|
7771
8085
|
}
|
|
7772
|
-
headerRecord.
|
|
8086
|
+
headerRecord.writeUint32(rawLastModDate);
|
|
7773
8087
|
headerRecord.skip(4);
|
|
7774
8088
|
if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
|
|
7775
|
-
headerRecord.
|
|
8089
|
+
headerRecord.writeUint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
|
|
7776
8090
|
} else {
|
|
7777
8091
|
headerRecord.skip(4);
|
|
7778
8092
|
}
|
|
7779
8093
|
if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
|
|
7780
|
-
headerRecord.
|
|
8094
|
+
headerRecord.writeUint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
|
|
7781
8095
|
} else {
|
|
7782
8096
|
headerRecord.skip(4);
|
|
7783
8097
|
}
|
|
7784
|
-
headerRecord.
|
|
7785
|
-
headerRecord.
|
|
8098
|
+
headerRecord.writeUint16(getLength(rawFilename));
|
|
8099
|
+
headerRecord.writeUint16(extraFieldLength);
|
|
7786
8100
|
return {
|
|
7787
8101
|
headerArray,
|
|
7788
8102
|
headerView,
|
|
@@ -8365,6 +8679,7 @@ setDefaultConfiguration({
|
|
|
8365
8679
|
const ERR_ENTRY_EXISTS = "Entry filename already exists";
|
|
8366
8680
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
8367
8681
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
8682
|
+
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
8368
8683
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
8369
8684
|
const ERR_ABORTED = "The operation was aborted";
|
|
8370
8685
|
const ABORT_ERROR_NAME = "AbortError";
|
|
@@ -8397,13 +8712,14 @@ class ZipEntry {
|
|
|
8397
8712
|
fs,
|
|
8398
8713
|
name,
|
|
8399
8714
|
data: params.data,
|
|
8400
|
-
options: params.options,
|
|
8715
|
+
options: params.options && Object.assign({}, params.options),
|
|
8401
8716
|
id: fs.entryIdCounter++,
|
|
8402
8717
|
parent,
|
|
8403
8718
|
children: [],
|
|
8404
8719
|
uncompressedSize: params.uncompressedSize || 0,
|
|
8405
8720
|
undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
|
|
8406
|
-
passThrough: params.passThrough
|
|
8721
|
+
passThrough: params.passThrough,
|
|
8722
|
+
defaultLastModDate: params.defaultLastModDate || new Date()
|
|
8407
8723
|
});
|
|
8408
8724
|
if (parent || !fs.root) {
|
|
8409
8725
|
fs.entries[zipEntry.id] = zipEntry;
|
|
@@ -8413,12 +8729,6 @@ class ZipEntry {
|
|
|
8413
8729
|
}
|
|
8414
8730
|
}
|
|
8415
8731
|
|
|
8416
|
-
moveTo(target) {
|
|
8417
|
-
// deprecated
|
|
8418
|
-
const zipEntry = this;
|
|
8419
|
-
zipEntry.fs.move(zipEntry, target);
|
|
8420
|
-
}
|
|
8421
|
-
|
|
8422
8732
|
getFullname() {
|
|
8423
8733
|
return this.getRelativeName();
|
|
8424
8734
|
}
|
|
@@ -8450,6 +8760,11 @@ class ZipEntry {
|
|
|
8450
8760
|
this.name = name;
|
|
8451
8761
|
}
|
|
8452
8762
|
}
|
|
8763
|
+
|
|
8764
|
+
setOptions(options) {
|
|
8765
|
+
const entryOptions = Object.assign({}, this.options, options);
|
|
8766
|
+
this.options = Object.fromEntries(Object.entries(entryOptions).filter(([, value]) => value !== UNDEFINED_VALUE));
|
|
8767
|
+
}
|
|
8453
8768
|
}
|
|
8454
8769
|
|
|
8455
8770
|
class ZipFileEntry extends ZipEntry {
|
|
@@ -8476,7 +8791,7 @@ class ZipFileEntry extends ZipEntry {
|
|
|
8476
8791
|
const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
|
|
8477
8792
|
const dataSize = zipEntry.uncompressedSize || reader.size;
|
|
8478
8793
|
await Promise.all([initStream(reader), initStream(writer, dataSize)]);
|
|
8479
|
-
const
|
|
8794
|
+
const signal = checkSignalOption(options.signal);
|
|
8480
8795
|
const readable = createProgressReadable(zipEntry, reader, options, signal);
|
|
8481
8796
|
const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
|
|
8482
8797
|
zipEntry.uncompressedSize = reader.size;
|
|
@@ -8694,10 +9009,6 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
8694
9009
|
});
|
|
8695
9010
|
}
|
|
8696
9011
|
|
|
8697
|
-
addData(name, params) {
|
|
8698
|
-
return addChild(this, name, params);
|
|
8699
|
-
}
|
|
8700
|
-
|
|
8701
9012
|
importBlob(blob, options) {
|
|
8702
9013
|
return this.importZip(new BlobReader(blob), options);
|
|
8703
9014
|
}
|
|
@@ -8811,7 +9122,7 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
8811
9122
|
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
8812
9123
|
options.bufferedWrite = true;
|
|
8813
9124
|
}
|
|
8814
|
-
const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
|
|
9125
|
+
const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
|
|
8815
9126
|
const zipWriter = new ZipWriter(writer, options);
|
|
8816
9127
|
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
|
|
8817
9128
|
await zipWriter.close(options.globalComment);
|
|
@@ -8821,12 +9132,13 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
8821
9132
|
getExportedSize(options = {}) {
|
|
8822
9133
|
const zipEntry = this;
|
|
8823
9134
|
options = Object.assign({}, options);
|
|
9135
|
+
checkReaderOptions(options.readerOptions);
|
|
8824
9136
|
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
8825
9137
|
options.bufferedWrite = true;
|
|
8826
9138
|
}
|
|
8827
9139
|
const writeOrderGuaranteed = !options.bufferedWrite ||
|
|
8828
9140
|
(options.keepOrder !== false && zipEntry.children.every(child => !child.children.length));
|
|
8829
|
-
return getEntriesSize(options,
|
|
9141
|
+
return getEntriesSize(options, zipEntry.getChildren({ recursive: true }).filter(child => !isImplicitDirectory(child)).map(child => {
|
|
8830
9142
|
const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
|
|
8831
9143
|
return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
|
|
8832
9144
|
}), writeOrderGuaranteed, options.globalComment);
|
|
@@ -8865,7 +9177,7 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
8865
9177
|
}
|
|
8866
9178
|
|
|
8867
9179
|
|
|
8868
|
-
class
|
|
9180
|
+
class ZipFS {
|
|
8869
9181
|
|
|
8870
9182
|
constructor() {
|
|
8871
9183
|
resetFS(this);
|
|
@@ -8981,10 +9293,6 @@ class FS {
|
|
|
8981
9293
|
return this.root.addFile(file, options);
|
|
8982
9294
|
}
|
|
8983
9295
|
|
|
8984
|
-
addData(name, params) {
|
|
8985
|
-
return this.root.addData(name, params);
|
|
8986
|
-
}
|
|
8987
|
-
|
|
8988
9296
|
importBlob(blob, options) {
|
|
8989
9297
|
resetFS(this);
|
|
8990
9298
|
return this.root.importBlob(blob, options);
|
|
@@ -9052,7 +9360,7 @@ class FS {
|
|
|
9052
9360
|
}
|
|
9053
9361
|
}
|
|
9054
9362
|
|
|
9055
|
-
const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
|
|
9363
|
+
const fs = { FS: ZipFS, ZipDirectoryEntry, ZipFileEntry };
|
|
9056
9364
|
|
|
9057
9365
|
function getTotalSize(entries, getEntrySize) {
|
|
9058
9366
|
let size = 0;
|
|
@@ -9196,7 +9504,7 @@ function detach(entry) {
|
|
|
9196
9504
|
}
|
|
9197
9505
|
|
|
9198
9506
|
function forwardAbort(signal, abortController) {
|
|
9199
|
-
if (!signal) {
|
|
9507
|
+
if (!checkSignalOption(signal)) {
|
|
9200
9508
|
return () => { };
|
|
9201
9509
|
}
|
|
9202
9510
|
if (signal.aborted) {
|
|
@@ -9292,7 +9600,7 @@ function getChildEntryOptions(child, selectedEntry, options) {
|
|
|
9292
9600
|
};
|
|
9293
9601
|
}
|
|
9294
9602
|
}
|
|
9295
|
-
const entryOptions = Object.assign({}, zipEntryMetadata, options,
|
|
9603
|
+
const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
|
|
9296
9604
|
if (!child.directory && entryOptions.passThrough && entryOptions.uncompressedSize === UNDEFINED_VALUE) {
|
|
9297
9605
|
throw new Error(ERR_INVALID_PASS_THROUGH);
|
|
9298
9606
|
}
|
|
@@ -9307,11 +9615,22 @@ function getDeterminedSize(child, passThrough) {
|
|
|
9307
9615
|
return child.undeterminedSize ? UNDEFINED_VALUE : getExtractedSize(child, passThrough);
|
|
9308
9616
|
}
|
|
9309
9617
|
|
|
9618
|
+
function checkReaderOptions(readerOptions) {
|
|
9619
|
+
if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
|
|
9620
|
+
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
9621
|
+
}
|
|
9622
|
+
return readerOptions;
|
|
9623
|
+
}
|
|
9624
|
+
|
|
9310
9625
|
function isPassThrough(child, options) {
|
|
9311
9626
|
const { readerOptions } = options;
|
|
9312
9627
|
return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
|
|
9313
9628
|
}
|
|
9314
9629
|
|
|
9630
|
+
function isImplicitDirectory(child) {
|
|
9631
|
+
return child.directory && child.data === null;
|
|
9632
|
+
}
|
|
9633
|
+
|
|
9315
9634
|
function getUserExtraField(extraField) {
|
|
9316
9635
|
if (extraField) {
|
|
9317
9636
|
const userExtraField = new Map();
|
|
@@ -9329,7 +9648,7 @@ function getUserExtraField(extraField) {
|
|
|
9329
9648
|
async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
9330
9649
|
const { onstart, onprogress, onend, onentryprogress } = options;
|
|
9331
9650
|
const selectedEntry = entry;
|
|
9332
|
-
const totalEntries = getTotalSize(entry.children, ()
|
|
9651
|
+
const totalEntries = getTotalSize(entry.children, child => isImplicitDirectory(child) ? 0 : 1);
|
|
9333
9652
|
let writtenSize = 0;
|
|
9334
9653
|
let writtenEntries = 0;
|
|
9335
9654
|
if (onstart) {
|
|
@@ -9358,6 +9677,9 @@ async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
|
9358
9677
|
}
|
|
9359
9678
|
|
|
9360
9679
|
async function addChild(child) {
|
|
9680
|
+
if (isImplicitDirectory(child)) {
|
|
9681
|
+
return;
|
|
9682
|
+
}
|
|
9361
9683
|
const { name, entryOptions } = getChildEntryOptions(child, selectedEntry, options);
|
|
9362
9684
|
let entryWrittenSize = 0;
|
|
9363
9685
|
const entryMetadata = await zipWriter.add(name, readers.get(child), Object.assign(entryOptions, {
|
|
@@ -9391,7 +9713,7 @@ function addFileSystemHandle(zipEntry, handle, options) {
|
|
|
9391
9713
|
if (handle.kind == "file") {
|
|
9392
9714
|
const file = await handle.getFile();
|
|
9393
9715
|
addedEntries.push(
|
|
9394
|
-
parentEntry
|
|
9716
|
+
addChild(parentEntry, file.name, {
|
|
9395
9717
|
Reader: function () {
|
|
9396
9718
|
const readable = file.stream();
|
|
9397
9719
|
const size = file.size;
|
|
@@ -9425,10 +9747,11 @@ function addFileSystemHandle(zipEntry, handle, options) {
|
|
|
9425
9747
|
|
|
9426
9748
|
async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
9427
9749
|
const { onstart, onprogress, onend } = options;
|
|
9750
|
+
const readerOptions = checkReaderOptions(options.readerOptions);
|
|
9428
9751
|
const abortController = new AbortController();
|
|
9429
9752
|
const { signal } = abortController;
|
|
9430
9753
|
const releaseSignal = forwardAbort(options.signal, abortController);
|
|
9431
|
-
const getDataOptions = Object.assign({}, options,
|
|
9754
|
+
const getDataOptions = Object.assign({}, options, readerOptions, {
|
|
9432
9755
|
signal,
|
|
9433
9756
|
onstart: UNDEFINED_VALUE,
|
|
9434
9757
|
onprogress: UNDEFINED_VALUE,
|
|
@@ -9715,7 +10038,7 @@ function decodeMimeTypes(data) {
|
|
|
9715
10038
|
*/
|
|
9716
10039
|
|
|
9717
10040
|
|
|
9718
|
-
|
|
10041
|
+
a(setDefaultConfiguration);
|
|
9719
10042
|
|
|
9720
10043
|
exports.BlobReader = BlobReader;
|
|
9721
10044
|
exports.BlobWriter = BlobWriter;
|
|
@@ -9728,6 +10051,7 @@ exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
|
|
|
9728
10051
|
exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
|
|
9729
10052
|
exports.ERR_ENCRYPTED = ERR_ENCRYPTED;
|
|
9730
10053
|
exports.ERR_ENCRYPTED_CENTRAL_DIRECTORY = ERR_ENCRYPTED_CENTRAL_DIRECTORY;
|
|
10054
|
+
exports.ERR_ENTRY_DATA_OUT_OF_BOUNDS = ERR_ENTRY_DATA_OUT_OF_BOUNDS;
|
|
9731
10055
|
exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
|
|
9732
10056
|
exports.ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND;
|
|
9733
10057
|
exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
|
|
@@ -9738,22 +10062,31 @@ exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
|
|
|
9738
10062
|
exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
|
|
9739
10063
|
exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
|
|
9740
10064
|
exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
|
|
10065
|
+
exports.ERR_INVALID_COMMENT_TYPE = ERR_INVALID_COMMENT_TYPE;
|
|
9741
10066
|
exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
|
|
9742
10067
|
exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
|
|
10068
|
+
exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
|
|
9743
10069
|
exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
|
|
9744
10070
|
exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
|
|
10071
|
+
exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
|
|
9745
10072
|
exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
|
|
10073
|
+
exports.ERR_INVALID_EXTRAFIELD = ERR_INVALID_EXTRAFIELD;
|
|
9746
10074
|
exports.ERR_INVALID_EXTRAFIELD_DATA = ERR_INVALID_EXTRAFIELD_DATA;
|
|
10075
|
+
exports.ERR_INVALID_EXTRAFIELD_DATA_TYPE = ERR_INVALID_EXTRAFIELD_DATA_TYPE;
|
|
9747
10076
|
exports.ERR_INVALID_EXTRAFIELD_TYPE = ERR_INVALID_EXTRAFIELD_TYPE;
|
|
9748
10077
|
exports.ERR_INVALID_FILENAME_VALIDATION = ERR_INVALID_FILENAME_VALIDATION;
|
|
10078
|
+
exports.ERR_INVALID_FUNCTION_OPTION = ERR_INVALID_FUNCTION_OPTION;
|
|
9749
10079
|
exports.ERR_INVALID_GID = ERR_INVALID_GID;
|
|
9750
10080
|
exports.ERR_INVALID_LEVEL = ERR_INVALID_LEVEL;
|
|
9751
10081
|
exports.ERR_INVALID_MAX_APPENDED_DATA_SIZE = ERR_INVALID_MAX_APPENDED_DATA_SIZE;
|
|
10082
|
+
exports.ERR_INVALID_MAX_WORKERS = ERR_INVALID_MAX_WORKERS;
|
|
9752
10083
|
exports.ERR_INVALID_MSDOS_ATTRIBUTES = ERR_INVALID_MSDOS_ATTRIBUTES;
|
|
9753
10084
|
exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
|
|
9754
10085
|
exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
|
|
9755
10086
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
9756
10087
|
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
10088
|
+
exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
|
|
10089
|
+
exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
|
|
9757
10090
|
exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
|
|
9758
10091
|
exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
|
|
9759
10092
|
exports.ERR_INVALID_STRICTNESS = ERR_INVALID_STRICTNESS;
|
|
@@ -9793,6 +10126,10 @@ exports.TextWriter = TextWriter;
|
|
|
9793
10126
|
exports.Uint8ArrayReader = Uint8ArrayReader;
|
|
9794
10127
|
exports.Uint8ArrayWriter = Uint8ArrayWriter;
|
|
9795
10128
|
exports.Writer = Writer;
|
|
10129
|
+
exports.ZipDirectoryEntry = ZipDirectoryEntry;
|
|
10130
|
+
exports.ZipEntry = ZipEntry;
|
|
10131
|
+
exports.ZipFS = ZipFS;
|
|
10132
|
+
exports.ZipFileEntry = ZipFileEntry;
|
|
9796
10133
|
exports.ZipReader = ZipReader;
|
|
9797
10134
|
exports.ZipReaderStream = ZipReaderStream;
|
|
9798
10135
|
exports.ZipWriter = ZipWriter;
|