@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-legacy.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);
|
|
215
355
|
}
|
|
216
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);
|
|
365
|
+
}
|
|
366
|
+
} else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
|
|
367
|
+
checkFunctionOption(propertyValue);
|
|
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=new Uint8Array(30).fill(5);function z(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="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",p=(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(e),z(j));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(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(j.subarray(0,r)),z(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.indexOf(r[n])<<18|W.indexOf(r[n+1])<<12|(63&W.indexOf(r[n+2]))<<6|63&W.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[f>>18&63]+W[f>>12&63]+W[f>>6&63]+W[63&f];}const c=f-n;if(1===c){const f=r[n]<<16;t+=W[f>>18&63]+W[f>>12&63]+"==";}else if(2===c){const f=r[n]<<16|r[n+1]<<8;t+=W[f>>18&63]+W[f>>12&63]+W[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=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));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
|
|
|
@@ -3550,7 +3799,7 @@
|
|
|
3550
3799
|
class TextWriter extends BlobWriter {
|
|
3551
3800
|
|
|
3552
3801
|
constructor(encoding) {
|
|
3553
|
-
super(
|
|
3802
|
+
super();
|
|
3554
3803
|
Object.assign(this, {
|
|
3555
3804
|
encoding,
|
|
3556
3805
|
utf8: !encoding || encoding.toLowerCase() == "utf-8"
|
|
@@ -3566,14 +3815,7 @@
|
|
|
3566
3815
|
if (blob.text && utf8) {
|
|
3567
3816
|
return blob.text();
|
|
3568
3817
|
} else {
|
|
3569
|
-
|
|
3570
|
-
return new Promise((resolve, reject) => {
|
|
3571
|
-
Object.assign(reader, {
|
|
3572
|
-
onload: ({ target }) => resolve(target.result),
|
|
3573
|
-
onerror: () => reject(reader.error)
|
|
3574
|
-
});
|
|
3575
|
-
reader.readAsText(blob, encoding);
|
|
3576
|
-
});
|
|
3818
|
+
return decodeTextRemovingBOM(new Uint8Array(await blob.arrayBuffer()), encoding);
|
|
3577
3819
|
}
|
|
3578
3820
|
}
|
|
3579
3821
|
}
|
|
@@ -4031,9 +4273,8 @@
|
|
|
4031
4273
|
|
|
4032
4274
|
async init() {
|
|
4033
4275
|
const reader = this;
|
|
4034
|
-
const { readers } = reader;
|
|
4035
4276
|
reader.lastDiskNumber = 0;
|
|
4036
|
-
await Promise.all(readers.map(
|
|
4277
|
+
const readers = reader.readers = await Promise.all(reader.readers.map(initDiskReader));
|
|
4037
4278
|
reader.diskOffsets = readers.map(diskReader => {
|
|
4038
4279
|
const diskOffset = reader.size;
|
|
4039
4280
|
reader.size += diskReader.size;
|
|
@@ -4228,89 +4469,27 @@
|
|
|
4228
4469
|
}
|
|
4229
4470
|
}
|
|
4230
4471
|
|
|
4231
|
-
function
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
Redistribution and use in source and binary forms, with or without
|
|
4239
|
-
modification, are permitted provided that the following conditions are met:
|
|
4240
|
-
|
|
4241
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
4242
|
-
this list of conditions and the following disclaimer.
|
|
4243
|
-
|
|
4244
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
4245
|
-
notice, this list of conditions and the following disclaimer in
|
|
4246
|
-
the documentation and/or other materials provided with the distribution.
|
|
4247
|
-
|
|
4248
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
4249
|
-
derived from this software without specific prior written permission.
|
|
4250
|
-
|
|
4251
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4252
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4253
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4254
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4255
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4256
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4257
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4258
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4259
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4260
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4261
|
-
*/
|
|
4262
|
-
|
|
4263
|
-
/* global TextDecoder */
|
|
4264
|
-
|
|
4265
|
-
const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
|
|
4266
|
-
const VALID_CP437 = CP437.length == 256;
|
|
4267
|
-
|
|
4268
|
-
function decodeCP437(stringValue) {
|
|
4269
|
-
if (VALID_CP437) {
|
|
4270
|
-
let result = "";
|
|
4271
|
-
for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
|
|
4272
|
-
result += CP437[stringValue[indexCharacter]];
|
|
4273
|
-
}
|
|
4274
|
-
return result;
|
|
4275
|
-
} else {
|
|
4276
|
-
return new TextDecoder().decode(stringValue);
|
|
4472
|
+
async function initDiskReader(diskReader) {
|
|
4473
|
+
diskReader = new GenericReader(diskReader);
|
|
4474
|
+
await initStream(diskReader);
|
|
4475
|
+
if (diskReader.size === UNDEFINED_VALUE || !diskReader.readUint8Array) {
|
|
4476
|
+
diskReader = new BlobReader(await streamToBlob(diskReader.readable));
|
|
4477
|
+
await initStream(diskReader);
|
|
4277
4478
|
}
|
|
4479
|
+
return diskReader;
|
|
4278
4480
|
}
|
|
4279
4481
|
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
Redistribution and use in source and binary forms, with or without
|
|
4284
|
-
modification, are permitted provided that the following conditions are met:
|
|
4285
|
-
|
|
4286
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
4287
|
-
this list of conditions and the following disclaimer.
|
|
4288
|
-
|
|
4289
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
4290
|
-
notice, this list of conditions and the following disclaimer in
|
|
4291
|
-
the documentation and/or other materials provided with the distribution.
|
|
4292
|
-
|
|
4293
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
4294
|
-
derived from this software without specific prior written permission.
|
|
4295
|
-
|
|
4296
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4297
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4298
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4299
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4300
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4301
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4302
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4303
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4304
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4305
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4306
|
-
*/
|
|
4307
|
-
|
|
4482
|
+
function readUint8Array(reader, offset, size) {
|
|
4483
|
+
return reader.readUint8Array(offset, size);
|
|
4484
|
+
}
|
|
4308
4485
|
|
|
4309
|
-
function
|
|
4310
|
-
if (
|
|
4311
|
-
return
|
|
4486
|
+
function createReadable(reader, options) {
|
|
4487
|
+
if (reader.createReadable) {
|
|
4488
|
+
return reader.createReadable(options);
|
|
4489
|
+
} else if (reader.readUint8Array) {
|
|
4490
|
+
return Reader.prototype.createReadable.call(reader, options);
|
|
4312
4491
|
} else {
|
|
4313
|
-
return
|
|
4492
|
+
return reader.readable;
|
|
4314
4493
|
}
|
|
4315
4494
|
}
|
|
4316
4495
|
|
|
@@ -4386,6 +4565,10 @@
|
|
|
4386
4565
|
const PROPERTY_NAME_SETGID = "setgid";
|
|
4387
4566
|
const PROPERTY_NAME_STICKY = "sticky";
|
|
4388
4567
|
const PROPERTY_NAME_BITFLAG = "bitFlag";
|
|
4568
|
+
const PROPERTY_NAME_RAW_BITFLAG = "rawBitFlag";
|
|
4569
|
+
const PROPERTY_NAME_FILENAME_LENGTH = "filenameLength";
|
|
4570
|
+
const PROPERTY_NAME_EXTRA_FIELD_LENGTH = "extraFieldLength";
|
|
4571
|
+
const PROPERTY_NAME_UNIX_EXTERNAL_UPPER = "unixExternalUpper";
|
|
4389
4572
|
const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
|
|
4390
4573
|
const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
|
|
4391
4574
|
const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
|
|
@@ -4438,10 +4621,14 @@
|
|
|
4438
4621
|
PROPERTY_NAME_UID,
|
|
4439
4622
|
PROPERTY_NAME_GID,
|
|
4440
4623
|
PROPERTY_NAME_UNIX_MODE,
|
|
4624
|
+
PROPERTY_NAME_UNIX_EXTERNAL_UPPER,
|
|
4441
4625
|
PROPERTY_NAME_SETUID,
|
|
4442
4626
|
PROPERTY_NAME_SETGID,
|
|
4443
4627
|
PROPERTY_NAME_STICKY,
|
|
4444
4628
|
PROPERTY_NAME_BITFLAG,
|
|
4629
|
+
PROPERTY_NAME_RAW_BITFLAG,
|
|
4630
|
+
PROPERTY_NAME_FILENAME_LENGTH,
|
|
4631
|
+
PROPERTY_NAME_EXTRA_FIELD_LENGTH,
|
|
4445
4632
|
PROPERTY_NAME_FILENAME_UTF8,
|
|
4446
4633
|
PROPERTY_NAME_COMMENT_UTF8,
|
|
4447
4634
|
PROPERTY_NAME_RAW_EXTRA_FIELD,
|
|
@@ -4462,82 +4649,6 @@
|
|
|
4462
4649
|
|
|
4463
4650
|
}
|
|
4464
4651
|
|
|
4465
|
-
/*
|
|
4466
|
-
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
4467
|
-
|
|
4468
|
-
Redistribution and use in source and binary forms, with or without
|
|
4469
|
-
modification, are permitted provided that the following conditions are met:
|
|
4470
|
-
|
|
4471
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
4472
|
-
this list of conditions and the following disclaimer.
|
|
4473
|
-
|
|
4474
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
4475
|
-
notice, this list of conditions and the following disclaimer in
|
|
4476
|
-
the documentation and/or other materials provided with the distribution.
|
|
4477
|
-
|
|
4478
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
4479
|
-
derived from this software without specific prior written permission.
|
|
4480
|
-
|
|
4481
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4482
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4483
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4484
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4485
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4486
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4487
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4488
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4489
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4490
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4491
|
-
*/
|
|
4492
|
-
|
|
4493
|
-
const OPTION_FILENAME_ENCODING = "filenameEncoding";
|
|
4494
|
-
const OPTION_COMMENT_ENCODING = "commentEncoding";
|
|
4495
|
-
const OPTION_DECODE_TEXT = "decodeText";
|
|
4496
|
-
const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
|
|
4497
|
-
const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
|
|
4498
|
-
const OPTION_PASSWORD = "password";
|
|
4499
|
-
const OPTION_RAW_PASSWORD = "rawPassword";
|
|
4500
|
-
const OPTION_PASS_THROUGH = "passThrough";
|
|
4501
|
-
const OPTION_SIGNAL = "signal";
|
|
4502
|
-
const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
|
|
4503
|
-
const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
|
|
4504
|
-
const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
|
|
4505
|
-
const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
|
|
4506
|
-
const OPTION_CHECK_SIGNATURE = "checkSignature";
|
|
4507
|
-
const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
4508
|
-
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
4509
|
-
const OPTION_USE_WEB_WORKERS = "useWebWorkers";
|
|
4510
|
-
const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
|
|
4511
|
-
const OPTION_TRANSFER_STREAMS = "transferStreams";
|
|
4512
|
-
const OPTION_PREVENT_CLOSE = "preventClose";
|
|
4513
|
-
const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
|
|
4514
|
-
const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
|
|
4515
|
-
const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
|
|
4516
|
-
const OPTION_KEEP_ORDER = "keepOrder";
|
|
4517
|
-
const OPTION_LEVEL = "level";
|
|
4518
|
-
const OPTION_BUFFERED_WRITE = "bufferedWrite";
|
|
4519
|
-
const OPTION_CREATE_TEMP_STREAM = "createTempStream";
|
|
4520
|
-
const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
|
|
4521
|
-
const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
|
|
4522
|
-
const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
|
|
4523
|
-
const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
|
|
4524
|
-
const OPTION_ENCODE_TEXT = "encodeText";
|
|
4525
|
-
const OPTION_OFFSET = "offset";
|
|
4526
|
-
const OPTION_USDZ = "usdz";
|
|
4527
|
-
const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
|
|
4528
|
-
const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
|
|
4529
|
-
const OPTION_STRICTNESS = "strictness";
|
|
4530
|
-
const OPTION_FILENAME_VALIDATION = "filenameValidation";
|
|
4531
|
-
const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
|
|
4532
|
-
const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
|
|
4533
|
-
const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
|
|
4534
|
-
const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
|
|
4535
|
-
const TEXT_TYPE_FILENAME = "filename";
|
|
4536
|
-
const TEXT_TYPE_COMMENT = "comment";
|
|
4537
|
-
const STRICTNESS_STRICT = "strict";
|
|
4538
|
-
const STRICTNESS_BALANCED = "balanced";
|
|
4539
|
-
const STRICTNESS_TOLERANT = "tolerant";
|
|
4540
|
-
|
|
4541
4652
|
/*
|
|
4542
4653
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4543
4654
|
|
|
@@ -4578,6 +4689,7 @@
|
|
|
4578
4689
|
const ERR_UNSUPPORTED_COMPRESSION$1 = "Compression method not supported";
|
|
4579
4690
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4580
4691
|
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4692
|
+
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4581
4693
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4582
4694
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
4583
4695
|
const ERR_UNSAFE_FILENAME = "Unsafe filename";
|
|
@@ -4598,7 +4710,7 @@
|
|
|
4598
4710
|
];
|
|
4599
4711
|
const ZIP64_EXTRACTION = {
|
|
4600
4712
|
[MAX_16_BITS]: {
|
|
4601
|
-
getValue: getUint32,
|
|
4713
|
+
getValue: getUint32$1,
|
|
4602
4714
|
bytes: 4
|
|
4603
4715
|
},
|
|
4604
4716
|
[MAX_32_BITS]: {
|
|
@@ -4607,6 +4719,7 @@
|
|
|
4607
4719
|
}
|
|
4608
4720
|
};
|
|
4609
4721
|
const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
|
|
4722
|
+
const MAX_DEFLATE_EXPANSION_RATIO = 1032;
|
|
4610
4723
|
const CENTRAL_DIRECTORY_UNREACHABLE = 0;
|
|
4611
4724
|
const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
|
|
4612
4725
|
const CENTRAL_DIRECTORY_REACHABLE = 2;
|
|
@@ -4617,7 +4730,6 @@
|
|
|
4617
4730
|
Object.assign(this, {
|
|
4618
4731
|
reader: new GenericReader(reader),
|
|
4619
4732
|
options,
|
|
4620
|
-
config: getConfiguration(),
|
|
4621
4733
|
readRanges: new Map()
|
|
4622
4734
|
});
|
|
4623
4735
|
}
|
|
@@ -4625,7 +4737,6 @@
|
|
|
4625
4737
|
async* getEntriesGenerator(options = {}) {
|
|
4626
4738
|
const zipReader = this;
|
|
4627
4739
|
let { reader } = zipReader;
|
|
4628
|
-
const { config } = zipReader;
|
|
4629
4740
|
await initStream(reader);
|
|
4630
4741
|
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
4631
4742
|
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
@@ -4634,7 +4745,7 @@
|
|
|
4634
4745
|
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
4635
4746
|
throw new Error(ERR_BAD_FORMAT);
|
|
4636
4747
|
}
|
|
4637
|
-
const strictness = getStrictness(
|
|
4748
|
+
const strictness = getStrictness(options, zipReader.options);
|
|
4638
4749
|
const checkAmbiguity = strictness == STRICTNESS_STRICT;
|
|
4639
4750
|
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
4640
4751
|
const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
|
|
@@ -4642,9 +4753,7 @@
|
|
|
4642
4753
|
const normalizeFilename = getOptionValue$1(zipReader, options, OPTION_NORMALIZE_FILENAME);
|
|
4643
4754
|
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
4644
4755
|
if (!endOfDirectoryInfo) {
|
|
4645
|
-
|
|
4646
|
-
const signatureView = getDataView(signatureArray);
|
|
4647
|
-
if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
|
|
4756
|
+
if (await startsWithSplitZipSignature$1(reader)) {
|
|
4648
4757
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4649
4758
|
} else {
|
|
4650
4759
|
throw new Error(ERR_EOCDR_NOT_FOUND);
|
|
@@ -4654,18 +4763,18 @@
|
|
|
4654
4763
|
throwAmbiguousArchive("multiple end of central directory records");
|
|
4655
4764
|
}
|
|
4656
4765
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
4657
|
-
let directoryDataLength = getUint32(endOfDirectoryView, 12);
|
|
4658
|
-
let directoryDataOffset = getUint32(endOfDirectoryView, 16);
|
|
4766
|
+
let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
|
|
4767
|
+
let directoryDataOffset = getUint32$1(endOfDirectoryView, 16);
|
|
4659
4768
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
4660
|
-
const commentLength = getUint16(endOfDirectoryView, 20);
|
|
4769
|
+
const commentLength = getUint16$1(endOfDirectoryView, 20);
|
|
4661
4770
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
4662
4771
|
if (reader.size - appendedDataOffset > maxAppendedDataSize) {
|
|
4663
4772
|
throwAmbiguousArchive("appended data");
|
|
4664
4773
|
}
|
|
4665
|
-
let lastDiskNumber = getUint16(endOfDirectoryView, 4);
|
|
4774
|
+
let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
|
|
4666
4775
|
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
4667
|
-
let diskNumber = getUint16(endOfDirectoryView, 6);
|
|
4668
|
-
let filesLength = getUint16(endOfDirectoryView, 10);
|
|
4776
|
+
let diskNumber = getUint16$1(endOfDirectoryView, 6);
|
|
4777
|
+
let filesLength = getUint16$1(endOfDirectoryView, 10);
|
|
4669
4778
|
let prependedDataLength = 0;
|
|
4670
4779
|
let startOffset;
|
|
4671
4780
|
let zip64EndOfDirectory;
|
|
@@ -4681,12 +4790,12 @@
|
|
|
4681
4790
|
EMPTY_UINT8_ARRAY;
|
|
4682
4791
|
const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
|
|
4683
4792
|
if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
|
|
4684
|
-
getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
4685
|
-
directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4793
|
+
getUint32$1(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
4794
|
+
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4686
4795
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4687
4796
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4688
4797
|
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4689
|
-
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
4798
|
+
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
4690
4799
|
directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
|
|
4691
4800
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4692
4801
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
@@ -4696,7 +4805,7 @@
|
|
|
4696
4805
|
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4697
4806
|
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4698
4807
|
}
|
|
4699
|
-
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4808
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4700
4809
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
4701
4810
|
}
|
|
4702
4811
|
zip64EndOfDirectory = true;
|
|
@@ -4711,13 +4820,13 @@
|
|
|
4711
4820
|
}
|
|
4712
4821
|
}
|
|
4713
4822
|
if (lastDiskNumber == MAX_16_BITS) {
|
|
4714
|
-
lastDiskNumber = getUint32(endOfDirectoryView, 16);
|
|
4715
|
-
} else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
|
|
4823
|
+
lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
|
|
4824
|
+
} else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
|
|
4716
4825
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
4717
4826
|
}
|
|
4718
4827
|
if (diskNumber == MAX_16_BITS) {
|
|
4719
|
-
diskNumber = getUint32(endOfDirectoryView, 20);
|
|
4720
|
-
} else if (checkAmbiguity && diskNumber != getUint32(endOfDirectoryView, 20)) {
|
|
4828
|
+
diskNumber = getUint32$1(endOfDirectoryView, 20);
|
|
4829
|
+
} else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
|
|
4721
4830
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
4722
4831
|
}
|
|
4723
4832
|
if (filesLength == MAX_16_BITS) {
|
|
@@ -4755,11 +4864,11 @@
|
|
|
4755
4864
|
}
|
|
4756
4865
|
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4757
4866
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4758
|
-
const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4867
|
+
const storedPointsAtDirectory = getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4759
4868
|
let reconcile = !storedPointsAtDirectory;
|
|
4760
4869
|
if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4761
4870
|
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
|
|
4762
|
-
reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4871
|
+
reconcile = getUint32$1(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4763
4872
|
}
|
|
4764
4873
|
if (reconcile) {
|
|
4765
4874
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -4783,10 +4892,10 @@
|
|
|
4783
4892
|
}
|
|
4784
4893
|
zipReader.directoryOffset = directoryDataOffset;
|
|
4785
4894
|
zipReader.directoryLength = declaredDirectoryDataLength;
|
|
4786
|
-
const decryptCentralDirectory =
|
|
4895
|
+
const decryptCentralDirectory = getFunctionOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
|
|
4787
4896
|
let decryptedDirectory;
|
|
4788
4897
|
if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
|
|
4789
|
-
getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
|
|
4898
|
+
getUint32$1(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
|
|
4790
4899
|
(zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4791
4900
|
directoryArray = await decryptCentralDirectory(directoryArray, directoryEncryptionInfo);
|
|
4792
4901
|
directoryView = getDataView(directoryArray);
|
|
@@ -4799,8 +4908,8 @@
|
|
|
4799
4908
|
const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
|
|
4800
4909
|
let duplicateFilename;
|
|
4801
4910
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4802
|
-
const fileEntry = new ZipEntry(reader,
|
|
4803
|
-
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4911
|
+
const fileEntry = new ZipEntry(reader, zipReader.options);
|
|
4912
|
+
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4804
4913
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4805
4914
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
4806
4915
|
}
|
|
@@ -4811,16 +4920,16 @@
|
|
|
4811
4920
|
const filenameOffset = offset + CENTRAL_FILE_HEADER_LENGTH;
|
|
4812
4921
|
const extraFieldOffset = filenameOffset + fileEntry.filenameLength;
|
|
4813
4922
|
const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
|
|
4814
|
-
const versionMadeBy = getUint16(directoryView, offset + 4);
|
|
4923
|
+
const versionMadeBy = getUint16$1(directoryView, offset + 4);
|
|
4815
4924
|
const msDosCompatible = versionMadeBy >> 8 == 0;
|
|
4816
4925
|
const unixCompatible = versionMadeBy >> 8 == 3;
|
|
4817
4926
|
const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
|
|
4818
|
-
const commentLength = getUint16(directoryView, offset + 32);
|
|
4927
|
+
const commentLength = getUint16$1(directoryView, offset + 32);
|
|
4819
4928
|
const endOffset = commentOffset + commentLength;
|
|
4820
4929
|
const rawComment = directoryArray.subarray(commentOffset, endOffset);
|
|
4821
4930
|
const filenameUTF8 = languageEncodingFlag;
|
|
4822
4931
|
const commentUTF8 = languageEncodingFlag;
|
|
4823
|
-
const externalFileAttributes = getUint32(directoryView, offset + 38);
|
|
4932
|
+
const externalFileAttributes = getUint32$1(directoryView, offset + 38);
|
|
4824
4933
|
const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
|
|
4825
4934
|
const msdosAttributes = {
|
|
4826
4935
|
readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
|
|
@@ -4829,8 +4938,8 @@
|
|
|
4829
4938
|
directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
|
|
4830
4939
|
archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
|
|
4831
4940
|
};
|
|
4832
|
-
const offsetFileEntry = getUint32(directoryView, offset + 42);
|
|
4833
|
-
const decode =
|
|
4941
|
+
const offsetFileEntry = getUint32$1(directoryView, offset + 42);
|
|
4942
|
+
const decode = getFunctionOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
|
|
4834
4943
|
const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
|
|
4835
4944
|
const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
|
|
4836
4945
|
let filename = decode(rawFilename, rawFilenameEncoding, TEXT_TYPE_FILENAME);
|
|
@@ -4856,12 +4965,13 @@
|
|
|
4856
4965
|
index: indexFile,
|
|
4857
4966
|
versionMadeBy,
|
|
4858
4967
|
msDosCompatible,
|
|
4968
|
+
zip64: false,
|
|
4859
4969
|
compressedSize: 0,
|
|
4860
4970
|
uncompressedSize: 0,
|
|
4861
4971
|
commentLength,
|
|
4862
4972
|
offset: offsetFileEntry,
|
|
4863
|
-
diskNumberStart: getUint16(directoryView, offset + 34),
|
|
4864
|
-
internalFileAttributes: getUint16(directoryView, offset + 36),
|
|
4973
|
+
diskNumberStart: getUint16$1(directoryView, offset + 34),
|
|
4974
|
+
internalFileAttributes: getUint16$1(directoryView, offset + 36),
|
|
4865
4975
|
externalFileAttributes,
|
|
4866
4976
|
msdosAttributesRaw,
|
|
4867
4977
|
msdosAttributes,
|
|
@@ -4929,8 +5039,8 @@
|
|
|
4929
5039
|
yield entry;
|
|
4930
5040
|
}
|
|
4931
5041
|
let offsetAfterSignature = offset;
|
|
4932
|
-
if (offset + 6 <= directoryArray.length && getUint32(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
4933
|
-
const signatureDataLength = getUint16(directoryView, offset + 4);
|
|
5042
|
+
if (offset + 6 <= directoryArray.length && getUint32$1(directoryView, offset) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
5043
|
+
const signatureDataLength = getUint16$1(directoryView, offset + 4);
|
|
4934
5044
|
if (offset + 6 + signatureDataLength <= directoryArray.length) {
|
|
4935
5045
|
zipReader.digitalSignature = directoryArray.subarray(offset + 6, offset + 6 + signatureDataLength);
|
|
4936
5046
|
offsetAfterSignature = offset + 6 + signatureDataLength;
|
|
@@ -4942,13 +5052,17 @@
|
|
|
4942
5052
|
if (duplicateFilename) {
|
|
4943
5053
|
throwAmbiguousArchive("duplicate filename");
|
|
4944
5054
|
}
|
|
4945
|
-
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > 0))) {
|
|
4946
|
-
throwAmbiguousArchive("prepended data");
|
|
4947
|
-
}
|
|
4948
5055
|
const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
|
|
4949
5056
|
const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
|
|
5057
|
+
const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
|
|
5058
|
+
startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
|
|
5059
|
+
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
|
|
5060
|
+
throwAmbiguousArchive("prepended data");
|
|
5061
|
+
}
|
|
4950
5062
|
if (extractPrependedData) {
|
|
4951
|
-
zipReader.prependedData = startOffset >
|
|
5063
|
+
zipReader.prependedData = startOffset > splitZipSignatureLength ?
|
|
5064
|
+
await readUint8Array(reader, splitZipSignatureLength, startOffset - splitZipSignatureLength) :
|
|
5065
|
+
EMPTY_UINT8_ARRAY;
|
|
4952
5066
|
}
|
|
4953
5067
|
zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : EMPTY_UINT8_ARRAY;
|
|
4954
5068
|
if (extractAppendedData) {
|
|
@@ -5015,16 +5129,16 @@
|
|
|
5015
5129
|
|
|
5016
5130
|
class ZipEntry {
|
|
5017
5131
|
|
|
5018
|
-
constructor(reader,
|
|
5132
|
+
constructor(reader, options) {
|
|
5019
5133
|
Object.assign(this, {
|
|
5020
5134
|
reader,
|
|
5021
|
-
config,
|
|
5022
5135
|
options
|
|
5023
5136
|
});
|
|
5024
5137
|
}
|
|
5025
5138
|
|
|
5026
5139
|
async getData(writer, fileEntry, readRanges, options = {}) {
|
|
5027
5140
|
const zipEntry = this;
|
|
5141
|
+
const config = getConfiguration();
|
|
5028
5142
|
const {
|
|
5029
5143
|
reader,
|
|
5030
5144
|
index,
|
|
@@ -5033,7 +5147,6 @@
|
|
|
5033
5147
|
extraFieldAES,
|
|
5034
5148
|
extraFieldZip64,
|
|
5035
5149
|
compressionMethod,
|
|
5036
|
-
config,
|
|
5037
5150
|
bitFlag,
|
|
5038
5151
|
rawBitFlag,
|
|
5039
5152
|
crc32,
|
|
@@ -5051,6 +5164,7 @@
|
|
|
5051
5164
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
5052
5165
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
5053
5166
|
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
5167
|
+
checkPasswordOption(password, rawPassword);
|
|
5054
5168
|
password = password && password.length && password;
|
|
5055
5169
|
rawPassword = rawPassword && rawPassword.length && rawPassword;
|
|
5056
5170
|
if (extraFieldAES) {
|
|
@@ -5058,7 +5172,7 @@
|
|
|
5058
5172
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
|
|
5059
5173
|
}
|
|
5060
5174
|
}
|
|
5061
|
-
if (dataArray.length < HEADER_SIZE || getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
5175
|
+
if (dataArray.length < HEADER_SIZE || getUint32$1(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
5062
5176
|
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
5063
5177
|
}
|
|
5064
5178
|
readCommonHeader(localDirectory, dataView, 4);
|
|
@@ -5066,9 +5180,12 @@
|
|
|
5066
5180
|
extraFieldLength,
|
|
5067
5181
|
filenameLength
|
|
5068
5182
|
} = localDirectory;
|
|
5069
|
-
const
|
|
5183
|
+
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5184
|
+
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5185
|
+
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
5186
|
+
const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
|
|
5070
5187
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
5071
|
-
if (
|
|
5188
|
+
if (checkLocalFilename && (filenameLength || extraFieldLength)) {
|
|
5072
5189
|
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
5073
5190
|
rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
|
|
5074
5191
|
localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
|
|
@@ -5077,17 +5194,26 @@
|
|
|
5077
5194
|
await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
|
|
5078
5195
|
EMPTY_UINT8_ARRAY;
|
|
5079
5196
|
}
|
|
5197
|
+
if (checkLocalFilename) {
|
|
5198
|
+
localDirectory.rawFilename = rawLocalFilename;
|
|
5199
|
+
}
|
|
5080
5200
|
readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
|
|
5081
|
-
if (
|
|
5082
|
-
|
|
5201
|
+
if (checkLocalDirectory) {
|
|
5202
|
+
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
|
|
5083
5203
|
}
|
|
5084
|
-
const { lastAccessDate, creationDate } = localDirectory;
|
|
5204
|
+
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5085
5205
|
if (lastAccessDate) {
|
|
5086
5206
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5087
5207
|
}
|
|
5088
5208
|
if (creationDate) {
|
|
5089
5209
|
fileEntry.creationDate = creationDate;
|
|
5090
5210
|
}
|
|
5211
|
+
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
5212
|
+
fileEntry.uid = uid;
|
|
5213
|
+
}
|
|
5214
|
+
if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
|
|
5215
|
+
fileEntry.gid = gid;
|
|
5216
|
+
}
|
|
5091
5217
|
const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
|
|
5092
5218
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
5093
5219
|
if (!passThrough) {
|
|
@@ -5108,9 +5234,12 @@
|
|
|
5108
5234
|
}
|
|
5109
5235
|
}
|
|
5110
5236
|
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
5237
|
+
if (dataOffset + compressedSize > reader.size) {
|
|
5238
|
+
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5239
|
+
}
|
|
5111
5240
|
const size = compressedSize;
|
|
5112
5241
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5113
|
-
const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
|
|
5242
|
+
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5114
5243
|
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5115
5244
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
5116
5245
|
const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
|
|
@@ -5118,6 +5247,8 @@
|
|
|
5118
5247
|
checkOverlappingEntry = true;
|
|
5119
5248
|
}
|
|
5120
5249
|
const { onstart, onprogress, onend } = options;
|
|
5250
|
+
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
|
|
5251
|
+
const outputSize = passThrough ? compressedSize : uncompressedSize;
|
|
5121
5252
|
const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
|
|
5122
5253
|
let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5123
5254
|
if (deflate64) {
|
|
@@ -5138,9 +5269,9 @@
|
|
|
5138
5269
|
checkCrc32,
|
|
5139
5270
|
checkAuthenticationCode: getOptionValue$1(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
|
|
5140
5271
|
passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((crc32 >>> 24) & MAX_8_BITS)),
|
|
5141
|
-
outputSize
|
|
5272
|
+
outputSize,
|
|
5142
5273
|
crc32,
|
|
5143
|
-
compressed
|
|
5274
|
+
compressed,
|
|
5144
5275
|
encrypted,
|
|
5145
5276
|
useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
|
|
5146
5277
|
useCompressionStream,
|
|
@@ -5177,11 +5308,11 @@
|
|
|
5177
5308
|
writer = new WritableStream();
|
|
5178
5309
|
}
|
|
5179
5310
|
writer = new GenericWriter(writer);
|
|
5180
|
-
await initStream(writer,
|
|
5311
|
+
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5181
5312
|
({ writable } = writer);
|
|
5182
|
-
const { outputSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5183
|
-
writer.size +=
|
|
5184
|
-
if (
|
|
5313
|
+
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5314
|
+
writer.size += writtenSize;
|
|
5315
|
+
if (writtenSize != outputSize) {
|
|
5185
5316
|
throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
5186
5317
|
}
|
|
5187
5318
|
}
|
|
@@ -5215,7 +5346,7 @@
|
|
|
5215
5346
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5216
5347
|
const maxOffset = Math.min(directoryView.byteLength, 1024) - 3;
|
|
5217
5348
|
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5218
|
-
if (getUint32(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5349
|
+
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5219
5350
|
return true;
|
|
5220
5351
|
}
|
|
5221
5352
|
}
|
|
@@ -5226,15 +5357,15 @@
|
|
|
5226
5357
|
const directoryEncryptionInfo = { rawExtensibleData };
|
|
5227
5358
|
if (rawExtensibleData.length >= 28) {
|
|
5228
5359
|
const extensibleDataView = getDataView(rawExtensibleData);
|
|
5229
|
-
const hashDataLength = getUint16(extensibleDataView, 26);
|
|
5360
|
+
const hashDataLength = getUint16$1(extensibleDataView, 26);
|
|
5230
5361
|
Object.assign(directoryEncryptionInfo, {
|
|
5231
|
-
compressionMethod: getUint16(extensibleDataView, 0),
|
|
5362
|
+
compressionMethod: getUint16$1(extensibleDataView, 0),
|
|
5232
5363
|
compressedSize: Number(getBigUint64(extensibleDataView, 2)),
|
|
5233
5364
|
uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
|
|
5234
|
-
encryptionAlgorithm: getUint16(extensibleDataView, 18),
|
|
5235
|
-
bitLength: getUint16(extensibleDataView, 20),
|
|
5236
|
-
flags: getUint16(extensibleDataView, 22),
|
|
5237
|
-
hashAlgorithm: getUint16(extensibleDataView, 24),
|
|
5365
|
+
encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
|
|
5366
|
+
bitLength: getUint16$1(extensibleDataView, 20),
|
|
5367
|
+
flags: getUint16$1(extensibleDataView, 22),
|
|
5368
|
+
hashAlgorithm: getUint16$1(extensibleDataView, 24),
|
|
5238
5369
|
hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
|
|
5239
5370
|
});
|
|
5240
5371
|
}
|
|
@@ -5242,12 +5373,12 @@
|
|
|
5242
5373
|
}
|
|
5243
5374
|
|
|
5244
5375
|
function readCommonHeader(directory, dataView, offset) {
|
|
5245
|
-
const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
|
|
5376
|
+
const rawBitFlag = directory.rawBitFlag = getUint16$1(dataView, offset + 2);
|
|
5246
5377
|
const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
|
|
5247
|
-
const rawLastModDate = getUint32(dataView, offset + 6);
|
|
5378
|
+
const rawLastModDate = getUint32$1(dataView, offset + 6);
|
|
5248
5379
|
Object.assign(directory, {
|
|
5249
5380
|
encrypted,
|
|
5250
|
-
version: getUint16(dataView, offset),
|
|
5381
|
+
version: getUint16$1(dataView, offset),
|
|
5251
5382
|
bitFlag: {
|
|
5252
5383
|
level: (rawBitFlag & BITFLAG_LEVEL) >> 1,
|
|
5253
5384
|
dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR,
|
|
@@ -5255,8 +5386,8 @@
|
|
|
5255
5386
|
},
|
|
5256
5387
|
rawLastModDate,
|
|
5257
5388
|
lastModDate: getDate(rawLastModDate),
|
|
5258
|
-
filenameLength: getUint16(dataView, offset + 22),
|
|
5259
|
-
extraFieldLength: getUint16(dataView, offset + 24)
|
|
5389
|
+
filenameLength: getUint16$1(dataView, offset + 22),
|
|
5390
|
+
extraFieldLength: getUint16$1(dataView, offset + 24)
|
|
5260
5391
|
});
|
|
5261
5392
|
}
|
|
5262
5393
|
|
|
@@ -5267,8 +5398,8 @@
|
|
|
5267
5398
|
let offsetExtraField = 0;
|
|
5268
5399
|
try {
|
|
5269
5400
|
while (offsetExtraField < rawExtraField.length) {
|
|
5270
|
-
const type = getUint16(rawExtraFieldView, offsetExtraField);
|
|
5271
|
-
const size = getUint16(rawExtraFieldView, offsetExtraField + 2);
|
|
5401
|
+
const type = getUint16$1(rawExtraFieldView, offsetExtraField);
|
|
5402
|
+
const size = getUint16$1(rawExtraFieldView, offsetExtraField + 2);
|
|
5272
5403
|
extraField.set(type, {
|
|
5273
5404
|
type,
|
|
5274
5405
|
data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size)
|
|
@@ -5278,12 +5409,12 @@
|
|
|
5278
5409
|
} catch {
|
|
5279
5410
|
// ignored
|
|
5280
5411
|
}
|
|
5281
|
-
const compressionMethod = getUint16(dataView, offset + 4);
|
|
5412
|
+
const compressionMethod = getUint16$1(dataView, offset + 4);
|
|
5282
5413
|
Object.assign(directory, {
|
|
5283
|
-
signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5284
|
-
crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5285
|
-
compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
|
|
5286
|
-
uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5414
|
+
signature: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5415
|
+
crc32: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5416
|
+
compressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
|
|
5417
|
+
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5287
5418
|
});
|
|
5288
5419
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5289
5420
|
if (extraFieldZip64) {
|
|
@@ -5323,10 +5454,12 @@
|
|
|
5323
5454
|
directory.extraFieldNTFS = extraFieldNTFS;
|
|
5324
5455
|
}
|
|
5325
5456
|
const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
|
|
5457
|
+
let unixIdsRead;
|
|
5326
5458
|
if (extraFieldUnix) {
|
|
5327
|
-
readExtraFieldUnix(extraFieldUnix, directory, false);
|
|
5459
|
+
unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
|
|
5328
5460
|
directory.extraFieldUnix = extraFieldUnix;
|
|
5329
|
-
}
|
|
5461
|
+
}
|
|
5462
|
+
if (!unixIdsRead) {
|
|
5330
5463
|
const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
|
|
5331
5464
|
if (extraFieldInfoZip) {
|
|
5332
5465
|
readExtraFieldUnix(extraFieldInfoZip, directory, true);
|
|
@@ -5370,11 +5503,11 @@
|
|
|
5370
5503
|
computedCrc32.append(fileEntry[rawPropertyName]);
|
|
5371
5504
|
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
5372
5505
|
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
5373
|
-
const nameCrc32 = getUint32(extraFieldView, 1);
|
|
5506
|
+
const nameCrc32 = getUint32$1(extraFieldView, 1);
|
|
5374
5507
|
Object.assign(extraFieldUnicode, {
|
|
5375
5508
|
version: getUint8(extraFieldView, 0),
|
|
5376
5509
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
5377
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32(computedCrc32View, 0)
|
|
5510
|
+
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5378
5511
|
});
|
|
5379
5512
|
if (extraFieldUnicode.valid) {
|
|
5380
5513
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -5390,7 +5523,7 @@
|
|
|
5390
5523
|
vendorId: getUint8(extraFieldView, 2),
|
|
5391
5524
|
strength,
|
|
5392
5525
|
originalCompressionMethod: compressionMethod,
|
|
5393
|
-
compressionMethod: getUint16(extraFieldView, 5)
|
|
5526
|
+
compressionMethod: getUint16$1(extraFieldView, 5)
|
|
5394
5527
|
});
|
|
5395
5528
|
directory.compressionMethod = extraFieldAES.compressionMethod;
|
|
5396
5529
|
if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1$1) {
|
|
@@ -5404,8 +5537,8 @@
|
|
|
5404
5537
|
let tag1Data;
|
|
5405
5538
|
try {
|
|
5406
5539
|
while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) {
|
|
5407
|
-
const tagValue = getUint16(extraFieldView, offsetExtraField);
|
|
5408
|
-
const attributeSize = getUint16(extraFieldView, offsetExtraField + 2);
|
|
5540
|
+
const tagValue = getUint16$1(extraFieldView, offsetExtraField);
|
|
5541
|
+
const attributeSize = getUint16$1(extraFieldView, offsetExtraField + 2);
|
|
5409
5542
|
if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) {
|
|
5410
5543
|
tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize);
|
|
5411
5544
|
}
|
|
@@ -5429,7 +5562,7 @@
|
|
|
5429
5562
|
const creationDate = getDateNTFS(rawCreationDate);
|
|
5430
5563
|
const extraFieldData = { lastModDate, lastAccessDate, creationDate };
|
|
5431
5564
|
Object.assign(extraFieldNTFS, extraFieldData);
|
|
5432
|
-
Object.assign(directory, extraFieldData);
|
|
5565
|
+
Object.assign(directory, extraFieldData, { rawLastAccessDate, rawCreationDate });
|
|
5433
5566
|
}
|
|
5434
5567
|
}
|
|
5435
5568
|
|
|
@@ -5438,12 +5571,12 @@
|
|
|
5438
5571
|
return;
|
|
5439
5572
|
}
|
|
5440
5573
|
const extraFieldView = getDataView(extraField.data);
|
|
5441
|
-
const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
|
|
5442
|
-
const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
|
|
5574
|
+
const lastAccessDate = new Date((getUint32$1(extraFieldView, 0) | 0) * 1000);
|
|
5575
|
+
const lastModDate = new Date((getUint32$1(extraFieldView, 4) | 0) * 1000);
|
|
5443
5576
|
const extraFieldData = { lastAccessDate, lastModDate };
|
|
5444
5577
|
if (extraField.data.length >= 12) {
|
|
5445
|
-
extraFieldData.uid = getUint16(extraFieldView, 8);
|
|
5446
|
-
extraFieldData.gid = getUint16(extraFieldView, 10);
|
|
5578
|
+
extraFieldData.uid = getUint16$1(extraFieldView, 8);
|
|
5579
|
+
extraFieldData.gid = getUint16$1(extraFieldView, 10);
|
|
5447
5580
|
}
|
|
5448
5581
|
Object.assign(extraField, extraFieldData);
|
|
5449
5582
|
Object.assign(directory, extraFieldData);
|
|
@@ -5463,8 +5596,8 @@
|
|
|
5463
5596
|
gid = unpackUnixId(extraField.data.subarray(offset, offset + gidSize));
|
|
5464
5597
|
Object.assign(extraField, { version, uid, gid });
|
|
5465
5598
|
} else if (extraField.data.length >= 4) {
|
|
5466
|
-
uid = getUint16(view, 0);
|
|
5467
|
-
gid = getUint16(view, 2);
|
|
5599
|
+
uid = getUint16$1(view, 0);
|
|
5600
|
+
gid = getUint16$1(view, 2);
|
|
5468
5601
|
Object.assign(extraField, { uid, gid });
|
|
5469
5602
|
}
|
|
5470
5603
|
if (uid !== UNDEFINED_VALUE) {
|
|
@@ -5473,6 +5606,7 @@
|
|
|
5473
5606
|
if (gid !== UNDEFINED_VALUE) {
|
|
5474
5607
|
directory.gid = gid;
|
|
5475
5608
|
}
|
|
5609
|
+
return uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE;
|
|
5476
5610
|
} catch {
|
|
5477
5611
|
// ignored
|
|
5478
5612
|
}
|
|
@@ -5513,7 +5647,7 @@
|
|
|
5513
5647
|
let offset = 1;
|
|
5514
5648
|
timeProperties.forEach((propertyName, indexProperty) => {
|
|
5515
5649
|
if (extraFieldExtendedTimestamp.data.length >= offset + 4) {
|
|
5516
|
-
const time = getUint32(extraFieldView, offset);
|
|
5650
|
+
const time = getUint32$1(extraFieldView, offset);
|
|
5517
5651
|
directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date((time | 0) * 1000);
|
|
5518
5652
|
const rawPropertyName = timeRawProperties[indexProperty];
|
|
5519
5653
|
extraFieldExtendedTimestamp[rawPropertyName] = time;
|
|
@@ -5545,26 +5679,25 @@
|
|
|
5545
5679
|
}
|
|
5546
5680
|
if (dataDescriptorLength) {
|
|
5547
5681
|
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
|
|
5548
|
-
const
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
if (extraFieldZip64) {
|
|
5555
|
-
readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
|
|
5556
|
-
readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
|
|
5557
|
-
} else {
|
|
5558
|
-
readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
|
|
5559
|
-
readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
|
|
5560
|
-
}
|
|
5561
|
-
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
|
|
5682
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
5683
|
+
let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
5684
|
+
getUint32$1(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
5685
|
+
if (signature) {
|
|
5686
|
+
const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
|
|
5687
|
+
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
|
|
5562
5688
|
if (matchCrc32 &&
|
|
5563
|
-
|
|
5564
|
-
|
|
5689
|
+
signedDataDescriptor.compressedSize == compressedSize &&
|
|
5690
|
+
signedDataDescriptor.uncompressedSize == uncompressedSize) {
|
|
5565
5691
|
dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
5692
|
+
} else {
|
|
5693
|
+
signature = false;
|
|
5566
5694
|
}
|
|
5567
5695
|
}
|
|
5696
|
+
if (dataDescriptorArray.length >= dataDescriptorLength) {
|
|
5697
|
+
const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
|
|
5698
|
+
localDataDescriptor.signature = signature;
|
|
5699
|
+
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
5700
|
+
}
|
|
5568
5701
|
}
|
|
5569
5702
|
const range = {
|
|
5570
5703
|
start: offset,
|
|
@@ -5581,22 +5714,80 @@
|
|
|
5581
5714
|
readRanges.set(index, range);
|
|
5582
5715
|
}
|
|
5583
5716
|
|
|
5717
|
+
function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
|
|
5718
|
+
const crc32 = getUint32$1(dataDescriptorView, offset);
|
|
5719
|
+
let compressedSize;
|
|
5720
|
+
let uncompressedSize;
|
|
5721
|
+
if (extraFieldZip64) {
|
|
5722
|
+
compressedSize = getBigUint64(dataDescriptorView, offset + 4);
|
|
5723
|
+
uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
|
|
5724
|
+
} else {
|
|
5725
|
+
compressedSize = getUint32$1(dataDescriptorView, offset + 4);
|
|
5726
|
+
uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
|
|
5727
|
+
}
|
|
5728
|
+
return { crc32, compressedSize, uncompressedSize };
|
|
5729
|
+
}
|
|
5730
|
+
|
|
5584
5731
|
function getDiskOffset$1(reader, diskNumber) {
|
|
5585
5732
|
return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
|
|
5586
5733
|
}
|
|
5587
5734
|
|
|
5735
|
+
async function startsWithSplitZipSignature$1(reader) {
|
|
5736
|
+
return await getFirstSignature(reader) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
5737
|
+
}
|
|
5738
|
+
|
|
5739
|
+
async function startsWithSplitZipMarker(reader) {
|
|
5740
|
+
const signature = await getFirstSignature(reader);
|
|
5741
|
+
return signature == SPLIT_ZIP_FILE_SIGNATURE || signature == TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE;
|
|
5742
|
+
}
|
|
5743
|
+
|
|
5744
|
+
async function getFirstSignature(reader) {
|
|
5745
|
+
const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
5746
|
+
return getUint32$1(getDataView(signatureArray));
|
|
5747
|
+
}
|
|
5748
|
+
|
|
5588
5749
|
function isStrictnessValue(value) {
|
|
5589
5750
|
return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
|
|
5590
5751
|
}
|
|
5591
5752
|
|
|
5592
|
-
function
|
|
5593
|
-
|
|
5594
|
-
|
|
5753
|
+
function getDecodableOutputSize(outputSize, compressedSize, compressed) {
|
|
5754
|
+
return Math.min(outputSize, compressed ? compressedSize * MAX_DEFLATE_EXPANSION_RATIO : compressedSize);
|
|
5755
|
+
}
|
|
5756
|
+
|
|
5757
|
+
function getStrictness(options, inheritedOptions) {
|
|
5758
|
+
return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
|
|
5759
|
+
}
|
|
5760
|
+
|
|
5761
|
+
function resolveStrictness(options, inheritedStrictness) {
|
|
5762
|
+
const strictness = options[OPTION_STRICTNESS];
|
|
5763
|
+
if (strictness !== UNDEFINED_VALUE) {
|
|
5764
|
+
if (!isStrictnessValue(strictness)) {
|
|
5765
|
+
throw new Error(ERR_INVALID_STRICTNESS);
|
|
5766
|
+
}
|
|
5767
|
+
return strictness;
|
|
5768
|
+
}
|
|
5769
|
+
const checkAmbiguity = options[OPTION_CHECK_AMBIGUITY];
|
|
5770
|
+
if (checkAmbiguity === UNDEFINED_VALUE) {
|
|
5771
|
+
return inheritedStrictness;
|
|
5772
|
+
}
|
|
5773
|
+
if (checkAmbiguity) {
|
|
5774
|
+
return STRICTNESS_STRICT;
|
|
5775
|
+
}
|
|
5776
|
+
return inheritedStrictness == STRICTNESS_TOLERANT ? STRICTNESS_TOLERANT : STRICTNESS_BALANCED;
|
|
5777
|
+
}
|
|
5778
|
+
|
|
5779
|
+
function getCheckLocalDirectory(checkLocalDirectory, strictness) {
|
|
5780
|
+
if (checkLocalDirectory === UNDEFINED_VALUE) {
|
|
5781
|
+
return strictness != STRICTNESS_TOLERANT;
|
|
5595
5782
|
}
|
|
5596
|
-
|
|
5597
|
-
|
|
5783
|
+
return Boolean(checkLocalDirectory);
|
|
5784
|
+
}
|
|
5785
|
+
|
|
5786
|
+
function getCheckLocalFilename(checkLocalFilename, strictness) {
|
|
5787
|
+
if (checkLocalFilename === UNDEFINED_VALUE) {
|
|
5788
|
+
return strictness == STRICTNESS_STRICT;
|
|
5598
5789
|
}
|
|
5599
|
-
return
|
|
5790
|
+
return Boolean(checkLocalFilename);
|
|
5600
5791
|
}
|
|
5601
5792
|
|
|
5602
5793
|
function getFilenameValidation(filenameValidation, strictness) {
|
|
@@ -5625,7 +5816,7 @@
|
|
|
5625
5816
|
|
|
5626
5817
|
function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
|
|
5627
5818
|
if (maxAppendedDataSize !== UNDEFINED_VALUE) {
|
|
5628
|
-
const size = toNumber
|
|
5819
|
+
const size = toNumber(maxAppendedDataSize);
|
|
5629
5820
|
if (typeof size != NUMBER_TYPE || Number.isNaN(size) || size < 0) {
|
|
5630
5821
|
throw new Error(ERR_INVALID_MAX_APPENDED_DATA_SIZE);
|
|
5631
5822
|
}
|
|
@@ -5648,7 +5839,7 @@
|
|
|
5648
5839
|
let plausibleEndOfDirectoryInfo;
|
|
5649
5840
|
let endOfDirectoryReachingEndCount = 0;
|
|
5650
5841
|
for await (const [anchoredView, anchoredOffset, anchoredArray, indexByte, offset] of scanEndOfCentralDirectory(reader, anchoredLength)) {
|
|
5651
|
-
const commentLength = getUint16(anchoredView, indexByte + 20);
|
|
5842
|
+
const commentLength = getUint16$1(anchoredView, indexByte + 20);
|
|
5652
5843
|
if (offset + END_OF_CENTRAL_DIR_LENGTH + commentLength == size) {
|
|
5653
5844
|
const reachability = await getCentralDirectoryReachability(reader, anchoredView, anchoredOffset, indexByte, offset, size, remoteProbeBudget);
|
|
5654
5845
|
if (reachability == CENTRAL_DIRECTORY_REACHABLE) {
|
|
@@ -5699,7 +5890,7 @@
|
|
|
5699
5890
|
const scanArray = await readUint8Array(reader, scanOffset, scanLength);
|
|
5700
5891
|
const scanView = getDataView(scanArray);
|
|
5701
5892
|
for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5702
|
-
if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
5893
|
+
if (getUint32$1(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
5703
5894
|
yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
|
|
5704
5895
|
}
|
|
5705
5896
|
}
|
|
@@ -5710,9 +5901,9 @@
|
|
|
5710
5901
|
}
|
|
5711
5902
|
|
|
5712
5903
|
async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
|
|
5713
|
-
const filesLength = getUint16(view, indexByte + 10);
|
|
5714
|
-
const directoryDataLength = getUint32(view, indexByte + 12);
|
|
5715
|
-
const directoryDataOffset = getUint32(view, indexByte + 16);
|
|
5904
|
+
const filesLength = getUint16$1(view, indexByte + 10);
|
|
5905
|
+
const directoryDataLength = getUint32$1(view, indexByte + 12);
|
|
5906
|
+
const directoryDataOffset = getUint32$1(view, indexByte + 16);
|
|
5716
5907
|
if (filesLength == MAX_16_BITS || directoryDataLength == MAX_32_BITS || directoryDataOffset == MAX_32_BITS) {
|
|
5717
5908
|
const locatorSignature = await readSignature(reader, view, anchoredOffset, offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, size, remoteProbeBudget);
|
|
5718
5909
|
return locatorSignature == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE ? CENTRAL_DIRECTORY_REACHABLE : CENTRAL_DIRECTORY_UNREACHABLE;
|
|
@@ -5720,7 +5911,7 @@
|
|
|
5720
5911
|
if (!filesLength && !directoryDataLength) {
|
|
5721
5912
|
return CENTRAL_DIRECTORY_PLAUSIBLE;
|
|
5722
5913
|
}
|
|
5723
|
-
const directoryDiskNumber = getUint16(view, indexByte + 6);
|
|
5914
|
+
const directoryDiskNumber = getUint16$1(view, indexByte + 6);
|
|
5724
5915
|
for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
|
|
5725
5916
|
if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5726
5917
|
return CENTRAL_DIRECTORY_REACHABLE;
|
|
@@ -5734,20 +5925,21 @@
|
|
|
5734
5925
|
return UNDEFINED_VALUE;
|
|
5735
5926
|
}
|
|
5736
5927
|
if (signatureOffset >= anchoredOffset) {
|
|
5737
|
-
return getUint32(view, signatureOffset - anchoredOffset);
|
|
5928
|
+
return getUint32$1(view, signatureOffset - anchoredOffset);
|
|
5738
5929
|
}
|
|
5739
5930
|
if (remoteProbeBudget.count > 0) {
|
|
5740
5931
|
remoteProbeBudget.count--;
|
|
5741
5932
|
const signatureArray = await readUint8Array(reader, signatureOffset, 4);
|
|
5742
|
-
return getUint32(getDataView(signatureArray), 0);
|
|
5933
|
+
return getUint32$1(getDataView(signatureArray), 0);
|
|
5743
5934
|
}
|
|
5744
5935
|
return UNDEFINED_VALUE;
|
|
5745
5936
|
}
|
|
5746
5937
|
|
|
5747
|
-
function
|
|
5938
|
+
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
|
|
5748
5939
|
const { rawFilename } = zipEntry;
|
|
5749
|
-
if (
|
|
5750
|
-
rawLocalFilename.
|
|
5940
|
+
if (checkLocalFilename &&
|
|
5941
|
+
(rawLocalFilename.length != rawFilename.length ||
|
|
5942
|
+
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
5751
5943
|
throwAmbiguousArchive("mismatched local file header (filename)");
|
|
5752
5944
|
}
|
|
5753
5945
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
@@ -5775,10 +5967,11 @@
|
|
|
5775
5967
|
return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
|
|
5776
5968
|
}
|
|
5777
5969
|
|
|
5778
|
-
function
|
|
5779
|
-
return
|
|
5970
|
+
function getFunctionOptionValue$1(zipReader, options, name) {
|
|
5971
|
+
return checkFunctionOption(getOptionValue$1(zipReader, options, name));
|
|
5780
5972
|
}
|
|
5781
5973
|
|
|
5974
|
+
|
|
5782
5975
|
function getDate(timeRaw) {
|
|
5783
5976
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
5784
5977
|
return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
@@ -5792,11 +5985,11 @@
|
|
|
5792
5985
|
return view.getUint8(offset);
|
|
5793
5986
|
}
|
|
5794
5987
|
|
|
5795
|
-
function getUint16(view, offset) {
|
|
5988
|
+
function getUint16$1(view, offset) {
|
|
5796
5989
|
return view.getUint16(offset, true);
|
|
5797
5990
|
}
|
|
5798
5991
|
|
|
5799
|
-
function getUint32(view, offset) {
|
|
5992
|
+
function getUint32$1(view, offset) {
|
|
5800
5993
|
return view.getUint32(offset, true);
|
|
5801
5994
|
}
|
|
5802
5995
|
|
|
@@ -5811,6 +6004,7 @@
|
|
|
5811
6004
|
ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
|
|
5812
6005
|
ERR_ENCRYPTED: ERR_ENCRYPTED,
|
|
5813
6006
|
ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
|
|
6007
|
+
ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
|
|
5814
6008
|
ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
|
|
5815
6009
|
ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
|
|
5816
6010
|
ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
@@ -5865,13 +6059,18 @@
|
|
|
5865
6059
|
|
|
5866
6060
|
const ERR_DUPLICATED_NAME = "File already exists";
|
|
5867
6061
|
const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
|
|
6062
|
+
const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
|
|
5868
6063
|
const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
|
|
6064
|
+
const ERR_INVALID_ENTRY_COMMENT_TYPE = "Invalid file entry comment (must be a string)";
|
|
6065
|
+
const ERR_INVALID_DATE = "Invalid date (must be a valid Date instance)";
|
|
5869
6066
|
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
5870
6067
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
5871
6068
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
5872
6069
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
5873
6070
|
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
5874
|
-
const
|
|
6071
|
+
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
6072
|
+
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
6073
|
+
const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
|
|
5875
6074
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
5876
6075
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
5877
6076
|
const MIN_UNIX_TIME = -2147483648;
|
|
@@ -5891,7 +6090,6 @@
|
|
|
5891
6090
|
const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
|
|
5892
6091
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
5893
6092
|
const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
|
|
5894
|
-
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
5895
6093
|
const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
5896
6094
|
|
|
5897
6095
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
@@ -5916,8 +6114,7 @@
|
|
|
5916
6114
|
writer,
|
|
5917
6115
|
addSplitZipSignature,
|
|
5918
6116
|
options,
|
|
5919
|
-
|
|
5920
|
-
files: new Map(),
|
|
6117
|
+
fileEntries: new Map(),
|
|
5921
6118
|
filenames: new Set(),
|
|
5922
6119
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
5923
6120
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
@@ -5933,15 +6130,28 @@
|
|
|
5933
6130
|
}
|
|
5934
6131
|
reader = new GenericReader(reader);
|
|
5935
6132
|
await initStream(reader);
|
|
6133
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6134
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6135
|
+
await initStream(reader);
|
|
6136
|
+
}
|
|
5936
6137
|
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5937
|
-
const zipReader$1 = new ZipReader(reader
|
|
6138
|
+
const zipReader$1 = new ZipReader(reader);
|
|
5938
6139
|
const entries = await zipReader$1.getEntries();
|
|
5939
6140
|
await zipReader$1.close();
|
|
5940
6141
|
await initStream(this.writer);
|
|
5941
|
-
|
|
5942
|
-
|
|
6142
|
+
const { directoryOffset } = zipReader$1;
|
|
6143
|
+
let splitZipSignatureLength = 0;
|
|
6144
|
+
if (this.addSplitZipSignature) {
|
|
6145
|
+
delete this.addSplitZipSignature;
|
|
6146
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
6147
|
+
await writeData(this.writer, getSplitZipSignatureArray());
|
|
6148
|
+
splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6149
|
+
this.offset += splitZipSignatureLength;
|
|
6150
|
+
}
|
|
6151
|
+
}
|
|
6152
|
+
const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
|
|
5943
6153
|
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
5944
|
-
this.
|
|
6154
|
+
this.fileEntries = new Map(entries.map(entry => {
|
|
5945
6155
|
const {
|
|
5946
6156
|
version,
|
|
5947
6157
|
rawLastModDate,
|
|
@@ -5996,11 +6206,12 @@
|
|
|
5996
6206
|
if (crc32 !== UNDEFINED_VALUE) {
|
|
5997
6207
|
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
5998
6208
|
}
|
|
6209
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
5999
6210
|
Object.assign(entry, {
|
|
6000
6211
|
zip64UncompressedSize,
|
|
6001
6212
|
zip64CompressedSize,
|
|
6002
|
-
|
|
6003
|
-
diskNumberStart
|
|
6213
|
+
offset,
|
|
6214
|
+
diskNumberStart,
|
|
6004
6215
|
zip64DiskNumberStart: false,
|
|
6005
6216
|
rawExtraFieldZip64,
|
|
6006
6217
|
rawExtraFieldAES,
|
|
@@ -6020,11 +6231,8 @@
|
|
|
6020
6231
|
async add(name = "", reader, options = {}) {
|
|
6021
6232
|
const zipWriter = this;
|
|
6022
6233
|
options = Object.assign({}, options);
|
|
6023
|
-
const {
|
|
6024
|
-
|
|
6025
|
-
config
|
|
6026
|
-
} = zipWriter;
|
|
6027
|
-
if (workers < config.maxWorkers) {
|
|
6234
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
6235
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
6028
6236
|
workers++;
|
|
6029
6237
|
} else {
|
|
6030
6238
|
await new Promise(resolve => pendingEntries.push(resolve));
|
|
@@ -6061,16 +6269,16 @@
|
|
|
6061
6269
|
}
|
|
6062
6270
|
|
|
6063
6271
|
remove(entry) {
|
|
6064
|
-
const { filenames,
|
|
6272
|
+
const { filenames, fileEntries } = this;
|
|
6065
6273
|
// deno-lint-ignore valid-typeof
|
|
6066
6274
|
if (typeof entry == STRING_TYPE) {
|
|
6067
|
-
entry =
|
|
6275
|
+
entry = fileEntries.get(entry);
|
|
6068
6276
|
}
|
|
6069
6277
|
if (entry && entry.filename !== UNDEFINED_VALUE) {
|
|
6070
6278
|
const { filename } = entry;
|
|
6071
|
-
if (filenames.has(filename) &&
|
|
6279
|
+
if (filenames.has(filename) && fileEntries.has(filename)) {
|
|
6072
6280
|
filenames.delete(filename);
|
|
6073
|
-
|
|
6281
|
+
fileEntries.delete(filename);
|
|
6074
6282
|
return true;
|
|
6075
6283
|
}
|
|
6076
6284
|
}
|
|
@@ -6081,6 +6289,9 @@
|
|
|
6081
6289
|
const zipWriter = this;
|
|
6082
6290
|
const { pendingAddFileCalls, writer } = this;
|
|
6083
6291
|
const { writable } = writer;
|
|
6292
|
+
if (!(comment instanceof Uint8Array)) {
|
|
6293
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
6294
|
+
}
|
|
6084
6295
|
if (getLength(comment) > MAX_16_BITS) {
|
|
6085
6296
|
throw new Error(ERR_INVALID_COMMENT);
|
|
6086
6297
|
}
|
|
@@ -6164,12 +6375,12 @@
|
|
|
6164
6375
|
const metadataInfo = resolveMetadata(zipWriter, name, options);
|
|
6165
6376
|
const { comment } = metadataInfo;
|
|
6166
6377
|
const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
|
|
6167
|
-
zipWriter.
|
|
6378
|
+
zipWriter.fileEntries.set(name, UNDEFINED_VALUE);
|
|
6168
6379
|
let fileEntry;
|
|
6169
6380
|
try {
|
|
6170
6381
|
const { resolvedOptions } = metadataInfo;
|
|
6171
6382
|
if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
|
|
6172
|
-
!resolvedOptions.passThrough && !(await supportsDeflate(
|
|
6383
|
+
!resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
|
|
6173
6384
|
resolvedOptions.level = 0;
|
|
6174
6385
|
}
|
|
6175
6386
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
@@ -6177,8 +6388,6 @@
|
|
|
6177
6388
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
6178
6389
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
6179
6390
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
6180
|
-
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
6181
|
-
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
6182
6391
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
6183
6392
|
crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
|
|
6184
6393
|
offset: zipWriter.offset - diskOffset,
|
|
@@ -6189,17 +6398,23 @@
|
|
|
6189
6398
|
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
6190
6399
|
fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
|
|
6191
6400
|
} catch (error) {
|
|
6192
|
-
zipWriter.
|
|
6401
|
+
zipWriter.fileEntries.delete(name);
|
|
6193
6402
|
throw error;
|
|
6194
6403
|
}
|
|
6195
|
-
Object.assign(fileEntry, {
|
|
6404
|
+
Object.assign(fileEntry, {
|
|
6405
|
+
name,
|
|
6406
|
+
comment,
|
|
6407
|
+
extraField,
|
|
6408
|
+
[PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
|
|
6409
|
+
[PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
|
|
6410
|
+
});
|
|
6196
6411
|
return new Entry(fileEntry);
|
|
6197
6412
|
}
|
|
6198
6413
|
|
|
6199
6414
|
function resolveAttributes(zipWriter, name, options) {
|
|
6200
6415
|
name = name.trim();
|
|
6201
6416
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
6202
|
-
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ?
|
|
6417
|
+
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
6203
6418
|
const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
|
|
6204
6419
|
const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
|
|
6205
6420
|
const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
|
|
@@ -6227,21 +6442,21 @@
|
|
|
6227
6442
|
if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
6228
6443
|
unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE;
|
|
6229
6444
|
}
|
|
6230
|
-
let msdosAttributesRaw =
|
|
6445
|
+
let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
|
|
6231
6446
|
let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
|
|
6232
|
-
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
|
|
6447
|
+
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType || executable;
|
|
6233
6448
|
const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
|
|
6234
6449
|
if (hasUnixMetadata) {
|
|
6235
6450
|
msDosCompatible = false;
|
|
6236
|
-
versionMadeBy = (versionMadeBy &
|
|
6451
|
+
versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
|
|
6237
6452
|
} else if (hasMsDosProvided) {
|
|
6238
6453
|
msDosCompatible = true;
|
|
6239
6454
|
versionMadeBy = (versionMadeBy & MAX_8_BITS);
|
|
6240
6455
|
}
|
|
6241
|
-
if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
6456
|
+
if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
6242
6457
|
throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
|
|
6243
6458
|
}
|
|
6244
|
-
if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
|
|
6459
|
+
if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
|
|
6245
6460
|
throw new Error(ERR_INVALID_MSDOS_DATA);
|
|
6246
6461
|
}
|
|
6247
6462
|
if (versionMadeBy > MAX_16_BITS) {
|
|
@@ -6273,11 +6488,10 @@
|
|
|
6273
6488
|
externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
|
|
6274
6489
|
}
|
|
6275
6490
|
}
|
|
6276
|
-
let unixExternalUpper;
|
|
6277
6491
|
if (!msDosCompatible) {
|
|
6278
6492
|
const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
|
|
6279
|
-
|
|
6280
|
-
unixMode = unixMode === UNDEFINED_VALUE ?
|
|
6493
|
+
const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
6494
|
+
unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
|
|
6281
6495
|
if (setuid) {
|
|
6282
6496
|
unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
|
|
6283
6497
|
} else {
|
|
@@ -6306,17 +6520,20 @@
|
|
|
6306
6520
|
if (hasMsDosProvided) {
|
|
6307
6521
|
externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
|
|
6308
6522
|
}
|
|
6523
|
+
const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
6524
|
+
const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
|
|
6309
6525
|
return {
|
|
6310
6526
|
name,
|
|
6311
6527
|
resolvedOptions: {
|
|
6312
6528
|
versionMadeBy,
|
|
6313
|
-
msDosCompatible,
|
|
6529
|
+
msDosCompatible: Boolean(msDosCompatible),
|
|
6314
6530
|
externalFileAttributes,
|
|
6315
6531
|
unixExternalUpper,
|
|
6316
6532
|
uid,
|
|
6317
6533
|
gid,
|
|
6318
6534
|
unixMode,
|
|
6319
6535
|
unixExtraFieldType,
|
|
6536
|
+
symlink,
|
|
6320
6537
|
setuid,
|
|
6321
6538
|
setgid,
|
|
6322
6539
|
sticky,
|
|
@@ -6327,7 +6544,7 @@
|
|
|
6327
6544
|
}
|
|
6328
6545
|
|
|
6329
6546
|
function resolveMetadata(zipWriter, name, options) {
|
|
6330
|
-
const encode =
|
|
6547
|
+
const encode = getFunctionOptionValue(zipWriter, options, OPTION_ENCODE_TEXT) || encodeText;
|
|
6331
6548
|
let rawFilename = encode(name, TEXT_TYPE_FILENAME);
|
|
6332
6549
|
if (rawFilename === UNDEFINED_VALUE) {
|
|
6333
6550
|
rawFilename = encodeText(name);
|
|
@@ -6336,6 +6553,10 @@
|
|
|
6336
6553
|
throw new Error(ERR_INVALID_ENTRY_NAME);
|
|
6337
6554
|
}
|
|
6338
6555
|
const comment = options[PROPERTY_NAME_COMMENT] || "";
|
|
6556
|
+
// deno-lint-ignore valid-typeof
|
|
6557
|
+
if (typeof comment != STRING_TYPE) {
|
|
6558
|
+
throw new Error(ERR_INVALID_ENTRY_COMMENT_TYPE);
|
|
6559
|
+
}
|
|
6339
6560
|
let rawComment = encode(comment, TEXT_TYPE_COMMENT);
|
|
6340
6561
|
if (rawComment === UNDEFINED_VALUE) {
|
|
6341
6562
|
rawComment = encodeText(comment);
|
|
@@ -6347,16 +6568,14 @@
|
|
|
6347
6568
|
if (version > MAX_16_BITS) {
|
|
6348
6569
|
throw new Error(ERR_INVALID_VERSION);
|
|
6349
6570
|
}
|
|
6350
|
-
const lastModDate =
|
|
6351
|
-
const lastAccessDate =
|
|
6352
|
-
const creationDate =
|
|
6571
|
+
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
6572
|
+
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6573
|
+
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6353
6574
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
6354
6575
|
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
6355
6576
|
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
6356
6577
|
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
6357
|
-
|
|
6358
|
-
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
6359
|
-
}
|
|
6578
|
+
checkPasswordOption(password, rawPassword);
|
|
6360
6579
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
6361
6580
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
6362
6581
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
@@ -6365,9 +6584,9 @@
|
|
|
6365
6584
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
6366
6585
|
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
6367
6586
|
const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
|
|
6368
|
-
const createTempStream =
|
|
6587
|
+
const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
6369
6588
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
6370
|
-
const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
|
|
6589
|
+
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
6371
6590
|
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
|
|
6372
6591
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
6373
6592
|
const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
@@ -6447,18 +6666,26 @@
|
|
|
6447
6666
|
if (!extraField) {
|
|
6448
6667
|
return EMPTY_UINT8_ARRAY;
|
|
6449
6668
|
}
|
|
6669
|
+
if (!(extraField instanceof Map)) {
|
|
6670
|
+
throw new Error(ERR_INVALID_EXTRAFIELD);
|
|
6671
|
+
}
|
|
6450
6672
|
let extraFieldSize = 0;
|
|
6451
6673
|
let offset = 0;
|
|
6452
|
-
extraField.forEach(data => extraFieldSize += 4 + getLength(data));
|
|
6453
|
-
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
6454
|
-
const rawExtraFieldView = getDataView(rawExtraField);
|
|
6455
6674
|
extraField.forEach((data, type) => {
|
|
6456
|
-
if (type > MAX_16_BITS) {
|
|
6675
|
+
if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
|
|
6457
6676
|
throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
|
|
6458
6677
|
}
|
|
6678
|
+
if (!(data instanceof Uint8Array)) {
|
|
6679
|
+
throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
|
|
6680
|
+
}
|
|
6459
6681
|
if (getLength(data) > MAX_16_BITS) {
|
|
6460
6682
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
6461
6683
|
}
|
|
6684
|
+
extraFieldSize += 4 + getLength(data);
|
|
6685
|
+
});
|
|
6686
|
+
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
6687
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
6688
|
+
extraField.forEach((data, type) => {
|
|
6462
6689
|
setUint16(rawExtraFieldView, offset, type);
|
|
6463
6690
|
setUint16(rawExtraFieldView, offset + 2, getLength(data));
|
|
6464
6691
|
arraySet(rawExtraField, data, offset + 4);
|
|
@@ -6546,7 +6773,7 @@
|
|
|
6546
6773
|
|
|
6547
6774
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
6548
6775
|
const {
|
|
6549
|
-
|
|
6776
|
+
fileEntries,
|
|
6550
6777
|
writer
|
|
6551
6778
|
} = zipWriter;
|
|
6552
6779
|
const {
|
|
@@ -6568,12 +6795,12 @@
|
|
|
6568
6795
|
let writerSizeBeforeEntry;
|
|
6569
6796
|
let flushedBufferedSize = 0;
|
|
6570
6797
|
let fileWriter;
|
|
6571
|
-
|
|
6798
|
+
fileEntries.set(name, fileEntry);
|
|
6572
6799
|
zipWriter.lastFileEntry = fileEntry;
|
|
6573
6800
|
try {
|
|
6574
6801
|
let lockPreviousFileEntry;
|
|
6575
6802
|
if (keepOrder) {
|
|
6576
|
-
lockPreviousFileEntry = previousFileEntry && previousFileEntry.
|
|
6803
|
+
lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
|
|
6577
6804
|
requestLockCurrentFileEntry();
|
|
6578
6805
|
}
|
|
6579
6806
|
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
|
|
@@ -6594,11 +6821,8 @@
|
|
|
6594
6821
|
const diskOffset = getDiskOffset(writer);
|
|
6595
6822
|
if (zipWriter.addSplitZipSignature) {
|
|
6596
6823
|
delete zipWriter.addSplitZipSignature;
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
6600
|
-
await writeData(writer, signatureArray);
|
|
6601
|
-
zipWriter.offset += 4;
|
|
6824
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
6825
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6602
6826
|
}
|
|
6603
6827
|
if (usdz && !bufferedWrite) {
|
|
6604
6828
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -6616,11 +6840,11 @@
|
|
|
6616
6840
|
writerSizeBeforeEntry = writer.size;
|
|
6617
6841
|
await writeData(fileWriter, localHeaderArray);
|
|
6618
6842
|
}
|
|
6619
|
-
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo,
|
|
6843
|
+
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, getConfiguration(), options);
|
|
6620
6844
|
if (!bufferedWrite) {
|
|
6621
6845
|
writingEntryData = false;
|
|
6622
6846
|
}
|
|
6623
|
-
|
|
6847
|
+
fileEntries.set(name, fileEntry);
|
|
6624
6848
|
fileEntry.filename = name;
|
|
6625
6849
|
if (bufferedWrite) {
|
|
6626
6850
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
@@ -6661,7 +6885,7 @@
|
|
|
6661
6885
|
zipWriter.offset += flushedBufferedSize;
|
|
6662
6886
|
}
|
|
6663
6887
|
}
|
|
6664
|
-
|
|
6888
|
+
fileEntries.delete(name);
|
|
6665
6889
|
throw error;
|
|
6666
6890
|
} finally {
|
|
6667
6891
|
if (bufferedWrite) {
|
|
@@ -6683,7 +6907,7 @@
|
|
|
6683
6907
|
}
|
|
6684
6908
|
|
|
6685
6909
|
function requestLockCurrentFileEntry() {
|
|
6686
|
-
fileEntry.
|
|
6910
|
+
fileEntry.lockFileEntry = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
|
|
6687
6911
|
}
|
|
6688
6912
|
|
|
6689
6913
|
async function requestLockWriter() {
|
|
@@ -6703,7 +6927,7 @@
|
|
|
6703
6927
|
}
|
|
6704
6928
|
}
|
|
6705
6929
|
|
|
6706
|
-
async function createFileEntry(reader, writer, { diskNumberStart,
|
|
6930
|
+
async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry }, entryInfo, config, options) {
|
|
6707
6931
|
const {
|
|
6708
6932
|
headerInfo,
|
|
6709
6933
|
dataDescriptorInfo,
|
|
@@ -6758,6 +6982,7 @@
|
|
|
6758
6982
|
uid,
|
|
6759
6983
|
gid,
|
|
6760
6984
|
unixMode,
|
|
6985
|
+
symlink,
|
|
6761
6986
|
setuid,
|
|
6762
6987
|
setgid,
|
|
6763
6988
|
sticky,
|
|
@@ -6770,7 +6995,7 @@
|
|
|
6770
6995
|
codecURI
|
|
6771
6996
|
} = options;
|
|
6772
6997
|
const fileEntry = {
|
|
6773
|
-
|
|
6998
|
+
lockFileEntry,
|
|
6774
6999
|
versionMadeBy,
|
|
6775
7000
|
zip64,
|
|
6776
7001
|
directory: Boolean(directory),
|
|
@@ -6794,6 +7019,7 @@
|
|
|
6794
7019
|
uid,
|
|
6795
7020
|
gid,
|
|
6796
7021
|
unixMode,
|
|
7022
|
+
symlink: Boolean(symlink),
|
|
6797
7023
|
setuid,
|
|
6798
7024
|
setgid,
|
|
6799
7025
|
sticky,
|
|
@@ -6811,7 +7037,7 @@
|
|
|
6811
7037
|
}
|
|
6812
7038
|
const { writable } = writer;
|
|
6813
7039
|
if (reader) {
|
|
6814
|
-
const readable = toCompatibleReadable(
|
|
7040
|
+
const readable = toCompatibleReadable(createReadable(reader));
|
|
6815
7041
|
const size = reader.size;
|
|
6816
7042
|
const workerOptions = {
|
|
6817
7043
|
options: {
|
|
@@ -6874,8 +7100,8 @@
|
|
|
6874
7100
|
rawLastModDate,
|
|
6875
7101
|
creationDate,
|
|
6876
7102
|
lastAccessDate,
|
|
6877
|
-
encrypted,
|
|
6878
|
-
zipCrypto,
|
|
7103
|
+
encrypted: Boolean(encrypted),
|
|
7104
|
+
zipCrypto: Boolean(zipCrypto),
|
|
6879
7105
|
size: metadataSize + compressedSize,
|
|
6880
7106
|
compressionMethod,
|
|
6881
7107
|
version,
|
|
@@ -6923,14 +7149,14 @@
|
|
|
6923
7149
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
6924
7150
|
const length = 4 + 16;
|
|
6925
7151
|
const extraFieldZip64 = createRecordWriter(length);
|
|
6926
|
-
extraFieldZip64.
|
|
6927
|
-
extraFieldZip64.
|
|
7152
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
7153
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
6928
7154
|
rawLocalExtraFieldZip64 = extraFieldZip64.array;
|
|
6929
7155
|
if (zip64ExtraFieldComplete) {
|
|
6930
|
-
extraFieldZip64.
|
|
7156
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
6931
7157
|
if (uncompressedFile) {
|
|
6932
7158
|
const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
6933
|
-
extraFieldZip64.
|
|
7159
|
+
extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
|
|
6934
7160
|
}
|
|
6935
7161
|
}
|
|
6936
7162
|
} else {
|
|
@@ -6939,8 +7165,8 @@
|
|
|
6939
7165
|
let rawExtraFieldAES;
|
|
6940
7166
|
if (encrypted && !zipCrypto) {
|
|
6941
7167
|
const extraFieldAES = createRecordWriter(getLength(EXTRAFIELD_DATA_AES) + 2);
|
|
6942
|
-
extraFieldAES.
|
|
6943
|
-
extraFieldAES.
|
|
7168
|
+
extraFieldAES.writeUint16(EXTRAFIELD_TYPE_AES);
|
|
7169
|
+
extraFieldAES.writeBytes(EXTRAFIELD_DATA_AES);
|
|
6944
7170
|
rawExtraFieldAES = extraFieldAES.array;
|
|
6945
7171
|
rawExtraFieldAES[8] = encryptionStrength;
|
|
6946
7172
|
} else {
|
|
@@ -6956,15 +7182,15 @@
|
|
|
6956
7182
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
6957
7183
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
6958
7184
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
6959
|
-
extraFieldTimestamp.
|
|
6960
|
-
extraFieldTimestamp.
|
|
6961
|
-
extraFieldTimestamp.
|
|
6962
|
-
extraFieldTimestamp.
|
|
7185
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7186
|
+
extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
|
|
7187
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7188
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
6963
7189
|
if (lastAccessDate) {
|
|
6964
|
-
extraFieldTimestamp.
|
|
7190
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(lastAccessDate)));
|
|
6965
7191
|
}
|
|
6966
7192
|
if (creationDate) {
|
|
6967
|
-
extraFieldTimestamp.
|
|
7193
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(creationDate)));
|
|
6968
7194
|
}
|
|
6969
7195
|
rawExtraFieldExtendedTimestamp = extraFieldTimestamp.array;
|
|
6970
7196
|
} else {
|
|
@@ -6977,14 +7203,14 @@
|
|
|
6977
7203
|
try {
|
|
6978
7204
|
const lastModTimeNTFS = getTimeNTFS(lastModDate);
|
|
6979
7205
|
const extraFieldNTFS = createRecordWriter(36);
|
|
6980
|
-
extraFieldNTFS.
|
|
6981
|
-
extraFieldNTFS.
|
|
7206
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS);
|
|
7207
|
+
extraFieldNTFS.writeUint16(32);
|
|
6982
7208
|
extraFieldNTFS.skip(4);
|
|
6983
|
-
extraFieldNTFS.
|
|
6984
|
-
extraFieldNTFS.
|
|
6985
|
-
extraFieldNTFS.
|
|
6986
|
-
extraFieldNTFS.
|
|
6987
|
-
extraFieldNTFS.
|
|
7209
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS_TAG1);
|
|
7210
|
+
extraFieldNTFS.writeUint16(24);
|
|
7211
|
+
extraFieldNTFS.writeUint64(lastModTimeNTFS);
|
|
7212
|
+
extraFieldNTFS.writeUint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
|
|
7213
|
+
extraFieldNTFS.writeUint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
|
|
6988
7214
|
rawExtraFieldNTFS = extraFieldNTFS.array;
|
|
6989
7215
|
} catch {
|
|
6990
7216
|
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
@@ -7003,20 +7229,20 @@
|
|
|
7003
7229
|
const gidBytes = packUnixId(gid);
|
|
7004
7230
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
7005
7231
|
const extraFieldUnix = createRecordWriter(4 + payloadLength);
|
|
7006
|
-
extraFieldUnix.
|
|
7007
|
-
extraFieldUnix.
|
|
7008
|
-
extraFieldUnix.
|
|
7009
|
-
extraFieldUnix.
|
|
7010
|
-
extraFieldUnix.
|
|
7011
|
-
extraFieldUnix.
|
|
7012
|
-
extraFieldUnix.
|
|
7232
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
|
|
7233
|
+
extraFieldUnix.writeUint16(payloadLength);
|
|
7234
|
+
extraFieldUnix.writeUint8(1);
|
|
7235
|
+
extraFieldUnix.writeUint8(uidBytes.length);
|
|
7236
|
+
extraFieldUnix.writeBytes(uidBytes);
|
|
7237
|
+
extraFieldUnix.writeUint8(gidBytes.length);
|
|
7238
|
+
extraFieldUnix.writeBytes(gidBytes);
|
|
7013
7239
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
7014
7240
|
} else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
7015
7241
|
const extraFieldUnix = createRecordWriter(8);
|
|
7016
|
-
extraFieldUnix.
|
|
7017
|
-
extraFieldUnix.
|
|
7018
|
-
extraFieldUnix.
|
|
7019
|
-
extraFieldUnix.
|
|
7242
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
|
|
7243
|
+
extraFieldUnix.writeUint16(4);
|
|
7244
|
+
extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
|
|
7245
|
+
extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
|
|
7020
7246
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
7021
7247
|
} else {
|
|
7022
7248
|
rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
|
|
@@ -7066,18 +7292,18 @@
|
|
|
7066
7292
|
const localHeader = createRecordWriter(HEADER_SIZE + getLength(rawFilename) + extraFieldLength);
|
|
7067
7293
|
const localHeaderArray = localHeader.array;
|
|
7068
7294
|
const localHeaderView = getDataView(localHeaderArray);
|
|
7069
|
-
localHeader.
|
|
7070
|
-
localHeader.
|
|
7071
|
-
localHeader.
|
|
7295
|
+
localHeader.writeUint32(LOCAL_FILE_HEADER_SIGNATURE);
|
|
7296
|
+
localHeader.writeBytes(headerArray);
|
|
7297
|
+
localHeader.writeBytes(rawFilename);
|
|
7072
7298
|
if (writeLocalExtraFieldZip64) {
|
|
7073
|
-
localHeader.
|
|
7074
|
-
}
|
|
7075
|
-
localHeader.
|
|
7076
|
-
localHeader.
|
|
7077
|
-
localHeader.
|
|
7078
|
-
localHeader.
|
|
7079
|
-
localHeader.
|
|
7080
|
-
localHeader.
|
|
7299
|
+
localHeader.writeBytes(rawLocalExtraFieldZip64);
|
|
7300
|
+
}
|
|
7301
|
+
localHeader.writeBytes(rawExtraFieldAES);
|
|
7302
|
+
localHeader.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
7303
|
+
localHeader.writeBytes(rawExtraFieldNTFS);
|
|
7304
|
+
localHeader.writeBytes(rawExtraFieldUnix);
|
|
7305
|
+
localHeader.writeBytes(rawExtraField);
|
|
7306
|
+
localHeader.writeBytes(rawLocalExtraField);
|
|
7081
7307
|
if (dataDescriptor) {
|
|
7082
7308
|
if (!zip64CompressedSize) {
|
|
7083
7309
|
setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, 0);
|
|
@@ -7267,7 +7493,7 @@
|
|
|
7267
7493
|
|
|
7268
7494
|
|
|
7269
7495
|
async function closeFile(zipWriter, comment, options) {
|
|
7270
|
-
const directoryDataLength = createDirectoryRecords(zipWriter.
|
|
7496
|
+
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
7271
7497
|
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7272
7498
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
7273
7499
|
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
@@ -7297,19 +7523,19 @@
|
|
|
7297
7523
|
if (zip64Offset || zip64DiskNumberStart || zip64UncompressedSize || zip64CompressedSize) {
|
|
7298
7524
|
const length = 4 + (zip64UncompressedSize ? 8 : 0) + (zip64CompressedSize ? 8 : 0) + (zip64Offset ? 8 : 0) + (zip64DiskNumberStart ? 4 : 0);
|
|
7299
7525
|
const extraFieldZip64 = createRecordWriter(length);
|
|
7300
|
-
extraFieldZip64.
|
|
7301
|
-
extraFieldZip64.
|
|
7526
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
7527
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
7302
7528
|
if (zip64UncompressedSize) {
|
|
7303
|
-
extraFieldZip64.
|
|
7529
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
7304
7530
|
}
|
|
7305
7531
|
if (zip64CompressedSize) {
|
|
7306
|
-
extraFieldZip64.
|
|
7532
|
+
extraFieldZip64.writeUint64(compressedSize);
|
|
7307
7533
|
}
|
|
7308
7534
|
if (zip64Offset) {
|
|
7309
|
-
extraFieldZip64.
|
|
7535
|
+
extraFieldZip64.writeUint64(fileEntry.offset);
|
|
7310
7536
|
}
|
|
7311
7537
|
if (zip64DiskNumberStart) {
|
|
7312
|
-
extraFieldZip64.
|
|
7538
|
+
extraFieldZip64.writeUint32(fileEntry.diskNumberStart);
|
|
7313
7539
|
}
|
|
7314
7540
|
rawExtraFieldZip64 = extraFieldZip64.array;
|
|
7315
7541
|
} else {
|
|
@@ -7322,10 +7548,10 @@
|
|
|
7322
7548
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
7323
7549
|
if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
|
|
7324
7550
|
const extraFieldTimestamp = createRecordWriter(9);
|
|
7325
|
-
extraFieldTimestamp.
|
|
7326
|
-
extraFieldTimestamp.
|
|
7327
|
-
extraFieldTimestamp.
|
|
7328
|
-
extraFieldTimestamp.
|
|
7551
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7552
|
+
extraFieldTimestamp.writeUint16(5);
|
|
7553
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7554
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
7329
7555
|
rawExtraFieldTimestamp = extraFieldTimestamp.array;
|
|
7330
7556
|
} else {
|
|
7331
7557
|
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
@@ -7347,14 +7573,14 @@
|
|
|
7347
7573
|
}
|
|
7348
7574
|
|
|
7349
7575
|
async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
7350
|
-
const {
|
|
7576
|
+
const { fileEntries, writer } = zipWriter;
|
|
7351
7577
|
const directoryArray = new Uint8Array(directoryDataLength);
|
|
7352
7578
|
await initStream(writer);
|
|
7353
7579
|
let offset = 0;
|
|
7354
7580
|
let directoryDiskOffset = 0;
|
|
7355
7581
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
7356
7582
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
7357
|
-
for (const [indexFileEntry, fileEntry] of Array.from(
|
|
7583
|
+
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
7358
7584
|
const {
|
|
7359
7585
|
offset: fileEntryOffset,
|
|
7360
7586
|
rawFilename,
|
|
@@ -7399,28 +7625,28 @@
|
|
|
7399
7625
|
setUint16(headerView, HEADER_OFFSET_VERSION, VERSION_ZIP64);
|
|
7400
7626
|
}
|
|
7401
7627
|
const directoryRecord = createRecordWriter(directoryRecordLength);
|
|
7402
|
-
directoryRecord.
|
|
7403
|
-
directoryRecord.
|
|
7404
|
-
directoryRecord.
|
|
7405
|
-
directoryRecord.
|
|
7406
|
-
directoryRecord.
|
|
7407
|
-
directoryRecord.
|
|
7408
|
-
directoryRecord.
|
|
7409
|
-
directoryRecord.
|
|
7410
|
-
directoryRecord.
|
|
7411
|
-
directoryRecord.
|
|
7412
|
-
directoryRecord.
|
|
7413
|
-
directoryRecord.
|
|
7414
|
-
directoryRecord.
|
|
7415
|
-
directoryRecord.
|
|
7416
|
-
directoryRecord.
|
|
7417
|
-
directoryRecord.
|
|
7418
|
-
directoryRecord.
|
|
7628
|
+
directoryRecord.writeUint32(CENTRAL_FILE_HEADER_SIGNATURE);
|
|
7629
|
+
directoryRecord.writeUint16(versionMadeBy);
|
|
7630
|
+
directoryRecord.writeBytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
|
|
7631
|
+
directoryRecord.writeUint16(extraFieldLength);
|
|
7632
|
+
directoryRecord.writeUint16(getLength(rawComment));
|
|
7633
|
+
directoryRecord.writeUint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
|
|
7634
|
+
directoryRecord.writeUint16(internalFileAttributes);
|
|
7635
|
+
directoryRecord.writeUint32(externalFileAttributes);
|
|
7636
|
+
directoryRecord.writeUint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
|
|
7637
|
+
directoryRecord.writeBytes(rawFilename);
|
|
7638
|
+
directoryRecord.writeBytes(rawExtraFieldZip64);
|
|
7639
|
+
directoryRecord.writeBytes(rawExtraFieldAES);
|
|
7640
|
+
directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
7641
|
+
directoryRecord.writeBytes(rawExtraFieldNTFS);
|
|
7642
|
+
directoryRecord.writeBytes(rawExtraFieldUnix);
|
|
7643
|
+
directoryRecord.writeBytes(rawExtraField);
|
|
7644
|
+
directoryRecord.writeBytes(rawComment);
|
|
7419
7645
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
7420
7646
|
offset += directoryRecordLength;
|
|
7421
7647
|
if (options.onprogress) {
|
|
7422
7648
|
try {
|
|
7423
|
-
await options.onprogress(indexFileEntry + 1,
|
|
7649
|
+
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
7424
7650
|
} catch {
|
|
7425
7651
|
// ignored
|
|
7426
7652
|
}
|
|
@@ -7434,7 +7660,7 @@
|
|
|
7434
7660
|
}
|
|
7435
7661
|
|
|
7436
7662
|
async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
7437
|
-
const signCentralDirectory =
|
|
7663
|
+
const signCentralDirectory = getFunctionOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
|
|
7438
7664
|
if (signCentralDirectory) {
|
|
7439
7665
|
const signatureData = await signCentralDirectory(directoryArray);
|
|
7440
7666
|
const signatureDataLength = getLength(signatureData);
|
|
@@ -7442,9 +7668,9 @@
|
|
|
7442
7668
|
throw new Error(ERR_INVALID_SIGNATURE_DATA);
|
|
7443
7669
|
}
|
|
7444
7670
|
const signatureRecord = createRecordWriter(6 + signatureDataLength);
|
|
7445
|
-
signatureRecord.
|
|
7446
|
-
signatureRecord.
|
|
7447
|
-
signatureRecord.
|
|
7671
|
+
signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
|
|
7672
|
+
signatureRecord.writeUint16(signatureDataLength);
|
|
7673
|
+
signatureRecord.writeBytes(signatureData);
|
|
7448
7674
|
await writeData(zipWriter.writer, signatureRecord.array);
|
|
7449
7675
|
return 6 + signatureDataLength;
|
|
7450
7676
|
}
|
|
@@ -7455,7 +7681,7 @@
|
|
|
7455
7681
|
const { writer } = zipWriter;
|
|
7456
7682
|
const { directoryStart, signatureLength } = cdInfo;
|
|
7457
7683
|
let { directoryDataLength } = cdInfo;
|
|
7458
|
-
let
|
|
7684
|
+
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
7459
7685
|
let diskNumber = directoryStart.diskNumber;
|
|
7460
7686
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
7461
7687
|
let lastDiskNumber = getDiskNumber(writer);
|
|
@@ -7463,7 +7689,7 @@
|
|
|
7463
7689
|
lastDiskNumber++;
|
|
7464
7690
|
}
|
|
7465
7691
|
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7466
|
-
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS ||
|
|
7692
|
+
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
7467
7693
|
if (zip64 === false) {
|
|
7468
7694
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
7469
7695
|
} else {
|
|
@@ -7480,37 +7706,37 @@
|
|
|
7480
7706
|
}
|
|
7481
7707
|
lastDiskNumber = getDiskNumber(writer);
|
|
7482
7708
|
if (zip64) {
|
|
7483
|
-
endOfdirectoryRecord.
|
|
7484
|
-
endOfdirectoryRecord.
|
|
7485
|
-
endOfdirectoryRecord.
|
|
7486
|
-
endOfdirectoryRecord.
|
|
7487
|
-
endOfdirectoryRecord.
|
|
7488
|
-
endOfdirectoryRecord.
|
|
7489
|
-
endOfdirectoryRecord.
|
|
7490
|
-
endOfdirectoryRecord.
|
|
7491
|
-
endOfdirectoryRecord.
|
|
7492
|
-
endOfdirectoryRecord.
|
|
7493
|
-
endOfdirectoryRecord.
|
|
7494
|
-
endOfdirectoryRecord.
|
|
7495
|
-
endOfdirectoryRecord.
|
|
7496
|
-
endOfdirectoryRecord.
|
|
7709
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7710
|
+
endOfdirectoryRecord.writeUint64(44);
|
|
7711
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
7712
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
7713
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7714
|
+
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
7715
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7716
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7717
|
+
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
7718
|
+
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
7719
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
7720
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7721
|
+
endOfdirectoryRecord.writeUint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
|
|
7722
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber + 1);
|
|
7497
7723
|
const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
|
|
7498
7724
|
if (supportZip64SplitFile) {
|
|
7499
7725
|
lastDiskNumber = MAX_16_BITS;
|
|
7500
7726
|
diskNumber = MAX_16_BITS;
|
|
7501
7727
|
}
|
|
7502
|
-
|
|
7728
|
+
fileEntriesLength = MAX_16_BITS;
|
|
7503
7729
|
directoryOffset = MAX_32_BITS;
|
|
7504
7730
|
directoryDataLength = MAX_32_BITS;
|
|
7505
7731
|
}
|
|
7506
|
-
endOfdirectoryRecord.
|
|
7507
|
-
endOfdirectoryRecord.
|
|
7508
|
-
endOfdirectoryRecord.
|
|
7509
|
-
endOfdirectoryRecord.
|
|
7510
|
-
endOfdirectoryRecord.
|
|
7511
|
-
endOfdirectoryRecord.
|
|
7512
|
-
endOfdirectoryRecord.
|
|
7513
|
-
endOfdirectoryRecord.
|
|
7732
|
+
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7733
|
+
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
7734
|
+
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
7735
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7736
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7737
|
+
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
7738
|
+
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
7739
|
+
endOfdirectoryRecord.writeUint16(commentLength);
|
|
7514
7740
|
await writeData(writer, endOfdirectoryRecord.array);
|
|
7515
7741
|
if (commentLength) {
|
|
7516
7742
|
await writeData(writer, comment);
|
|
@@ -7523,11 +7749,11 @@
|
|
|
7523
7749
|
let offset = 0;
|
|
7524
7750
|
return {
|
|
7525
7751
|
array,
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7752
|
+
writeUint8: value => { setUint8(view, offset, value); offset += 1; },
|
|
7753
|
+
writeUint16: value => { setUint16(view, offset, value); offset += 2; },
|
|
7754
|
+
writeUint32: value => { setUint32(view, offset, value); offset += 4; },
|
|
7755
|
+
writeUint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
|
|
7756
|
+
writeBytes: value => { arraySet(array, value, offset); offset += getLength(value); },
|
|
7531
7757
|
skip: count => offset += count
|
|
7532
7758
|
};
|
|
7533
7759
|
}
|
|
@@ -7551,6 +7777,71 @@
|
|
|
7551
7777
|
return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
|
|
7552
7778
|
}
|
|
7553
7779
|
|
|
7780
|
+
async function startsWithSplitZipSignature(reader) {
|
|
7781
|
+
const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
7782
|
+
return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
7783
|
+
}
|
|
7784
|
+
|
|
7785
|
+
async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
|
|
7786
|
+
const { writer } = zipWriter;
|
|
7787
|
+
const entryPositions = new Map();
|
|
7788
|
+
if (writer.closeDisk) {
|
|
7789
|
+
const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
|
|
7790
|
+
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
7791
|
+
let copiedLength = 0;
|
|
7792
|
+
for (const entry of sortedEntries) {
|
|
7793
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
7794
|
+
await copyData(zipWriter, reader, copiedLength, sourceOffset - copiedLength);
|
|
7795
|
+
if (exceedsAvailableSize(writer, await getLocalHeaderLength(reader, sourceOffset))) {
|
|
7796
|
+
await writer.closeDisk();
|
|
7797
|
+
}
|
|
7798
|
+
entryPositions.set(entry, {
|
|
7799
|
+
offset: getSegmentOffset(zipWriter, writer),
|
|
7800
|
+
diskNumberStart: getDiskNumber(writer)
|
|
7801
|
+
});
|
|
7802
|
+
copiedLength = sourceOffset;
|
|
7803
|
+
}
|
|
7804
|
+
await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
|
|
7805
|
+
} else {
|
|
7806
|
+
await copyData(zipWriter, reader, 0, directoryOffset);
|
|
7807
|
+
entries.forEach(entry => entryPositions.set(entry, {
|
|
7808
|
+
offset: splitZipSignatureLength + getSourceOffset(reader, entry),
|
|
7809
|
+
diskNumberStart: 0
|
|
7810
|
+
}));
|
|
7811
|
+
}
|
|
7812
|
+
return entryPositions;
|
|
7813
|
+
}
|
|
7814
|
+
|
|
7815
|
+
async function copyData(zipWriter, reader, offset, size) {
|
|
7816
|
+
if (size > 0) {
|
|
7817
|
+
const { writer } = zipWriter;
|
|
7818
|
+
await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
|
|
7819
|
+
writer.size += size;
|
|
7820
|
+
zipWriter.offset += size;
|
|
7821
|
+
}
|
|
7822
|
+
}
|
|
7823
|
+
|
|
7824
|
+
async function getLocalHeaderLength(reader, offset) {
|
|
7825
|
+
const headerArray = await readUint8Array(reader, offset, HEADER_SIZE);
|
|
7826
|
+
if (getLength(headerArray) < HEADER_SIZE) {
|
|
7827
|
+
return HEADER_SIZE;
|
|
7828
|
+
}
|
|
7829
|
+
const headerView = getDataView(headerArray);
|
|
7830
|
+
return HEADER_SIZE +
|
|
7831
|
+
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
7832
|
+
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
7833
|
+
}
|
|
7834
|
+
|
|
7835
|
+
function getSourceOffset(reader, { offset, diskNumberStart }) {
|
|
7836
|
+
return offset + (reader.getDiskOffset ? reader.getDiskOffset(diskNumberStart) : 0);
|
|
7837
|
+
}
|
|
7838
|
+
|
|
7839
|
+
function getSplitZipSignatureArray() {
|
|
7840
|
+
const signatureArray = new Uint8Array(SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
7841
|
+
setUint32(getDataView(signatureArray), 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
7842
|
+
return signatureArray;
|
|
7843
|
+
}
|
|
7844
|
+
|
|
7554
7845
|
async function writeData(writer, array) {
|
|
7555
7846
|
const { writable } = writer;
|
|
7556
7847
|
const streamWriter = writable.getWriter();
|
|
@@ -7602,6 +7893,21 @@
|
|
|
7602
7893
|
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
7603
7894
|
}
|
|
7604
7895
|
|
|
7896
|
+
function getDateOptionValue(zipWriter, options, name, defaultValue) {
|
|
7897
|
+
const date = getOptionValue(zipWriter, options, name, defaultValue);
|
|
7898
|
+
if (date === null) {
|
|
7899
|
+
return defaultValue;
|
|
7900
|
+
}
|
|
7901
|
+
if (date !== UNDEFINED_VALUE && (typeof date.getTime != FUNCTION_TYPE || Number.isNaN(date.getTime()))) {
|
|
7902
|
+
throw new Error(ERR_INVALID_DATE);
|
|
7903
|
+
}
|
|
7904
|
+
return date;
|
|
7905
|
+
}
|
|
7906
|
+
|
|
7907
|
+
function getFunctionOptionValue(zipWriter, options, name) {
|
|
7908
|
+
return checkFunctionOption(getOptionValue(zipWriter, options, name));
|
|
7909
|
+
}
|
|
7910
|
+
|
|
7605
7911
|
function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
|
|
7606
7912
|
const value = getAliasedValue(options, name, deprecatedName);
|
|
7607
7913
|
const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
|
|
@@ -7616,9 +7922,6 @@
|
|
|
7616
7922
|
return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
|
|
7617
7923
|
}
|
|
7618
7924
|
|
|
7619
|
-
function toNumber(value) {
|
|
7620
|
-
return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
|
|
7621
|
-
}
|
|
7622
7925
|
|
|
7623
7926
|
function getMaximumCompressedSize(uncompressedSize) {
|
|
7624
7927
|
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
@@ -7630,6 +7933,14 @@
|
|
|
7630
7933
|
: compressionMethod !== COMPRESSION_METHOD_STORE;
|
|
7631
7934
|
}
|
|
7632
7935
|
|
|
7936
|
+
function getUint16(view, offset) {
|
|
7937
|
+
return view.getUint16(offset, true);
|
|
7938
|
+
}
|
|
7939
|
+
|
|
7940
|
+
function getUint32(view, offset) {
|
|
7941
|
+
return view.getUint32(offset, true);
|
|
7942
|
+
}
|
|
7943
|
+
|
|
7633
7944
|
function setUint8(view, offset, value) {
|
|
7634
7945
|
view.setUint8(offset, value);
|
|
7635
7946
|
}
|
|
@@ -7673,9 +7984,9 @@
|
|
|
7673
7984
|
const headerRecord = createRecordWriter(HEADER_SIZE - 4);
|
|
7674
7985
|
const headerArray = headerRecord.array;
|
|
7675
7986
|
const headerView = getDataView(headerArray);
|
|
7676
|
-
headerRecord.
|
|
7677
|
-
headerRecord.
|
|
7678
|
-
headerRecord.
|
|
7987
|
+
headerRecord.writeUint16(version);
|
|
7988
|
+
headerRecord.writeUint16(bitFlag);
|
|
7989
|
+
headerRecord.writeUint16(compressionMethod);
|
|
7679
7990
|
if (rawLastModDate === UNDEFINED_VALUE) {
|
|
7680
7991
|
const dateArray = new Uint32Array(1);
|
|
7681
7992
|
const dateView = getDataView(dateArray);
|
|
@@ -7683,20 +7994,20 @@
|
|
|
7683
7994
|
setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
|
|
7684
7995
|
rawLastModDate = dateArray[0];
|
|
7685
7996
|
}
|
|
7686
|
-
headerRecord.
|
|
7997
|
+
headerRecord.writeUint32(rawLastModDate);
|
|
7687
7998
|
headerRecord.skip(4);
|
|
7688
7999
|
if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
|
|
7689
|
-
headerRecord.
|
|
8000
|
+
headerRecord.writeUint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
|
|
7690
8001
|
} else {
|
|
7691
8002
|
headerRecord.skip(4);
|
|
7692
8003
|
}
|
|
7693
8004
|
if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
|
|
7694
|
-
headerRecord.
|
|
8005
|
+
headerRecord.writeUint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
|
|
7695
8006
|
} else {
|
|
7696
8007
|
headerRecord.skip(4);
|
|
7697
8008
|
}
|
|
7698
|
-
headerRecord.
|
|
7699
|
-
headerRecord.
|
|
8009
|
+
headerRecord.writeUint16(getLength(rawFilename));
|
|
8010
|
+
headerRecord.writeUint16(extraFieldLength);
|
|
7700
8011
|
return {
|
|
7701
8012
|
headerArray,
|
|
7702
8013
|
headerView,
|
|
@@ -8238,7 +8549,7 @@
|
|
|
8238
8549
|
*/
|
|
8239
8550
|
|
|
8240
8551
|
|
|
8241
|
-
|
|
8552
|
+
a(setDefaultConfiguration);
|
|
8242
8553
|
|
|
8243
8554
|
exports.BlobReader = BlobReader;
|
|
8244
8555
|
exports.BlobWriter = BlobWriter;
|
|
@@ -8250,6 +8561,7 @@
|
|
|
8250
8561
|
exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
|
|
8251
8562
|
exports.ERR_ENCRYPTED = ERR_ENCRYPTED;
|
|
8252
8563
|
exports.ERR_ENCRYPTED_CENTRAL_DIRECTORY = ERR_ENCRYPTED_CENTRAL_DIRECTORY;
|
|
8564
|
+
exports.ERR_ENTRY_DATA_OUT_OF_BOUNDS = ERR_ENTRY_DATA_OUT_OF_BOUNDS;
|
|
8253
8565
|
exports.ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND;
|
|
8254
8566
|
exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
|
|
8255
8567
|
exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
|
|
@@ -8259,21 +8571,29 @@
|
|
|
8259
8571
|
exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
|
|
8260
8572
|
exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
|
|
8261
8573
|
exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
|
|
8574
|
+
exports.ERR_INVALID_COMMENT_TYPE = ERR_INVALID_COMMENT_TYPE;
|
|
8262
8575
|
exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
|
|
8263
8576
|
exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
|
|
8577
|
+
exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
|
|
8264
8578
|
exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
|
|
8265
8579
|
exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
|
|
8580
|
+
exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
|
|
8266
8581
|
exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
|
|
8582
|
+
exports.ERR_INVALID_EXTRAFIELD = ERR_INVALID_EXTRAFIELD;
|
|
8267
8583
|
exports.ERR_INVALID_EXTRAFIELD_DATA = ERR_INVALID_EXTRAFIELD_DATA;
|
|
8584
|
+
exports.ERR_INVALID_EXTRAFIELD_DATA_TYPE = ERR_INVALID_EXTRAFIELD_DATA_TYPE;
|
|
8268
8585
|
exports.ERR_INVALID_EXTRAFIELD_TYPE = ERR_INVALID_EXTRAFIELD_TYPE;
|
|
8269
8586
|
exports.ERR_INVALID_FILENAME_VALIDATION = ERR_INVALID_FILENAME_VALIDATION;
|
|
8587
|
+
exports.ERR_INVALID_FUNCTION_OPTION = ERR_INVALID_FUNCTION_OPTION;
|
|
8270
8588
|
exports.ERR_INVALID_GID = ERR_INVALID_GID;
|
|
8271
8589
|
exports.ERR_INVALID_LEVEL = ERR_INVALID_LEVEL;
|
|
8272
8590
|
exports.ERR_INVALID_MAX_APPENDED_DATA_SIZE = ERR_INVALID_MAX_APPENDED_DATA_SIZE;
|
|
8591
|
+
exports.ERR_INVALID_MAX_WORKERS = ERR_INVALID_MAX_WORKERS;
|
|
8273
8592
|
exports.ERR_INVALID_MSDOS_ATTRIBUTES = ERR_INVALID_MSDOS_ATTRIBUTES;
|
|
8274
8593
|
exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
|
|
8275
8594
|
exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
|
|
8276
8595
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
8596
|
+
exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
|
|
8277
8597
|
exports.ERR_INVALID_SIGNATURE = ERR_INVALID_SIGNATURE;
|
|
8278
8598
|
exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
|
|
8279
8599
|
exports.ERR_INVALID_STRICTNESS = ERR_INVALID_STRICTNESS;
|