@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/dist/zip-fs-native.js
CHANGED
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
|
|
46
46
|
const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
|
|
47
47
|
const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
|
|
48
|
+
const TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE = 0x30304b50;
|
|
48
49
|
const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
|
|
49
50
|
const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
|
|
50
51
|
const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
const DATA_DESCRIPTOR_RECORD_LENGTH = 12;
|
|
62
63
|
const DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH = 20;
|
|
63
64
|
const DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH = 4;
|
|
65
|
+
const SPLIT_ZIP_FILE_SIGNATURE_LENGTH = 4;
|
|
64
66
|
|
|
65
67
|
const EXTRAFIELD_TYPE_ZIP64 = 0x0001;
|
|
66
68
|
const EXTRAFIELD_TYPE_AES = 0x9901;
|
|
@@ -102,6 +104,9 @@
|
|
|
102
104
|
const VERSION_ZIP64 = 0x2D;
|
|
103
105
|
const VERSION_AES = 0x33;
|
|
104
106
|
|
|
107
|
+
const VERSION_MADE_BY_MSDOS = 0x0014;
|
|
108
|
+
const VERSION_MADE_BY_UNIX = 0x0300;
|
|
109
|
+
|
|
105
110
|
const DIRECTORY_SIGNATURE = "/";
|
|
106
111
|
|
|
107
112
|
const HEADER_SIZE = 30;
|
|
@@ -109,6 +114,8 @@
|
|
|
109
114
|
const HEADER_OFFSET_SIGNATURE = 10;
|
|
110
115
|
const HEADER_OFFSET_COMPRESSED_SIZE = 14;
|
|
111
116
|
const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18;
|
|
117
|
+
const HEADER_OFFSET_FILENAME_LENGTH = 22;
|
|
118
|
+
const HEADER_OFFSET_EXTRAFIELD_LENGTH = 24;
|
|
112
119
|
const LOCAL_HEADER_COMMON_OFFSET = 4;
|
|
113
120
|
|
|
114
121
|
const MAX_DATE = new Date(2107, 11, 31, 23, 59, 58);
|
|
@@ -121,9 +128,116 @@
|
|
|
121
128
|
const OBJECT_TYPE = "object";
|
|
122
129
|
const STRING_TYPE = "string";
|
|
123
130
|
const NUMBER_TYPE = "number";
|
|
131
|
+
const BOOLEAN_TYPE = "boolean";
|
|
124
132
|
|
|
125
133
|
const EMPTY_UINT8_ARRAY = new Uint8Array();
|
|
126
134
|
|
|
135
|
+
/*
|
|
136
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
137
|
+
|
|
138
|
+
Redistribution and use in source and binary forms, with or without
|
|
139
|
+
modification, are permitted provided that the following conditions are met:
|
|
140
|
+
|
|
141
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
142
|
+
this list of conditions and the following disclaimer.
|
|
143
|
+
|
|
144
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
145
|
+
notice, this list of conditions and the following disclaimer in
|
|
146
|
+
the documentation and/or other materials provided with the distribution.
|
|
147
|
+
|
|
148
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
149
|
+
derived from this software without specific prior written permission.
|
|
150
|
+
|
|
151
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
152
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
153
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
154
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
155
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
156
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
157
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
158
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
159
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
160
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
161
|
+
*/
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
const OPTION_FILENAME_ENCODING = "filenameEncoding";
|
|
165
|
+
const OPTION_COMMENT_ENCODING = "commentEncoding";
|
|
166
|
+
const OPTION_DECODE_TEXT = "decodeText";
|
|
167
|
+
const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
|
|
168
|
+
const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
|
|
169
|
+
const OPTION_PASSWORD = "password";
|
|
170
|
+
const OPTION_RAW_PASSWORD = "rawPassword";
|
|
171
|
+
const OPTION_PASS_THROUGH = "passThrough";
|
|
172
|
+
const OPTION_SIGNAL = "signal";
|
|
173
|
+
const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
|
|
174
|
+
const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
|
|
175
|
+
const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
|
|
176
|
+
const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
|
|
177
|
+
const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
|
|
178
|
+
const OPTION_CHECK_SIGNATURE = "checkSignature";
|
|
179
|
+
const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
180
|
+
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
181
|
+
const OPTION_USE_WEB_WORKERS = "useWebWorkers";
|
|
182
|
+
const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
|
|
183
|
+
const OPTION_TRANSFER_STREAMS = "transferStreams";
|
|
184
|
+
const OPTION_PREVENT_CLOSE = "preventClose";
|
|
185
|
+
const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
|
|
186
|
+
const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
|
|
187
|
+
const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
|
|
188
|
+
const OPTION_KEEP_ORDER = "keepOrder";
|
|
189
|
+
const OPTION_LEVEL = "level";
|
|
190
|
+
const OPTION_BUFFERED_WRITE = "bufferedWrite";
|
|
191
|
+
const OPTION_CREATE_TEMP_STREAM = "createTempStream";
|
|
192
|
+
const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
|
|
193
|
+
const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
|
|
194
|
+
const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
|
|
195
|
+
const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
|
|
196
|
+
const OPTION_ENCODE_TEXT = "encodeText";
|
|
197
|
+
const OPTION_OFFSET = "offset";
|
|
198
|
+
const OPTION_USDZ = "usdz";
|
|
199
|
+
const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
|
|
200
|
+
const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
|
|
201
|
+
const OPTION_STRICTNESS = "strictness";
|
|
202
|
+
const OPTION_FILENAME_VALIDATION = "filenameValidation";
|
|
203
|
+
const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
|
|
204
|
+
const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
|
|
205
|
+
const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
|
|
206
|
+
const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
|
|
207
|
+
const TEXT_TYPE_FILENAME = "filename";
|
|
208
|
+
const TEXT_TYPE_COMMENT = "comment";
|
|
209
|
+
const STRICTNESS_STRICT = "strict";
|
|
210
|
+
const STRICTNESS_BALANCED = "balanced";
|
|
211
|
+
const STRICTNESS_TOLERANT = "tolerant";
|
|
212
|
+
|
|
213
|
+
const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
|
|
214
|
+
const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
|
|
215
|
+
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
216
|
+
|
|
217
|
+
function checkFunctionOption(value) {
|
|
218
|
+
if (value && typeof value != FUNCTION_TYPE) {
|
|
219
|
+
throw new Error(ERR_INVALID_FUNCTION_OPTION);
|
|
220
|
+
}
|
|
221
|
+
return value;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function checkSignalOption(signal) {
|
|
225
|
+
if (signal && (typeof signal.addEventListener != FUNCTION_TYPE || typeof signal.aborted != BOOLEAN_TYPE)) {
|
|
226
|
+
throw new Error(ERR_INVALID_SIGNAL);
|
|
227
|
+
}
|
|
228
|
+
return signal || UNDEFINED_VALUE;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function checkPasswordOption(password, rawPassword) {
|
|
232
|
+
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
233
|
+
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function toNumber(value) {
|
|
238
|
+
return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
|
|
239
|
+
}
|
|
240
|
+
|
|
127
241
|
/*
|
|
128
242
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
129
243
|
|
|
@@ -153,7 +267,10 @@
|
|
|
153
267
|
*/
|
|
154
268
|
|
|
155
269
|
|
|
270
|
+
const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
|
|
156
271
|
const MINIMUM_CHUNK_SIZE = 64;
|
|
272
|
+
const MINIMUM_PROPERTY_VALUE = 1;
|
|
273
|
+
const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
|
|
157
274
|
let maxWorkers = 2;
|
|
158
275
|
try {
|
|
159
276
|
if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
|
|
@@ -165,7 +282,7 @@
|
|
|
165
282
|
const DEFAULT_CONFIGURATION = {
|
|
166
283
|
workerURI: "./core/web-worker-wasm.js",
|
|
167
284
|
wasmURI: "./core/streams/zlib-wasm/zlib-streams.wasm",
|
|
168
|
-
chunkSize:
|
|
285
|
+
chunkSize: DEFAULT_CHUNK_SIZE$1,
|
|
169
286
|
maxWorkers,
|
|
170
287
|
terminateWorkerTimeout: 5000,
|
|
171
288
|
workerStarvationTimeout: 5000,
|
|
@@ -177,24 +294,38 @@
|
|
|
177
294
|
DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
178
295
|
};
|
|
179
296
|
|
|
180
|
-
const
|
|
297
|
+
const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
|
|
298
|
+
|
|
299
|
+
const STRING_PROPERTY_NAMES = [
|
|
181
300
|
"baseURI",
|
|
182
301
|
"wasmURI",
|
|
183
|
-
"workerURI"
|
|
184
|
-
|
|
302
|
+
"workerURI"
|
|
303
|
+
];
|
|
304
|
+
const BOOLEAN_PROPERTY_NAMES = [
|
|
305
|
+
"useCompressionStream",
|
|
306
|
+
"useWebWorkers",
|
|
307
|
+
"transferStreams"
|
|
308
|
+
];
|
|
309
|
+
const NUMBER_PROPERTY_NAMES = [
|
|
185
310
|
"chunkSize",
|
|
186
|
-
|
|
311
|
+
PROPERTY_NAME_MAX_WORKERS,
|
|
187
312
|
"terminateWorkerTimeout",
|
|
188
313
|
"workerStarvationTimeout",
|
|
189
|
-
"workerStartupTimeout"
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
"
|
|
314
|
+
"workerStartupTimeout"
|
|
315
|
+
];
|
|
316
|
+
const FUNCTION_PROPERTY_NAMES = [
|
|
317
|
+
"createWorker",
|
|
193
318
|
"CompressionStream",
|
|
194
319
|
"DecompressionStream",
|
|
195
320
|
"CompressionStreamFallback",
|
|
196
321
|
"DecompressionStreamFallback"
|
|
197
322
|
];
|
|
323
|
+
const CONFIGURABLE_PROPERTY_NAMES = [
|
|
324
|
+
...STRING_PROPERTY_NAMES,
|
|
325
|
+
...BOOLEAN_PROPERTY_NAMES,
|
|
326
|
+
...NUMBER_PROPERTY_NAMES,
|
|
327
|
+
...FUNCTION_PROPERTY_NAMES
|
|
328
|
+
];
|
|
198
329
|
|
|
199
330
|
const config = { ...DEFAULT_CONFIGURATION };
|
|
200
331
|
|
|
@@ -203,20 +334,43 @@
|
|
|
203
334
|
}
|
|
204
335
|
|
|
205
336
|
function getChunkSize(config) {
|
|
206
|
-
return
|
|
337
|
+
return normalizeChunkSize(config.chunkSize);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function normalizeChunkSize(chunkSize) {
|
|
341
|
+
chunkSize = toNumber(chunkSize);
|
|
342
|
+
return Number.isInteger(chunkSize) && chunkSize >= MINIMUM_PROPERTY_VALUE ? Math.max(chunkSize, MINIMUM_CHUNK_SIZE) : DEFAULT_CHUNK_SIZE$1;
|
|
207
343
|
}
|
|
208
344
|
|
|
209
345
|
function configure(configuration) {
|
|
210
|
-
|
|
346
|
+
Object.assign(config, checkConfiguration(normalizeConfiguration(configuration)));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function checkConfiguration(configuration) {
|
|
350
|
+
const checkedConfiguration = {};
|
|
211
351
|
for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
|
|
212
352
|
const propertyValue = configuration[propertyName];
|
|
213
353
|
if (propertyValue !== UNDEFINED_VALUE) {
|
|
214
|
-
|
|
354
|
+
checkedConfiguration[propertyName] = checkPropertyValue(propertyName, propertyValue);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return checkedConfiguration;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function checkPropertyValue(propertyName, propertyValue) {
|
|
361
|
+
if (NUMBER_PROPERTY_NAMES.includes(propertyName)) {
|
|
362
|
+
propertyValue = toNumber(propertyValue);
|
|
363
|
+
if (propertyName == PROPERTY_NAME_MAX_WORKERS && (!Number.isInteger(propertyValue) || propertyValue < MINIMUM_PROPERTY_VALUE)) {
|
|
364
|
+
throw new Error(ERR_INVALID_MAX_WORKERS);
|
|
215
365
|
}
|
|
366
|
+
} else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
|
|
367
|
+
checkFunctionOption(propertyValue);
|
|
216
368
|
}
|
|
369
|
+
return propertyValue;
|
|
217
370
|
}
|
|
218
371
|
|
|
219
372
|
function normalizeConfiguration(configuration) {
|
|
373
|
+
configuration = configuration || {};
|
|
220
374
|
const { CompressionStreamZlib, DecompressionStreamZlib } = configuration;
|
|
221
375
|
if (CompressionStreamZlib === UNDEFINED_VALUE && DecompressionStreamZlib === UNDEFINED_VALUE) {
|
|
222
376
|
return configuration;
|
|
@@ -232,14 +386,9 @@
|
|
|
232
386
|
}
|
|
233
387
|
|
|
234
388
|
function setDefaultConfiguration(configuration) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (propertyValue !== UNDEFINED_VALUE) {
|
|
239
|
-
DEFAULT_CONFIGURATION[propertyName] = propertyValue;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
configure(configuration);
|
|
389
|
+
const checkedConfiguration = checkConfiguration(normalizeConfiguration(configuration));
|
|
390
|
+
Object.assign(DEFAULT_CONFIGURATION, checkedConfiguration);
|
|
391
|
+
Object.assign(config, checkedConfiguration);
|
|
243
392
|
}
|
|
244
393
|
|
|
245
394
|
function resetConfiguration() {
|
|
@@ -249,7 +398,7 @@
|
|
|
249
398
|
Object.assign(config, DEFAULT_CONFIGURATION);
|
|
250
399
|
}
|
|
251
400
|
|
|
252
|
-
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;
|
|
401
|
+
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;
|
|
253
402
|
|
|
254
403
|
/*
|
|
255
404
|
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
@@ -1397,13 +1546,13 @@
|
|
|
1397
1546
|
const {
|
|
1398
1547
|
ctr,
|
|
1399
1548
|
hmac,
|
|
1400
|
-
|
|
1549
|
+
pendingInput,
|
|
1401
1550
|
ready
|
|
1402
1551
|
} = this;
|
|
1403
1552
|
if (hmac && ctr) {
|
|
1404
1553
|
await ready;
|
|
1405
|
-
const chunkToDecrypt = subarray(
|
|
1406
|
-
const originalAuthenticationCode = subarray(
|
|
1554
|
+
const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1555
|
+
const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1407
1556
|
let decryptedChunkArray = EMPTY_UINT8_ARRAY;
|
|
1408
1557
|
if (chunkToDecrypt.length) {
|
|
1409
1558
|
const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
|
|
@@ -1412,7 +1561,7 @@
|
|
|
1412
1561
|
decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
|
|
1413
1562
|
}
|
|
1414
1563
|
const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1415
|
-
let invalidAuthenticationCode =
|
|
1564
|
+
let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
|
|
1416
1565
|
for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
|
|
1417
1566
|
invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
|
|
1418
1567
|
}
|
|
@@ -1456,14 +1605,14 @@
|
|
|
1456
1605
|
const {
|
|
1457
1606
|
ctr,
|
|
1458
1607
|
hmac,
|
|
1459
|
-
|
|
1608
|
+
pendingInput,
|
|
1460
1609
|
ready
|
|
1461
1610
|
} = this;
|
|
1462
1611
|
if (hmac && ctr) {
|
|
1463
1612
|
await ready;
|
|
1464
1613
|
let encryptedChunkArray = EMPTY_UINT8_ARRAY;
|
|
1465
|
-
if (
|
|
1466
|
-
const encryptedChunk = ctr.update(toBits(codecBytes,
|
|
1614
|
+
if (pendingInput.length) {
|
|
1615
|
+
const encryptedChunk = ctr.update(toBits(codecBytes, pendingInput));
|
|
1467
1616
|
hmac.update(encryptedChunk);
|
|
1468
1617
|
encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
|
|
1469
1618
|
}
|
|
@@ -1480,7 +1629,7 @@
|
|
|
1480
1629
|
ready: new Promise(resolve => aesCrypto.resolveReady = resolve),
|
|
1481
1630
|
password: encodePassword(password, rawPassword),
|
|
1482
1631
|
strength: encryptionStrength - 1,
|
|
1483
|
-
|
|
1632
|
+
pendingInput: EMPTY_UINT8_ARRAY
|
|
1484
1633
|
});
|
|
1485
1634
|
}
|
|
1486
1635
|
|
|
@@ -1488,10 +1637,10 @@
|
|
|
1488
1637
|
const {
|
|
1489
1638
|
ctr,
|
|
1490
1639
|
hmac,
|
|
1491
|
-
|
|
1640
|
+
pendingInput
|
|
1492
1641
|
} = aesCrypto;
|
|
1493
|
-
if (
|
|
1494
|
-
input = concat(
|
|
1642
|
+
if (pendingInput.length) {
|
|
1643
|
+
input = concat(pendingInput, input);
|
|
1495
1644
|
}
|
|
1496
1645
|
const inputLength = input.length - paddingEnd;
|
|
1497
1646
|
output = expand(output, paddingStart + (inputLength - (inputLength % BLOCK_LENGTH)));
|
|
@@ -1507,7 +1656,7 @@
|
|
|
1507
1656
|
}
|
|
1508
1657
|
output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
|
|
1509
1658
|
}
|
|
1510
|
-
aesCrypto.
|
|
1659
|
+
aesCrypto.pendingInput = subarray(input, offset);
|
|
1511
1660
|
return output;
|
|
1512
1661
|
}
|
|
1513
1662
|
|
|
@@ -2758,6 +2907,7 @@
|
|
|
2758
2907
|
worker,
|
|
2759
2908
|
workerAlive: false,
|
|
2760
2909
|
terminated: false,
|
|
2910
|
+
startupError: null,
|
|
2761
2911
|
interface: {
|
|
2762
2912
|
run: async () => {
|
|
2763
2913
|
try {
|
|
@@ -2785,6 +2935,13 @@
|
|
|
2785
2935
|
}
|
|
2786
2936
|
|
|
2787
2937
|
async function runWebWorker(workerData, config) {
|
|
2938
|
+
if (!workerData.worker) {
|
|
2939
|
+
const { startupError } = workerData;
|
|
2940
|
+
workerData.startupError = null;
|
|
2941
|
+
const error = startupError || new Error(ERR_WORKER_STARTUP_TIMEOUT);
|
|
2942
|
+
error.workerStartupFailed = true;
|
|
2943
|
+
throw error;
|
|
2944
|
+
}
|
|
2788
2945
|
let resolveResult, rejectResult;
|
|
2789
2946
|
const result = new Promise((resolve, reject) => {
|
|
2790
2947
|
resolveResult = resolve;
|
|
@@ -2998,11 +3155,12 @@
|
|
|
2998
3155
|
if (!workerAlive) {
|
|
2999
3156
|
workerData.worker = null;
|
|
3000
3157
|
}
|
|
3158
|
+
let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
|
|
3159
|
+
if (!workerAlive) {
|
|
3160
|
+
error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
|
|
3161
|
+
workerData.startupError = error;
|
|
3162
|
+
}
|
|
3001
3163
|
if (rejectResult) {
|
|
3002
|
-
let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
|
|
3003
|
-
if (!workerAlive) {
|
|
3004
|
-
error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
|
|
3005
|
-
}
|
|
3006
3164
|
rejectResult(error);
|
|
3007
3165
|
if (writer) {
|
|
3008
3166
|
writer.releaseLock();
|
|
@@ -3271,6 +3429,96 @@
|
|
|
3271
3429
|
resetWebWorkerSupport();
|
|
3272
3430
|
}
|
|
3273
3431
|
|
|
3432
|
+
/*
|
|
3433
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3434
|
+
|
|
3435
|
+
Redistribution and use in source and binary forms, with or without
|
|
3436
|
+
modification, are permitted provided that the following conditions are met:
|
|
3437
|
+
|
|
3438
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
3439
|
+
this list of conditions and the following disclaimer.
|
|
3440
|
+
|
|
3441
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
3442
|
+
notice, this list of conditions and the following disclaimer in
|
|
3443
|
+
the documentation and/or other materials provided with the distribution.
|
|
3444
|
+
|
|
3445
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
3446
|
+
derived from this software without specific prior written permission.
|
|
3447
|
+
|
|
3448
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
3449
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
3450
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
3451
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
3452
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
3453
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
3454
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
3455
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
3456
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
3457
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3458
|
+
*/
|
|
3459
|
+
|
|
3460
|
+
/* global TextDecoder */
|
|
3461
|
+
|
|
3462
|
+
const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
|
|
3463
|
+
const VALID_CP437 = CP437.length == 256;
|
|
3464
|
+
|
|
3465
|
+
function decodeCP437(stringValue) {
|
|
3466
|
+
if (VALID_CP437) {
|
|
3467
|
+
let result = "";
|
|
3468
|
+
for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
|
|
3469
|
+
result += CP437[stringValue[indexCharacter]];
|
|
3470
|
+
}
|
|
3471
|
+
return result;
|
|
3472
|
+
} else {
|
|
3473
|
+
return new TextDecoder().decode(stringValue);
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3476
|
+
|
|
3477
|
+
/*
|
|
3478
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3479
|
+
|
|
3480
|
+
Redistribution and use in source and binary forms, with or without
|
|
3481
|
+
modification, are permitted provided that the following conditions are met:
|
|
3482
|
+
|
|
3483
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
3484
|
+
this list of conditions and the following disclaimer.
|
|
3485
|
+
|
|
3486
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
3487
|
+
notice, this list of conditions and the following disclaimer in
|
|
3488
|
+
the documentation and/or other materials provided with the distribution.
|
|
3489
|
+
|
|
3490
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
3491
|
+
derived from this software without specific prior written permission.
|
|
3492
|
+
|
|
3493
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
3494
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
3495
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
3496
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
3497
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
3498
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
3499
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
3500
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
3501
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
3502
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3503
|
+
*/
|
|
3504
|
+
|
|
3505
|
+
|
|
3506
|
+
function decodeText(value, encoding) {
|
|
3507
|
+
return decode(value, encoding, true);
|
|
3508
|
+
}
|
|
3509
|
+
|
|
3510
|
+
function decodeTextRemovingBOM(value, encoding) {
|
|
3511
|
+
return decode(value, encoding, false);
|
|
3512
|
+
}
|
|
3513
|
+
|
|
3514
|
+
function decode(value, encoding, ignoreBOM) {
|
|
3515
|
+
if (encoding && encoding.trim().toLowerCase() == "cp437") {
|
|
3516
|
+
return decodeCP437(value);
|
|
3517
|
+
} else {
|
|
3518
|
+
return new TextDecoder(encoding, { ignoreBOM }).decode(value);
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3274
3522
|
/*
|
|
3275
3523
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
3276
3524
|
|
|
@@ -3343,6 +3591,7 @@
|
|
|
3343
3591
|
createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
|
|
3344
3592
|
const reader = this;
|
|
3345
3593
|
let chunkOffset = 0;
|
|
3594
|
+
chunkSize = normalizeChunkSize(chunkSize);
|
|
3346
3595
|
return new ReadableStream({
|
|
3347
3596
|
async pull(controller) {
|
|
3348
3597
|
const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
|
|
@@ -3350,7 +3599,7 @@
|
|
|
3350
3599
|
if (data.length) {
|
|
3351
3600
|
controller.enqueue(data);
|
|
3352
3601
|
}
|
|
3353
|
-
if ((chunkOffset + chunkSize >= size) || (
|
|
3602
|
+
if ((chunkOffset + chunkSize >= size) || (!data.length && dataSize)) {
|
|
3354
3603
|
controller.close();
|
|
3355
3604
|
} else {
|
|
3356
3605
|
chunkOffset += chunkSize;
|
|
@@ -3430,31 +3679,31 @@
|
|
|
3430
3679
|
Object.assign(this, {
|
|
3431
3680
|
contentType,
|
|
3432
3681
|
data: "data:" + (contentType || "") + ";base64,",
|
|
3433
|
-
|
|
3682
|
+
pendingCharacters: ""
|
|
3434
3683
|
});
|
|
3435
3684
|
}
|
|
3436
3685
|
|
|
3437
3686
|
writeUint8Array(array) {
|
|
3438
3687
|
const writer = this;
|
|
3439
3688
|
let indexArray;
|
|
3440
|
-
let dataString = writer.
|
|
3441
|
-
const delta = writer.
|
|
3442
|
-
writer.
|
|
3689
|
+
let dataString = writer.pendingCharacters;
|
|
3690
|
+
const delta = writer.pendingCharacters.length;
|
|
3691
|
+
writer.pendingCharacters = "";
|
|
3443
3692
|
for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
|
|
3444
3693
|
dataString += String.fromCharCode(array[indexArray]);
|
|
3445
3694
|
}
|
|
3446
3695
|
for (; indexArray < array.length; indexArray++) {
|
|
3447
|
-
writer.
|
|
3696
|
+
writer.pendingCharacters += String.fromCharCode(array[indexArray]);
|
|
3448
3697
|
}
|
|
3449
3698
|
if (dataString.length > 2) {
|
|
3450
3699
|
writer.data += btoa(dataString);
|
|
3451
3700
|
} else {
|
|
3452
|
-
writer.
|
|
3701
|
+
writer.pendingCharacters = dataString + writer.pendingCharacters;
|
|
3453
3702
|
}
|
|
3454
3703
|
}
|
|
3455
3704
|
|
|
3456
3705
|
getData() {
|
|
3457
|
-
return this.data + btoa(this.
|
|
3706
|
+
return this.data + btoa(this.pendingCharacters);
|
|
3458
3707
|
}
|
|
3459
3708
|
}
|
|
3460
3709
|
|
|
@@ -3484,7 +3733,7 @@
|
|
|
3484
3733
|
constructor(blob) {
|
|
3485
3734
|
super();
|
|
3486
3735
|
Object.assign(this, {
|
|
3487
|
-
blob,
|
|
3736
|
+
sourceBlob: blob,
|
|
3488
3737
|
size: blob.size
|
|
3489
3738
|
});
|
|
3490
3739
|
if (!blobSliceProbe) {
|
|
@@ -3494,13 +3743,13 @@
|
|
|
3494
3743
|
|
|
3495
3744
|
createReadable(options) {
|
|
3496
3745
|
const reader = this;
|
|
3497
|
-
const {
|
|
3746
|
+
const { sourceBlob, size } = reader;
|
|
3498
3747
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
3499
3748
|
if (!offset && readSize >= size) {
|
|
3500
|
-
return toCompatibleReadable(
|
|
3749
|
+
return toCompatibleReadable(sourceBlob.stream());
|
|
3501
3750
|
}
|
|
3502
3751
|
if (blobSliceReliable) {
|
|
3503
|
-
return toCompatibleReadable(
|
|
3752
|
+
return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
|
|
3504
3753
|
}
|
|
3505
3754
|
return super.createReadable(options);
|
|
3506
3755
|
}
|
|
@@ -3509,7 +3758,7 @@
|
|
|
3509
3758
|
const reader = this;
|
|
3510
3759
|
const offsetEnd = offset + length;
|
|
3511
3760
|
const readsWholeBlob = !offset && offsetEnd >= reader.size;
|
|
3512
|
-
const blob = readsWholeBlob ? reader.
|
|
3761
|
+
const blob = readsWholeBlob ? reader.sourceBlob : reader.sourceBlob.slice(offset, offsetEnd);
|
|
3513
3762
|
let arrayBuffer = await blob.arrayBuffer();
|
|
3514
3763
|
const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
|
|
3515
3764
|
if (sliceIgnoredByBuggyImplementation) {
|
|
@@ -3531,12 +3780,12 @@
|
|
|
3531
3780
|
}
|
|
3532
3781
|
});
|
|
3533
3782
|
writer.contentType = contentType;
|
|
3534
|
-
writer.
|
|
3535
|
-
writer.
|
|
3783
|
+
writer.blobPromise = streamToBlob(transformStream.readable, contentType);
|
|
3784
|
+
writer.blobPromise.catch(() => { });
|
|
3536
3785
|
}
|
|
3537
3786
|
|
|
3538
3787
|
getData() {
|
|
3539
|
-
return this.
|
|
3788
|
+
return this.blobPromise;
|
|
3540
3789
|
}
|
|
3541
3790
|
}
|
|
3542
3791
|
|
|
@@ -3570,7 +3819,7 @@
|
|
|
3570
3819
|
class TextWriter extends BlobWriter {
|
|
3571
3820
|
|
|
3572
3821
|
constructor(encoding) {
|
|
3573
|
-
super(
|
|
3822
|
+
super();
|
|
3574
3823
|
Object.assign(this, {
|
|
3575
3824
|
encoding,
|
|
3576
3825
|
utf8: !encoding || encoding.toLowerCase() == "utf-8"
|
|
@@ -3586,14 +3835,7 @@
|
|
|
3586
3835
|
if (blob.text && utf8) {
|
|
3587
3836
|
return blob.text();
|
|
3588
3837
|
} else {
|
|
3589
|
-
|
|
3590
|
-
return new Promise((resolve, reject) => {
|
|
3591
|
-
Object.assign(reader, {
|
|
3592
|
-
onload: ({ target }) => resolve(target.result),
|
|
3593
|
-
onerror: () => reject(reader.error)
|
|
3594
|
-
});
|
|
3595
|
-
reader.readAsText(blob, encoding);
|
|
3596
|
-
});
|
|
3838
|
+
return decodeTextRemovingBOM(new Uint8Array(await blob.arrayBuffer()), encoding);
|
|
3597
3839
|
}
|
|
3598
3840
|
}
|
|
3599
3841
|
}
|
|
@@ -4051,9 +4293,8 @@
|
|
|
4051
4293
|
|
|
4052
4294
|
async init() {
|
|
4053
4295
|
const reader = this;
|
|
4054
|
-
const { readers } = reader;
|
|
4055
4296
|
reader.lastDiskNumber = 0;
|
|
4056
|
-
await Promise.all(readers.map(
|
|
4297
|
+
const readers = reader.readers = await Promise.all(reader.readers.map(initDiskReader));
|
|
4057
4298
|
reader.diskOffsets = readers.map(diskReader => {
|
|
4058
4299
|
const diskOffset = reader.size;
|
|
4059
4300
|
reader.size += diskReader.size;
|
|
@@ -4248,89 +4489,27 @@
|
|
|
4248
4489
|
}
|
|
4249
4490
|
}
|
|
4250
4491
|
|
|
4251
|
-
function
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
Redistribution and use in source and binary forms, with or without
|
|
4259
|
-
modification, are permitted provided that the following conditions are met:
|
|
4260
|
-
|
|
4261
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
4262
|
-
this list of conditions and the following disclaimer.
|
|
4263
|
-
|
|
4264
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
4265
|
-
notice, this list of conditions and the following disclaimer in
|
|
4266
|
-
the documentation and/or other materials provided with the distribution.
|
|
4267
|
-
|
|
4268
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
4269
|
-
derived from this software without specific prior written permission.
|
|
4270
|
-
|
|
4271
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4272
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4273
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4274
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4275
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4276
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4277
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4278
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4279
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4280
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4281
|
-
*/
|
|
4282
|
-
|
|
4283
|
-
/* global TextDecoder */
|
|
4284
|
-
|
|
4285
|
-
const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
|
|
4286
|
-
const VALID_CP437 = CP437.length == 256;
|
|
4287
|
-
|
|
4288
|
-
function decodeCP437(stringValue) {
|
|
4289
|
-
if (VALID_CP437) {
|
|
4290
|
-
let result = "";
|
|
4291
|
-
for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
|
|
4292
|
-
result += CP437[stringValue[indexCharacter]];
|
|
4293
|
-
}
|
|
4294
|
-
return result;
|
|
4295
|
-
} else {
|
|
4296
|
-
return new TextDecoder().decode(stringValue);
|
|
4492
|
+
async function initDiskReader(diskReader) {
|
|
4493
|
+
diskReader = new GenericReader(diskReader);
|
|
4494
|
+
await initStream(diskReader);
|
|
4495
|
+
if (diskReader.size === UNDEFINED_VALUE || !diskReader.readUint8Array) {
|
|
4496
|
+
diskReader = new BlobReader(await streamToBlob(diskReader.readable));
|
|
4497
|
+
await initStream(diskReader);
|
|
4297
4498
|
}
|
|
4499
|
+
return diskReader;
|
|
4298
4500
|
}
|
|
4299
4501
|
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
Redistribution and use in source and binary forms, with or without
|
|
4304
|
-
modification, are permitted provided that the following conditions are met:
|
|
4305
|
-
|
|
4306
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
4307
|
-
this list of conditions and the following disclaimer.
|
|
4308
|
-
|
|
4309
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
4310
|
-
notice, this list of conditions and the following disclaimer in
|
|
4311
|
-
the documentation and/or other materials provided with the distribution.
|
|
4312
|
-
|
|
4313
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
4314
|
-
derived from this software without specific prior written permission.
|
|
4315
|
-
|
|
4316
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4317
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4318
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4319
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4320
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4321
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4322
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4323
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4324
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4325
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4326
|
-
*/
|
|
4327
|
-
|
|
4502
|
+
function readUint8Array(reader, offset, size) {
|
|
4503
|
+
return reader.readUint8Array(offset, size);
|
|
4504
|
+
}
|
|
4328
4505
|
|
|
4329
|
-
function
|
|
4330
|
-
if (
|
|
4331
|
-
return
|
|
4506
|
+
function createReadable(reader, options) {
|
|
4507
|
+
if (reader.createReadable) {
|
|
4508
|
+
return reader.createReadable(options);
|
|
4509
|
+
} else if (reader.readUint8Array) {
|
|
4510
|
+
return Reader.prototype.createReadable.call(reader, options);
|
|
4332
4511
|
} else {
|
|
4333
|
-
return
|
|
4512
|
+
return reader.readable;
|
|
4334
4513
|
}
|
|
4335
4514
|
}
|
|
4336
4515
|
|
|
@@ -4406,6 +4585,10 @@
|
|
|
4406
4585
|
const PROPERTY_NAME_SETGID = "setgid";
|
|
4407
4586
|
const PROPERTY_NAME_STICKY = "sticky";
|
|
4408
4587
|
const PROPERTY_NAME_BITFLAG = "bitFlag";
|
|
4588
|
+
const PROPERTY_NAME_RAW_BITFLAG = "rawBitFlag";
|
|
4589
|
+
const PROPERTY_NAME_FILENAME_LENGTH = "filenameLength";
|
|
4590
|
+
const PROPERTY_NAME_EXTRA_FIELD_LENGTH = "extraFieldLength";
|
|
4591
|
+
const PROPERTY_NAME_UNIX_EXTERNAL_UPPER = "unixExternalUpper";
|
|
4409
4592
|
const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
|
|
4410
4593
|
const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
|
|
4411
4594
|
const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
|
|
@@ -4458,10 +4641,14 @@
|
|
|
4458
4641
|
PROPERTY_NAME_UID,
|
|
4459
4642
|
PROPERTY_NAME_GID,
|
|
4460
4643
|
PROPERTY_NAME_UNIX_MODE,
|
|
4644
|
+
PROPERTY_NAME_UNIX_EXTERNAL_UPPER,
|
|
4461
4645
|
PROPERTY_NAME_SETUID,
|
|
4462
4646
|
PROPERTY_NAME_SETGID,
|
|
4463
4647
|
PROPERTY_NAME_STICKY,
|
|
4464
4648
|
PROPERTY_NAME_BITFLAG,
|
|
4649
|
+
PROPERTY_NAME_RAW_BITFLAG,
|
|
4650
|
+
PROPERTY_NAME_FILENAME_LENGTH,
|
|
4651
|
+
PROPERTY_NAME_EXTRA_FIELD_LENGTH,
|
|
4465
4652
|
PROPERTY_NAME_FILENAME_UTF8,
|
|
4466
4653
|
PROPERTY_NAME_COMMENT_UTF8,
|
|
4467
4654
|
PROPERTY_NAME_RAW_EXTRA_FIELD,
|
|
@@ -4482,82 +4669,6 @@
|
|
|
4482
4669
|
|
|
4483
4670
|
}
|
|
4484
4671
|
|
|
4485
|
-
/*
|
|
4486
|
-
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
4487
|
-
|
|
4488
|
-
Redistribution and use in source and binary forms, with or without
|
|
4489
|
-
modification, are permitted provided that the following conditions are met:
|
|
4490
|
-
|
|
4491
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
4492
|
-
this list of conditions and the following disclaimer.
|
|
4493
|
-
|
|
4494
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
4495
|
-
notice, this list of conditions and the following disclaimer in
|
|
4496
|
-
the documentation and/or other materials provided with the distribution.
|
|
4497
|
-
|
|
4498
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
4499
|
-
derived from this software without specific prior written permission.
|
|
4500
|
-
|
|
4501
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4502
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4503
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4504
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4505
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4506
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4507
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4508
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4509
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4510
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4511
|
-
*/
|
|
4512
|
-
|
|
4513
|
-
const OPTION_FILENAME_ENCODING = "filenameEncoding";
|
|
4514
|
-
const OPTION_COMMENT_ENCODING = "commentEncoding";
|
|
4515
|
-
const OPTION_DECODE_TEXT = "decodeText";
|
|
4516
|
-
const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
|
|
4517
|
-
const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
|
|
4518
|
-
const OPTION_PASSWORD = "password";
|
|
4519
|
-
const OPTION_RAW_PASSWORD = "rawPassword";
|
|
4520
|
-
const OPTION_PASS_THROUGH = "passThrough";
|
|
4521
|
-
const OPTION_SIGNAL = "signal";
|
|
4522
|
-
const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
|
|
4523
|
-
const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
|
|
4524
|
-
const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
|
|
4525
|
-
const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
|
|
4526
|
-
const OPTION_CHECK_SIGNATURE = "checkSignature";
|
|
4527
|
-
const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
4528
|
-
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
4529
|
-
const OPTION_USE_WEB_WORKERS = "useWebWorkers";
|
|
4530
|
-
const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
|
|
4531
|
-
const OPTION_TRANSFER_STREAMS = "transferStreams";
|
|
4532
|
-
const OPTION_PREVENT_CLOSE = "preventClose";
|
|
4533
|
-
const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
|
|
4534
|
-
const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
|
|
4535
|
-
const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
|
|
4536
|
-
const OPTION_KEEP_ORDER = "keepOrder";
|
|
4537
|
-
const OPTION_LEVEL = "level";
|
|
4538
|
-
const OPTION_BUFFERED_WRITE = "bufferedWrite";
|
|
4539
|
-
const OPTION_CREATE_TEMP_STREAM = "createTempStream";
|
|
4540
|
-
const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
|
|
4541
|
-
const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
|
|
4542
|
-
const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
|
|
4543
|
-
const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
|
|
4544
|
-
const OPTION_ENCODE_TEXT = "encodeText";
|
|
4545
|
-
const OPTION_OFFSET = "offset";
|
|
4546
|
-
const OPTION_USDZ = "usdz";
|
|
4547
|
-
const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
|
|
4548
|
-
const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
|
|
4549
|
-
const OPTION_STRICTNESS = "strictness";
|
|
4550
|
-
const OPTION_FILENAME_VALIDATION = "filenameValidation";
|
|
4551
|
-
const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
|
|
4552
|
-
const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
|
|
4553
|
-
const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
|
|
4554
|
-
const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
|
|
4555
|
-
const TEXT_TYPE_FILENAME = "filename";
|
|
4556
|
-
const TEXT_TYPE_COMMENT = "comment";
|
|
4557
|
-
const STRICTNESS_STRICT = "strict";
|
|
4558
|
-
const STRICTNESS_BALANCED = "balanced";
|
|
4559
|
-
const STRICTNESS_TOLERANT = "tolerant";
|
|
4560
|
-
|
|
4561
4672
|
/*
|
|
4562
4673
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4563
4674
|
|
|
@@ -4598,6 +4709,7 @@
|
|
|
4598
4709
|
const ERR_UNSUPPORTED_COMPRESSION$1 = "Compression method not supported";
|
|
4599
4710
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4600
4711
|
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4712
|
+
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4601
4713
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4602
4714
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
4603
4715
|
const ERR_UNSAFE_FILENAME = "Unsafe filename";
|
|
@@ -4618,7 +4730,7 @@
|
|
|
4618
4730
|
];
|
|
4619
4731
|
const ZIP64_EXTRACTION = {
|
|
4620
4732
|
[MAX_16_BITS]: {
|
|
4621
|
-
getValue: getUint32,
|
|
4733
|
+
getValue: getUint32$1,
|
|
4622
4734
|
bytes: 4
|
|
4623
4735
|
},
|
|
4624
4736
|
[MAX_32_BITS]: {
|
|
@@ -4627,6 +4739,7 @@
|
|
|
4627
4739
|
}
|
|
4628
4740
|
};
|
|
4629
4741
|
const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
|
|
4742
|
+
const MAX_DEFLATE_EXPANSION_RATIO = 1032;
|
|
4630
4743
|
const CENTRAL_DIRECTORY_UNREACHABLE = 0;
|
|
4631
4744
|
const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
|
|
4632
4745
|
const CENTRAL_DIRECTORY_REACHABLE = 2;
|
|
@@ -4637,7 +4750,6 @@
|
|
|
4637
4750
|
Object.assign(this, {
|
|
4638
4751
|
reader: new GenericReader(reader),
|
|
4639
4752
|
options,
|
|
4640
|
-
config: getConfiguration(),
|
|
4641
4753
|
readRanges: new Map()
|
|
4642
4754
|
});
|
|
4643
4755
|
}
|
|
@@ -4645,7 +4757,6 @@
|
|
|
4645
4757
|
async* getEntriesGenerator(options = {}) {
|
|
4646
4758
|
const zipReader = this;
|
|
4647
4759
|
let { reader } = zipReader;
|
|
4648
|
-
const { config } = zipReader;
|
|
4649
4760
|
await initStream(reader);
|
|
4650
4761
|
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
4651
4762
|
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
@@ -4654,7 +4765,7 @@
|
|
|
4654
4765
|
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
4655
4766
|
throw new Error(ERR_BAD_FORMAT);
|
|
4656
4767
|
}
|
|
4657
|
-
const strictness = getStrictness(
|
|
4768
|
+
const strictness = getStrictness(options, zipReader.options);
|
|
4658
4769
|
const checkAmbiguity = strictness == STRICTNESS_STRICT;
|
|
4659
4770
|
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
4660
4771
|
const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
|
|
@@ -4662,9 +4773,7 @@
|
|
|
4662
4773
|
const normalizeFilename = getOptionValue$1(zipReader, options, OPTION_NORMALIZE_FILENAME);
|
|
4663
4774
|
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
4664
4775
|
if (!endOfDirectoryInfo) {
|
|
4665
|
-
|
|
4666
|
-
const signatureView = getDataView(signatureArray);
|
|
4667
|
-
if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
|
|
4776
|
+
if (await startsWithSplitZipSignature$1(reader)) {
|
|
4668
4777
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4669
4778
|
} else {
|
|
4670
4779
|
throw new Error(ERR_EOCDR_NOT_FOUND);
|
|
@@ -4674,18 +4783,18 @@
|
|
|
4674
4783
|
throwAmbiguousArchive("multiple end of central directory records");
|
|
4675
4784
|
}
|
|
4676
4785
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
4677
|
-
let directoryDataLength = getUint32(endOfDirectoryView, 12);
|
|
4678
|
-
let directoryDataOffset = getUint32(endOfDirectoryView, 16);
|
|
4786
|
+
let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
|
|
4787
|
+
let directoryDataOffset = getUint32$1(endOfDirectoryView, 16);
|
|
4679
4788
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
4680
|
-
const commentLength = getUint16(endOfDirectoryView, 20);
|
|
4789
|
+
const commentLength = getUint16$1(endOfDirectoryView, 20);
|
|
4681
4790
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
4682
4791
|
if (reader.size - appendedDataOffset > maxAppendedDataSize) {
|
|
4683
4792
|
throwAmbiguousArchive("appended data");
|
|
4684
4793
|
}
|
|
4685
|
-
let lastDiskNumber = getUint16(endOfDirectoryView, 4);
|
|
4794
|
+
let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
|
|
4686
4795
|
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
4687
|
-
let diskNumber = getUint16(endOfDirectoryView, 6);
|
|
4688
|
-
let filesLength = getUint16(endOfDirectoryView, 10);
|
|
4796
|
+
let diskNumber = getUint16$1(endOfDirectoryView, 6);
|
|
4797
|
+
let filesLength = getUint16$1(endOfDirectoryView, 10);
|
|
4689
4798
|
let prependedDataLength = 0;
|
|
4690
4799
|
let startOffset;
|
|
4691
4800
|
let zip64EndOfDirectory;
|
|
@@ -4701,12 +4810,12 @@
|
|
|
4701
4810
|
EMPTY_UINT8_ARRAY;
|
|
4702
4811
|
const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
|
|
4703
4812
|
if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
|
|
4704
|
-
getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
4705
|
-
directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4813
|
+
getUint32$1(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
4814
|
+
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4706
4815
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4707
4816
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4708
4817
|
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4709
|
-
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
4818
|
+
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
4710
4819
|
directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
|
|
4711
4820
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4712
4821
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
@@ -4716,7 +4825,7 @@
|
|
|
4716
4825
|
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4717
4826
|
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4718
4827
|
}
|
|
4719
|
-
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4828
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4720
4829
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
4721
4830
|
}
|
|
4722
4831
|
zip64EndOfDirectory = true;
|
|
@@ -4731,13 +4840,13 @@
|
|
|
4731
4840
|
}
|
|
4732
4841
|
}
|
|
4733
4842
|
if (lastDiskNumber == MAX_16_BITS) {
|
|
4734
|
-
lastDiskNumber = getUint32(endOfDirectoryView, 16);
|
|
4735
|
-
} else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
|
|
4843
|
+
lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
|
|
4844
|
+
} else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
|
|
4736
4845
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
4737
4846
|
}
|
|
4738
4847
|
if (diskNumber == MAX_16_BITS) {
|
|
4739
|
-
diskNumber = getUint32(endOfDirectoryView, 20);
|
|
4740
|
-
} else if (checkAmbiguity && diskNumber != getUint32(endOfDirectoryView, 20)) {
|
|
4848
|
+
diskNumber = getUint32$1(endOfDirectoryView, 20);
|
|
4849
|
+
} else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
|
|
4741
4850
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
4742
4851
|
}
|
|
4743
4852
|
if (filesLength == MAX_16_BITS) {
|
|
@@ -4775,11 +4884,11 @@
|
|
|
4775
4884
|
}
|
|
4776
4885
|
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4777
4886
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4778
|
-
const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4887
|
+
const storedPointsAtDirectory = getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4779
4888
|
let reconcile = !storedPointsAtDirectory;
|
|
4780
4889
|
if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4781
4890
|
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
|
|
4782
|
-
reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4891
|
+
reconcile = getUint32$1(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4783
4892
|
}
|
|
4784
4893
|
if (reconcile) {
|
|
4785
4894
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -4803,10 +4912,10 @@
|
|
|
4803
4912
|
}
|
|
4804
4913
|
zipReader.directoryOffset = directoryDataOffset;
|
|
4805
4914
|
zipReader.directoryLength = declaredDirectoryDataLength;
|
|
4806
|
-
const decryptCentralDirectory =
|
|
4915
|
+
const decryptCentralDirectory = getFunctionOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
|
|
4807
4916
|
let decryptedDirectory;
|
|
4808
4917
|
if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
|
|
4809
|
-
getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
|
|
4918
|
+
getUint32$1(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
|
|
4810
4919
|
(zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4811
4920
|
directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
|
|
4812
4921
|
directoryView = getDataView(directoryArray);
|
|
@@ -4819,8 +4928,8 @@
|
|
|
4819
4928
|
const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
|
|
4820
4929
|
let duplicateFilename;
|
|
4821
4930
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4822
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
4823
|
-
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4931
|
+
const fileEntry = new ZipEntry$1(reader, zipReader.options);
|
|
4932
|
+
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4824
4933
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4825
4934
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
4826
4935
|
}
|
|
@@ -4831,16 +4940,16 @@
|
|
|
4831
4940
|
const filenameOffset = offset + CENTRAL_FILE_HEADER_LENGTH;
|
|
4832
4941
|
const extraFieldOffset = filenameOffset + fileEntry.filenameLength;
|
|
4833
4942
|
const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
|
|
4834
|
-
const versionMadeBy = getUint16(directoryView, offset + 4);
|
|
4943
|
+
const versionMadeBy = getUint16$1(directoryView, offset + 4);
|
|
4835
4944
|
const msDosCompatible = versionMadeBy >> 8 == 0;
|
|
4836
4945
|
const unixCompatible = versionMadeBy >> 8 == 3;
|
|
4837
4946
|
const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
|
|
4838
|
-
const commentLength = getUint16(directoryView, offset + 32);
|
|
4947
|
+
const commentLength = getUint16$1(directoryView, offset + 32);
|
|
4839
4948
|
const endOffset = commentOffset + commentLength;
|
|
4840
4949
|
const rawComment = directoryArray.subarray(commentOffset, endOffset);
|
|
4841
4950
|
const filenameUTF8 = languageEncodingFlag;
|
|
4842
4951
|
const commentUTF8 = languageEncodingFlag;
|
|
4843
|
-
const externalFileAttributes = getUint32(directoryView, offset + 38);
|
|
4952
|
+
const externalFileAttributes = getUint32$1(directoryView, offset + 38);
|
|
4844
4953
|
const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
|
|
4845
4954
|
const msdosAttributes = {
|
|
4846
4955
|
readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
|
|
@@ -4849,8 +4958,8 @@
|
|
|
4849
4958
|
directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
|
|
4850
4959
|
archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
|
|
4851
4960
|
};
|
|
4852
|
-
const offsetFileEntry = getUint32(directoryView, offset + 42);
|
|
4853
|
-
const decode =
|
|
4961
|
+
const offsetFileEntry = getUint32$1(directoryView, offset + 42);
|
|
4962
|
+
const decode = getFunctionOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
|
|
4854
4963
|
const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
|
|
4855
4964
|
const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
|
|
4856
4965
|
let filename = decode(rawFilename, rawFilenameEncoding, TEXT_TYPE_FILENAME);
|
|
@@ -4876,12 +4985,13 @@
|
|
|
4876
4985
|
index: indexFile,
|
|
4877
4986
|
versionMadeBy,
|
|
4878
4987
|
msDosCompatible,
|
|
4988
|
+
zip64: false,
|
|
4879
4989
|
compressedSize: 0,
|
|
4880
4990
|
uncompressedSize: 0,
|
|
4881
4991
|
commentLength,
|
|
4882
4992
|
offset: offsetFileEntry,
|
|
4883
|
-
diskNumberStart: getUint16(directoryView, offset + 34),
|
|
4884
|
-
internalFileAttributes: getUint16(directoryView, offset + 36),
|
|
4993
|
+
diskNumberStart: getUint16$1(directoryView, offset + 34),
|
|
4994
|
+
internalFileAttributes: getUint16$1(directoryView, offset + 36),
|
|
4885
4995
|
externalFileAttributes,
|
|
4886
4996
|
msdosAttributesRaw,
|
|
4887
4997
|
msdosAttributes,
|
|
@@ -4949,8 +5059,8 @@
|
|
|
4949
5059
|
yield entry;
|
|
4950
5060
|
}
|
|
4951
5061
|
let offsetAfterSignature = offset;
|
|
4952
|
-
if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
4953
|
-
const signatureDataLength = getUint16(directoryView, offset + 4);
|
|
5062
|
+
if (offset + 6 <= directoryArray.length && getUint32$1(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
5063
|
+
const signatureDataLength = getUint16$1(directoryView, offset + 4);
|
|
4954
5064
|
if (offset + 6 + signatureDataLength <= directoryArray.length) {
|
|
4955
5065
|
zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
|
|
4956
5066
|
offsetAfterSignature = offset + 6 + signatureDataLength;
|
|
@@ -4962,13 +5072,17 @@
|
|
|
4962
5072
|
if (duplicateFilename) {
|
|
4963
5073
|
throwAmbiguousArchive("duplicate filename");
|
|
4964
5074
|
}
|
|
4965
|
-
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > 0))) {
|
|
4966
|
-
throwAmbiguousArchive("prepended data");
|
|
4967
|
-
}
|
|
4968
5075
|
const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
|
|
4969
5076
|
const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
|
|
5077
|
+
const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
|
|
5078
|
+
startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
|
|
5079
|
+
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
|
|
5080
|
+
throwAmbiguousArchive("prepended data");
|
|
5081
|
+
}
|
|
4970
5082
|
if (extractPrependedData) {
|
|
4971
|
-
zipReader.prependedData = startOffset >
|
|
5083
|
+
zipReader.prependedData = startOffset > splitZipSignatureLength ?
|
|
5084
|
+
await readUint8Array(reader, splitZipSignatureLength, startOffset - splitZipSignatureLength) :
|
|
5085
|
+
EMPTY_UINT8_ARRAY;
|
|
4972
5086
|
}
|
|
4973
5087
|
zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : EMPTY_UINT8_ARRAY;
|
|
4974
5088
|
if (extractAppendedData) {
|
|
@@ -5035,16 +5149,16 @@
|
|
|
5035
5149
|
|
|
5036
5150
|
let ZipEntry$1 = class ZipEntry {
|
|
5037
5151
|
|
|
5038
|
-
constructor(reader,
|
|
5152
|
+
constructor(reader, options) {
|
|
5039
5153
|
Object.assign(this, {
|
|
5040
5154
|
reader,
|
|
5041
|
-
config,
|
|
5042
5155
|
options
|
|
5043
5156
|
});
|
|
5044
5157
|
}
|
|
5045
5158
|
|
|
5046
5159
|
async getData(writer, fileEntry, readRanges, options = {}) {
|
|
5047
5160
|
const zipEntry = this;
|
|
5161
|
+
const config = getConfiguration();
|
|
5048
5162
|
const {
|
|
5049
5163
|
reader,
|
|
5050
5164
|
index,
|
|
@@ -5053,7 +5167,6 @@
|
|
|
5053
5167
|
extraFieldAES,
|
|
5054
5168
|
extraFieldZip64,
|
|
5055
5169
|
compressionMethod,
|
|
5056
|
-
config,
|
|
5057
5170
|
bitFlag,
|
|
5058
5171
|
rawBitFlag,
|
|
5059
5172
|
crc32,
|
|
@@ -5071,6 +5184,7 @@
|
|
|
5071
5184
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
5072
5185
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
5073
5186
|
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
5187
|
+
checkPasswordOption(password, rawPassword);
|
|
5074
5188
|
password = password && password.length && password;
|
|
5075
5189
|
rawPassword = rawPassword && rawPassword.length && rawPassword;
|
|
5076
5190
|
if (extraFieldAES) {
|
|
@@ -5078,7 +5192,7 @@
|
|
|
5078
5192
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
|
|
5079
5193
|
}
|
|
5080
5194
|
}
|
|
5081
|
-
if (dataArray.length < HEADER_SIZE || getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
5195
|
+
if (dataArray.length < HEADER_SIZE || getUint32$1(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
5082
5196
|
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
5083
5197
|
}
|
|
5084
5198
|
readCommonHeader(localDirectory, dataView, 4);
|
|
@@ -5086,9 +5200,12 @@
|
|
|
5086
5200
|
extraFieldLength,
|
|
5087
5201
|
filenameLength
|
|
5088
5202
|
} = localDirectory;
|
|
5089
|
-
const
|
|
5203
|
+
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5204
|
+
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5205
|
+
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
5206
|
+
const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
|
|
5090
5207
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
5091
|
-
if (
|
|
5208
|
+
if (checkLocalFilename && (filenameLength || extraFieldLength)) {
|
|
5092
5209
|
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
5093
5210
|
rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
|
|
5094
5211
|
localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
|
|
@@ -5097,17 +5214,26 @@
|
|
|
5097
5214
|
await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
|
|
5098
5215
|
EMPTY_UINT8_ARRAY;
|
|
5099
5216
|
}
|
|
5217
|
+
if (checkLocalFilename) {
|
|
5218
|
+
localDirectory.rawFilename = rawLocalFilename;
|
|
5219
|
+
}
|
|
5100
5220
|
readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
|
|
5101
|
-
if (
|
|
5102
|
-
|
|
5221
|
+
if (checkLocalDirectory) {
|
|
5222
|
+
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
|
|
5103
5223
|
}
|
|
5104
|
-
const { lastAccessDate, creationDate } = localDirectory;
|
|
5224
|
+
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5105
5225
|
if (lastAccessDate) {
|
|
5106
5226
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5107
5227
|
}
|
|
5108
5228
|
if (creationDate) {
|
|
5109
5229
|
fileEntry.creationDate = creationDate;
|
|
5110
5230
|
}
|
|
5231
|
+
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
5232
|
+
fileEntry.uid = uid;
|
|
5233
|
+
}
|
|
5234
|
+
if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
|
|
5235
|
+
fileEntry.gid = gid;
|
|
5236
|
+
}
|
|
5111
5237
|
const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
|
|
5112
5238
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
5113
5239
|
if (!passThrough) {
|
|
@@ -5128,9 +5254,12 @@
|
|
|
5128
5254
|
}
|
|
5129
5255
|
}
|
|
5130
5256
|
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
5257
|
+
if (dataOffset + compressedSize > reader.size) {
|
|
5258
|
+
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5259
|
+
}
|
|
5131
5260
|
const size = compressedSize;
|
|
5132
5261
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5133
|
-
const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
|
|
5262
|
+
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5134
5263
|
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5135
5264
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
5136
5265
|
const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
|
|
@@ -5138,6 +5267,8 @@
|
|
|
5138
5267
|
checkOverlappingEntry = true;
|
|
5139
5268
|
}
|
|
5140
5269
|
const { onstart, onprogress, onend } = options;
|
|
5270
|
+
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
|
|
5271
|
+
const outputSize = passThrough ? compressedSize : uncompressedSize;
|
|
5141
5272
|
const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
|
|
5142
5273
|
let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5143
5274
|
if (deflate64) {
|
|
@@ -5158,9 +5289,9 @@
|
|
|
5158
5289
|
checkCrc32,
|
|
5159
5290
|
checkAuthenticationCode: getOptionValue$1(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
|
|
5160
5291
|
passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((crc32 >>> 24) & MAX_8_BITS)),
|
|
5161
|
-
outputSize
|
|
5292
|
+
outputSize,
|
|
5162
5293
|
crc32,
|
|
5163
|
-
compressed
|
|
5294
|
+
compressed,
|
|
5164
5295
|
encrypted,
|
|
5165
5296
|
useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
|
|
5166
5297
|
useCompressionStream,
|
|
@@ -5197,11 +5328,11 @@
|
|
|
5197
5328
|
writer = new WritableStream();
|
|
5198
5329
|
}
|
|
5199
5330
|
writer = new GenericWriter(writer);
|
|
5200
|
-
await initStream(writer,
|
|
5331
|
+
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5201
5332
|
({ writable } = writer);
|
|
5202
|
-
const { outputSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5203
|
-
writer.size +=
|
|
5204
|
-
if (
|
|
5333
|
+
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5334
|
+
writer.size += writtenSize;
|
|
5335
|
+
if (writtenSize != outputSize) {
|
|
5205
5336
|
throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
5206
5337
|
}
|
|
5207
5338
|
}
|
|
@@ -5235,7 +5366,7 @@
|
|
|
5235
5366
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5236
5367
|
const maxOffset = Math.min(directoryView.byteLength, 1024) - 3;
|
|
5237
5368
|
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5238
|
-
if (getUint32(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5369
|
+
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5239
5370
|
return true;
|
|
5240
5371
|
}
|
|
5241
5372
|
}
|
|
@@ -5246,15 +5377,15 @@
|
|
|
5246
5377
|
const directoryEncryptionInfo = { rawExtensibleData };
|
|
5247
5378
|
if (rawExtensibleData.length >= 28) {
|
|
5248
5379
|
const extensibleDataView = getDataView(rawExtensibleData);
|
|
5249
|
-
const hashDataLength = getUint16(extensibleDataView, 26);
|
|
5380
|
+
const hashDataLength = getUint16$1(extensibleDataView, 26);
|
|
5250
5381
|
Object.assign(directoryEncryptionInfo, {
|
|
5251
|
-
compressionMethod: getUint16(extensibleDataView, 0),
|
|
5382
|
+
compressionMethod: getUint16$1(extensibleDataView, 0),
|
|
5252
5383
|
compressedSize: Number(getBigUint64(extensibleDataView, 2)),
|
|
5253
5384
|
uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
|
|
5254
|
-
encryptionAlgorithm: getUint16(extensibleDataView, 18),
|
|
5255
|
-
bitLength: getUint16(extensibleDataView, 20),
|
|
5256
|
-
flags: getUint16(extensibleDataView, 22),
|
|
5257
|
-
hashAlgorithm: getUint16(extensibleDataView, 24),
|
|
5385
|
+
encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
|
|
5386
|
+
bitLength: getUint16$1(extensibleDataView, 20),
|
|
5387
|
+
flags: getUint16$1(extensibleDataView, 22),
|
|
5388
|
+
hashAlgorithm: getUint16$1(extensibleDataView, 24),
|
|
5258
5389
|
hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
|
|
5259
5390
|
});
|
|
5260
5391
|
}
|
|
@@ -5262,12 +5393,12 @@
|
|
|
5262
5393
|
}
|
|
5263
5394
|
|
|
5264
5395
|
function readCommonHeader(directory, dataView, offset) {
|
|
5265
|
-
const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
|
|
5396
|
+
const rawBitFlag = directory.rawBitFlag = getUint16$1(dataView, offset + 2);
|
|
5266
5397
|
const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
|
|
5267
|
-
const rawLastModDate = getUint32(dataView, offset + 6);
|
|
5398
|
+
const rawLastModDate = getUint32$1(dataView, offset + 6);
|
|
5268
5399
|
Object.assign(directory, {
|
|
5269
5400
|
encrypted,
|
|
5270
|
-
version: getUint16(dataView, offset),
|
|
5401
|
+
version: getUint16$1(dataView, offset),
|
|
5271
5402
|
bitFlag: {
|
|
5272
5403
|
level: (rawBitFlag & BITFLAG_LEVEL) >> 1,
|
|
5273
5404
|
dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR,
|
|
@@ -5275,8 +5406,8 @@
|
|
|
5275
5406
|
},
|
|
5276
5407
|
rawLastModDate,
|
|
5277
5408
|
lastModDate: getDate(rawLastModDate),
|
|
5278
|
-
filenameLength: getUint16(dataView, offset + 22),
|
|
5279
|
-
extraFieldLength: getUint16(dataView, offset + 24)
|
|
5409
|
+
filenameLength: getUint16$1(dataView, offset + 22),
|
|
5410
|
+
extraFieldLength: getUint16$1(dataView, offset + 24)
|
|
5280
5411
|
});
|
|
5281
5412
|
}
|
|
5282
5413
|
|
|
@@ -5287,8 +5418,8 @@
|
|
|
5287
5418
|
let offsetExtraField = 0;
|
|
5288
5419
|
try {
|
|
5289
5420
|
while (offsetExtraField < rawExtraField.length) {
|
|
5290
|
-
const type = getUint16(rawExtraFieldView, offsetExtraField);
|
|
5291
|
-
const size = getUint16(rawExtraFieldView, offsetExtraField + 2);
|
|
5421
|
+
const type = getUint16$1(rawExtraFieldView, offsetExtraField);
|
|
5422
|
+
const size = getUint16$1(rawExtraFieldView, offsetExtraField + 2);
|
|
5292
5423
|
extraField.set(type, {
|
|
5293
5424
|
type,
|
|
5294
5425
|
data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size)
|
|
@@ -5298,12 +5429,12 @@
|
|
|
5298
5429
|
} catch {
|
|
5299
5430
|
// ignored
|
|
5300
5431
|
}
|
|
5301
|
-
const compressionMethod = getUint16(dataView, offset + 4);
|
|
5432
|
+
const compressionMethod = getUint16$1(dataView, offset + 4);
|
|
5302
5433
|
Object.assign(directory, {
|
|
5303
|
-
signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5304
|
-
crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5305
|
-
compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
|
|
5306
|
-
uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5434
|
+
signature: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5435
|
+
crc32: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5436
|
+
compressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
|
|
5437
|
+
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5307
5438
|
});
|
|
5308
5439
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5309
5440
|
if (extraFieldZip64) {
|
|
@@ -5343,10 +5474,12 @@
|
|
|
5343
5474
|
directory.extraFieldNTFS = extraFieldNTFS;
|
|
5344
5475
|
}
|
|
5345
5476
|
const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
|
|
5477
|
+
let unixIdsRead;
|
|
5346
5478
|
if (extraFieldUnix) {
|
|
5347
|
-
readExtraFieldUnix(extraFieldUnix, directory, false);
|
|
5479
|
+
unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
|
|
5348
5480
|
directory.extraFieldUnix = extraFieldUnix;
|
|
5349
|
-
}
|
|
5481
|
+
}
|
|
5482
|
+
if (!unixIdsRead) {
|
|
5350
5483
|
const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
|
|
5351
5484
|
if (extraFieldInfoZip) {
|
|
5352
5485
|
readExtraFieldUnix(extraFieldInfoZip, directory, true);
|
|
@@ -5390,11 +5523,11 @@
|
|
|
5390
5523
|
computedCrc32.append(fileEntry[rawPropertyName]);
|
|
5391
5524
|
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
5392
5525
|
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
5393
|
-
const nameCrc32 = getUint32(extraFieldView, 1);
|
|
5526
|
+
const nameCrc32 = getUint32$1(extraFieldView, 1);
|
|
5394
5527
|
Object.assign(extraFieldUnicode, {
|
|
5395
5528
|
version: getUint8(extraFieldView, 0),
|
|
5396
5529
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
5397
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32(computedCrc32View, 0)
|
|
5530
|
+
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5398
5531
|
});
|
|
5399
5532
|
if (extraFieldUnicode.valid) {
|
|
5400
5533
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -5410,7 +5543,7 @@
|
|
|
5410
5543
|
vendorId: getUint8(extraFieldView, 2),
|
|
5411
5544
|
strength,
|
|
5412
5545
|
originalCompressionMethod: compressionMethod,
|
|
5413
|
-
compressionMethod: getUint16(extraFieldView, 5)
|
|
5546
|
+
compressionMethod: getUint16$1(extraFieldView, 5)
|
|
5414
5547
|
});
|
|
5415
5548
|
directory.compressionMethod = extraFieldAES.compressionMethod;
|
|
5416
5549
|
if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1$1) {
|
|
@@ -5424,8 +5557,8 @@
|
|
|
5424
5557
|
let tag1Data;
|
|
5425
5558
|
try {
|
|
5426
5559
|
while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) {
|
|
5427
|
-
const tagValue = getUint16(extraFieldView, offsetExtraField);
|
|
5428
|
-
const attributeSize = getUint16(extraFieldView, offsetExtraField + 2);
|
|
5560
|
+
const tagValue = getUint16$1(extraFieldView, offsetExtraField);
|
|
5561
|
+
const attributeSize = getUint16$1(extraFieldView, offsetExtraField + 2);
|
|
5429
5562
|
if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) {
|
|
5430
5563
|
tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize);
|
|
5431
5564
|
}
|
|
@@ -5449,7 +5582,7 @@
|
|
|
5449
5582
|
const creationDate = getDateNTFS(rawCreationDate);
|
|
5450
5583
|
const extraFieldData = { lastModDate, lastAccessDate, creationDate };
|
|
5451
5584
|
Object.assign(extraFieldNTFS, extraFieldData);
|
|
5452
|
-
Object.assign(directory, extraFieldData);
|
|
5585
|
+
Object.assign(directory, extraFieldData, { rawLastAccessDate, rawCreationDate });
|
|
5453
5586
|
}
|
|
5454
5587
|
}
|
|
5455
5588
|
|
|
@@ -5458,12 +5591,12 @@
|
|
|
5458
5591
|
return;
|
|
5459
5592
|
}
|
|
5460
5593
|
const extraFieldView = getDataView(extraField.data);
|
|
5461
|
-
const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
|
|
5462
|
-
const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
|
|
5594
|
+
const lastAccessDate = new Date((getUint32$1(extraFieldView, 0) | 0) * 1000);
|
|
5595
|
+
const lastModDate = new Date((getUint32$1(extraFieldView, 4) | 0) * 1000);
|
|
5463
5596
|
const extraFieldData = { lastAccessDate, lastModDate };
|
|
5464
5597
|
if (extraField.data.length >= 12) {
|
|
5465
|
-
extraFieldData.uid = getUint16(extraFieldView, 8);
|
|
5466
|
-
extraFieldData.gid = getUint16(extraFieldView, 10);
|
|
5598
|
+
extraFieldData.uid = getUint16$1(extraFieldView, 8);
|
|
5599
|
+
extraFieldData.gid = getUint16$1(extraFieldView, 10);
|
|
5467
5600
|
}
|
|
5468
5601
|
Object.assign(extraField, extraFieldData);
|
|
5469
5602
|
Object.assign(directory, extraFieldData);
|
|
@@ -5483,8 +5616,8 @@
|
|
|
5483
5616
|
gid = unpackUnixId(extraField.data.subarray(offset, offset + gidSize));
|
|
5484
5617
|
Object.assign(extraField, { version, uid, gid });
|
|
5485
5618
|
} else if (extraField.data.length >= 4) {
|
|
5486
|
-
uid = getUint16(view, 0);
|
|
5487
|
-
gid = getUint16(view, 2);
|
|
5619
|
+
uid = getUint16$1(view, 0);
|
|
5620
|
+
gid = getUint16$1(view, 2);
|
|
5488
5621
|
Object.assign(extraField, { uid, gid });
|
|
5489
5622
|
}
|
|
5490
5623
|
if (uid !== UNDEFINED_VALUE) {
|
|
@@ -5493,6 +5626,7 @@
|
|
|
5493
5626
|
if (gid !== UNDEFINED_VALUE) {
|
|
5494
5627
|
directory.gid = gid;
|
|
5495
5628
|
}
|
|
5629
|
+
return uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE;
|
|
5496
5630
|
} catch {
|
|
5497
5631
|
// ignored
|
|
5498
5632
|
}
|
|
@@ -5533,7 +5667,7 @@
|
|
|
5533
5667
|
let offset = 1;
|
|
5534
5668
|
timeProperties.forEach((propertyName, indexProperty) => {
|
|
5535
5669
|
if (extraFieldExtendedTimestamp.data.length >= offset + 4) {
|
|
5536
|
-
const time = getUint32(extraFieldView, offset);
|
|
5670
|
+
const time = getUint32$1(extraFieldView, offset);
|
|
5537
5671
|
directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date((time | 0) * 1000);
|
|
5538
5672
|
const rawPropertyName = timeRawProperties[indexProperty];
|
|
5539
5673
|
extraFieldExtendedTimestamp[rawPropertyName] = time;
|
|
@@ -5565,26 +5699,25 @@
|
|
|
5565
5699
|
}
|
|
5566
5700
|
if (dataDescriptorLength) {
|
|
5567
5701
|
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
|
|
5568
|
-
const
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
if (extraFieldZip64) {
|
|
5575
|
-
readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
|
|
5576
|
-
readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
|
|
5577
|
-
} else {
|
|
5578
|
-
readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
|
|
5579
|
-
readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
|
|
5580
|
-
}
|
|
5581
|
-
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
|
|
5702
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
5703
|
+
let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
5704
|
+
getUint32$1(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
5705
|
+
if (signature) {
|
|
5706
|
+
const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
|
|
5707
|
+
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
|
|
5582
5708
|
if (matchCrc32 &&
|
|
5583
|
-
|
|
5584
|
-
|
|
5709
|
+
signedDataDescriptor.compressedSize == compressedSize &&
|
|
5710
|
+
signedDataDescriptor.uncompressedSize == uncompressedSize) {
|
|
5585
5711
|
dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
5712
|
+
} else {
|
|
5713
|
+
signature = false;
|
|
5586
5714
|
}
|
|
5587
5715
|
}
|
|
5716
|
+
if (dataDescriptorArray.length >= dataDescriptorLength) {
|
|
5717
|
+
const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
|
|
5718
|
+
localDataDescriptor.signature = signature;
|
|
5719
|
+
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
5720
|
+
}
|
|
5588
5721
|
}
|
|
5589
5722
|
const range = {
|
|
5590
5723
|
start: offset,
|
|
@@ -5601,22 +5734,80 @@
|
|
|
5601
5734
|
readRanges.set(index, range);
|
|
5602
5735
|
}
|
|
5603
5736
|
|
|
5737
|
+
function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
|
|
5738
|
+
const crc32 = getUint32$1(dataDescriptorView, offset);
|
|
5739
|
+
let compressedSize;
|
|
5740
|
+
let uncompressedSize;
|
|
5741
|
+
if (extraFieldZip64) {
|
|
5742
|
+
compressedSize = getBigUint64(dataDescriptorView, offset + 4);
|
|
5743
|
+
uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
|
|
5744
|
+
} else {
|
|
5745
|
+
compressedSize = getUint32$1(dataDescriptorView, offset + 4);
|
|
5746
|
+
uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
|
|
5747
|
+
}
|
|
5748
|
+
return { crc32, compressedSize, uncompressedSize };
|
|
5749
|
+
}
|
|
5750
|
+
|
|
5604
5751
|
function getDiskOffset$1(reader, diskNumber) {
|
|
5605
5752
|
return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
|
|
5606
5753
|
}
|
|
5607
5754
|
|
|
5755
|
+
async function startsWithSplitZipSignature$1(reader) {
|
|
5756
|
+
return await getFirstSignature(reader) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
5757
|
+
}
|
|
5758
|
+
|
|
5759
|
+
async function startsWithSplitZipMarker(reader) {
|
|
5760
|
+
const signature = await getFirstSignature(reader);
|
|
5761
|
+
return signature == SPLIT_ZIP_FILE_SIGNATURE || signature == TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE;
|
|
5762
|
+
}
|
|
5763
|
+
|
|
5764
|
+
async function getFirstSignature(reader) {
|
|
5765
|
+
const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
5766
|
+
return getUint32$1(getDataView(signatureArray));
|
|
5767
|
+
}
|
|
5768
|
+
|
|
5608
5769
|
function isStrictnessValue(value) {
|
|
5609
5770
|
return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
|
|
5610
5771
|
}
|
|
5611
5772
|
|
|
5612
|
-
function
|
|
5613
|
-
|
|
5614
|
-
|
|
5773
|
+
function getDecodableOutputSize(outputSize, compressedSize, compressed) {
|
|
5774
|
+
return Math.min(outputSize, compressed ? compressedSize * MAX_DEFLATE_EXPANSION_RATIO : compressedSize);
|
|
5775
|
+
}
|
|
5776
|
+
|
|
5777
|
+
function getStrictness(options, inheritedOptions) {
|
|
5778
|
+
return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
|
|
5779
|
+
}
|
|
5780
|
+
|
|
5781
|
+
function resolveStrictness(options, inheritedStrictness) {
|
|
5782
|
+
const strictness = options[OPTION_STRICTNESS];
|
|
5783
|
+
if (strictness !== UNDEFINED_VALUE) {
|
|
5784
|
+
if (!isStrictnessValue(strictness)) {
|
|
5785
|
+
throw new Error(ERR_INVALID_STRICTNESS);
|
|
5786
|
+
}
|
|
5787
|
+
return strictness;
|
|
5788
|
+
}
|
|
5789
|
+
const checkAmbiguity = options[OPTION_CHECK_AMBIGUITY];
|
|
5790
|
+
if (checkAmbiguity === UNDEFINED_VALUE) {
|
|
5791
|
+
return inheritedStrictness;
|
|
5615
5792
|
}
|
|
5616
|
-
if (
|
|
5617
|
-
|
|
5793
|
+
if (checkAmbiguity) {
|
|
5794
|
+
return STRICTNESS_STRICT;
|
|
5618
5795
|
}
|
|
5619
|
-
return
|
|
5796
|
+
return inheritedStrictness == STRICTNESS_TOLERANT ? STRICTNESS_TOLERANT : STRICTNESS_BALANCED;
|
|
5797
|
+
}
|
|
5798
|
+
|
|
5799
|
+
function getCheckLocalDirectory(checkLocalDirectory, strictness) {
|
|
5800
|
+
if (checkLocalDirectory === UNDEFINED_VALUE) {
|
|
5801
|
+
return strictness != STRICTNESS_TOLERANT;
|
|
5802
|
+
}
|
|
5803
|
+
return Boolean(checkLocalDirectory);
|
|
5804
|
+
}
|
|
5805
|
+
|
|
5806
|
+
function getCheckLocalFilename(checkLocalFilename, strictness) {
|
|
5807
|
+
if (checkLocalFilename === UNDEFINED_VALUE) {
|
|
5808
|
+
return strictness == STRICTNESS_STRICT;
|
|
5809
|
+
}
|
|
5810
|
+
return Boolean(checkLocalFilename);
|
|
5620
5811
|
}
|
|
5621
5812
|
|
|
5622
5813
|
function getFilenameValidation(filenameValidation, strictness) {
|
|
@@ -5645,7 +5836,7 @@
|
|
|
5645
5836
|
|
|
5646
5837
|
function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
|
|
5647
5838
|
if (maxAppendedDataSize !== UNDEFINED_VALUE) {
|
|
5648
|
-
const size = toNumber
|
|
5839
|
+
const size = toNumber(maxAppendedDataSize);
|
|
5649
5840
|
if (typeof size != NUMBER_TYPE || Number.isNaN(size) || size < 0) {
|
|
5650
5841
|
throw new Error(ERR_INVALID_MAX_APPENDED_DATA_SIZE);
|
|
5651
5842
|
}
|
|
@@ -5668,7 +5859,7 @@
|
|
|
5668
5859
|
let plausibleEndOfDirectoryInfo;
|
|
5669
5860
|
let endOfDirectoryReachingEndCount = 0;
|
|
5670
5861
|
for await (const [anchoredView, anchoredOffset, anchoredArray, indexByte, offset] of scanEndOfCentralDirectory(reader, anchoredLength)) {
|
|
5671
|
-
const commentLength = getUint16(anchoredView, indexByte + 20);
|
|
5862
|
+
const commentLength = getUint16$1(anchoredView, indexByte + 20);
|
|
5672
5863
|
if (offset + END_OF_CENTRAL_DIR_LENGTH + commentLength == size) {
|
|
5673
5864
|
const reachability = await getCentralDirectoryReachability(reader, anchoredView, anchoredOffset, indexByte, offset, size, remoteProbeBudget);
|
|
5674
5865
|
if (reachability == CENTRAL_DIRECTORY_REACHABLE) {
|
|
@@ -5719,7 +5910,7 @@
|
|
|
5719
5910
|
const scanArray = await readUint8Array(reader, scanOffset, scanLength);
|
|
5720
5911
|
const scanView = getDataView(scanArray);
|
|
5721
5912
|
for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5722
|
-
if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
5913
|
+
if (getUint32$1(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
5723
5914
|
yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
|
|
5724
5915
|
}
|
|
5725
5916
|
}
|
|
@@ -5730,9 +5921,9 @@
|
|
|
5730
5921
|
}
|
|
5731
5922
|
|
|
5732
5923
|
async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
|
|
5733
|
-
const filesLength = getUint16(view, indexByte + 10);
|
|
5734
|
-
const directoryDataLength = getUint32(view, indexByte + 12);
|
|
5735
|
-
const directoryDataOffset = getUint32(view, indexByte + 16);
|
|
5924
|
+
const filesLength = getUint16$1(view, indexByte + 10);
|
|
5925
|
+
const directoryDataLength = getUint32$1(view, indexByte + 12);
|
|
5926
|
+
const directoryDataOffset = getUint32$1(view, indexByte + 16);
|
|
5736
5927
|
if (filesLength == MAX_16_BITS || directoryDataLength == MAX_32_BITS || directoryDataOffset == MAX_32_BITS) {
|
|
5737
5928
|
const locatorSignature = await readSignature(reader, view, anchoredOffset, offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, size, remoteProbeBudget);
|
|
5738
5929
|
return locatorSignature == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE ? CENTRAL_DIRECTORY_REACHABLE : CENTRAL_DIRECTORY_UNREACHABLE;
|
|
@@ -5740,7 +5931,7 @@
|
|
|
5740
5931
|
if (!filesLength && !directoryDataLength) {
|
|
5741
5932
|
return CENTRAL_DIRECTORY_PLAUSIBLE;
|
|
5742
5933
|
}
|
|
5743
|
-
const directoryDiskNumber = getUint16(view, indexByte + 6);
|
|
5934
|
+
const directoryDiskNumber = getUint16$1(view, indexByte + 6);
|
|
5744
5935
|
for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
|
|
5745
5936
|
if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5746
5937
|
return CENTRAL_DIRECTORY_REACHABLE;
|
|
@@ -5754,20 +5945,21 @@
|
|
|
5754
5945
|
return UNDEFINED_VALUE;
|
|
5755
5946
|
}
|
|
5756
5947
|
if (signatureOffset >= anchoredOffset) {
|
|
5757
|
-
return getUint32(view, signatureOffset - anchoredOffset);
|
|
5948
|
+
return getUint32$1(view, signatureOffset - anchoredOffset);
|
|
5758
5949
|
}
|
|
5759
5950
|
if (remoteProbeBudget.count > 0) {
|
|
5760
5951
|
remoteProbeBudget.count--;
|
|
5761
5952
|
const signatureArray = await readUint8Array(reader, signatureOffset, 4);
|
|
5762
|
-
return getUint32(getDataView(signatureArray), 0);
|
|
5953
|
+
return getUint32$1(getDataView(signatureArray), 0);
|
|
5763
5954
|
}
|
|
5764
5955
|
return UNDEFINED_VALUE;
|
|
5765
5956
|
}
|
|
5766
5957
|
|
|
5767
|
-
function
|
|
5958
|
+
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
|
|
5768
5959
|
const { rawFilename } = zipEntry;
|
|
5769
|
-
if (
|
|
5770
|
-
rawLocalFilename.
|
|
5960
|
+
if (checkLocalFilename &&
|
|
5961
|
+
(rawLocalFilename.length != rawFilename.length ||
|
|
5962
|
+
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
5771
5963
|
throwAmbiguousArchive("mismatched local file header (filename)");
|
|
5772
5964
|
}
|
|
5773
5965
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
@@ -5795,10 +5987,11 @@
|
|
|
5795
5987
|
return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
|
|
5796
5988
|
}
|
|
5797
5989
|
|
|
5798
|
-
function
|
|
5799
|
-
return
|
|
5990
|
+
function getFunctionOptionValue$1(zipReader, options, name) {
|
|
5991
|
+
return checkFunctionOption(getOptionValue$1(zipReader, options, name));
|
|
5800
5992
|
}
|
|
5801
5993
|
|
|
5994
|
+
|
|
5802
5995
|
function getDate(timeRaw) {
|
|
5803
5996
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
5804
5997
|
return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
@@ -5812,11 +6005,11 @@
|
|
|
5812
6005
|
return view.getUint8(offset);
|
|
5813
6006
|
}
|
|
5814
6007
|
|
|
5815
|
-
function getUint16(view, offset) {
|
|
6008
|
+
function getUint16$1(view, offset) {
|
|
5816
6009
|
return view.getUint16(offset, true);
|
|
5817
6010
|
}
|
|
5818
6011
|
|
|
5819
|
-
function getUint32(view, offset) {
|
|
6012
|
+
function getUint32$1(view, offset) {
|
|
5820
6013
|
return view.getUint32(offset, true);
|
|
5821
6014
|
}
|
|
5822
6015
|
|
|
@@ -5831,6 +6024,7 @@
|
|
|
5831
6024
|
ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
|
|
5832
6025
|
ERR_ENCRYPTED: ERR_ENCRYPTED,
|
|
5833
6026
|
ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
|
|
6027
|
+
ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
|
|
5834
6028
|
ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
|
|
5835
6029
|
ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
|
|
5836
6030
|
ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
@@ -5885,13 +6079,18 @@
|
|
|
5885
6079
|
|
|
5886
6080
|
const ERR_DUPLICATED_NAME = "File already exists";
|
|
5887
6081
|
const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
|
|
6082
|
+
const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
|
|
5888
6083
|
const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
|
|
6084
|
+
const ERR_INVALID_ENTRY_COMMENT_TYPE = "Invalid file entry comment (must be a string)";
|
|
6085
|
+
const ERR_INVALID_DATE = "Invalid date (must be a valid Date instance)";
|
|
5889
6086
|
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
5890
6087
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
5891
6088
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
5892
6089
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
5893
6090
|
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
5894
|
-
const
|
|
6091
|
+
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
6092
|
+
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
6093
|
+
const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
|
|
5895
6094
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
5896
6095
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
5897
6096
|
const MIN_UNIX_TIME = -2147483648;
|
|
@@ -5911,7 +6110,6 @@
|
|
|
5911
6110
|
const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
|
|
5912
6111
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
5913
6112
|
const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
|
|
5914
|
-
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
5915
6113
|
const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
5916
6114
|
|
|
5917
6115
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
@@ -5936,8 +6134,7 @@
|
|
|
5936
6134
|
writer,
|
|
5937
6135
|
addSplitZipSignature,
|
|
5938
6136
|
options,
|
|
5939
|
-
|
|
5940
|
-
files: new Map(),
|
|
6137
|
+
fileEntries: new Map(),
|
|
5941
6138
|
filenames: new Set(),
|
|
5942
6139
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
5943
6140
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
@@ -5953,15 +6150,28 @@
|
|
|
5953
6150
|
}
|
|
5954
6151
|
reader = new GenericReader(reader);
|
|
5955
6152
|
await initStream(reader);
|
|
6153
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6154
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6155
|
+
await initStream(reader);
|
|
6156
|
+
}
|
|
5956
6157
|
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5957
|
-
const zipReader$1 = new ZipReader(reader
|
|
6158
|
+
const zipReader$1 = new ZipReader(reader);
|
|
5958
6159
|
const entries = await zipReader$1.getEntries();
|
|
5959
6160
|
await zipReader$1.close();
|
|
5960
6161
|
await initStream(this.writer);
|
|
5961
|
-
|
|
5962
|
-
|
|
6162
|
+
const { directoryOffset } = zipReader$1;
|
|
6163
|
+
let splitZipSignatureLength = 0;
|
|
6164
|
+
if (this.addSplitZipSignature) {
|
|
6165
|
+
delete this.addSplitZipSignature;
|
|
6166
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
6167
|
+
await writeData(this.writer, getSplitZipSignatureArray());
|
|
6168
|
+
splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6169
|
+
this.offset += splitZipSignatureLength;
|
|
6170
|
+
}
|
|
6171
|
+
}
|
|
6172
|
+
const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
|
|
5963
6173
|
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
5964
|
-
this.
|
|
6174
|
+
this.fileEntries = new Map(entries.map(entry => {
|
|
5965
6175
|
const {
|
|
5966
6176
|
version,
|
|
5967
6177
|
rawLastModDate,
|
|
@@ -6016,11 +6226,12 @@
|
|
|
6016
6226
|
if (crc32 !== UNDEFINED_VALUE) {
|
|
6017
6227
|
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6018
6228
|
}
|
|
6229
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6019
6230
|
Object.assign(entry, {
|
|
6020
6231
|
zip64UncompressedSize,
|
|
6021
6232
|
zip64CompressedSize,
|
|
6022
|
-
|
|
6023
|
-
diskNumberStart
|
|
6233
|
+
offset,
|
|
6234
|
+
diskNumberStart,
|
|
6024
6235
|
zip64DiskNumberStart: false,
|
|
6025
6236
|
rawExtraFieldZip64,
|
|
6026
6237
|
rawExtraFieldAES,
|
|
@@ -6040,11 +6251,8 @@
|
|
|
6040
6251
|
async add(name = "", reader, options = {}) {
|
|
6041
6252
|
const zipWriter = this;
|
|
6042
6253
|
options = Object.assign({}, options);
|
|
6043
|
-
const {
|
|
6044
|
-
|
|
6045
|
-
config
|
|
6046
|
-
} = zipWriter;
|
|
6047
|
-
if (workers < config.maxWorkers) {
|
|
6254
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
6255
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
6048
6256
|
workers++;
|
|
6049
6257
|
} else {
|
|
6050
6258
|
await new Promise(resolve => pendingEntries.push(resolve));
|
|
@@ -6081,16 +6289,16 @@
|
|
|
6081
6289
|
}
|
|
6082
6290
|
|
|
6083
6291
|
remove(entry) {
|
|
6084
|
-
const { filenames,
|
|
6292
|
+
const { filenames, fileEntries } = this;
|
|
6085
6293
|
// deno-lint-ignore valid-typeof
|
|
6086
6294
|
if (typeof entry == STRING_TYPE) {
|
|
6087
|
-
entry =
|
|
6295
|
+
entry = fileEntries.get(entry);
|
|
6088
6296
|
}
|
|
6089
6297
|
if (entry && entry.filename !== UNDEFINED_VALUE) {
|
|
6090
6298
|
const { filename } = entry;
|
|
6091
|
-
if (filenames.has(filename) &&
|
|
6299
|
+
if (filenames.has(filename) && fileEntries.has(filename)) {
|
|
6092
6300
|
filenames.delete(filename);
|
|
6093
|
-
|
|
6301
|
+
fileEntries.delete(filename);
|
|
6094
6302
|
return true;
|
|
6095
6303
|
}
|
|
6096
6304
|
}
|
|
@@ -6101,6 +6309,9 @@
|
|
|
6101
6309
|
const zipWriter = this;
|
|
6102
6310
|
const { pendingAddFileCalls, writer } = this;
|
|
6103
6311
|
const { writable } = writer;
|
|
6312
|
+
if (!(comment instanceof Uint8Array)) {
|
|
6313
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
6314
|
+
}
|
|
6104
6315
|
if (getLength(comment) > MAX_16_BITS) {
|
|
6105
6316
|
throw new Error(ERR_INVALID_COMMENT);
|
|
6106
6317
|
}
|
|
@@ -6184,12 +6395,12 @@
|
|
|
6184
6395
|
const metadataInfo = resolveMetadata(zipWriter, name, options);
|
|
6185
6396
|
const { comment } = metadataInfo;
|
|
6186
6397
|
const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
|
|
6187
|
-
zipWriter.
|
|
6398
|
+
zipWriter.fileEntries.set(name, UNDEFINED_VALUE);
|
|
6188
6399
|
let fileEntry;
|
|
6189
6400
|
try {
|
|
6190
6401
|
const { resolvedOptions } = metadataInfo;
|
|
6191
6402
|
if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
|
|
6192
|
-
!resolvedOptions.passThrough && !(await supportsDeflate(
|
|
6403
|
+
!resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
|
|
6193
6404
|
resolvedOptions.level = 0;
|
|
6194
6405
|
}
|
|
6195
6406
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
@@ -6197,8 +6408,6 @@
|
|
|
6197
6408
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
6198
6409
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
6199
6410
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
6200
|
-
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
6201
|
-
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
6202
6411
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
6203
6412
|
crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
|
|
6204
6413
|
offset: zipWriter.offset - diskOffset,
|
|
@@ -6209,17 +6418,23 @@
|
|
|
6209
6418
|
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
6210
6419
|
fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
|
|
6211
6420
|
} catch (error) {
|
|
6212
|
-
zipWriter.
|
|
6421
|
+
zipWriter.fileEntries.delete(name);
|
|
6213
6422
|
throw error;
|
|
6214
6423
|
}
|
|
6215
|
-
Object.assign(fileEntry, {
|
|
6424
|
+
Object.assign(fileEntry, {
|
|
6425
|
+
name,
|
|
6426
|
+
comment,
|
|
6427
|
+
extraField,
|
|
6428
|
+
[PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
|
|
6429
|
+
[PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
|
|
6430
|
+
});
|
|
6216
6431
|
return new Entry(fileEntry);
|
|
6217
6432
|
}
|
|
6218
6433
|
|
|
6219
6434
|
function resolveAttributes(zipWriter, name, options) {
|
|
6220
6435
|
name = name.trim();
|
|
6221
6436
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
6222
|
-
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ?
|
|
6437
|
+
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
6223
6438
|
const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
|
|
6224
6439
|
const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
|
|
6225
6440
|
const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
|
|
@@ -6247,21 +6462,21 @@
|
|
|
6247
6462
|
if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
6248
6463
|
unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
|
|
6249
6464
|
}
|
|
6250
|
-
let msdosAttributesRaw =
|
|
6465
|
+
let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
|
|
6251
6466
|
let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
|
|
6252
|
-
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
|
|
6467
|
+
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType || executable;
|
|
6253
6468
|
const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
|
|
6254
6469
|
if (hasUnixMetadata) {
|
|
6255
6470
|
msDosCompatible = false;
|
|
6256
|
-
versionMadeBy = (versionMadeBy &
|
|
6471
|
+
versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
|
|
6257
6472
|
} else if (hasMsDosProvided) {
|
|
6258
6473
|
msDosCompatible = true;
|
|
6259
6474
|
versionMadeBy = (versionMadeBy & MAX_8_BITS);
|
|
6260
6475
|
}
|
|
6261
|
-
if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
6476
|
+
if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
6262
6477
|
throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
|
|
6263
6478
|
}
|
|
6264
|
-
if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
|
|
6479
|
+
if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
|
|
6265
6480
|
throw new Error(ERR_INVALID_MSDOS_DATA);
|
|
6266
6481
|
}
|
|
6267
6482
|
if (versionMadeBy > MAX_16_BITS) {
|
|
@@ -6293,11 +6508,10 @@
|
|
|
6293
6508
|
externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
|
|
6294
6509
|
}
|
|
6295
6510
|
}
|
|
6296
|
-
let unixExternalUpper;
|
|
6297
6511
|
if (!msDosCompatible) {
|
|
6298
6512
|
const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
|
|
6299
|
-
|
|
6300
|
-
unixMode = unixMode === UNDEFINED_VALUE ?
|
|
6513
|
+
const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
6514
|
+
unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
|
|
6301
6515
|
if (setuid) {
|
|
6302
6516
|
unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
|
|
6303
6517
|
} else {
|
|
@@ -6326,17 +6540,20 @@
|
|
|
6326
6540
|
if (hasMsDosProvided) {
|
|
6327
6541
|
externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
|
|
6328
6542
|
}
|
|
6543
|
+
const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
6544
|
+
const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
|
|
6329
6545
|
return {
|
|
6330
6546
|
name,
|
|
6331
6547
|
resolvedOptions: {
|
|
6332
6548
|
versionMadeBy,
|
|
6333
|
-
msDosCompatible,
|
|
6549
|
+
msDosCompatible: Boolean(msDosCompatible),
|
|
6334
6550
|
externalFileAttributes,
|
|
6335
6551
|
unixExternalUpper,
|
|
6336
6552
|
uid,
|
|
6337
6553
|
gid,
|
|
6338
6554
|
unixMode,
|
|
6339
6555
|
unixExtraFieldType,
|
|
6556
|
+
symlink,
|
|
6340
6557
|
setuid,
|
|
6341
6558
|
setgid,
|
|
6342
6559
|
sticky,
|
|
@@ -6347,7 +6564,7 @@
|
|
|
6347
6564
|
}
|
|
6348
6565
|
|
|
6349
6566
|
function resolveMetadata(zipWriter, name, options) {
|
|
6350
|
-
const encode =
|
|
6567
|
+
const encode = getFunctionOptionValue(zipWriter, options, OPTION_ENCODE_TEXT) || encodeText;
|
|
6351
6568
|
let rawFilename = encode(name, TEXT_TYPE_FILENAME);
|
|
6352
6569
|
if (rawFilename === UNDEFINED_VALUE) {
|
|
6353
6570
|
rawFilename = encodeText(name);
|
|
@@ -6356,6 +6573,10 @@
|
|
|
6356
6573
|
throw new Error(ERR_INVALID_ENTRY_NAME);
|
|
6357
6574
|
}
|
|
6358
6575
|
const comment = options[PROPERTY_NAME_COMMENT] || "";
|
|
6576
|
+
// deno-lint-ignore valid-typeof
|
|
6577
|
+
if (typeof comment != STRING_TYPE) {
|
|
6578
|
+
throw new Error(ERR_INVALID_ENTRY_COMMENT_TYPE);
|
|
6579
|
+
}
|
|
6359
6580
|
let rawComment = encode(comment, TEXT_TYPE_COMMENT);
|
|
6360
6581
|
if (rawComment === UNDEFINED_VALUE) {
|
|
6361
6582
|
rawComment = encodeText(comment);
|
|
@@ -6367,16 +6588,14 @@
|
|
|
6367
6588
|
if (version > MAX_16_BITS) {
|
|
6368
6589
|
throw new Error(ERR_INVALID_VERSION);
|
|
6369
6590
|
}
|
|
6370
|
-
const lastModDate =
|
|
6371
|
-
const lastAccessDate =
|
|
6372
|
-
const creationDate =
|
|
6591
|
+
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
6592
|
+
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6593
|
+
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6373
6594
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
6374
6595
|
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
6375
6596
|
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
6376
6597
|
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
6377
|
-
|
|
6378
|
-
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
6379
|
-
}
|
|
6598
|
+
checkPasswordOption(password, rawPassword);
|
|
6380
6599
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
6381
6600
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
6382
6601
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
@@ -6385,9 +6604,9 @@
|
|
|
6385
6604
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
6386
6605
|
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
6387
6606
|
const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
|
|
6388
|
-
const createTempStream =
|
|
6607
|
+
const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
6389
6608
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
6390
|
-
const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
|
|
6609
|
+
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
6391
6610
|
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
|
|
6392
6611
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
6393
6612
|
const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
@@ -6467,18 +6686,26 @@
|
|
|
6467
6686
|
if (!extraField) {
|
|
6468
6687
|
return EMPTY_UINT8_ARRAY;
|
|
6469
6688
|
}
|
|
6689
|
+
if (!(extraField instanceof Map)) {
|
|
6690
|
+
throw new Error(ERR_INVALID_EXTRAFIELD);
|
|
6691
|
+
}
|
|
6470
6692
|
let extraFieldSize = 0;
|
|
6471
6693
|
let offset = 0;
|
|
6472
|
-
extraField.forEach(data => extraFieldSize += 4 + getLength(data));
|
|
6473
|
-
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
6474
|
-
const rawExtraFieldView = getDataView(rawExtraField);
|
|
6475
6694
|
extraField.forEach((data, type) => {
|
|
6476
|
-
if (type > MAX_16_BITS) {
|
|
6695
|
+
if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
|
|
6477
6696
|
throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
|
|
6478
6697
|
}
|
|
6698
|
+
if (!(data instanceof Uint8Array)) {
|
|
6699
|
+
throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
|
|
6700
|
+
}
|
|
6479
6701
|
if (getLength(data) > MAX_16_BITS) {
|
|
6480
6702
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
6481
6703
|
}
|
|
6704
|
+
extraFieldSize += 4 + getLength(data);
|
|
6705
|
+
});
|
|
6706
|
+
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
6707
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
6708
|
+
extraField.forEach((data, type) => {
|
|
6482
6709
|
setUint16(rawExtraFieldView, offset, type);
|
|
6483
6710
|
setUint16(rawExtraFieldView, offset + 2, getLength(data));
|
|
6484
6711
|
arraySet(rawExtraField, data, offset + 4);
|
|
@@ -6565,10 +6792,13 @@
|
|
|
6565
6792
|
}
|
|
6566
6793
|
|
|
6567
6794
|
async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
|
|
6568
|
-
const zipWriter = { options: writerOptions
|
|
6569
|
-
if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
|
|
6795
|
+
const zipWriter = { options: writerOptions };
|
|
6796
|
+
if (checkFunctionOption(writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY])) {
|
|
6570
6797
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
6571
6798
|
}
|
|
6799
|
+
if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
|
|
6800
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
6801
|
+
}
|
|
6572
6802
|
const commentLength = getLength(comment);
|
|
6573
6803
|
if (commentLength > MAX_16_BITS) {
|
|
6574
6804
|
throw new Error(ERR_INVALID_COMMENT);
|
|
@@ -6589,7 +6819,7 @@
|
|
|
6589
6819
|
({ name } = attributesInfo);
|
|
6590
6820
|
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
6591
6821
|
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
6592
|
-
!metadata.passThrough && !(await supportsDeflate(
|
|
6822
|
+
!metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
|
|
6593
6823
|
metadata.level = 0;
|
|
6594
6824
|
}
|
|
6595
6825
|
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
@@ -6638,7 +6868,7 @@
|
|
|
6638
6868
|
|
|
6639
6869
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
6640
6870
|
const {
|
|
6641
|
-
|
|
6871
|
+
fileEntries,
|
|
6642
6872
|
writer
|
|
6643
6873
|
} = zipWriter;
|
|
6644
6874
|
const {
|
|
@@ -6660,12 +6890,12 @@
|
|
|
6660
6890
|
let writerSizeBeforeEntry;
|
|
6661
6891
|
let flushedBufferedSize = 0;
|
|
6662
6892
|
let fileWriter;
|
|
6663
|
-
|
|
6893
|
+
fileEntries.set(name, fileEntry);
|
|
6664
6894
|
zipWriter.lastFileEntry = fileEntry;
|
|
6665
6895
|
try {
|
|
6666
6896
|
let lockPreviousFileEntry;
|
|
6667
6897
|
if (keepOrder) {
|
|
6668
|
-
lockPreviousFileEntry = previousFileEntry && previousFileEntry.
|
|
6898
|
+
lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
|
|
6669
6899
|
requestLockCurrentFileEntry();
|
|
6670
6900
|
}
|
|
6671
6901
|
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
|
|
@@ -6686,11 +6916,8 @@
|
|
|
6686
6916
|
const diskOffset = getDiskOffset(writer);
|
|
6687
6917
|
if (zipWriter.addSplitZipSignature) {
|
|
6688
6918
|
delete zipWriter.addSplitZipSignature;
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
6692
|
-
await writeData(writer, signatureArray);
|
|
6693
|
-
zipWriter.offset += 4;
|
|
6919
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
6920
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6694
6921
|
}
|
|
6695
6922
|
if (usdz && !bufferedWrite) {
|
|
6696
6923
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -6708,11 +6935,11 @@
|
|
|
6708
6935
|
writerSizeBeforeEntry = writer.size;
|
|
6709
6936
|
await writeData(fileWriter, localHeaderArray);
|
|
6710
6937
|
}
|
|
6711
|
-
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo,
|
|
6938
|
+
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, getConfiguration(), options);
|
|
6712
6939
|
if (!bufferedWrite) {
|
|
6713
6940
|
writingEntryData = false;
|
|
6714
6941
|
}
|
|
6715
|
-
|
|
6942
|
+
fileEntries.set(name, fileEntry);
|
|
6716
6943
|
fileEntry.filename = name;
|
|
6717
6944
|
if (bufferedWrite) {
|
|
6718
6945
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
@@ -6753,7 +6980,7 @@
|
|
|
6753
6980
|
zipWriter.offset += flushedBufferedSize;
|
|
6754
6981
|
}
|
|
6755
6982
|
}
|
|
6756
|
-
|
|
6983
|
+
fileEntries.delete(name);
|
|
6757
6984
|
throw error;
|
|
6758
6985
|
} finally {
|
|
6759
6986
|
if (bufferedWrite) {
|
|
@@ -6775,7 +7002,7 @@
|
|
|
6775
7002
|
}
|
|
6776
7003
|
|
|
6777
7004
|
function requestLockCurrentFileEntry() {
|
|
6778
|
-
fileEntry.
|
|
7005
|
+
fileEntry.lockFileEntry = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
|
|
6779
7006
|
}
|
|
6780
7007
|
|
|
6781
7008
|
async function requestLockWriter() {
|
|
@@ -6795,7 +7022,7 @@
|
|
|
6795
7022
|
}
|
|
6796
7023
|
}
|
|
6797
7024
|
|
|
6798
|
-
async function createFileEntry(reader, writer, { diskNumberStart,
|
|
7025
|
+
async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry }, entryInfo, config, options) {
|
|
6799
7026
|
const {
|
|
6800
7027
|
headerInfo,
|
|
6801
7028
|
dataDescriptorInfo,
|
|
@@ -6850,6 +7077,7 @@
|
|
|
6850
7077
|
uid,
|
|
6851
7078
|
gid,
|
|
6852
7079
|
unixMode,
|
|
7080
|
+
symlink,
|
|
6853
7081
|
setuid,
|
|
6854
7082
|
setgid,
|
|
6855
7083
|
sticky,
|
|
@@ -6862,7 +7090,7 @@
|
|
|
6862
7090
|
codecURI
|
|
6863
7091
|
} = options;
|
|
6864
7092
|
const fileEntry = {
|
|
6865
|
-
|
|
7093
|
+
lockFileEntry,
|
|
6866
7094
|
versionMadeBy,
|
|
6867
7095
|
zip64,
|
|
6868
7096
|
directory: Boolean(directory),
|
|
@@ -6886,6 +7114,7 @@
|
|
|
6886
7114
|
uid,
|
|
6887
7115
|
gid,
|
|
6888
7116
|
unixMode,
|
|
7117
|
+
symlink: Boolean(symlink),
|
|
6889
7118
|
setuid,
|
|
6890
7119
|
setgid,
|
|
6891
7120
|
sticky,
|
|
@@ -6903,7 +7132,7 @@
|
|
|
6903
7132
|
}
|
|
6904
7133
|
const { writable } = writer;
|
|
6905
7134
|
if (reader) {
|
|
6906
|
-
const readable = toCompatibleReadable(
|
|
7135
|
+
const readable = toCompatibleReadable(createReadable(reader));
|
|
6907
7136
|
const size = reader.size;
|
|
6908
7137
|
const workerOptions = {
|
|
6909
7138
|
options: {
|
|
@@ -6966,8 +7195,8 @@
|
|
|
6966
7195
|
rawLastModDate,
|
|
6967
7196
|
creationDate,
|
|
6968
7197
|
lastAccessDate,
|
|
6969
|
-
encrypted,
|
|
6970
|
-
zipCrypto,
|
|
7198
|
+
encrypted: Boolean(encrypted),
|
|
7199
|
+
zipCrypto: Boolean(zipCrypto),
|
|
6971
7200
|
size: metadataSize + compressedSize,
|
|
6972
7201
|
compressionMethod,
|
|
6973
7202
|
version,
|
|
@@ -7015,14 +7244,14 @@
|
|
|
7015
7244
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
7016
7245
|
const length = 4 + 16;
|
|
7017
7246
|
const extraFieldZip64 = createRecordWriter(length);
|
|
7018
|
-
extraFieldZip64.
|
|
7019
|
-
extraFieldZip64.
|
|
7247
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
7248
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
7020
7249
|
rawLocalExtraFieldZip64 = extraFieldZip64.array;
|
|
7021
7250
|
if (zip64ExtraFieldComplete) {
|
|
7022
|
-
extraFieldZip64.
|
|
7251
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
7023
7252
|
if (uncompressedFile) {
|
|
7024
7253
|
const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
7025
|
-
extraFieldZip64.
|
|
7254
|
+
extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
|
|
7026
7255
|
}
|
|
7027
7256
|
}
|
|
7028
7257
|
} else {
|
|
@@ -7031,8 +7260,8 @@
|
|
|
7031
7260
|
let rawExtraFieldAES;
|
|
7032
7261
|
if (encrypted && !zipCrypto) {
|
|
7033
7262
|
const extraFieldAES = createRecordWriter(getLength(EXTRAFIELD_DATA_AES) + 2);
|
|
7034
|
-
extraFieldAES.
|
|
7035
|
-
extraFieldAES.
|
|
7263
|
+
extraFieldAES.writeUint16(EXTRAFIELD_TYPE_AES);
|
|
7264
|
+
extraFieldAES.writeBytes(EXTRAFIELD_DATA_AES);
|
|
7036
7265
|
rawExtraFieldAES = extraFieldAES.array;
|
|
7037
7266
|
rawExtraFieldAES[8] = encryptionStrength;
|
|
7038
7267
|
} else {
|
|
@@ -7048,15 +7277,15 @@
|
|
|
7048
7277
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
7049
7278
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
7050
7279
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
7051
|
-
extraFieldTimestamp.
|
|
7052
|
-
extraFieldTimestamp.
|
|
7053
|
-
extraFieldTimestamp.
|
|
7054
|
-
extraFieldTimestamp.
|
|
7280
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7281
|
+
extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
|
|
7282
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7283
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
7055
7284
|
if (lastAccessDate) {
|
|
7056
|
-
extraFieldTimestamp.
|
|
7285
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(lastAccessDate)));
|
|
7057
7286
|
}
|
|
7058
7287
|
if (creationDate) {
|
|
7059
|
-
extraFieldTimestamp.
|
|
7288
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(creationDate)));
|
|
7060
7289
|
}
|
|
7061
7290
|
rawExtraFieldExtendedTimestamp = extraFieldTimestamp.array;
|
|
7062
7291
|
} else {
|
|
@@ -7069,14 +7298,14 @@
|
|
|
7069
7298
|
try {
|
|
7070
7299
|
const lastModTimeNTFS = getTimeNTFS(lastModDate);
|
|
7071
7300
|
const extraFieldNTFS = createRecordWriter(36);
|
|
7072
|
-
extraFieldNTFS.
|
|
7073
|
-
extraFieldNTFS.
|
|
7301
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS);
|
|
7302
|
+
extraFieldNTFS.writeUint16(32);
|
|
7074
7303
|
extraFieldNTFS.skip(4);
|
|
7075
|
-
extraFieldNTFS.
|
|
7076
|
-
extraFieldNTFS.
|
|
7077
|
-
extraFieldNTFS.
|
|
7078
|
-
extraFieldNTFS.
|
|
7079
|
-
extraFieldNTFS.
|
|
7304
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS_TAG1);
|
|
7305
|
+
extraFieldNTFS.writeUint16(24);
|
|
7306
|
+
extraFieldNTFS.writeUint64(lastModTimeNTFS);
|
|
7307
|
+
extraFieldNTFS.writeUint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
|
|
7308
|
+
extraFieldNTFS.writeUint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
|
|
7080
7309
|
rawExtraFieldNTFS = extraFieldNTFS.array;
|
|
7081
7310
|
} catch {
|
|
7082
7311
|
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
@@ -7095,20 +7324,20 @@
|
|
|
7095
7324
|
const gidBytes = packUnixId(gid);
|
|
7096
7325
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
7097
7326
|
const extraFieldUnix = createRecordWriter(4 + payloadLength);
|
|
7098
|
-
extraFieldUnix.
|
|
7099
|
-
extraFieldUnix.
|
|
7100
|
-
extraFieldUnix.
|
|
7101
|
-
extraFieldUnix.
|
|
7102
|
-
extraFieldUnix.
|
|
7103
|
-
extraFieldUnix.
|
|
7104
|
-
extraFieldUnix.
|
|
7327
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
|
|
7328
|
+
extraFieldUnix.writeUint16(payloadLength);
|
|
7329
|
+
extraFieldUnix.writeUint8(1);
|
|
7330
|
+
extraFieldUnix.writeUint8(uidBytes.length);
|
|
7331
|
+
extraFieldUnix.writeBytes(uidBytes);
|
|
7332
|
+
extraFieldUnix.writeUint8(gidBytes.length);
|
|
7333
|
+
extraFieldUnix.writeBytes(gidBytes);
|
|
7105
7334
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
7106
7335
|
} else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
7107
7336
|
const extraFieldUnix = createRecordWriter(8);
|
|
7108
|
-
extraFieldUnix.
|
|
7109
|
-
extraFieldUnix.
|
|
7110
|
-
extraFieldUnix.
|
|
7111
|
-
extraFieldUnix.
|
|
7337
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
|
|
7338
|
+
extraFieldUnix.writeUint16(4);
|
|
7339
|
+
extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
|
|
7340
|
+
extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
|
|
7112
7341
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
7113
7342
|
} else {
|
|
7114
7343
|
rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
|
|
@@ -7158,18 +7387,18 @@
|
|
|
7158
7387
|
const localHeader = createRecordWriter(HEADER_SIZE + getLength(rawFilename) + extraFieldLength);
|
|
7159
7388
|
const localHeaderArray = localHeader.array;
|
|
7160
7389
|
const localHeaderView = getDataView(localHeaderArray);
|
|
7161
|
-
localHeader.
|
|
7162
|
-
localHeader.
|
|
7163
|
-
localHeader.
|
|
7390
|
+
localHeader.writeUint32(LOCAL_FILE_HEADER_SIGNATURE);
|
|
7391
|
+
localHeader.writeBytes(headerArray);
|
|
7392
|
+
localHeader.writeBytes(rawFilename);
|
|
7164
7393
|
if (writeLocalExtraFieldZip64) {
|
|
7165
|
-
localHeader.
|
|
7166
|
-
}
|
|
7167
|
-
localHeader.
|
|
7168
|
-
localHeader.
|
|
7169
|
-
localHeader.
|
|
7170
|
-
localHeader.
|
|
7171
|
-
localHeader.
|
|
7172
|
-
localHeader.
|
|
7394
|
+
localHeader.writeBytes(rawLocalExtraFieldZip64);
|
|
7395
|
+
}
|
|
7396
|
+
localHeader.writeBytes(rawExtraFieldAES);
|
|
7397
|
+
localHeader.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
7398
|
+
localHeader.writeBytes(rawExtraFieldNTFS);
|
|
7399
|
+
localHeader.writeBytes(rawExtraFieldUnix);
|
|
7400
|
+
localHeader.writeBytes(rawExtraField);
|
|
7401
|
+
localHeader.writeBytes(rawLocalExtraField);
|
|
7173
7402
|
if (dataDescriptor) {
|
|
7174
7403
|
if (!zip64CompressedSize) {
|
|
7175
7404
|
setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, 0);
|
|
@@ -7359,7 +7588,7 @@
|
|
|
7359
7588
|
|
|
7360
7589
|
|
|
7361
7590
|
async function closeFile(zipWriter, comment, options) {
|
|
7362
|
-
const directoryDataLength = createDirectoryRecords(zipWriter.
|
|
7591
|
+
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
7363
7592
|
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7364
7593
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
7365
7594
|
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
@@ -7389,19 +7618,19 @@
|
|
|
7389
7618
|
if (zip64Offset || zip64DiskNumberStart || zip64UncompressedSize || zip64CompressedSize) {
|
|
7390
7619
|
const length = 4 + (zip64UncompressedSize ? 8 : 0) + (zip64CompressedSize ? 8 : 0) + (zip64Offset ? 8 : 0) + (zip64DiskNumberStart ? 4 : 0);
|
|
7391
7620
|
const extraFieldZip64 = createRecordWriter(length);
|
|
7392
|
-
extraFieldZip64.
|
|
7393
|
-
extraFieldZip64.
|
|
7621
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
7622
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
7394
7623
|
if (zip64UncompressedSize) {
|
|
7395
|
-
extraFieldZip64.
|
|
7624
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
7396
7625
|
}
|
|
7397
7626
|
if (zip64CompressedSize) {
|
|
7398
|
-
extraFieldZip64.
|
|
7627
|
+
extraFieldZip64.writeUint64(compressedSize);
|
|
7399
7628
|
}
|
|
7400
7629
|
if (zip64Offset) {
|
|
7401
|
-
extraFieldZip64.
|
|
7630
|
+
extraFieldZip64.writeUint64(fileEntry.offset);
|
|
7402
7631
|
}
|
|
7403
7632
|
if (zip64DiskNumberStart) {
|
|
7404
|
-
extraFieldZip64.
|
|
7633
|
+
extraFieldZip64.writeUint32(fileEntry.diskNumberStart);
|
|
7405
7634
|
}
|
|
7406
7635
|
rawExtraFieldZip64 = extraFieldZip64.array;
|
|
7407
7636
|
} else {
|
|
@@ -7414,10 +7643,10 @@
|
|
|
7414
7643
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
7415
7644
|
if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
|
|
7416
7645
|
const extraFieldTimestamp = createRecordWriter(9);
|
|
7417
|
-
extraFieldTimestamp.
|
|
7418
|
-
extraFieldTimestamp.
|
|
7419
|
-
extraFieldTimestamp.
|
|
7420
|
-
extraFieldTimestamp.
|
|
7646
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7647
|
+
extraFieldTimestamp.writeUint16(5);
|
|
7648
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7649
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
7421
7650
|
rawExtraFieldTimestamp = extraFieldTimestamp.array;
|
|
7422
7651
|
} else {
|
|
7423
7652
|
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
@@ -7439,14 +7668,14 @@
|
|
|
7439
7668
|
}
|
|
7440
7669
|
|
|
7441
7670
|
async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
7442
|
-
const {
|
|
7671
|
+
const { fileEntries, writer } = zipWriter;
|
|
7443
7672
|
const directoryArray = new Uint8Array(directoryDataLength);
|
|
7444
7673
|
await initStream(writer);
|
|
7445
7674
|
let offset = 0;
|
|
7446
7675
|
let directoryDiskOffset = 0;
|
|
7447
7676
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
7448
7677
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
7449
|
-
for (const [indexFileEntry, fileEntry] of Array.from(
|
|
7678
|
+
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
7450
7679
|
const {
|
|
7451
7680
|
offset: fileEntryOffset,
|
|
7452
7681
|
rawFilename,
|
|
@@ -7491,28 +7720,28 @@
|
|
|
7491
7720
|
setUint16(headerView, HEADER_OFFSET_VERSION, VERSION_ZIP64);
|
|
7492
7721
|
}
|
|
7493
7722
|
const directoryRecord = createRecordWriter(directoryRecordLength);
|
|
7494
|
-
directoryRecord.
|
|
7495
|
-
directoryRecord.
|
|
7496
|
-
directoryRecord.
|
|
7497
|
-
directoryRecord.
|
|
7498
|
-
directoryRecord.
|
|
7499
|
-
directoryRecord.
|
|
7500
|
-
directoryRecord.
|
|
7501
|
-
directoryRecord.
|
|
7502
|
-
directoryRecord.
|
|
7503
|
-
directoryRecord.
|
|
7504
|
-
directoryRecord.
|
|
7505
|
-
directoryRecord.
|
|
7506
|
-
directoryRecord.
|
|
7507
|
-
directoryRecord.
|
|
7508
|
-
directoryRecord.
|
|
7509
|
-
directoryRecord.
|
|
7510
|
-
directoryRecord.
|
|
7723
|
+
directoryRecord.writeUint32(CENTRAL_FILE_HEADER_SIGNATURE);
|
|
7724
|
+
directoryRecord.writeUint16(versionMadeBy);
|
|
7725
|
+
directoryRecord.writeBytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
|
|
7726
|
+
directoryRecord.writeUint16(extraFieldLength);
|
|
7727
|
+
directoryRecord.writeUint16(getLength(rawComment));
|
|
7728
|
+
directoryRecord.writeUint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
|
|
7729
|
+
directoryRecord.writeUint16(internalFileAttributes);
|
|
7730
|
+
directoryRecord.writeUint32(externalFileAttributes);
|
|
7731
|
+
directoryRecord.writeUint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
|
|
7732
|
+
directoryRecord.writeBytes(rawFilename);
|
|
7733
|
+
directoryRecord.writeBytes(rawExtraFieldZip64);
|
|
7734
|
+
directoryRecord.writeBytes(rawExtraFieldAES);
|
|
7735
|
+
directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
7736
|
+
directoryRecord.writeBytes(rawExtraFieldNTFS);
|
|
7737
|
+
directoryRecord.writeBytes(rawExtraFieldUnix);
|
|
7738
|
+
directoryRecord.writeBytes(rawExtraField);
|
|
7739
|
+
directoryRecord.writeBytes(rawComment);
|
|
7511
7740
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
7512
7741
|
offset += directoryRecordLength;
|
|
7513
7742
|
if (options.onprogress) {
|
|
7514
7743
|
try {
|
|
7515
|
-
await options.onprogress(indexFileEntry + 1,
|
|
7744
|
+
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
7516
7745
|
} catch {
|
|
7517
7746
|
// ignored
|
|
7518
7747
|
}
|
|
@@ -7526,7 +7755,7 @@
|
|
|
7526
7755
|
}
|
|
7527
7756
|
|
|
7528
7757
|
async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
7529
|
-
const signCentralDirectory =
|
|
7758
|
+
const signCentralDirectory = getFunctionOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
|
|
7530
7759
|
if (signCentralDirectory) {
|
|
7531
7760
|
const signatureData = await signCentralDirectory(directoryArray);
|
|
7532
7761
|
const signatureDataLength = getLength(signatureData);
|
|
@@ -7534,9 +7763,9 @@
|
|
|
7534
7763
|
throw new Error(ERR_INVALID_SIGNATURE_DATA);
|
|
7535
7764
|
}
|
|
7536
7765
|
const signatureRecord = createRecordWriter(6 + signatureDataLength);
|
|
7537
|
-
signatureRecord.
|
|
7538
|
-
signatureRecord.
|
|
7539
|
-
signatureRecord.
|
|
7766
|
+
signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
|
|
7767
|
+
signatureRecord.writeUint16(signatureDataLength);
|
|
7768
|
+
signatureRecord.writeBytes(signatureData);
|
|
7540
7769
|
await writeData(zipWriter.writer, signatureRecord.array);
|
|
7541
7770
|
return 6 + signatureDataLength;
|
|
7542
7771
|
}
|
|
@@ -7547,7 +7776,7 @@
|
|
|
7547
7776
|
const { writer } = zipWriter;
|
|
7548
7777
|
const { directoryStart, signatureLength } = cdInfo;
|
|
7549
7778
|
let { directoryDataLength } = cdInfo;
|
|
7550
|
-
let
|
|
7779
|
+
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
7551
7780
|
let diskNumber = directoryStart.diskNumber;
|
|
7552
7781
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
7553
7782
|
let lastDiskNumber = getDiskNumber(writer);
|
|
@@ -7555,7 +7784,7 @@
|
|
|
7555
7784
|
lastDiskNumber++;
|
|
7556
7785
|
}
|
|
7557
7786
|
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7558
|
-
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS ||
|
|
7787
|
+
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
7559
7788
|
if (zip64 === false) {
|
|
7560
7789
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
7561
7790
|
} else {
|
|
@@ -7572,37 +7801,37 @@
|
|
|
7572
7801
|
}
|
|
7573
7802
|
lastDiskNumber = getDiskNumber(writer);
|
|
7574
7803
|
if (zip64) {
|
|
7575
|
-
endOfdirectoryRecord.
|
|
7576
|
-
endOfdirectoryRecord.
|
|
7577
|
-
endOfdirectoryRecord.
|
|
7578
|
-
endOfdirectoryRecord.
|
|
7579
|
-
endOfdirectoryRecord.
|
|
7580
|
-
endOfdirectoryRecord.
|
|
7581
|
-
endOfdirectoryRecord.
|
|
7582
|
-
endOfdirectoryRecord.
|
|
7583
|
-
endOfdirectoryRecord.
|
|
7584
|
-
endOfdirectoryRecord.
|
|
7585
|
-
endOfdirectoryRecord.
|
|
7586
|
-
endOfdirectoryRecord.
|
|
7587
|
-
endOfdirectoryRecord.
|
|
7588
|
-
endOfdirectoryRecord.
|
|
7804
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7805
|
+
endOfdirectoryRecord.writeUint64(44);
|
|
7806
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
7807
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
7808
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7809
|
+
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
7810
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7811
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7812
|
+
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
7813
|
+
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
7814
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
7815
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7816
|
+
endOfdirectoryRecord.writeUint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
|
|
7817
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber + 1);
|
|
7589
7818
|
const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
|
|
7590
7819
|
if (supportZip64SplitFile) {
|
|
7591
7820
|
lastDiskNumber = MAX_16_BITS;
|
|
7592
7821
|
diskNumber = MAX_16_BITS;
|
|
7593
7822
|
}
|
|
7594
|
-
|
|
7823
|
+
fileEntriesLength = MAX_16_BITS;
|
|
7595
7824
|
directoryOffset = MAX_32_BITS;
|
|
7596
7825
|
directoryDataLength = MAX_32_BITS;
|
|
7597
7826
|
}
|
|
7598
|
-
endOfdirectoryRecord.
|
|
7599
|
-
endOfdirectoryRecord.
|
|
7600
|
-
endOfdirectoryRecord.
|
|
7601
|
-
endOfdirectoryRecord.
|
|
7602
|
-
endOfdirectoryRecord.
|
|
7603
|
-
endOfdirectoryRecord.
|
|
7604
|
-
endOfdirectoryRecord.
|
|
7605
|
-
endOfdirectoryRecord.
|
|
7827
|
+
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7828
|
+
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
7829
|
+
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
7830
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7831
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7832
|
+
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
7833
|
+
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
7834
|
+
endOfdirectoryRecord.writeUint16(commentLength);
|
|
7606
7835
|
await writeData(writer, endOfdirectoryRecord.array);
|
|
7607
7836
|
if (commentLength) {
|
|
7608
7837
|
await writeData(writer, comment);
|
|
@@ -7615,11 +7844,11 @@
|
|
|
7615
7844
|
let offset = 0;
|
|
7616
7845
|
return {
|
|
7617
7846
|
array,
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7847
|
+
writeUint8: value => { setUint8(view, offset, value); offset += 1; },
|
|
7848
|
+
writeUint16: value => { setUint16(view, offset, value); offset += 2; },
|
|
7849
|
+
writeUint32: value => { setUint32(view, offset, value); offset += 4; },
|
|
7850
|
+
writeUint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
|
|
7851
|
+
writeBytes: value => { arraySet(array, value, offset); offset += getLength(value); },
|
|
7623
7852
|
skip: count => offset += count
|
|
7624
7853
|
};
|
|
7625
7854
|
}
|
|
@@ -7643,6 +7872,71 @@
|
|
|
7643
7872
|
return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
|
|
7644
7873
|
}
|
|
7645
7874
|
|
|
7875
|
+
async function startsWithSplitZipSignature(reader) {
|
|
7876
|
+
const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
7877
|
+
return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
7878
|
+
}
|
|
7879
|
+
|
|
7880
|
+
async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
|
|
7881
|
+
const { writer } = zipWriter;
|
|
7882
|
+
const entryPositions = new Map();
|
|
7883
|
+
if (writer.closeDisk) {
|
|
7884
|
+
const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
|
|
7885
|
+
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
7886
|
+
let copiedLength = 0;
|
|
7887
|
+
for (const entry of sortedEntries) {
|
|
7888
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
7889
|
+
await copyData(zipWriter, reader, copiedLength, sourceOffset - copiedLength);
|
|
7890
|
+
if (exceedsAvailableSize(writer, await getLocalHeaderLength(reader, sourceOffset))) {
|
|
7891
|
+
await writer.closeDisk();
|
|
7892
|
+
}
|
|
7893
|
+
entryPositions.set(entry, {
|
|
7894
|
+
offset: getSegmentOffset(zipWriter, writer),
|
|
7895
|
+
diskNumberStart: getDiskNumber(writer)
|
|
7896
|
+
});
|
|
7897
|
+
copiedLength = sourceOffset;
|
|
7898
|
+
}
|
|
7899
|
+
await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
|
|
7900
|
+
} else {
|
|
7901
|
+
await copyData(zipWriter, reader, 0, directoryOffset);
|
|
7902
|
+
entries.forEach(entry => entryPositions.set(entry, {
|
|
7903
|
+
offset: splitZipSignatureLength + getSourceOffset(reader, entry),
|
|
7904
|
+
diskNumberStart: 0
|
|
7905
|
+
}));
|
|
7906
|
+
}
|
|
7907
|
+
return entryPositions;
|
|
7908
|
+
}
|
|
7909
|
+
|
|
7910
|
+
async function copyData(zipWriter, reader, offset, size) {
|
|
7911
|
+
if (size > 0) {
|
|
7912
|
+
const { writer } = zipWriter;
|
|
7913
|
+
await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
|
|
7914
|
+
writer.size += size;
|
|
7915
|
+
zipWriter.offset += size;
|
|
7916
|
+
}
|
|
7917
|
+
}
|
|
7918
|
+
|
|
7919
|
+
async function getLocalHeaderLength(reader, offset) {
|
|
7920
|
+
const headerArray = await readUint8Array(reader, offset, HEADER_SIZE);
|
|
7921
|
+
if (getLength(headerArray) < HEADER_SIZE) {
|
|
7922
|
+
return HEADER_SIZE;
|
|
7923
|
+
}
|
|
7924
|
+
const headerView = getDataView(headerArray);
|
|
7925
|
+
return HEADER_SIZE +
|
|
7926
|
+
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
7927
|
+
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
7928
|
+
}
|
|
7929
|
+
|
|
7930
|
+
function getSourceOffset(reader, { offset, diskNumberStart }) {
|
|
7931
|
+
return offset + (reader.getDiskOffset ? reader.getDiskOffset(diskNumberStart) : 0);
|
|
7932
|
+
}
|
|
7933
|
+
|
|
7934
|
+
function getSplitZipSignatureArray() {
|
|
7935
|
+
const signatureArray = new Uint8Array(SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
7936
|
+
setUint32(getDataView(signatureArray), 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
7937
|
+
return signatureArray;
|
|
7938
|
+
}
|
|
7939
|
+
|
|
7646
7940
|
async function writeData(writer, array) {
|
|
7647
7941
|
const { writable } = writer;
|
|
7648
7942
|
const streamWriter = writable.getWriter();
|
|
@@ -7694,6 +7988,21 @@
|
|
|
7694
7988
|
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
7695
7989
|
}
|
|
7696
7990
|
|
|
7991
|
+
function getDateOptionValue(zipWriter, options, name, defaultValue) {
|
|
7992
|
+
const date = getOptionValue(zipWriter, options, name, defaultValue);
|
|
7993
|
+
if (date === null) {
|
|
7994
|
+
return defaultValue;
|
|
7995
|
+
}
|
|
7996
|
+
if (date !== UNDEFINED_VALUE && (typeof date.getTime != FUNCTION_TYPE || Number.isNaN(date.getTime()))) {
|
|
7997
|
+
throw new Error(ERR_INVALID_DATE);
|
|
7998
|
+
}
|
|
7999
|
+
return date;
|
|
8000
|
+
}
|
|
8001
|
+
|
|
8002
|
+
function getFunctionOptionValue(zipWriter, options, name) {
|
|
8003
|
+
return checkFunctionOption(getOptionValue(zipWriter, options, name));
|
|
8004
|
+
}
|
|
8005
|
+
|
|
7697
8006
|
function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
|
|
7698
8007
|
const value = getAliasedValue(options, name, deprecatedName);
|
|
7699
8008
|
const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
|
|
@@ -7708,9 +8017,6 @@
|
|
|
7708
8017
|
return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
|
|
7709
8018
|
}
|
|
7710
8019
|
|
|
7711
|
-
function toNumber(value) {
|
|
7712
|
-
return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
|
|
7713
|
-
}
|
|
7714
8020
|
|
|
7715
8021
|
function getMaximumCompressedSize(uncompressedSize) {
|
|
7716
8022
|
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
@@ -7722,6 +8028,14 @@
|
|
|
7722
8028
|
: compressionMethod !== COMPRESSION_METHOD_STORE;
|
|
7723
8029
|
}
|
|
7724
8030
|
|
|
8031
|
+
function getUint16(view, offset) {
|
|
8032
|
+
return view.getUint16(offset, true);
|
|
8033
|
+
}
|
|
8034
|
+
|
|
8035
|
+
function getUint32(view, offset) {
|
|
8036
|
+
return view.getUint32(offset, true);
|
|
8037
|
+
}
|
|
8038
|
+
|
|
7725
8039
|
function setUint8(view, offset, value) {
|
|
7726
8040
|
view.setUint8(offset, value);
|
|
7727
8041
|
}
|
|
@@ -7765,9 +8079,9 @@
|
|
|
7765
8079
|
const headerRecord = createRecordWriter(HEADER_SIZE - 4);
|
|
7766
8080
|
const headerArray = headerRecord.array;
|
|
7767
8081
|
const headerView = getDataView(headerArray);
|
|
7768
|
-
headerRecord.
|
|
7769
|
-
headerRecord.
|
|
7770
|
-
headerRecord.
|
|
8082
|
+
headerRecord.writeUint16(version);
|
|
8083
|
+
headerRecord.writeUint16(bitFlag);
|
|
8084
|
+
headerRecord.writeUint16(compressionMethod);
|
|
7771
8085
|
if (rawLastModDate === UNDEFINED_VALUE) {
|
|
7772
8086
|
const dateArray = new Uint32Array(1);
|
|
7773
8087
|
const dateView = getDataView(dateArray);
|
|
@@ -7775,20 +8089,20 @@
|
|
|
7775
8089
|
setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
|
|
7776
8090
|
rawLastModDate = dateArray[0];
|
|
7777
8091
|
}
|
|
7778
|
-
headerRecord.
|
|
8092
|
+
headerRecord.writeUint32(rawLastModDate);
|
|
7779
8093
|
headerRecord.skip(4);
|
|
7780
8094
|
if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
|
|
7781
|
-
headerRecord.
|
|
8095
|
+
headerRecord.writeUint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
|
|
7782
8096
|
} else {
|
|
7783
8097
|
headerRecord.skip(4);
|
|
7784
8098
|
}
|
|
7785
8099
|
if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
|
|
7786
|
-
headerRecord.
|
|
8100
|
+
headerRecord.writeUint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
|
|
7787
8101
|
} else {
|
|
7788
8102
|
headerRecord.skip(4);
|
|
7789
8103
|
}
|
|
7790
|
-
headerRecord.
|
|
7791
|
-
headerRecord.
|
|
8104
|
+
headerRecord.writeUint16(getLength(rawFilename));
|
|
8105
|
+
headerRecord.writeUint16(extraFieldLength);
|
|
7792
8106
|
return {
|
|
7793
8107
|
headerArray,
|
|
7794
8108
|
headerView,
|
|
@@ -8371,6 +8685,7 @@
|
|
|
8371
8685
|
const ERR_ENTRY_EXISTS = "Entry filename already exists";
|
|
8372
8686
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
8373
8687
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
8688
|
+
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
8374
8689
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
8375
8690
|
const ERR_ABORTED = "The operation was aborted";
|
|
8376
8691
|
const ABORT_ERROR_NAME = "AbortError";
|
|
@@ -8403,13 +8718,14 @@
|
|
|
8403
8718
|
fs,
|
|
8404
8719
|
name,
|
|
8405
8720
|
data: params.data,
|
|
8406
|
-
options: params.options,
|
|
8721
|
+
options: params.options && Object.assign({}, params.options),
|
|
8407
8722
|
id: fs.entryIdCounter++,
|
|
8408
8723
|
parent,
|
|
8409
8724
|
children: [],
|
|
8410
8725
|
uncompressedSize: params.uncompressedSize || 0,
|
|
8411
8726
|
undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
|
|
8412
|
-
passThrough: params.passThrough
|
|
8727
|
+
passThrough: params.passThrough,
|
|
8728
|
+
defaultLastModDate: params.defaultLastModDate || new Date()
|
|
8413
8729
|
});
|
|
8414
8730
|
if (parent || !fs.root) {
|
|
8415
8731
|
fs.entries[zipEntry.id] = zipEntry;
|
|
@@ -8419,12 +8735,6 @@
|
|
|
8419
8735
|
}
|
|
8420
8736
|
}
|
|
8421
8737
|
|
|
8422
|
-
moveTo(target) {
|
|
8423
|
-
// deprecated
|
|
8424
|
-
const zipEntry = this;
|
|
8425
|
-
zipEntry.fs.move(zipEntry, target);
|
|
8426
|
-
}
|
|
8427
|
-
|
|
8428
8738
|
getFullname() {
|
|
8429
8739
|
return this.getRelativeName();
|
|
8430
8740
|
}
|
|
@@ -8456,6 +8766,11 @@
|
|
|
8456
8766
|
this.name = name;
|
|
8457
8767
|
}
|
|
8458
8768
|
}
|
|
8769
|
+
|
|
8770
|
+
setOptions(options) {
|
|
8771
|
+
const entryOptions = Object.assign({}, this.options, options);
|
|
8772
|
+
this.options = Object.fromEntries(Object.entries(entryOptions).filter(([, value]) => value !== UNDEFINED_VALUE));
|
|
8773
|
+
}
|
|
8459
8774
|
}
|
|
8460
8775
|
|
|
8461
8776
|
class ZipFileEntry extends ZipEntry {
|
|
@@ -8482,7 +8797,7 @@
|
|
|
8482
8797
|
const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
|
|
8483
8798
|
const dataSize = zipEntry.uncompressedSize || reader.size;
|
|
8484
8799
|
await Promise.all([initStream(reader), initStream(writer, dataSize)]);
|
|
8485
|
-
const
|
|
8800
|
+
const signal = checkSignalOption(options.signal);
|
|
8486
8801
|
const readable = createProgressReadable(zipEntry, reader, options, signal);
|
|
8487
8802
|
const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
|
|
8488
8803
|
zipEntry.uncompressedSize = reader.size;
|
|
@@ -8700,10 +9015,6 @@
|
|
|
8700
9015
|
});
|
|
8701
9016
|
}
|
|
8702
9017
|
|
|
8703
|
-
addData(name, params) {
|
|
8704
|
-
return addChild(this, name, params);
|
|
8705
|
-
}
|
|
8706
|
-
|
|
8707
9018
|
importBlob(blob, options) {
|
|
8708
9019
|
return this.importZip(new BlobReader(blob), options);
|
|
8709
9020
|
}
|
|
@@ -8817,7 +9128,7 @@
|
|
|
8817
9128
|
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
8818
9129
|
options.bufferedWrite = true;
|
|
8819
9130
|
}
|
|
8820
|
-
const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
|
|
9131
|
+
const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
|
|
8821
9132
|
const zipWriter = new ZipWriter(writer, options);
|
|
8822
9133
|
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
|
|
8823
9134
|
await zipWriter.close(options.globalComment);
|
|
@@ -8827,12 +9138,13 @@
|
|
|
8827
9138
|
getExportedSize(options = {}) {
|
|
8828
9139
|
const zipEntry = this;
|
|
8829
9140
|
options = Object.assign({}, options);
|
|
9141
|
+
checkReaderOptions(options.readerOptions);
|
|
8830
9142
|
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
8831
9143
|
options.bufferedWrite = true;
|
|
8832
9144
|
}
|
|
8833
9145
|
const writeOrderGuaranteed = !options.bufferedWrite ||
|
|
8834
9146
|
(options.keepOrder !== false && zipEntry.children.every(child => !child.children.length));
|
|
8835
|
-
return getEntriesSize(options,
|
|
9147
|
+
return getEntriesSize(options, zipEntry.getChildren({ recursive: true }).filter(child => !isImplicitDirectory(child)).map(child => {
|
|
8836
9148
|
const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
|
|
8837
9149
|
return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
|
|
8838
9150
|
}), writeOrderGuaranteed, options.globalComment);
|
|
@@ -8871,7 +9183,7 @@
|
|
|
8871
9183
|
}
|
|
8872
9184
|
|
|
8873
9185
|
|
|
8874
|
-
class
|
|
9186
|
+
class ZipFS {
|
|
8875
9187
|
|
|
8876
9188
|
constructor() {
|
|
8877
9189
|
resetFS(this);
|
|
@@ -8987,10 +9299,6 @@
|
|
|
8987
9299
|
return this.root.addFile(file, options);
|
|
8988
9300
|
}
|
|
8989
9301
|
|
|
8990
|
-
addData(name, params) {
|
|
8991
|
-
return this.root.addData(name, params);
|
|
8992
|
-
}
|
|
8993
|
-
|
|
8994
9302
|
importBlob(blob, options) {
|
|
8995
9303
|
resetFS(this);
|
|
8996
9304
|
return this.root.importBlob(blob, options);
|
|
@@ -9058,7 +9366,7 @@
|
|
|
9058
9366
|
}
|
|
9059
9367
|
}
|
|
9060
9368
|
|
|
9061
|
-
const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
|
|
9369
|
+
const fs = { FS: ZipFS, ZipDirectoryEntry, ZipFileEntry };
|
|
9062
9370
|
|
|
9063
9371
|
function getTotalSize(entries, getEntrySize) {
|
|
9064
9372
|
let size = 0;
|
|
@@ -9202,7 +9510,7 @@
|
|
|
9202
9510
|
}
|
|
9203
9511
|
|
|
9204
9512
|
function forwardAbort(signal, abortController) {
|
|
9205
|
-
if (!signal) {
|
|
9513
|
+
if (!checkSignalOption(signal)) {
|
|
9206
9514
|
return () => { };
|
|
9207
9515
|
}
|
|
9208
9516
|
if (signal.aborted) {
|
|
@@ -9298,7 +9606,7 @@
|
|
|
9298
9606
|
};
|
|
9299
9607
|
}
|
|
9300
9608
|
}
|
|
9301
|
-
const entryOptions = Object.assign({}, zipEntryMetadata, options,
|
|
9609
|
+
const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
|
|
9302
9610
|
if (!child.directory && entryOptions.passThrough && entryOptions.uncompressedSize === UNDEFINED_VALUE) {
|
|
9303
9611
|
throw new Error(ERR_INVALID_PASS_THROUGH);
|
|
9304
9612
|
}
|
|
@@ -9313,11 +9621,22 @@
|
|
|
9313
9621
|
return child.undeterminedSize ? UNDEFINED_VALUE : getExtractedSize(child, passThrough);
|
|
9314
9622
|
}
|
|
9315
9623
|
|
|
9624
|
+
function checkReaderOptions(readerOptions) {
|
|
9625
|
+
if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
|
|
9626
|
+
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
9627
|
+
}
|
|
9628
|
+
return readerOptions;
|
|
9629
|
+
}
|
|
9630
|
+
|
|
9316
9631
|
function isPassThrough(child, options) {
|
|
9317
9632
|
const { readerOptions } = options;
|
|
9318
9633
|
return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
|
|
9319
9634
|
}
|
|
9320
9635
|
|
|
9636
|
+
function isImplicitDirectory(child) {
|
|
9637
|
+
return child.directory && child.data === null;
|
|
9638
|
+
}
|
|
9639
|
+
|
|
9321
9640
|
function getUserExtraField(extraField) {
|
|
9322
9641
|
if (extraField) {
|
|
9323
9642
|
const userExtraField = new Map();
|
|
@@ -9335,7 +9654,7 @@
|
|
|
9335
9654
|
async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
9336
9655
|
const { onstart, onprogress, onend, onentryprogress } = options;
|
|
9337
9656
|
const selectedEntry = entry;
|
|
9338
|
-
const totalEntries = getTotalSize(entry.children, ()
|
|
9657
|
+
const totalEntries = getTotalSize(entry.children, child => isImplicitDirectory(child) ? 0 : 1);
|
|
9339
9658
|
let writtenSize = 0;
|
|
9340
9659
|
let writtenEntries = 0;
|
|
9341
9660
|
if (onstart) {
|
|
@@ -9364,6 +9683,9 @@
|
|
|
9364
9683
|
}
|
|
9365
9684
|
|
|
9366
9685
|
async function addChild(child) {
|
|
9686
|
+
if (isImplicitDirectory(child)) {
|
|
9687
|
+
return;
|
|
9688
|
+
}
|
|
9367
9689
|
const { name, entryOptions } = getChildEntryOptions(child, selectedEntry, options);
|
|
9368
9690
|
let entryWrittenSize = 0;
|
|
9369
9691
|
const entryMetadata = await zipWriter.add(name, readers.get(child), Object.assign(entryOptions, {
|
|
@@ -9397,7 +9719,7 @@
|
|
|
9397
9719
|
if (handle.kind == "file") {
|
|
9398
9720
|
const file = await handle.getFile();
|
|
9399
9721
|
addedEntries.push(
|
|
9400
|
-
parentEntry
|
|
9722
|
+
addChild(parentEntry, file.name, {
|
|
9401
9723
|
Reader: function () {
|
|
9402
9724
|
const readable = file.stream();
|
|
9403
9725
|
const size = file.size;
|
|
@@ -9431,10 +9753,11 @@
|
|
|
9431
9753
|
|
|
9432
9754
|
async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
9433
9755
|
const { onstart, onprogress, onend } = options;
|
|
9756
|
+
const readerOptions = checkReaderOptions(options.readerOptions);
|
|
9434
9757
|
const abortController = new AbortController();
|
|
9435
9758
|
const { signal } = abortController;
|
|
9436
9759
|
const releaseSignal = forwardAbort(options.signal, abortController);
|
|
9437
|
-
const getDataOptions = Object.assign({}, options,
|
|
9760
|
+
const getDataOptions = Object.assign({}, options, readerOptions, {
|
|
9438
9761
|
signal,
|
|
9439
9762
|
onstart: UNDEFINED_VALUE,
|
|
9440
9763
|
onprogress: UNDEFINED_VALUE,
|
|
@@ -9721,7 +10044,7 @@
|
|
|
9721
10044
|
*/
|
|
9722
10045
|
|
|
9723
10046
|
|
|
9724
|
-
|
|
10047
|
+
a(setDefaultConfiguration);
|
|
9725
10048
|
|
|
9726
10049
|
exports.BlobReader = BlobReader;
|
|
9727
10050
|
exports.BlobWriter = BlobWriter;
|
|
@@ -9734,6 +10057,7 @@
|
|
|
9734
10057
|
exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
|
|
9735
10058
|
exports.ERR_ENCRYPTED = ERR_ENCRYPTED;
|
|
9736
10059
|
exports.ERR_ENCRYPTED_CENTRAL_DIRECTORY = ERR_ENCRYPTED_CENTRAL_DIRECTORY;
|
|
10060
|
+
exports.ERR_ENTRY_DATA_OUT_OF_BOUNDS = ERR_ENTRY_DATA_OUT_OF_BOUNDS;
|
|
9737
10061
|
exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
|
|
9738
10062
|
exports.ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND;
|
|
9739
10063
|
exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
|
|
@@ -9744,22 +10068,31 @@
|
|
|
9744
10068
|
exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
|
|
9745
10069
|
exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
|
|
9746
10070
|
exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
|
|
10071
|
+
exports.ERR_INVALID_COMMENT_TYPE = ERR_INVALID_COMMENT_TYPE;
|
|
9747
10072
|
exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
|
|
9748
10073
|
exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
|
|
10074
|
+
exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
|
|
9749
10075
|
exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
|
|
9750
10076
|
exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
|
|
10077
|
+
exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
|
|
9751
10078
|
exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
|
|
10079
|
+
exports.ERR_INVALID_EXTRAFIELD = ERR_INVALID_EXTRAFIELD;
|
|
9752
10080
|
exports.ERR_INVALID_EXTRAFIELD_DATA = ERR_INVALID_EXTRAFIELD_DATA;
|
|
10081
|
+
exports.ERR_INVALID_EXTRAFIELD_DATA_TYPE = ERR_INVALID_EXTRAFIELD_DATA_TYPE;
|
|
9753
10082
|
exports.ERR_INVALID_EXTRAFIELD_TYPE = ERR_INVALID_EXTRAFIELD_TYPE;
|
|
9754
10083
|
exports.ERR_INVALID_FILENAME_VALIDATION = ERR_INVALID_FILENAME_VALIDATION;
|
|
10084
|
+
exports.ERR_INVALID_FUNCTION_OPTION = ERR_INVALID_FUNCTION_OPTION;
|
|
9755
10085
|
exports.ERR_INVALID_GID = ERR_INVALID_GID;
|
|
9756
10086
|
exports.ERR_INVALID_LEVEL = ERR_INVALID_LEVEL;
|
|
9757
10087
|
exports.ERR_INVALID_MAX_APPENDED_DATA_SIZE = ERR_INVALID_MAX_APPENDED_DATA_SIZE;
|
|
10088
|
+
exports.ERR_INVALID_MAX_WORKERS = ERR_INVALID_MAX_WORKERS;
|
|
9758
10089
|
exports.ERR_INVALID_MSDOS_ATTRIBUTES = ERR_INVALID_MSDOS_ATTRIBUTES;
|
|
9759
10090
|
exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
|
|
9760
10091
|
exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
|
|
9761
10092
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
9762
10093
|
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
10094
|
+
exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
|
|
10095
|
+
exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
|
|
9763
10096
|
exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
|
|
9764
10097
|
exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
|
|
9765
10098
|
exports.ERR_INVALID_STRICTNESS = ERR_INVALID_STRICTNESS;
|
|
@@ -9799,6 +10132,10 @@
|
|
|
9799
10132
|
exports.Uint8ArrayReader = Uint8ArrayReader;
|
|
9800
10133
|
exports.Uint8ArrayWriter = Uint8ArrayWriter;
|
|
9801
10134
|
exports.Writer = Writer;
|
|
10135
|
+
exports.ZipDirectoryEntry = ZipDirectoryEntry;
|
|
10136
|
+
exports.ZipEntry = ZipEntry;
|
|
10137
|
+
exports.ZipFS = ZipFS;
|
|
10138
|
+
exports.ZipFileEntry = ZipFileEntry;
|
|
9802
10139
|
exports.ZipReader = ZipReader;
|
|
9803
10140
|
exports.ZipReaderStream = ZipReaderStream;
|
|
9804
10141
|
exports.ZipWriter = ZipWriter;
|