@zip.js/zip.js 2.8.53 → 2.8.55
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 +737 -491
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +745 -490
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +776 -525
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +738 -510
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +776 -525
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +790 -525
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +791 -526
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +746 -491
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +746 -491
- 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 +747 -492
- package/dist/zip.min.js +1 -1
- package/eslint.config.mjs +1 -0
- package/index-native.cjs +790 -525
- package/index-native.min.js +1 -1
- package/index.cjs +791 -526
- package/index.d.cts +422 -49
- package/index.d.ts +422 -49
- package/index.min.js +1 -1
- package/lib/core/configuration.js +62 -21
- package/lib/core/constants.js +13 -1
- package/lib/core/io.js +33 -27
- package/lib/core/options.js +44 -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-fs.js +39 -32
- package/lib/core/zip-reader.js +100 -38
- package/lib/core/zip-writer.js +301 -177
- package/lib/core/zlib-streams-inline.js +1 -1
- 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 +8 -2
package/dist/zip-fs-core.js
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
|
|
45
45
|
const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
|
|
46
46
|
const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
|
|
47
|
+
const TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE = 0x30304b50;
|
|
47
48
|
const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
|
|
48
49
|
const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
|
|
49
50
|
const DIGITAL_SIGNATURE_RECORD_SIGNATURE = 0x05054b50;
|
|
@@ -60,6 +61,7 @@
|
|
|
60
61
|
const DATA_DESCRIPTOR_RECORD_LENGTH = 12;
|
|
61
62
|
const DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH = 20;
|
|
62
63
|
const DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH = 4;
|
|
64
|
+
const SPLIT_ZIP_FILE_SIGNATURE_LENGTH = 4;
|
|
63
65
|
|
|
64
66
|
const EXTRAFIELD_TYPE_ZIP64 = 0x0001;
|
|
65
67
|
const EXTRAFIELD_TYPE_AES = 0x9901;
|
|
@@ -82,6 +84,7 @@
|
|
|
82
84
|
const BITFLAG_DATA_DESCRIPTOR = 0b1000;
|
|
83
85
|
const BITFLAG_STRONG_ENCRYPTION = 0b1000000;
|
|
84
86
|
const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
|
|
87
|
+
const BITFLAG_MASKED_LOCAL_HEADERS = 0b10000000000000;
|
|
85
88
|
const FILE_ATTR_MSDOS_DIR_MASK = 0b10000;
|
|
86
89
|
const FILE_ATTR_MSDOS_READONLY_MASK = 0x01;
|
|
87
90
|
const FILE_ATTR_MSDOS_HIDDEN_MASK = 0x02;
|
|
@@ -111,6 +114,8 @@
|
|
|
111
114
|
const HEADER_OFFSET_SIGNATURE = 10;
|
|
112
115
|
const HEADER_OFFSET_COMPRESSED_SIZE = 14;
|
|
113
116
|
const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18;
|
|
117
|
+
const HEADER_OFFSET_FILENAME_LENGTH = 22;
|
|
118
|
+
const HEADER_OFFSET_EXTRAFIELD_LENGTH = 24;
|
|
114
119
|
const LOCAL_HEADER_COMMON_OFFSET = 4;
|
|
115
120
|
|
|
116
121
|
const MAX_DATE = new Date(2107, 11, 31, 23, 59, 58);
|
|
@@ -123,9 +128,116 @@
|
|
|
123
128
|
const OBJECT_TYPE = "object";
|
|
124
129
|
const STRING_TYPE = "string";
|
|
125
130
|
const NUMBER_TYPE = "number";
|
|
131
|
+
const BOOLEAN_TYPE = "boolean";
|
|
126
132
|
|
|
127
133
|
const EMPTY_UINT8_ARRAY = new Uint8Array();
|
|
128
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
|
+
|
|
129
241
|
/*
|
|
130
242
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
131
243
|
|
|
@@ -155,7 +267,9 @@
|
|
|
155
267
|
*/
|
|
156
268
|
|
|
157
269
|
|
|
270
|
+
const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
|
|
158
271
|
const MINIMUM_CHUNK_SIZE = 64;
|
|
272
|
+
const MINIMUM_PROPERTY_VALUE = 1;
|
|
159
273
|
let maxWorkers = 2;
|
|
160
274
|
try {
|
|
161
275
|
if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
|
|
@@ -167,7 +281,7 @@
|
|
|
167
281
|
const DEFAULT_CONFIGURATION = {
|
|
168
282
|
workerURI: "./core/web-worker-wasm.js",
|
|
169
283
|
wasmURI: "./core/streams/zlib-wasm/zlib-streams.wasm",
|
|
170
|
-
chunkSize:
|
|
284
|
+
chunkSize: DEFAULT_CHUNK_SIZE$1,
|
|
171
285
|
maxWorkers,
|
|
172
286
|
terminateWorkerTimeout: 5000,
|
|
173
287
|
workerStarvationTimeout: 5000,
|
|
@@ -186,7 +300,12 @@
|
|
|
186
300
|
}
|
|
187
301
|
|
|
188
302
|
function getChunkSize(config) {
|
|
189
|
-
return
|
|
303
|
+
return normalizeChunkSize(config.chunkSize);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function normalizeChunkSize(chunkSize) {
|
|
307
|
+
chunkSize = toNumber(chunkSize);
|
|
308
|
+
return Number.isInteger(chunkSize) && chunkSize >= MINIMUM_PROPERTY_VALUE ? Math.max(chunkSize, MINIMUM_CHUNK_SIZE) : DEFAULT_CHUNK_SIZE$1;
|
|
190
309
|
}
|
|
191
310
|
|
|
192
311
|
/*
|
|
@@ -320,6 +439,96 @@
|
|
|
320
439
|
});
|
|
321
440
|
}
|
|
322
441
|
|
|
442
|
+
/*
|
|
443
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
444
|
+
|
|
445
|
+
Redistribution and use in source and binary forms, with or without
|
|
446
|
+
modification, are permitted provided that the following conditions are met:
|
|
447
|
+
|
|
448
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
449
|
+
this list of conditions and the following disclaimer.
|
|
450
|
+
|
|
451
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
452
|
+
notice, this list of conditions and the following disclaimer in
|
|
453
|
+
the documentation and/or other materials provided with the distribution.
|
|
454
|
+
|
|
455
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
456
|
+
derived from this software without specific prior written permission.
|
|
457
|
+
|
|
458
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
459
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
460
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
461
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
462
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
463
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
464
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
465
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
466
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
467
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
468
|
+
*/
|
|
469
|
+
|
|
470
|
+
/* global TextDecoder */
|
|
471
|
+
|
|
472
|
+
const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
|
|
473
|
+
const VALID_CP437 = CP437.length == 256;
|
|
474
|
+
|
|
475
|
+
function decodeCP437(stringValue) {
|
|
476
|
+
if (VALID_CP437) {
|
|
477
|
+
let result = "";
|
|
478
|
+
for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
|
|
479
|
+
result += CP437[stringValue[indexCharacter]];
|
|
480
|
+
}
|
|
481
|
+
return result;
|
|
482
|
+
} else {
|
|
483
|
+
return new TextDecoder().decode(stringValue);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/*
|
|
488
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
489
|
+
|
|
490
|
+
Redistribution and use in source and binary forms, with or without
|
|
491
|
+
modification, are permitted provided that the following conditions are met:
|
|
492
|
+
|
|
493
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
494
|
+
this list of conditions and the following disclaimer.
|
|
495
|
+
|
|
496
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
497
|
+
notice, this list of conditions and the following disclaimer in
|
|
498
|
+
the documentation and/or other materials provided with the distribution.
|
|
499
|
+
|
|
500
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
501
|
+
derived from this software without specific prior written permission.
|
|
502
|
+
|
|
503
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
504
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
505
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
506
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
507
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
508
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
509
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
510
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
511
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
512
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
513
|
+
*/
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
function decodeText(value, encoding) {
|
|
517
|
+
return decode(value, encoding, true);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function decodeTextRemovingBOM(value, encoding) {
|
|
521
|
+
return decode(value, encoding, false);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
function decode(value, encoding, ignoreBOM) {
|
|
525
|
+
if (encoding && encoding.trim().toLowerCase() == "cp437") {
|
|
526
|
+
return decodeCP437(value);
|
|
527
|
+
} else {
|
|
528
|
+
return new TextDecoder(encoding, { ignoreBOM }).decode(value);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
323
532
|
/*
|
|
324
533
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
325
534
|
|
|
@@ -392,6 +601,7 @@
|
|
|
392
601
|
createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
|
|
393
602
|
const reader = this;
|
|
394
603
|
let chunkOffset = 0;
|
|
604
|
+
chunkSize = normalizeChunkSize(chunkSize);
|
|
395
605
|
return new ReadableStream({
|
|
396
606
|
async pull(controller) {
|
|
397
607
|
const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
|
|
@@ -399,7 +609,7 @@
|
|
|
399
609
|
if (data.length) {
|
|
400
610
|
controller.enqueue(data);
|
|
401
611
|
}
|
|
402
|
-
if ((chunkOffset + chunkSize >= size) || (
|
|
612
|
+
if ((chunkOffset + chunkSize >= size) || (!data.length && dataSize)) {
|
|
403
613
|
controller.close();
|
|
404
614
|
} else {
|
|
405
615
|
chunkOffset += chunkSize;
|
|
@@ -479,31 +689,31 @@
|
|
|
479
689
|
Object.assign(this, {
|
|
480
690
|
contentType,
|
|
481
691
|
data: "data:" + (contentType || "") + ";base64,",
|
|
482
|
-
|
|
692
|
+
pendingCharacters: ""
|
|
483
693
|
});
|
|
484
694
|
}
|
|
485
695
|
|
|
486
696
|
writeUint8Array(array) {
|
|
487
697
|
const writer = this;
|
|
488
698
|
let indexArray;
|
|
489
|
-
let dataString = writer.
|
|
490
|
-
const delta = writer.
|
|
491
|
-
writer.
|
|
699
|
+
let dataString = writer.pendingCharacters;
|
|
700
|
+
const delta = writer.pendingCharacters.length;
|
|
701
|
+
writer.pendingCharacters = "";
|
|
492
702
|
for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
|
|
493
703
|
dataString += String.fromCharCode(array[indexArray]);
|
|
494
704
|
}
|
|
495
705
|
for (; indexArray < array.length; indexArray++) {
|
|
496
|
-
writer.
|
|
706
|
+
writer.pendingCharacters += String.fromCharCode(array[indexArray]);
|
|
497
707
|
}
|
|
498
708
|
if (dataString.length > 2) {
|
|
499
709
|
writer.data += btoa(dataString);
|
|
500
710
|
} else {
|
|
501
|
-
writer.
|
|
711
|
+
writer.pendingCharacters = dataString + writer.pendingCharacters;
|
|
502
712
|
}
|
|
503
713
|
}
|
|
504
714
|
|
|
505
715
|
getData() {
|
|
506
|
-
return this.data + btoa(this.
|
|
716
|
+
return this.data + btoa(this.pendingCharacters);
|
|
507
717
|
}
|
|
508
718
|
}
|
|
509
719
|
|
|
@@ -533,7 +743,7 @@
|
|
|
533
743
|
constructor(blob) {
|
|
534
744
|
super();
|
|
535
745
|
Object.assign(this, {
|
|
536
|
-
blob,
|
|
746
|
+
sourceBlob: blob,
|
|
537
747
|
size: blob.size
|
|
538
748
|
});
|
|
539
749
|
if (!blobSliceProbe) {
|
|
@@ -543,13 +753,13 @@
|
|
|
543
753
|
|
|
544
754
|
createReadable(options) {
|
|
545
755
|
const reader = this;
|
|
546
|
-
const {
|
|
756
|
+
const { sourceBlob, size } = reader;
|
|
547
757
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
548
758
|
if (!offset && readSize >= size) {
|
|
549
|
-
return toCompatibleReadable(
|
|
759
|
+
return toCompatibleReadable(sourceBlob.stream());
|
|
550
760
|
}
|
|
551
761
|
if (blobSliceReliable) {
|
|
552
|
-
return toCompatibleReadable(
|
|
762
|
+
return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
|
|
553
763
|
}
|
|
554
764
|
return super.createReadable(options);
|
|
555
765
|
}
|
|
@@ -558,7 +768,7 @@
|
|
|
558
768
|
const reader = this;
|
|
559
769
|
const offsetEnd = offset + length;
|
|
560
770
|
const readsWholeBlob = !offset && offsetEnd >= reader.size;
|
|
561
|
-
const blob = readsWholeBlob ? reader.
|
|
771
|
+
const blob = readsWholeBlob ? reader.sourceBlob : reader.sourceBlob.slice(offset, offsetEnd);
|
|
562
772
|
let arrayBuffer = await blob.arrayBuffer();
|
|
563
773
|
const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
|
|
564
774
|
if (sliceIgnoredByBuggyImplementation) {
|
|
@@ -580,12 +790,12 @@
|
|
|
580
790
|
}
|
|
581
791
|
});
|
|
582
792
|
writer.contentType = contentType;
|
|
583
|
-
writer.
|
|
584
|
-
writer.
|
|
793
|
+
writer.blobPromise = streamToBlob(transformStream.readable, contentType);
|
|
794
|
+
writer.blobPromise.catch(() => { });
|
|
585
795
|
}
|
|
586
796
|
|
|
587
797
|
getData() {
|
|
588
|
-
return this.
|
|
798
|
+
return this.blobPromise;
|
|
589
799
|
}
|
|
590
800
|
}
|
|
591
801
|
|
|
@@ -619,7 +829,7 @@
|
|
|
619
829
|
class TextWriter extends BlobWriter {
|
|
620
830
|
|
|
621
831
|
constructor(encoding) {
|
|
622
|
-
super(
|
|
832
|
+
super();
|
|
623
833
|
Object.assign(this, {
|
|
624
834
|
encoding,
|
|
625
835
|
utf8: !encoding || encoding.toLowerCase() == "utf-8"
|
|
@@ -635,14 +845,7 @@
|
|
|
635
845
|
if (blob.text && utf8) {
|
|
636
846
|
return blob.text();
|
|
637
847
|
} else {
|
|
638
|
-
|
|
639
|
-
return new Promise((resolve, reject) => {
|
|
640
|
-
Object.assign(reader, {
|
|
641
|
-
onload: ({ target }) => resolve(target.result),
|
|
642
|
-
onerror: () => reject(reader.error)
|
|
643
|
-
});
|
|
644
|
-
reader.readAsText(blob, encoding);
|
|
645
|
-
});
|
|
848
|
+
return decodeTextRemovingBOM(new Uint8Array(await blob.arrayBuffer()), encoding);
|
|
646
849
|
}
|
|
647
850
|
}
|
|
648
851
|
}
|
|
@@ -1303,6 +1506,16 @@
|
|
|
1303
1506
|
return reader.readUint8Array(offset, size);
|
|
1304
1507
|
}
|
|
1305
1508
|
|
|
1509
|
+
function createReadable(reader, options) {
|
|
1510
|
+
if (reader.createReadable) {
|
|
1511
|
+
return reader.createReadable(options);
|
|
1512
|
+
} else if (reader.readUint8Array) {
|
|
1513
|
+
return Reader.prototype.createReadable.call(reader, options);
|
|
1514
|
+
} else {
|
|
1515
|
+
return reader.readable;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1306
1519
|
/*
|
|
1307
1520
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
1308
1521
|
|
|
@@ -2460,13 +2673,13 @@
|
|
|
2460
2673
|
const {
|
|
2461
2674
|
ctr,
|
|
2462
2675
|
hmac,
|
|
2463
|
-
|
|
2676
|
+
pendingInput,
|
|
2464
2677
|
ready
|
|
2465
2678
|
} = this;
|
|
2466
2679
|
if (hmac && ctr) {
|
|
2467
2680
|
await ready;
|
|
2468
|
-
const chunkToDecrypt = subarray(
|
|
2469
|
-
const originalAuthenticationCode = subarray(
|
|
2681
|
+
const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
2682
|
+
const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
2470
2683
|
let decryptedChunkArray = EMPTY_UINT8_ARRAY;
|
|
2471
2684
|
if (chunkToDecrypt.length) {
|
|
2472
2685
|
const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
|
|
@@ -2475,7 +2688,7 @@
|
|
|
2475
2688
|
decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
|
|
2476
2689
|
}
|
|
2477
2690
|
const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
|
|
2478
|
-
let invalidAuthenticationCode =
|
|
2691
|
+
let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
|
|
2479
2692
|
for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
|
|
2480
2693
|
invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
|
|
2481
2694
|
}
|
|
@@ -2519,14 +2732,14 @@
|
|
|
2519
2732
|
const {
|
|
2520
2733
|
ctr,
|
|
2521
2734
|
hmac,
|
|
2522
|
-
|
|
2735
|
+
pendingInput,
|
|
2523
2736
|
ready
|
|
2524
2737
|
} = this;
|
|
2525
2738
|
if (hmac && ctr) {
|
|
2526
2739
|
await ready;
|
|
2527
2740
|
let encryptedChunkArray = EMPTY_UINT8_ARRAY;
|
|
2528
|
-
if (
|
|
2529
|
-
const encryptedChunk = ctr.update(toBits(codecBytes,
|
|
2741
|
+
if (pendingInput.length) {
|
|
2742
|
+
const encryptedChunk = ctr.update(toBits(codecBytes, pendingInput));
|
|
2530
2743
|
hmac.update(encryptedChunk);
|
|
2531
2744
|
encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
|
|
2532
2745
|
}
|
|
@@ -2543,7 +2756,7 @@
|
|
|
2543
2756
|
ready: new Promise(resolve => aesCrypto.resolveReady = resolve),
|
|
2544
2757
|
password: encodePassword(password, rawPassword),
|
|
2545
2758
|
strength: encryptionStrength - 1,
|
|
2546
|
-
|
|
2759
|
+
pendingInput: EMPTY_UINT8_ARRAY
|
|
2547
2760
|
});
|
|
2548
2761
|
}
|
|
2549
2762
|
|
|
@@ -2551,10 +2764,10 @@
|
|
|
2551
2764
|
const {
|
|
2552
2765
|
ctr,
|
|
2553
2766
|
hmac,
|
|
2554
|
-
|
|
2767
|
+
pendingInput
|
|
2555
2768
|
} = aesCrypto;
|
|
2556
|
-
if (
|
|
2557
|
-
input = concat(
|
|
2769
|
+
if (pendingInput.length) {
|
|
2770
|
+
input = concat(pendingInput, input);
|
|
2558
2771
|
}
|
|
2559
2772
|
const inputLength = input.length - paddingEnd;
|
|
2560
2773
|
output = expand(output, paddingStart + (inputLength - (inputLength % BLOCK_LENGTH)));
|
|
@@ -2570,7 +2783,7 @@
|
|
|
2570
2783
|
}
|
|
2571
2784
|
output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
|
|
2572
2785
|
}
|
|
2573
|
-
aesCrypto.
|
|
2786
|
+
aesCrypto.pendingInput = subarray(input, offset);
|
|
2574
2787
|
return output;
|
|
2575
2788
|
}
|
|
2576
2789
|
|
|
@@ -3694,88 +3907,6 @@
|
|
|
3694
3907
|
}
|
|
3695
3908
|
}
|
|
3696
3909
|
|
|
3697
|
-
/*
|
|
3698
|
-
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3699
|
-
|
|
3700
|
-
Redistribution and use in source and binary forms, with or without
|
|
3701
|
-
modification, are permitted provided that the following conditions are met:
|
|
3702
|
-
|
|
3703
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
3704
|
-
this list of conditions and the following disclaimer.
|
|
3705
|
-
|
|
3706
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
3707
|
-
notice, this list of conditions and the following disclaimer in
|
|
3708
|
-
the documentation and/or other materials provided with the distribution.
|
|
3709
|
-
|
|
3710
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
3711
|
-
derived from this software without specific prior written permission.
|
|
3712
|
-
|
|
3713
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
3714
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
3715
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
3716
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
3717
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
3718
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
3719
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
3720
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
3721
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
3722
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3723
|
-
*/
|
|
3724
|
-
|
|
3725
|
-
/* global TextDecoder */
|
|
3726
|
-
|
|
3727
|
-
const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
|
|
3728
|
-
const VALID_CP437 = CP437.length == 256;
|
|
3729
|
-
|
|
3730
|
-
function decodeCP437(stringValue) {
|
|
3731
|
-
if (VALID_CP437) {
|
|
3732
|
-
let result = "";
|
|
3733
|
-
for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
|
|
3734
|
-
result += CP437[stringValue[indexCharacter]];
|
|
3735
|
-
}
|
|
3736
|
-
return result;
|
|
3737
|
-
} else {
|
|
3738
|
-
return new TextDecoder().decode(stringValue);
|
|
3739
|
-
}
|
|
3740
|
-
}
|
|
3741
|
-
|
|
3742
|
-
/*
|
|
3743
|
-
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3744
|
-
|
|
3745
|
-
Redistribution and use in source and binary forms, with or without
|
|
3746
|
-
modification, are permitted provided that the following conditions are met:
|
|
3747
|
-
|
|
3748
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
3749
|
-
this list of conditions and the following disclaimer.
|
|
3750
|
-
|
|
3751
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
3752
|
-
notice, this list of conditions and the following disclaimer in
|
|
3753
|
-
the documentation and/or other materials provided with the distribution.
|
|
3754
|
-
|
|
3755
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
3756
|
-
derived from this software without specific prior written permission.
|
|
3757
|
-
|
|
3758
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
3759
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
3760
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
3761
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
3762
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
3763
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
3764
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
3765
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
3766
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
3767
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3768
|
-
*/
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
function decodeText(value, encoding) {
|
|
3772
|
-
if (encoding && encoding.trim().toLowerCase() == "cp437") {
|
|
3773
|
-
return decodeCP437(value);
|
|
3774
|
-
} else {
|
|
3775
|
-
return new TextDecoder(encoding, { ignoreBOM: true }).decode(value);
|
|
3776
|
-
}
|
|
3777
|
-
}
|
|
3778
|
-
|
|
3779
3910
|
/*
|
|
3780
3911
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
3781
3912
|
|
|
@@ -3932,83 +4063,6 @@
|
|
|
3932
4063
|
|
|
3933
4064
|
}
|
|
3934
4065
|
|
|
3935
|
-
/*
|
|
3936
|
-
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3937
|
-
|
|
3938
|
-
Redistribution and use in source and binary forms, with or without
|
|
3939
|
-
modification, are permitted provided that the following conditions are met:
|
|
3940
|
-
|
|
3941
|
-
1. Redistributions of source code must retain the above copyright notice,
|
|
3942
|
-
this list of conditions and the following disclaimer.
|
|
3943
|
-
|
|
3944
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
3945
|
-
notice, this list of conditions and the following disclaimer in
|
|
3946
|
-
the documentation and/or other materials provided with the distribution.
|
|
3947
|
-
|
|
3948
|
-
3. The names of the authors may not be used to endorse or promote products
|
|
3949
|
-
derived from this software without specific prior written permission.
|
|
3950
|
-
|
|
3951
|
-
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
3952
|
-
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
3953
|
-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
3954
|
-
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
3955
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
3956
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
3957
|
-
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
3958
|
-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
3959
|
-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
3960
|
-
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3961
|
-
*/
|
|
3962
|
-
|
|
3963
|
-
const OPTION_FILENAME_ENCODING = "filenameEncoding";
|
|
3964
|
-
const OPTION_COMMENT_ENCODING = "commentEncoding";
|
|
3965
|
-
const OPTION_DECODE_TEXT = "decodeText";
|
|
3966
|
-
const OPTION_EXTRACT_PREPENDED_DATA = "extractPrependedData";
|
|
3967
|
-
const OPTION_EXTRACT_APPENDED_DATA = "extractAppendedData";
|
|
3968
|
-
const OPTION_PASSWORD = "password";
|
|
3969
|
-
const OPTION_RAW_PASSWORD = "rawPassword";
|
|
3970
|
-
const OPTION_PASS_THROUGH = "passThrough";
|
|
3971
|
-
const OPTION_SIGNAL = "signal";
|
|
3972
|
-
const OPTION_CHECK_PASSWORD_ONLY = "checkPasswordOnly";
|
|
3973
|
-
const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
|
|
3974
|
-
const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
|
|
3975
|
-
const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
|
|
3976
|
-
const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
|
|
3977
|
-
const OPTION_CHECK_SIGNATURE = "checkSignature";
|
|
3978
|
-
const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
3979
|
-
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
3980
|
-
const OPTION_USE_WEB_WORKERS = "useWebWorkers";
|
|
3981
|
-
const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
|
|
3982
|
-
const OPTION_TRANSFER_STREAMS = "transferStreams";
|
|
3983
|
-
const OPTION_PREVENT_CLOSE = "preventClose";
|
|
3984
|
-
const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
|
|
3985
|
-
const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
|
|
3986
|
-
const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
|
|
3987
|
-
const OPTION_KEEP_ORDER = "keepOrder";
|
|
3988
|
-
const OPTION_LEVEL = "level";
|
|
3989
|
-
const OPTION_BUFFERED_WRITE = "bufferedWrite";
|
|
3990
|
-
const OPTION_CREATE_TEMP_STREAM = "createTempStream";
|
|
3991
|
-
const OPTION_DATA_DESCRIPTOR_SIGNATURE = "dataDescriptorSignature";
|
|
3992
|
-
const OPTION_USE_UNICODE_FILE_NAMES = "useUnicodeFileNames";
|
|
3993
|
-
const OPTION_DATA_DESCRIPTOR = "dataDescriptor";
|
|
3994
|
-
const OPTION_SUPPORT_ZIP64_SPLIT_FILE = "supportZip64SplitFile";
|
|
3995
|
-
const OPTION_ENCODE_TEXT = "encodeText";
|
|
3996
|
-
const OPTION_OFFSET = "offset";
|
|
3997
|
-
const OPTION_USDZ = "usdz";
|
|
3998
|
-
const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
|
|
3999
|
-
const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
|
|
4000
|
-
const OPTION_STRICTNESS = "strictness";
|
|
4001
|
-
const OPTION_FILENAME_VALIDATION = "filenameValidation";
|
|
4002
|
-
const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
|
|
4003
|
-
const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
|
|
4004
|
-
const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
|
|
4005
|
-
const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
|
|
4006
|
-
const TEXT_TYPE_FILENAME = "filename";
|
|
4007
|
-
const TEXT_TYPE_COMMENT = "comment";
|
|
4008
|
-
const STRICTNESS_STRICT = "strict";
|
|
4009
|
-
const STRICTNESS_BALANCED = "balanced";
|
|
4010
|
-
const STRICTNESS_TOLERANT = "tolerant";
|
|
4011
|
-
|
|
4012
4066
|
/*
|
|
4013
4067
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4014
4068
|
|
|
@@ -4049,6 +4103,7 @@
|
|
|
4049
4103
|
const ERR_UNSUPPORTED_COMPRESSION$1 = "Compression method not supported";
|
|
4050
4104
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4051
4105
|
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4106
|
+
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4052
4107
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4053
4108
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
4054
4109
|
const ERR_UNSAFE_FILENAME = "Unsafe filename";
|
|
@@ -4069,7 +4124,7 @@
|
|
|
4069
4124
|
];
|
|
4070
4125
|
const ZIP64_EXTRACTION = {
|
|
4071
4126
|
[MAX_16_BITS]: {
|
|
4072
|
-
getValue: getUint32,
|
|
4127
|
+
getValue: getUint32$1,
|
|
4073
4128
|
bytes: 4
|
|
4074
4129
|
},
|
|
4075
4130
|
[MAX_32_BITS]: {
|
|
@@ -4078,6 +4133,7 @@
|
|
|
4078
4133
|
}
|
|
4079
4134
|
};
|
|
4080
4135
|
const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
|
|
4136
|
+
const MAX_DEFLATE_EXPANSION_RATIO = 1032;
|
|
4081
4137
|
const CENTRAL_DIRECTORY_UNREACHABLE = 0;
|
|
4082
4138
|
const CENTRAL_DIRECTORY_PLAUSIBLE = 1;
|
|
4083
4139
|
const CENTRAL_DIRECTORY_REACHABLE = 2;
|
|
@@ -4088,7 +4144,6 @@
|
|
|
4088
4144
|
Object.assign(this, {
|
|
4089
4145
|
reader: new GenericReader(reader),
|
|
4090
4146
|
options,
|
|
4091
|
-
config: getConfiguration(),
|
|
4092
4147
|
readRanges: new Map()
|
|
4093
4148
|
});
|
|
4094
4149
|
}
|
|
@@ -4096,7 +4151,6 @@
|
|
|
4096
4151
|
async* getEntriesGenerator(options = {}) {
|
|
4097
4152
|
const zipReader = this;
|
|
4098
4153
|
let { reader } = zipReader;
|
|
4099
|
-
const { config } = zipReader;
|
|
4100
4154
|
await initStream(reader);
|
|
4101
4155
|
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
4102
4156
|
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
@@ -4113,9 +4167,7 @@
|
|
|
4113
4167
|
const normalizeFilename = getOptionValue$1(zipReader, options, OPTION_NORMALIZE_FILENAME);
|
|
4114
4168
|
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
4115
4169
|
if (!endOfDirectoryInfo) {
|
|
4116
|
-
|
|
4117
|
-
const signatureView = getDataView(signatureArray);
|
|
4118
|
-
if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
|
|
4170
|
+
if (await startsWithSplitZipSignature$1(reader)) {
|
|
4119
4171
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4120
4172
|
} else {
|
|
4121
4173
|
throw new Error(ERR_EOCDR_NOT_FOUND);
|
|
@@ -4125,22 +4177,23 @@
|
|
|
4125
4177
|
throwAmbiguousArchive("multiple end of central directory records");
|
|
4126
4178
|
}
|
|
4127
4179
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
4128
|
-
let directoryDataLength = getUint32(endOfDirectoryView, 12);
|
|
4129
|
-
let directoryDataOffset = getUint32(endOfDirectoryView, 16);
|
|
4180
|
+
let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
|
|
4181
|
+
let directoryDataOffset = getUint32$1(endOfDirectoryView, 16);
|
|
4130
4182
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
4131
|
-
const commentLength = getUint16(endOfDirectoryView, 20);
|
|
4183
|
+
const commentLength = getUint16$1(endOfDirectoryView, 20);
|
|
4132
4184
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
4133
4185
|
if (reader.size - appendedDataOffset > maxAppendedDataSize) {
|
|
4134
4186
|
throwAmbiguousArchive("appended data");
|
|
4135
4187
|
}
|
|
4136
|
-
let lastDiskNumber = getUint16(endOfDirectoryView, 4);
|
|
4188
|
+
let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
|
|
4137
4189
|
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
4138
|
-
let diskNumber = getUint16(endOfDirectoryView, 6);
|
|
4139
|
-
let filesLength = getUint16(endOfDirectoryView, 10);
|
|
4190
|
+
let diskNumber = getUint16$1(endOfDirectoryView, 6);
|
|
4191
|
+
let filesLength = getUint16$1(endOfDirectoryView, 10);
|
|
4140
4192
|
let prependedDataLength = 0;
|
|
4141
4193
|
let startOffset;
|
|
4142
4194
|
let zip64EndOfDirectory;
|
|
4143
4195
|
let zip64EndOfDirectoryVersion2;
|
|
4196
|
+
let zip64EndOfDirectoryLength = ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4144
4197
|
let directoryEncryptionInfo;
|
|
4145
4198
|
const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
|
|
4146
4199
|
if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
|
|
@@ -4152,12 +4205,12 @@
|
|
|
4152
4205
|
EMPTY_UINT8_ARRAY;
|
|
4153
4206
|
const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
|
|
4154
4207
|
if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
|
|
4155
|
-
getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
4156
|
-
directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4208
|
+
getUint32$1(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
4209
|
+
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4157
4210
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4158
4211
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4159
4212
|
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4160
|
-
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
4213
|
+
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
4161
4214
|
directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
|
|
4162
4215
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4163
4216
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
@@ -4167,7 +4220,7 @@
|
|
|
4167
4220
|
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4168
4221
|
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4169
4222
|
}
|
|
4170
|
-
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4223
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4171
4224
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
4172
4225
|
}
|
|
4173
4226
|
zip64EndOfDirectory = true;
|
|
@@ -4177,18 +4230,19 @@
|
|
|
4177
4230
|
Number(getBigUint64(endOfDirectoryView, 4)) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
|
|
4178
4231
|
reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4179
4232
|
if (extensibleDataLength > 0) {
|
|
4233
|
+
zip64EndOfDirectoryLength += extensibleDataLength;
|
|
4180
4234
|
const rawExtensibleData = await readUint8Array(reader, directoryDataOffset + ZIP64_END_OF_CENTRAL_DIR_LENGTH, extensibleDataLength);
|
|
4181
4235
|
directoryEncryptionInfo = getDirectoryEncryptionInfo(rawExtensibleData);
|
|
4182
4236
|
}
|
|
4183
4237
|
}
|
|
4184
4238
|
if (lastDiskNumber == MAX_16_BITS) {
|
|
4185
|
-
lastDiskNumber = getUint32(endOfDirectoryView, 16);
|
|
4186
|
-
} else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
|
|
4239
|
+
lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
|
|
4240
|
+
} else if (checkAmbiguity && lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
|
|
4187
4241
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
4188
4242
|
}
|
|
4189
4243
|
if (diskNumber == MAX_16_BITS) {
|
|
4190
|
-
diskNumber = getUint32(endOfDirectoryView, 20);
|
|
4191
|
-
} else if (checkAmbiguity && diskNumber != getUint32(endOfDirectoryView, 20)) {
|
|
4244
|
+
diskNumber = getUint32$1(endOfDirectoryView, 20);
|
|
4245
|
+
} else if (checkAmbiguity && diskNumber != getUint32$1(endOfDirectoryView, 20)) {
|
|
4192
4246
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
4193
4247
|
}
|
|
4194
4248
|
if (filesLength == MAX_16_BITS) {
|
|
@@ -4206,7 +4260,7 @@
|
|
|
4206
4260
|
}
|
|
4207
4261
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4208
4262
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4209
|
-
(zip64EndOfDirectory ?
|
|
4263
|
+
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4210
4264
|
if (directoryDataOffset >= reader.size) {
|
|
4211
4265
|
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4212
4266
|
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
@@ -4226,11 +4280,13 @@
|
|
|
4226
4280
|
}
|
|
4227
4281
|
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4228
4282
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4229
|
-
const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE
|
|
4283
|
+
const storedPointsAtDirectory = getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4284
|
+
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4285
|
+
detectEncryptedCentralDirectory(directoryView);
|
|
4230
4286
|
let reconcile = !storedPointsAtDirectory;
|
|
4231
4287
|
if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4232
4288
|
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
|
|
4233
|
-
reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4289
|
+
reconcile = getUint32$1(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
4234
4290
|
}
|
|
4235
4291
|
if (reconcile) {
|
|
4236
4292
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -4254,12 +4310,14 @@
|
|
|
4254
4310
|
}
|
|
4255
4311
|
zipReader.directoryOffset = directoryDataOffset;
|
|
4256
4312
|
zipReader.directoryLength = declaredDirectoryDataLength;
|
|
4257
|
-
const decryptCentralDirectory =
|
|
4258
|
-
let decryptedDirectory;
|
|
4313
|
+
const decryptCentralDirectory = getFunctionOptionValue$1(zipReader, options, OPTION_DECRYPT_CENTRAL_DIRECTORY);
|
|
4314
|
+
let decryptedDirectory, dataAfterEncryptedDirectory;
|
|
4259
4315
|
if (decryptCentralDirectory && filesLength && directoryArray.length >= 4 &&
|
|
4260
|
-
getUint32(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
|
|
4316
|
+
getUint32$1(directoryView, 0) != CENTRAL_FILE_HEADER_SIGNATURE &&
|
|
4261
4317
|
(zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4262
|
-
|
|
4318
|
+
const encryptedDirectoryDataLength = getEncryptedDirectoryDataLength(directoryEncryptionInfo, declaredDirectoryDataLength, directoryArray.length);
|
|
4319
|
+
dataAfterEncryptedDirectory = directoryArray.subarray(encryptedDirectoryDataLength);
|
|
4320
|
+
directoryArray = await decryptCentralDirectory(directoryArray.subarray(0, encryptedDirectoryDataLength), directoryEncryptionInfo);
|
|
4263
4321
|
directoryView = getDataView(directoryArray);
|
|
4264
4322
|
declaredDirectoryDataLength = directoryArray.length;
|
|
4265
4323
|
decryptedDirectory = true;
|
|
@@ -4270,8 +4328,8 @@
|
|
|
4270
4328
|
const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
|
|
4271
4329
|
let duplicateFilename;
|
|
4272
4330
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4273
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
4274
|
-
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4331
|
+
const fileEntry = new ZipEntry$1(reader, zipReader.options);
|
|
4332
|
+
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4275
4333
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4276
4334
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
4277
4335
|
}
|
|
@@ -4282,16 +4340,16 @@
|
|
|
4282
4340
|
const filenameOffset = offset + CENTRAL_FILE_HEADER_LENGTH;
|
|
4283
4341
|
const extraFieldOffset = filenameOffset + fileEntry.filenameLength;
|
|
4284
4342
|
const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
|
|
4285
|
-
const versionMadeBy = getUint16(directoryView, offset + 4);
|
|
4343
|
+
const versionMadeBy = getUint16$1(directoryView, offset + 4);
|
|
4286
4344
|
const msDosCompatible = versionMadeBy >> 8 == 0;
|
|
4287
4345
|
const unixCompatible = versionMadeBy >> 8 == 3;
|
|
4288
4346
|
const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
|
|
4289
|
-
const commentLength = getUint16(directoryView, offset + 32);
|
|
4347
|
+
const commentLength = getUint16$1(directoryView, offset + 32);
|
|
4290
4348
|
const endOffset = commentOffset + commentLength;
|
|
4291
4349
|
const rawComment = directoryArray.subarray(commentOffset, endOffset);
|
|
4292
4350
|
const filenameUTF8 = languageEncodingFlag;
|
|
4293
4351
|
const commentUTF8 = languageEncodingFlag;
|
|
4294
|
-
const externalFileAttributes = getUint32(directoryView, offset + 38);
|
|
4352
|
+
const externalFileAttributes = getUint32$1(directoryView, offset + 38);
|
|
4295
4353
|
const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
|
|
4296
4354
|
const msdosAttributes = {
|
|
4297
4355
|
readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
|
|
@@ -4300,8 +4358,8 @@
|
|
|
4300
4358
|
directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
|
|
4301
4359
|
archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
|
|
4302
4360
|
};
|
|
4303
|
-
const offsetFileEntry = getUint32(directoryView, offset + 42);
|
|
4304
|
-
const decode =
|
|
4361
|
+
const offsetFileEntry = getUint32$1(directoryView, offset + 42);
|
|
4362
|
+
const decode = getFunctionOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
|
|
4305
4363
|
const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
|
|
4306
4364
|
const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
|
|
4307
4365
|
let filename = decode(rawFilename, rawFilenameEncoding, TEXT_TYPE_FILENAME);
|
|
@@ -4325,6 +4383,7 @@
|
|
|
4325
4383
|
}
|
|
4326
4384
|
Object.assign(fileEntry, {
|
|
4327
4385
|
index: indexFile,
|
|
4386
|
+
decryptedDirectory,
|
|
4328
4387
|
versionMadeBy,
|
|
4329
4388
|
msDosCompatible,
|
|
4330
4389
|
zip64: false,
|
|
@@ -4332,8 +4391,8 @@
|
|
|
4332
4391
|
uncompressedSize: 0,
|
|
4333
4392
|
commentLength,
|
|
4334
4393
|
offset: offsetFileEntry,
|
|
4335
|
-
diskNumberStart: getUint16(directoryView, offset + 34),
|
|
4336
|
-
internalFileAttributes: getUint16(directoryView, offset + 36),
|
|
4394
|
+
diskNumberStart: getUint16$1(directoryView, offset + 34),
|
|
4395
|
+
internalFileAttributes: getUint16$1(directoryView, offset + 36),
|
|
4337
4396
|
externalFileAttributes,
|
|
4338
4397
|
msdosAttributesRaw,
|
|
4339
4398
|
msdosAttributes,
|
|
@@ -4401,12 +4460,11 @@
|
|
|
4401
4460
|
yield entry;
|
|
4402
4461
|
}
|
|
4403
4462
|
let offsetAfterSignature = offset;
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
}
|
|
4463
|
+
const digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
|
|
4464
|
+
(decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
|
|
4465
|
+
if (digitalSignature) {
|
|
4466
|
+
zipReader.digitalSignature = digitalSignature;
|
|
4467
|
+
offsetAfterSignature = offset + 6 + digitalSignature.length;
|
|
4410
4468
|
}
|
|
4411
4469
|
if (checkAmbiguity && offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) {
|
|
4412
4470
|
throwAmbiguousArchive("trailing central directory data");
|
|
@@ -4414,13 +4472,17 @@
|
|
|
4414
4472
|
if (duplicateFilename) {
|
|
4415
4473
|
throwAmbiguousArchive("duplicate filename");
|
|
4416
4474
|
}
|
|
4417
|
-
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > 0))) {
|
|
4418
|
-
throwAmbiguousArchive("prepended data");
|
|
4419
|
-
}
|
|
4420
4475
|
const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
|
|
4421
4476
|
const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
|
|
4477
|
+
const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
|
|
4478
|
+
startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
|
|
4479
|
+
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
|
|
4480
|
+
throwAmbiguousArchive("prepended data");
|
|
4481
|
+
}
|
|
4422
4482
|
if (extractPrependedData) {
|
|
4423
|
-
zipReader.prependedData = startOffset >
|
|
4483
|
+
zipReader.prependedData = startOffset > splitZipSignatureLength ?
|
|
4484
|
+
await readUint8Array(reader, splitZipSignatureLength, startOffset - splitZipSignatureLength) :
|
|
4485
|
+
EMPTY_UINT8_ARRAY;
|
|
4424
4486
|
}
|
|
4425
4487
|
zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : EMPTY_UINT8_ARRAY;
|
|
4426
4488
|
if (extractAppendedData) {
|
|
@@ -4447,16 +4509,16 @@
|
|
|
4447
4509
|
|
|
4448
4510
|
let ZipEntry$1 = class ZipEntry {
|
|
4449
4511
|
|
|
4450
|
-
constructor(reader,
|
|
4512
|
+
constructor(reader, options) {
|
|
4451
4513
|
Object.assign(this, {
|
|
4452
4514
|
reader,
|
|
4453
|
-
config,
|
|
4454
4515
|
options
|
|
4455
4516
|
});
|
|
4456
4517
|
}
|
|
4457
4518
|
|
|
4458
4519
|
async getData(writer, fileEntry, readRanges, options = {}) {
|
|
4459
4520
|
const zipEntry = this;
|
|
4521
|
+
const config = getConfiguration();
|
|
4460
4522
|
const {
|
|
4461
4523
|
reader,
|
|
4462
4524
|
index,
|
|
@@ -4465,7 +4527,6 @@
|
|
|
4465
4527
|
extraFieldAES,
|
|
4466
4528
|
extraFieldZip64,
|
|
4467
4529
|
compressionMethod,
|
|
4468
|
-
config,
|
|
4469
4530
|
bitFlag,
|
|
4470
4531
|
rawBitFlag,
|
|
4471
4532
|
crc32,
|
|
@@ -4483,6 +4544,7 @@
|
|
|
4483
4544
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
4484
4545
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
4485
4546
|
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
4547
|
+
checkPasswordOption(password, rawPassword);
|
|
4486
4548
|
password = password && password.length && password;
|
|
4487
4549
|
rawPassword = rawPassword && rawPassword.length && rawPassword;
|
|
4488
4550
|
if (extraFieldAES) {
|
|
@@ -4490,7 +4552,7 @@
|
|
|
4490
4552
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
|
|
4491
4553
|
}
|
|
4492
4554
|
}
|
|
4493
|
-
if (dataArray.length < HEADER_SIZE || getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
4555
|
+
if (dataArray.length < HEADER_SIZE || getUint32$1(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
4494
4556
|
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
4495
4557
|
}
|
|
4496
4558
|
readCommonHeader(localDirectory, dataView, 4);
|
|
@@ -4552,9 +4614,12 @@
|
|
|
4552
4614
|
}
|
|
4553
4615
|
}
|
|
4554
4616
|
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
4617
|
+
if (dataOffset + compressedSize > reader.size) {
|
|
4618
|
+
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
4619
|
+
}
|
|
4555
4620
|
const size = compressedSize;
|
|
4556
4621
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
4557
|
-
const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
|
|
4622
|
+
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
4558
4623
|
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
4559
4624
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
4560
4625
|
const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
|
|
@@ -4562,6 +4627,8 @@
|
|
|
4562
4627
|
checkOverlappingEntry = true;
|
|
4563
4628
|
}
|
|
4564
4629
|
const { onstart, onprogress, onend } = options;
|
|
4630
|
+
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThrough;
|
|
4631
|
+
const outputSize = passThrough ? compressedSize : uncompressedSize;
|
|
4565
4632
|
const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
|
|
4566
4633
|
let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
|
|
4567
4634
|
if (deflate64) {
|
|
@@ -4582,9 +4649,9 @@
|
|
|
4582
4649
|
checkCrc32,
|
|
4583
4650
|
checkAuthenticationCode: getOptionValue$1(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
|
|
4584
4651
|
passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((crc32 >>> 24) & MAX_8_BITS)),
|
|
4585
|
-
outputSize
|
|
4652
|
+
outputSize,
|
|
4586
4653
|
crc32,
|
|
4587
|
-
compressed
|
|
4654
|
+
compressed,
|
|
4588
4655
|
encrypted,
|
|
4589
4656
|
useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
|
|
4590
4657
|
useCompressionStream,
|
|
@@ -4621,11 +4688,11 @@
|
|
|
4621
4688
|
writer = new WritableStream();
|
|
4622
4689
|
}
|
|
4623
4690
|
writer = new GenericWriter(writer);
|
|
4624
|
-
await initStream(writer,
|
|
4691
|
+
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
4625
4692
|
({ writable } = writer);
|
|
4626
|
-
const { outputSize } = await runWorker({ readable, writable }, workerOptions);
|
|
4627
|
-
writer.size +=
|
|
4628
|
-
if (
|
|
4693
|
+
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
4694
|
+
writer.size += writtenSize;
|
|
4695
|
+
if (writtenSize != outputSize) {
|
|
4629
4696
|
throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
4630
4697
|
}
|
|
4631
4698
|
}
|
|
@@ -4659,26 +4726,47 @@
|
|
|
4659
4726
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
4660
4727
|
const maxOffset = Math.min(directoryView.byteLength, 1024) - 3;
|
|
4661
4728
|
for (let offset = 0; offset < maxOffset; offset++) {
|
|
4662
|
-
if (getUint32(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
4729
|
+
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
4663
4730
|
return true;
|
|
4664
4731
|
}
|
|
4665
4732
|
}
|
|
4666
4733
|
return false;
|
|
4667
4734
|
}
|
|
4668
4735
|
|
|
4736
|
+
function readDigitalSignature(signatureRecordArray) {
|
|
4737
|
+
if (signatureRecordArray.length >= 6) {
|
|
4738
|
+
const signatureRecordView = getDataView(signatureRecordArray);
|
|
4739
|
+
if (getUint32$1(signatureRecordView, 0) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
4740
|
+
const signatureDataLength = getUint16$1(signatureRecordView, 4);
|
|
4741
|
+
if (6 + signatureDataLength <= signatureRecordArray.length) {
|
|
4742
|
+
return signatureRecordArray.subarray(6, 6 + signatureDataLength);
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4745
|
+
}
|
|
4746
|
+
}
|
|
4747
|
+
|
|
4748
|
+
function getEncryptedDirectoryDataLength(directoryEncryptionInfo, declaredDirectoryDataLength, directoryDataLength) {
|
|
4749
|
+
const encryptedDirectoryDataLength = directoryEncryptionInfo && directoryEncryptionInfo.compressedSize ?
|
|
4750
|
+
directoryEncryptionInfo.compressedSize :
|
|
4751
|
+
declaredDirectoryDataLength;
|
|
4752
|
+
return encryptedDirectoryDataLength > 0 && encryptedDirectoryDataLength <= directoryDataLength ?
|
|
4753
|
+
encryptedDirectoryDataLength :
|
|
4754
|
+
directoryDataLength;
|
|
4755
|
+
}
|
|
4756
|
+
|
|
4669
4757
|
function getDirectoryEncryptionInfo(rawExtensibleData) {
|
|
4670
4758
|
const directoryEncryptionInfo = { rawExtensibleData };
|
|
4671
4759
|
if (rawExtensibleData.length >= 28) {
|
|
4672
4760
|
const extensibleDataView = getDataView(rawExtensibleData);
|
|
4673
|
-
const hashDataLength = getUint16(extensibleDataView, 26);
|
|
4761
|
+
const hashDataLength = getUint16$1(extensibleDataView, 26);
|
|
4674
4762
|
Object.assign(directoryEncryptionInfo, {
|
|
4675
|
-
compressionMethod: getUint16(extensibleDataView, 0),
|
|
4763
|
+
compressionMethod: getUint16$1(extensibleDataView, 0),
|
|
4676
4764
|
compressedSize: Number(getBigUint64(extensibleDataView, 2)),
|
|
4677
4765
|
uncompressedSize: Number(getBigUint64(extensibleDataView, 10)),
|
|
4678
|
-
encryptionAlgorithm: getUint16(extensibleDataView, 18),
|
|
4679
|
-
bitLength: getUint16(extensibleDataView, 20),
|
|
4680
|
-
flags: getUint16(extensibleDataView, 22),
|
|
4681
|
-
hashAlgorithm: getUint16(extensibleDataView, 24),
|
|
4766
|
+
encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
|
|
4767
|
+
bitLength: getUint16$1(extensibleDataView, 20),
|
|
4768
|
+
flags: getUint16$1(extensibleDataView, 22),
|
|
4769
|
+
hashAlgorithm: getUint16$1(extensibleDataView, 24),
|
|
4682
4770
|
hashData: rawExtensibleData.subarray(28, 28 + hashDataLength)
|
|
4683
4771
|
});
|
|
4684
4772
|
}
|
|
@@ -4686,12 +4774,12 @@
|
|
|
4686
4774
|
}
|
|
4687
4775
|
|
|
4688
4776
|
function readCommonHeader(directory, dataView, offset) {
|
|
4689
|
-
const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
|
|
4777
|
+
const rawBitFlag = directory.rawBitFlag = getUint16$1(dataView, offset + 2);
|
|
4690
4778
|
const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
|
|
4691
|
-
const rawLastModDate = getUint32(dataView, offset + 6);
|
|
4779
|
+
const rawLastModDate = getUint32$1(dataView, offset + 6);
|
|
4692
4780
|
Object.assign(directory, {
|
|
4693
4781
|
encrypted,
|
|
4694
|
-
version: getUint16(dataView, offset),
|
|
4782
|
+
version: getUint16$1(dataView, offset),
|
|
4695
4783
|
bitFlag: {
|
|
4696
4784
|
level: (rawBitFlag & BITFLAG_LEVEL) >> 1,
|
|
4697
4785
|
dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR,
|
|
@@ -4699,8 +4787,8 @@
|
|
|
4699
4787
|
},
|
|
4700
4788
|
rawLastModDate,
|
|
4701
4789
|
lastModDate: getDate(rawLastModDate),
|
|
4702
|
-
filenameLength: getUint16(dataView, offset + 22),
|
|
4703
|
-
extraFieldLength: getUint16(dataView, offset + 24)
|
|
4790
|
+
filenameLength: getUint16$1(dataView, offset + 22),
|
|
4791
|
+
extraFieldLength: getUint16$1(dataView, offset + 24)
|
|
4704
4792
|
});
|
|
4705
4793
|
}
|
|
4706
4794
|
|
|
@@ -4711,8 +4799,8 @@
|
|
|
4711
4799
|
let offsetExtraField = 0;
|
|
4712
4800
|
try {
|
|
4713
4801
|
while (offsetExtraField < rawExtraField.length) {
|
|
4714
|
-
const type = getUint16(rawExtraFieldView, offsetExtraField);
|
|
4715
|
-
const size = getUint16(rawExtraFieldView, offsetExtraField + 2);
|
|
4802
|
+
const type = getUint16$1(rawExtraFieldView, offsetExtraField);
|
|
4803
|
+
const size = getUint16$1(rawExtraFieldView, offsetExtraField + 2);
|
|
4716
4804
|
extraField.set(type, {
|
|
4717
4805
|
type,
|
|
4718
4806
|
data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size)
|
|
@@ -4722,12 +4810,12 @@
|
|
|
4722
4810
|
} catch {
|
|
4723
4811
|
// ignored
|
|
4724
4812
|
}
|
|
4725
|
-
const compressionMethod = getUint16(dataView, offset + 4);
|
|
4813
|
+
const compressionMethod = getUint16$1(dataView, offset + 4);
|
|
4726
4814
|
Object.assign(directory, {
|
|
4727
|
-
signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
4728
|
-
crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
4729
|
-
compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
|
|
4730
|
-
uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
4815
|
+
signature: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
4816
|
+
crc32: getUint32$1(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
4817
|
+
compressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
|
|
4818
|
+
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
4731
4819
|
});
|
|
4732
4820
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
4733
4821
|
if (extraFieldZip64) {
|
|
@@ -4816,11 +4904,11 @@
|
|
|
4816
4904
|
computedCrc32.append(fileEntry[rawPropertyName]);
|
|
4817
4905
|
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
4818
4906
|
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
4819
|
-
const nameCrc32 = getUint32(extraFieldView, 1);
|
|
4907
|
+
const nameCrc32 = getUint32$1(extraFieldView, 1);
|
|
4820
4908
|
Object.assign(extraFieldUnicode, {
|
|
4821
4909
|
version: getUint8(extraFieldView, 0),
|
|
4822
4910
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
4823
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32(computedCrc32View, 0)
|
|
4911
|
+
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
4824
4912
|
});
|
|
4825
4913
|
if (extraFieldUnicode.valid) {
|
|
4826
4914
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -4836,7 +4924,7 @@
|
|
|
4836
4924
|
vendorId: getUint8(extraFieldView, 2),
|
|
4837
4925
|
strength,
|
|
4838
4926
|
originalCompressionMethod: compressionMethod,
|
|
4839
|
-
compressionMethod: getUint16(extraFieldView, 5)
|
|
4927
|
+
compressionMethod: getUint16$1(extraFieldView, 5)
|
|
4840
4928
|
});
|
|
4841
4929
|
directory.compressionMethod = extraFieldAES.compressionMethod;
|
|
4842
4930
|
if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1$1) {
|
|
@@ -4850,8 +4938,8 @@
|
|
|
4850
4938
|
let tag1Data;
|
|
4851
4939
|
try {
|
|
4852
4940
|
while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) {
|
|
4853
|
-
const tagValue = getUint16(extraFieldView, offsetExtraField);
|
|
4854
|
-
const attributeSize = getUint16(extraFieldView, offsetExtraField + 2);
|
|
4941
|
+
const tagValue = getUint16$1(extraFieldView, offsetExtraField);
|
|
4942
|
+
const attributeSize = getUint16$1(extraFieldView, offsetExtraField + 2);
|
|
4855
4943
|
if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) {
|
|
4856
4944
|
tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize);
|
|
4857
4945
|
}
|
|
@@ -4884,12 +4972,12 @@
|
|
|
4884
4972
|
return;
|
|
4885
4973
|
}
|
|
4886
4974
|
const extraFieldView = getDataView(extraField.data);
|
|
4887
|
-
const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
|
|
4888
|
-
const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
|
|
4975
|
+
const lastAccessDate = new Date((getUint32$1(extraFieldView, 0) | 0) * 1000);
|
|
4976
|
+
const lastModDate = new Date((getUint32$1(extraFieldView, 4) | 0) * 1000);
|
|
4889
4977
|
const extraFieldData = { lastAccessDate, lastModDate };
|
|
4890
4978
|
if (extraField.data.length >= 12) {
|
|
4891
|
-
extraFieldData.uid = getUint16(extraFieldView, 8);
|
|
4892
|
-
extraFieldData.gid = getUint16(extraFieldView, 10);
|
|
4979
|
+
extraFieldData.uid = getUint16$1(extraFieldView, 8);
|
|
4980
|
+
extraFieldData.gid = getUint16$1(extraFieldView, 10);
|
|
4893
4981
|
}
|
|
4894
4982
|
Object.assign(extraField, extraFieldData);
|
|
4895
4983
|
Object.assign(directory, extraFieldData);
|
|
@@ -4909,8 +4997,8 @@
|
|
|
4909
4997
|
gid = unpackUnixId(extraField.data.subarray(offset, offset + gidSize));
|
|
4910
4998
|
Object.assign(extraField, { version, uid, gid });
|
|
4911
4999
|
} else if (extraField.data.length >= 4) {
|
|
4912
|
-
uid = getUint16(view, 0);
|
|
4913
|
-
gid = getUint16(view, 2);
|
|
5000
|
+
uid = getUint16$1(view, 0);
|
|
5001
|
+
gid = getUint16$1(view, 2);
|
|
4914
5002
|
Object.assign(extraField, { uid, gid });
|
|
4915
5003
|
}
|
|
4916
5004
|
if (uid !== UNDEFINED_VALUE) {
|
|
@@ -4960,7 +5048,7 @@
|
|
|
4960
5048
|
let offset = 1;
|
|
4961
5049
|
timeProperties.forEach((propertyName, indexProperty) => {
|
|
4962
5050
|
if (extraFieldExtendedTimestamp.data.length >= offset + 4) {
|
|
4963
|
-
const time = getUint32(extraFieldView, offset);
|
|
5051
|
+
const time = getUint32$1(extraFieldView, offset);
|
|
4964
5052
|
directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date((time | 0) * 1000);
|
|
4965
5053
|
const rawPropertyName = timeRawProperties[indexProperty];
|
|
4966
5054
|
extraFieldExtendedTimestamp[rawPropertyName] = time;
|
|
@@ -4994,7 +5082,7 @@
|
|
|
4994
5082
|
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
|
|
4995
5083
|
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
4996
5084
|
let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
4997
|
-
getUint32(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
5085
|
+
getUint32$1(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
4998
5086
|
if (signature) {
|
|
4999
5087
|
const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
|
|
5000
5088
|
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
|
|
@@ -5028,15 +5116,15 @@
|
|
|
5028
5116
|
}
|
|
5029
5117
|
|
|
5030
5118
|
function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
|
|
5031
|
-
const crc32 = getUint32(dataDescriptorView, offset);
|
|
5119
|
+
const crc32 = getUint32$1(dataDescriptorView, offset);
|
|
5032
5120
|
let compressedSize;
|
|
5033
5121
|
let uncompressedSize;
|
|
5034
5122
|
if (extraFieldZip64) {
|
|
5035
5123
|
compressedSize = getBigUint64(dataDescriptorView, offset + 4);
|
|
5036
5124
|
uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
|
|
5037
5125
|
} else {
|
|
5038
|
-
compressedSize = getUint32(dataDescriptorView, offset + 4);
|
|
5039
|
-
uncompressedSize = getUint32(dataDescriptorView, offset + 8);
|
|
5126
|
+
compressedSize = getUint32$1(dataDescriptorView, offset + 4);
|
|
5127
|
+
uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
|
|
5040
5128
|
}
|
|
5041
5129
|
return { crc32, compressedSize, uncompressedSize };
|
|
5042
5130
|
}
|
|
@@ -5045,10 +5133,28 @@
|
|
|
5045
5133
|
return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
|
|
5046
5134
|
}
|
|
5047
5135
|
|
|
5136
|
+
async function startsWithSplitZipSignature$1(reader) {
|
|
5137
|
+
return await getFirstSignature(reader) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
5138
|
+
}
|
|
5139
|
+
|
|
5140
|
+
async function startsWithSplitZipMarker(reader) {
|
|
5141
|
+
const signature = await getFirstSignature(reader);
|
|
5142
|
+
return signature == SPLIT_ZIP_FILE_SIGNATURE || signature == TEMPORARY_SPLIT_ZIP_FILE_SIGNATURE;
|
|
5143
|
+
}
|
|
5144
|
+
|
|
5145
|
+
async function getFirstSignature(reader) {
|
|
5146
|
+
const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
5147
|
+
return getUint32$1(getDataView(signatureArray));
|
|
5148
|
+
}
|
|
5149
|
+
|
|
5048
5150
|
function isStrictnessValue(value) {
|
|
5049
5151
|
return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
|
|
5050
5152
|
}
|
|
5051
5153
|
|
|
5154
|
+
function getDecodableOutputSize(outputSize, compressedSize, compressed) {
|
|
5155
|
+
return Math.min(outputSize, compressed ? compressedSize * MAX_DEFLATE_EXPANSION_RATIO : compressedSize);
|
|
5156
|
+
}
|
|
5157
|
+
|
|
5052
5158
|
function getStrictness(options, inheritedOptions) {
|
|
5053
5159
|
return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
|
|
5054
5160
|
}
|
|
@@ -5111,7 +5217,7 @@
|
|
|
5111
5217
|
|
|
5112
5218
|
function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
|
|
5113
5219
|
if (maxAppendedDataSize !== UNDEFINED_VALUE) {
|
|
5114
|
-
const size = toNumber
|
|
5220
|
+
const size = toNumber(maxAppendedDataSize);
|
|
5115
5221
|
if (typeof size != NUMBER_TYPE || Number.isNaN(size) || size < 0) {
|
|
5116
5222
|
throw new Error(ERR_INVALID_MAX_APPENDED_DATA_SIZE);
|
|
5117
5223
|
}
|
|
@@ -5134,7 +5240,7 @@
|
|
|
5134
5240
|
let plausibleEndOfDirectoryInfo;
|
|
5135
5241
|
let endOfDirectoryReachingEndCount = 0;
|
|
5136
5242
|
for await (const [anchoredView, anchoredOffset, anchoredArray, indexByte, offset] of scanEndOfCentralDirectory(reader, anchoredLength)) {
|
|
5137
|
-
const commentLength = getUint16(anchoredView, indexByte + 20);
|
|
5243
|
+
const commentLength = getUint16$1(anchoredView, indexByte + 20);
|
|
5138
5244
|
if (offset + END_OF_CENTRAL_DIR_LENGTH + commentLength == size) {
|
|
5139
5245
|
const reachability = await getCentralDirectoryReachability(reader, anchoredView, anchoredOffset, indexByte, offset, size, remoteProbeBudget);
|
|
5140
5246
|
if (reachability == CENTRAL_DIRECTORY_REACHABLE) {
|
|
@@ -5185,7 +5291,7 @@
|
|
|
5185
5291
|
const scanArray = await readUint8Array(reader, scanOffset, scanLength);
|
|
5186
5292
|
const scanView = getDataView(scanArray);
|
|
5187
5293
|
for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5188
|
-
if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
5294
|
+
if (getUint32$1(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
5189
5295
|
yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
|
|
5190
5296
|
}
|
|
5191
5297
|
}
|
|
@@ -5196,9 +5302,9 @@
|
|
|
5196
5302
|
}
|
|
5197
5303
|
|
|
5198
5304
|
async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
|
|
5199
|
-
const filesLength = getUint16(view, indexByte + 10);
|
|
5200
|
-
const directoryDataLength = getUint32(view, indexByte + 12);
|
|
5201
|
-
const directoryDataOffset = getUint32(view, indexByte + 16);
|
|
5305
|
+
const filesLength = getUint16$1(view, indexByte + 10);
|
|
5306
|
+
const directoryDataLength = getUint32$1(view, indexByte + 12);
|
|
5307
|
+
const directoryDataOffset = getUint32$1(view, indexByte + 16);
|
|
5202
5308
|
if (filesLength == MAX_16_BITS || directoryDataLength == MAX_32_BITS || directoryDataOffset == MAX_32_BITS) {
|
|
5203
5309
|
const locatorSignature = await readSignature(reader, view, anchoredOffset, offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, size, remoteProbeBudget);
|
|
5204
5310
|
return locatorSignature == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE ? CENTRAL_DIRECTORY_REACHABLE : CENTRAL_DIRECTORY_UNREACHABLE;
|
|
@@ -5206,7 +5312,7 @@
|
|
|
5206
5312
|
if (!filesLength && !directoryDataLength) {
|
|
5207
5313
|
return CENTRAL_DIRECTORY_PLAUSIBLE;
|
|
5208
5314
|
}
|
|
5209
|
-
const directoryDiskNumber = getUint16(view, indexByte + 6);
|
|
5315
|
+
const directoryDiskNumber = getUint16$1(view, indexByte + 6);
|
|
5210
5316
|
for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
|
|
5211
5317
|
if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5212
5318
|
return CENTRAL_DIRECTORY_REACHABLE;
|
|
@@ -5220,19 +5326,21 @@
|
|
|
5220
5326
|
return UNDEFINED_VALUE;
|
|
5221
5327
|
}
|
|
5222
5328
|
if (signatureOffset >= anchoredOffset) {
|
|
5223
|
-
return getUint32(view, signatureOffset - anchoredOffset);
|
|
5329
|
+
return getUint32$1(view, signatureOffset - anchoredOffset);
|
|
5224
5330
|
}
|
|
5225
5331
|
if (remoteProbeBudget.count > 0) {
|
|
5226
5332
|
remoteProbeBudget.count--;
|
|
5227
5333
|
const signatureArray = await readUint8Array(reader, signatureOffset, 4);
|
|
5228
|
-
return getUint32(getDataView(signatureArray), 0);
|
|
5334
|
+
return getUint32$1(getDataView(signatureArray), 0);
|
|
5229
5335
|
}
|
|
5230
5336
|
return UNDEFINED_VALUE;
|
|
5231
5337
|
}
|
|
5232
5338
|
|
|
5233
5339
|
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
|
|
5234
5340
|
const { rawFilename } = zipEntry;
|
|
5235
|
-
|
|
5341
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
5342
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
5343
|
+
if (checkLocalFilename && !maskedLocalDirectory &&
|
|
5236
5344
|
(rawLocalFilename.length != rawFilename.length ||
|
|
5237
5345
|
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
5238
5346
|
throwAmbiguousArchive("mismatched local file header (filename)");
|
|
@@ -5243,7 +5351,7 @@
|
|
|
5243
5351
|
if (localDirectory.compressionMethod != zipEntry.compressionMethod) {
|
|
5244
5352
|
throwAmbiguousArchive("mismatched local file header (compression method)");
|
|
5245
5353
|
}
|
|
5246
|
-
if (!localDirectory.bitFlag.dataDescriptor &&
|
|
5354
|
+
if (!localDirectory.bitFlag.dataDescriptor && !maskedLocalDirectory &&
|
|
5247
5355
|
(localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
|
|
5248
5356
|
(localDirectory.crc32 != zipEntry.crc32 ||
|
|
5249
5357
|
localDirectory.compressedSize != zipEntry.compressedSize ||
|
|
@@ -5262,10 +5370,11 @@
|
|
|
5262
5370
|
return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
|
|
5263
5371
|
}
|
|
5264
5372
|
|
|
5265
|
-
function
|
|
5266
|
-
return
|
|
5373
|
+
function getFunctionOptionValue$1(zipReader, options, name) {
|
|
5374
|
+
return checkFunctionOption(getOptionValue$1(zipReader, options, name));
|
|
5267
5375
|
}
|
|
5268
5376
|
|
|
5377
|
+
|
|
5269
5378
|
function getDate(timeRaw) {
|
|
5270
5379
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
5271
5380
|
return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
@@ -5279,11 +5388,11 @@
|
|
|
5279
5388
|
return view.getUint8(offset);
|
|
5280
5389
|
}
|
|
5281
5390
|
|
|
5282
|
-
function getUint16(view, offset) {
|
|
5391
|
+
function getUint16$1(view, offset) {
|
|
5283
5392
|
return view.getUint16(offset, true);
|
|
5284
5393
|
}
|
|
5285
5394
|
|
|
5286
|
-
function getUint32(view, offset) {
|
|
5395
|
+
function getUint32$1(view, offset) {
|
|
5287
5396
|
return view.getUint32(offset, true);
|
|
5288
5397
|
}
|
|
5289
5398
|
|
|
@@ -5298,6 +5407,7 @@
|
|
|
5298
5407
|
ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
|
|
5299
5408
|
ERR_ENCRYPTED: ERR_ENCRYPTED,
|
|
5300
5409
|
ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
|
|
5410
|
+
ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
|
|
5301
5411
|
ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
|
|
5302
5412
|
ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
|
|
5303
5413
|
ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
@@ -5352,12 +5462,16 @@
|
|
|
5352
5462
|
const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
|
|
5353
5463
|
const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
|
|
5354
5464
|
const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
|
|
5465
|
+
const ERR_INVALID_ENTRY_COMMENT_TYPE = "Invalid file entry comment (must be a string)";
|
|
5466
|
+
const ERR_INVALID_DATE = "Invalid date (must be a valid Date instance)";
|
|
5355
5467
|
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
5356
5468
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
5357
5469
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
5358
5470
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
5359
5471
|
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
5360
|
-
const
|
|
5472
|
+
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
5473
|
+
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
5474
|
+
const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
|
|
5361
5475
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
5362
5476
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
5363
5477
|
const MIN_UNIX_TIME = -2147483648;
|
|
@@ -5366,6 +5480,7 @@
|
|
|
5366
5480
|
const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
|
|
5367
5481
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
5368
5482
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
5483
|
+
const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
|
|
5369
5484
|
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
5370
5485
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
5371
5486
|
const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
|
|
@@ -5377,7 +5492,6 @@
|
|
|
5377
5492
|
const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
|
|
5378
5493
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
5379
5494
|
const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
|
|
5380
|
-
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
5381
5495
|
const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
5382
5496
|
|
|
5383
5497
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
@@ -5402,8 +5516,7 @@
|
|
|
5402
5516
|
writer,
|
|
5403
5517
|
addSplitZipSignature,
|
|
5404
5518
|
options,
|
|
5405
|
-
|
|
5406
|
-
files: new Map(),
|
|
5519
|
+
fileEntries: new Map(),
|
|
5407
5520
|
filenames: new Set(),
|
|
5408
5521
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
5409
5522
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
@@ -5424,14 +5537,23 @@
|
|
|
5424
5537
|
await initStream(reader);
|
|
5425
5538
|
}
|
|
5426
5539
|
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5427
|
-
const zipReader$1 = new ZipReader(reader
|
|
5540
|
+
const zipReader$1 = new ZipReader(reader);
|
|
5428
5541
|
const entries = await zipReader$1.getEntries();
|
|
5429
5542
|
await zipReader$1.close();
|
|
5430
5543
|
await initStream(this.writer);
|
|
5431
|
-
|
|
5432
|
-
|
|
5544
|
+
const { directoryOffset } = zipReader$1;
|
|
5545
|
+
let splitZipSignatureLength = 0;
|
|
5546
|
+
if (this.addSplitZipSignature) {
|
|
5547
|
+
delete this.addSplitZipSignature;
|
|
5548
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
5549
|
+
await writeData(this.writer, getSplitZipSignatureArray());
|
|
5550
|
+
splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
5551
|
+
this.offset += splitZipSignatureLength;
|
|
5552
|
+
}
|
|
5553
|
+
}
|
|
5554
|
+
const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
|
|
5433
5555
|
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
5434
|
-
this.
|
|
5556
|
+
this.fileEntries = new Map(entries.map(entry => {
|
|
5435
5557
|
const {
|
|
5436
5558
|
version,
|
|
5437
5559
|
rawLastModDate,
|
|
@@ -5486,11 +5608,12 @@
|
|
|
5486
5608
|
if (crc32 !== UNDEFINED_VALUE) {
|
|
5487
5609
|
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
5488
5610
|
}
|
|
5611
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
5489
5612
|
Object.assign(entry, {
|
|
5490
5613
|
zip64UncompressedSize,
|
|
5491
5614
|
zip64CompressedSize,
|
|
5492
|
-
|
|
5493
|
-
diskNumberStart
|
|
5615
|
+
offset,
|
|
5616
|
+
diskNumberStart,
|
|
5494
5617
|
zip64DiskNumberStart: false,
|
|
5495
5618
|
rawExtraFieldZip64,
|
|
5496
5619
|
rawExtraFieldAES,
|
|
@@ -5510,11 +5633,8 @@
|
|
|
5510
5633
|
async add(name = "", reader, options = {}) {
|
|
5511
5634
|
const zipWriter = this;
|
|
5512
5635
|
options = Object.assign({}, options);
|
|
5513
|
-
const {
|
|
5514
|
-
|
|
5515
|
-
config
|
|
5516
|
-
} = zipWriter;
|
|
5517
|
-
if (workers < config.maxWorkers) {
|
|
5636
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
5637
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
5518
5638
|
workers++;
|
|
5519
5639
|
} else {
|
|
5520
5640
|
await new Promise(resolve => pendingEntries.push(resolve));
|
|
@@ -5551,16 +5671,16 @@
|
|
|
5551
5671
|
}
|
|
5552
5672
|
|
|
5553
5673
|
remove(entry) {
|
|
5554
|
-
const { filenames,
|
|
5674
|
+
const { filenames, fileEntries } = this;
|
|
5555
5675
|
// deno-lint-ignore valid-typeof
|
|
5556
5676
|
if (typeof entry == STRING_TYPE) {
|
|
5557
|
-
entry =
|
|
5677
|
+
entry = fileEntries.get(entry);
|
|
5558
5678
|
}
|
|
5559
5679
|
if (entry && entry.filename !== UNDEFINED_VALUE) {
|
|
5560
5680
|
const { filename } = entry;
|
|
5561
|
-
if (filenames.has(filename) &&
|
|
5681
|
+
if (filenames.has(filename) && fileEntries.has(filename)) {
|
|
5562
5682
|
filenames.delete(filename);
|
|
5563
|
-
|
|
5683
|
+
fileEntries.delete(filename);
|
|
5564
5684
|
return true;
|
|
5565
5685
|
}
|
|
5566
5686
|
}
|
|
@@ -5595,12 +5715,12 @@
|
|
|
5595
5715
|
const metadataInfo = resolveMetadata(zipWriter, name, options);
|
|
5596
5716
|
const { comment } = metadataInfo;
|
|
5597
5717
|
const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
|
|
5598
|
-
zipWriter.
|
|
5718
|
+
zipWriter.fileEntries.set(name, UNDEFINED_VALUE);
|
|
5599
5719
|
let fileEntry;
|
|
5600
5720
|
try {
|
|
5601
5721
|
const { resolvedOptions } = metadataInfo;
|
|
5602
5722
|
if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
|
|
5603
|
-
!resolvedOptions.passThrough && !(await supportsDeflate(
|
|
5723
|
+
!resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
|
|
5604
5724
|
resolvedOptions.level = 0;
|
|
5605
5725
|
}
|
|
5606
5726
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
@@ -5618,7 +5738,7 @@
|
|
|
5618
5738
|
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
5619
5739
|
fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
|
|
5620
5740
|
} catch (error) {
|
|
5621
|
-
zipWriter.
|
|
5741
|
+
zipWriter.fileEntries.delete(name);
|
|
5622
5742
|
throw error;
|
|
5623
5743
|
}
|
|
5624
5744
|
Object.assign(fileEntry, {
|
|
@@ -5662,9 +5782,9 @@
|
|
|
5662
5782
|
if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
5663
5783
|
unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE$1;
|
|
5664
5784
|
}
|
|
5665
|
-
let msdosAttributesRaw =
|
|
5785
|
+
let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
|
|
5666
5786
|
let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
|
|
5667
|
-
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
|
|
5787
|
+
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType || executable;
|
|
5668
5788
|
const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
|
|
5669
5789
|
if (hasUnixMetadata) {
|
|
5670
5790
|
msDosCompatible = false;
|
|
@@ -5673,10 +5793,10 @@
|
|
|
5673
5793
|
msDosCompatible = true;
|
|
5674
5794
|
versionMadeBy = (versionMadeBy & MAX_8_BITS);
|
|
5675
5795
|
}
|
|
5676
|
-
if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
5796
|
+
if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
5677
5797
|
throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
|
|
5678
5798
|
}
|
|
5679
|
-
if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
|
|
5799
|
+
if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
|
|
5680
5800
|
throw new Error(ERR_INVALID_MSDOS_DATA);
|
|
5681
5801
|
}
|
|
5682
5802
|
if (versionMadeBy > MAX_16_BITS) {
|
|
@@ -5764,7 +5884,7 @@
|
|
|
5764
5884
|
}
|
|
5765
5885
|
|
|
5766
5886
|
function resolveMetadata(zipWriter, name, options) {
|
|
5767
|
-
const encode =
|
|
5887
|
+
const encode = getFunctionOptionValue(zipWriter, options, OPTION_ENCODE_TEXT) || encodeText;
|
|
5768
5888
|
let rawFilename = encode(name, TEXT_TYPE_FILENAME);
|
|
5769
5889
|
if (rawFilename === UNDEFINED_VALUE) {
|
|
5770
5890
|
rawFilename = encodeText(name);
|
|
@@ -5773,6 +5893,10 @@
|
|
|
5773
5893
|
throw new Error(ERR_INVALID_ENTRY_NAME);
|
|
5774
5894
|
}
|
|
5775
5895
|
const comment = options[PROPERTY_NAME_COMMENT] || "";
|
|
5896
|
+
// deno-lint-ignore valid-typeof
|
|
5897
|
+
if (typeof comment != STRING_TYPE) {
|
|
5898
|
+
throw new Error(ERR_INVALID_ENTRY_COMMENT_TYPE);
|
|
5899
|
+
}
|
|
5776
5900
|
let rawComment = encode(comment, TEXT_TYPE_COMMENT);
|
|
5777
5901
|
if (rawComment === UNDEFINED_VALUE) {
|
|
5778
5902
|
rawComment = encodeText(comment);
|
|
@@ -5784,16 +5908,14 @@
|
|
|
5784
5908
|
if (version > MAX_16_BITS) {
|
|
5785
5909
|
throw new Error(ERR_INVALID_VERSION);
|
|
5786
5910
|
}
|
|
5787
|
-
const lastModDate =
|
|
5788
|
-
const lastAccessDate =
|
|
5789
|
-
const creationDate =
|
|
5911
|
+
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
5912
|
+
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
5913
|
+
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
5790
5914
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
5791
5915
|
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
5792
5916
|
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
5793
5917
|
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
5794
|
-
|
|
5795
|
-
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
5796
|
-
}
|
|
5918
|
+
checkPasswordOption(password, rawPassword);
|
|
5797
5919
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
5798
5920
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
5799
5921
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
@@ -5802,9 +5924,9 @@
|
|
|
5802
5924
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
5803
5925
|
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
5804
5926
|
const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
|
|
5805
|
-
const createTempStream =
|
|
5927
|
+
const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
5806
5928
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
5807
|
-
const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
|
|
5929
|
+
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
5808
5930
|
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
|
|
5809
5931
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
5810
5932
|
const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
@@ -5824,6 +5946,9 @@
|
|
|
5824
5946
|
level = 0;
|
|
5825
5947
|
}
|
|
5826
5948
|
}
|
|
5949
|
+
if (passThrough) {
|
|
5950
|
+
level = UNDEFINED_VALUE;
|
|
5951
|
+
}
|
|
5827
5952
|
let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5828
5953
|
let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
|
|
5829
5954
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
@@ -5884,18 +6009,26 @@
|
|
|
5884
6009
|
if (!extraField) {
|
|
5885
6010
|
return EMPTY_UINT8_ARRAY;
|
|
5886
6011
|
}
|
|
6012
|
+
if (!(extraField instanceof Map)) {
|
|
6013
|
+
throw new Error(ERR_INVALID_EXTRAFIELD);
|
|
6014
|
+
}
|
|
5887
6015
|
let extraFieldSize = 0;
|
|
5888
6016
|
let offset = 0;
|
|
5889
|
-
extraField.forEach(data => extraFieldSize += 4 + getLength(data));
|
|
5890
|
-
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
5891
|
-
const rawExtraFieldView = getDataView(rawExtraField);
|
|
5892
6017
|
extraField.forEach((data, type) => {
|
|
5893
|
-
if (type > MAX_16_BITS) {
|
|
6018
|
+
if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
|
|
5894
6019
|
throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
|
|
5895
6020
|
}
|
|
6021
|
+
if (!(data instanceof Uint8Array)) {
|
|
6022
|
+
throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
|
|
6023
|
+
}
|
|
5896
6024
|
if (getLength(data) > MAX_16_BITS) {
|
|
5897
6025
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
5898
6026
|
}
|
|
6027
|
+
extraFieldSize += 4 + getLength(data);
|
|
6028
|
+
});
|
|
6029
|
+
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
6030
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
6031
|
+
extraField.forEach((data, type) => {
|
|
5899
6032
|
setUint16(rawExtraFieldView, offset, type);
|
|
5900
6033
|
setUint16(rawExtraFieldView, offset + 2, getLength(data));
|
|
5901
6034
|
arraySet(rawExtraField, data, offset + 4);
|
|
@@ -5927,6 +6060,9 @@
|
|
|
5927
6060
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
5928
6061
|
throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
|
|
5929
6062
|
}
|
|
6063
|
+
if (compressionMethod === UNDEFINED_VALUE) {
|
|
6064
|
+
throw new Error(ERR_UNDEFINED_COMPRESSION_METHOD);
|
|
6065
|
+
}
|
|
5930
6066
|
}
|
|
5931
6067
|
const zip64Enabled = zip64 === true;
|
|
5932
6068
|
const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
|
|
@@ -5982,8 +6118,8 @@
|
|
|
5982
6118
|
}
|
|
5983
6119
|
|
|
5984
6120
|
async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
|
|
5985
|
-
const zipWriter = { options: writerOptions
|
|
5986
|
-
if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
|
|
6121
|
+
const zipWriter = { options: writerOptions };
|
|
6122
|
+
if (checkFunctionOption(writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY])) {
|
|
5987
6123
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
5988
6124
|
}
|
|
5989
6125
|
if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
|
|
@@ -6009,7 +6145,7 @@
|
|
|
6009
6145
|
({ name } = attributesInfo);
|
|
6010
6146
|
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
6011
6147
|
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
6012
|
-
!metadata.passThrough && !(await supportsDeflate(
|
|
6148
|
+
!metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
|
|
6013
6149
|
metadata.level = 0;
|
|
6014
6150
|
}
|
|
6015
6151
|
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
@@ -6058,7 +6194,7 @@
|
|
|
6058
6194
|
|
|
6059
6195
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
6060
6196
|
const {
|
|
6061
|
-
|
|
6197
|
+
fileEntries,
|
|
6062
6198
|
writer
|
|
6063
6199
|
} = zipWriter;
|
|
6064
6200
|
const {
|
|
@@ -6080,12 +6216,12 @@
|
|
|
6080
6216
|
let writerSizeBeforeEntry;
|
|
6081
6217
|
let flushedBufferedSize = 0;
|
|
6082
6218
|
let fileWriter;
|
|
6083
|
-
|
|
6219
|
+
fileEntries.set(name, fileEntry);
|
|
6084
6220
|
zipWriter.lastFileEntry = fileEntry;
|
|
6085
6221
|
try {
|
|
6086
6222
|
let lockPreviousFileEntry;
|
|
6087
6223
|
if (keepOrder) {
|
|
6088
|
-
lockPreviousFileEntry = previousFileEntry && previousFileEntry.
|
|
6224
|
+
lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
|
|
6089
6225
|
requestLockCurrentFileEntry();
|
|
6090
6226
|
}
|
|
6091
6227
|
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
|
|
@@ -6106,11 +6242,8 @@
|
|
|
6106
6242
|
const diskOffset = getDiskOffset(writer);
|
|
6107
6243
|
if (zipWriter.addSplitZipSignature) {
|
|
6108
6244
|
delete zipWriter.addSplitZipSignature;
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
6112
|
-
await writeData(writer, signatureArray);
|
|
6113
|
-
zipWriter.offset += 4;
|
|
6245
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
6246
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6114
6247
|
}
|
|
6115
6248
|
if (usdz && !bufferedWrite) {
|
|
6116
6249
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -6128,11 +6261,11 @@
|
|
|
6128
6261
|
writerSizeBeforeEntry = writer.size;
|
|
6129
6262
|
await writeData(fileWriter, localHeaderArray);
|
|
6130
6263
|
}
|
|
6131
|
-
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo,
|
|
6264
|
+
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, getConfiguration(), options);
|
|
6132
6265
|
if (!bufferedWrite) {
|
|
6133
6266
|
writingEntryData = false;
|
|
6134
6267
|
}
|
|
6135
|
-
|
|
6268
|
+
fileEntries.set(name, fileEntry);
|
|
6136
6269
|
fileEntry.filename = name;
|
|
6137
6270
|
if (bufferedWrite) {
|
|
6138
6271
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
@@ -6173,7 +6306,7 @@
|
|
|
6173
6306
|
zipWriter.offset += flushedBufferedSize;
|
|
6174
6307
|
}
|
|
6175
6308
|
}
|
|
6176
|
-
|
|
6309
|
+
fileEntries.delete(name);
|
|
6177
6310
|
throw error;
|
|
6178
6311
|
} finally {
|
|
6179
6312
|
if (bufferedWrite) {
|
|
@@ -6195,7 +6328,7 @@
|
|
|
6195
6328
|
}
|
|
6196
6329
|
|
|
6197
6330
|
function requestLockCurrentFileEntry() {
|
|
6198
|
-
fileEntry.
|
|
6331
|
+
fileEntry.lockFileEntry = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
|
|
6199
6332
|
}
|
|
6200
6333
|
|
|
6201
6334
|
async function requestLockWriter() {
|
|
@@ -6215,7 +6348,7 @@
|
|
|
6215
6348
|
}
|
|
6216
6349
|
}
|
|
6217
6350
|
|
|
6218
|
-
async function createFileEntry(reader, writer, { diskNumberStart,
|
|
6351
|
+
async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry }, entryInfo, config, options) {
|
|
6219
6352
|
const {
|
|
6220
6353
|
headerInfo,
|
|
6221
6354
|
dataDescriptorInfo,
|
|
@@ -6283,7 +6416,7 @@
|
|
|
6283
6416
|
codecURI
|
|
6284
6417
|
} = options;
|
|
6285
6418
|
const fileEntry = {
|
|
6286
|
-
|
|
6419
|
+
lockFileEntry,
|
|
6287
6420
|
versionMadeBy,
|
|
6288
6421
|
zip64,
|
|
6289
6422
|
directory: Boolean(directory),
|
|
@@ -6325,7 +6458,7 @@
|
|
|
6325
6458
|
}
|
|
6326
6459
|
const { writable } = writer;
|
|
6327
6460
|
if (reader) {
|
|
6328
|
-
const readable = toCompatibleReadable(
|
|
6461
|
+
const readable = toCompatibleReadable(createReadable(reader));
|
|
6329
6462
|
const size = reader.size;
|
|
6330
6463
|
const workerOptions = {
|
|
6331
6464
|
options: {
|
|
@@ -6437,14 +6570,14 @@
|
|
|
6437
6570
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
6438
6571
|
const length = 4 + 16;
|
|
6439
6572
|
const extraFieldZip64 = createRecordWriter(length);
|
|
6440
|
-
extraFieldZip64.
|
|
6441
|
-
extraFieldZip64.
|
|
6573
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
6574
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
6442
6575
|
rawLocalExtraFieldZip64 = extraFieldZip64.array;
|
|
6443
6576
|
if (zip64ExtraFieldComplete) {
|
|
6444
|
-
extraFieldZip64.
|
|
6577
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
6445
6578
|
if (uncompressedFile) {
|
|
6446
6579
|
const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
6447
|
-
extraFieldZip64.
|
|
6580
|
+
extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
|
|
6448
6581
|
}
|
|
6449
6582
|
}
|
|
6450
6583
|
} else {
|
|
@@ -6453,8 +6586,8 @@
|
|
|
6453
6586
|
let rawExtraFieldAES;
|
|
6454
6587
|
if (encrypted && !zipCrypto) {
|
|
6455
6588
|
const extraFieldAES = createRecordWriter(getLength(EXTRAFIELD_DATA_AES) + 2);
|
|
6456
|
-
extraFieldAES.
|
|
6457
|
-
extraFieldAES.
|
|
6589
|
+
extraFieldAES.writeUint16(EXTRAFIELD_TYPE_AES);
|
|
6590
|
+
extraFieldAES.writeBytes(EXTRAFIELD_DATA_AES);
|
|
6458
6591
|
rawExtraFieldAES = extraFieldAES.array;
|
|
6459
6592
|
rawExtraFieldAES[8] = encryptionStrength;
|
|
6460
6593
|
} else {
|
|
@@ -6470,15 +6603,15 @@
|
|
|
6470
6603
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
6471
6604
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
6472
6605
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
6473
|
-
extraFieldTimestamp.
|
|
6474
|
-
extraFieldTimestamp.
|
|
6475
|
-
extraFieldTimestamp.
|
|
6476
|
-
extraFieldTimestamp.
|
|
6606
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
6607
|
+
extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
|
|
6608
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
6609
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
6477
6610
|
if (lastAccessDate) {
|
|
6478
|
-
extraFieldTimestamp.
|
|
6611
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(lastAccessDate)));
|
|
6479
6612
|
}
|
|
6480
6613
|
if (creationDate) {
|
|
6481
|
-
extraFieldTimestamp.
|
|
6614
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(creationDate)));
|
|
6482
6615
|
}
|
|
6483
6616
|
rawExtraFieldExtendedTimestamp = extraFieldTimestamp.array;
|
|
6484
6617
|
} else {
|
|
@@ -6491,14 +6624,14 @@
|
|
|
6491
6624
|
try {
|
|
6492
6625
|
const lastModTimeNTFS = getTimeNTFS(lastModDate);
|
|
6493
6626
|
const extraFieldNTFS = createRecordWriter(36);
|
|
6494
|
-
extraFieldNTFS.
|
|
6495
|
-
extraFieldNTFS.
|
|
6627
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS);
|
|
6628
|
+
extraFieldNTFS.writeUint16(32);
|
|
6496
6629
|
extraFieldNTFS.skip(4);
|
|
6497
|
-
extraFieldNTFS.
|
|
6498
|
-
extraFieldNTFS.
|
|
6499
|
-
extraFieldNTFS.
|
|
6500
|
-
extraFieldNTFS.
|
|
6501
|
-
extraFieldNTFS.
|
|
6630
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS_TAG1);
|
|
6631
|
+
extraFieldNTFS.writeUint16(24);
|
|
6632
|
+
extraFieldNTFS.writeUint64(lastModTimeNTFS);
|
|
6633
|
+
extraFieldNTFS.writeUint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
|
|
6634
|
+
extraFieldNTFS.writeUint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
|
|
6502
6635
|
rawExtraFieldNTFS = extraFieldNTFS.array;
|
|
6503
6636
|
} catch {
|
|
6504
6637
|
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
@@ -6517,20 +6650,20 @@
|
|
|
6517
6650
|
const gidBytes = packUnixId(gid);
|
|
6518
6651
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
6519
6652
|
const extraFieldUnix = createRecordWriter(4 + payloadLength);
|
|
6520
|
-
extraFieldUnix.
|
|
6521
|
-
extraFieldUnix.
|
|
6522
|
-
extraFieldUnix.
|
|
6523
|
-
extraFieldUnix.
|
|
6524
|
-
extraFieldUnix.
|
|
6525
|
-
extraFieldUnix.
|
|
6526
|
-
extraFieldUnix.
|
|
6653
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
|
|
6654
|
+
extraFieldUnix.writeUint16(payloadLength);
|
|
6655
|
+
extraFieldUnix.writeUint8(1);
|
|
6656
|
+
extraFieldUnix.writeUint8(uidBytes.length);
|
|
6657
|
+
extraFieldUnix.writeBytes(uidBytes);
|
|
6658
|
+
extraFieldUnix.writeUint8(gidBytes.length);
|
|
6659
|
+
extraFieldUnix.writeBytes(gidBytes);
|
|
6527
6660
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
6528
6661
|
} else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
6529
6662
|
const extraFieldUnix = createRecordWriter(8);
|
|
6530
|
-
extraFieldUnix.
|
|
6531
|
-
extraFieldUnix.
|
|
6532
|
-
extraFieldUnix.
|
|
6533
|
-
extraFieldUnix.
|
|
6663
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
|
|
6664
|
+
extraFieldUnix.writeUint16(4);
|
|
6665
|
+
extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
|
|
6666
|
+
extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
|
|
6534
6667
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
6535
6668
|
} else {
|
|
6536
6669
|
rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
|
|
@@ -6580,18 +6713,18 @@
|
|
|
6580
6713
|
const localHeader = createRecordWriter(HEADER_SIZE + getLength(rawFilename) + extraFieldLength);
|
|
6581
6714
|
const localHeaderArray = localHeader.array;
|
|
6582
6715
|
const localHeaderView = getDataView(localHeaderArray);
|
|
6583
|
-
localHeader.
|
|
6584
|
-
localHeader.
|
|
6585
|
-
localHeader.
|
|
6716
|
+
localHeader.writeUint32(LOCAL_FILE_HEADER_SIGNATURE);
|
|
6717
|
+
localHeader.writeBytes(headerArray);
|
|
6718
|
+
localHeader.writeBytes(rawFilename);
|
|
6586
6719
|
if (writeLocalExtraFieldZip64) {
|
|
6587
|
-
localHeader.
|
|
6588
|
-
}
|
|
6589
|
-
localHeader.
|
|
6590
|
-
localHeader.
|
|
6591
|
-
localHeader.
|
|
6592
|
-
localHeader.
|
|
6593
|
-
localHeader.
|
|
6594
|
-
localHeader.
|
|
6720
|
+
localHeader.writeBytes(rawLocalExtraFieldZip64);
|
|
6721
|
+
}
|
|
6722
|
+
localHeader.writeBytes(rawExtraFieldAES);
|
|
6723
|
+
localHeader.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
6724
|
+
localHeader.writeBytes(rawExtraFieldNTFS);
|
|
6725
|
+
localHeader.writeBytes(rawExtraFieldUnix);
|
|
6726
|
+
localHeader.writeBytes(rawExtraField);
|
|
6727
|
+
localHeader.writeBytes(rawLocalExtraField);
|
|
6595
6728
|
if (dataDescriptor) {
|
|
6596
6729
|
if (!zip64CompressedSize) {
|
|
6597
6730
|
setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, 0);
|
|
@@ -6781,7 +6914,7 @@
|
|
|
6781
6914
|
|
|
6782
6915
|
|
|
6783
6916
|
async function closeFile(zipWriter, comment, options) {
|
|
6784
|
-
const directoryDataLength = createDirectoryRecords(zipWriter.
|
|
6917
|
+
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
6785
6918
|
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
6786
6919
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
6787
6920
|
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
@@ -6811,19 +6944,19 @@
|
|
|
6811
6944
|
if (zip64Offset || zip64DiskNumberStart || zip64UncompressedSize || zip64CompressedSize) {
|
|
6812
6945
|
const length = 4 + (zip64UncompressedSize ? 8 : 0) + (zip64CompressedSize ? 8 : 0) + (zip64Offset ? 8 : 0) + (zip64DiskNumberStart ? 4 : 0);
|
|
6813
6946
|
const extraFieldZip64 = createRecordWriter(length);
|
|
6814
|
-
extraFieldZip64.
|
|
6815
|
-
extraFieldZip64.
|
|
6947
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
6948
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
6816
6949
|
if (zip64UncompressedSize) {
|
|
6817
|
-
extraFieldZip64.
|
|
6950
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
6818
6951
|
}
|
|
6819
6952
|
if (zip64CompressedSize) {
|
|
6820
|
-
extraFieldZip64.
|
|
6953
|
+
extraFieldZip64.writeUint64(compressedSize);
|
|
6821
6954
|
}
|
|
6822
6955
|
if (zip64Offset) {
|
|
6823
|
-
extraFieldZip64.
|
|
6956
|
+
extraFieldZip64.writeUint64(fileEntry.offset);
|
|
6824
6957
|
}
|
|
6825
6958
|
if (zip64DiskNumberStart) {
|
|
6826
|
-
extraFieldZip64.
|
|
6959
|
+
extraFieldZip64.writeUint32(fileEntry.diskNumberStart);
|
|
6827
6960
|
}
|
|
6828
6961
|
rawExtraFieldZip64 = extraFieldZip64.array;
|
|
6829
6962
|
} else {
|
|
@@ -6836,10 +6969,10 @@
|
|
|
6836
6969
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
6837
6970
|
if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
|
|
6838
6971
|
const extraFieldTimestamp = createRecordWriter(9);
|
|
6839
|
-
extraFieldTimestamp.
|
|
6840
|
-
extraFieldTimestamp.
|
|
6841
|
-
extraFieldTimestamp.
|
|
6842
|
-
extraFieldTimestamp.
|
|
6972
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
6973
|
+
extraFieldTimestamp.writeUint16(5);
|
|
6974
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
6975
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
6843
6976
|
rawExtraFieldTimestamp = extraFieldTimestamp.array;
|
|
6844
6977
|
} else {
|
|
6845
6978
|
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
@@ -6861,14 +6994,14 @@
|
|
|
6861
6994
|
}
|
|
6862
6995
|
|
|
6863
6996
|
async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
6864
|
-
const {
|
|
6997
|
+
const { fileEntries, writer } = zipWriter;
|
|
6865
6998
|
const directoryArray = new Uint8Array(directoryDataLength);
|
|
6866
6999
|
await initStream(writer);
|
|
6867
7000
|
let offset = 0;
|
|
6868
7001
|
let directoryDiskOffset = 0;
|
|
6869
7002
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
6870
7003
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
6871
|
-
for (const [indexFileEntry, fileEntry] of Array.from(
|
|
7004
|
+
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
6872
7005
|
const {
|
|
6873
7006
|
offset: fileEntryOffset,
|
|
6874
7007
|
rawFilename,
|
|
@@ -6913,28 +7046,28 @@
|
|
|
6913
7046
|
setUint16(headerView, HEADER_OFFSET_VERSION, VERSION_ZIP64);
|
|
6914
7047
|
}
|
|
6915
7048
|
const directoryRecord = createRecordWriter(directoryRecordLength);
|
|
6916
|
-
directoryRecord.
|
|
6917
|
-
directoryRecord.
|
|
6918
|
-
directoryRecord.
|
|
6919
|
-
directoryRecord.
|
|
6920
|
-
directoryRecord.
|
|
6921
|
-
directoryRecord.
|
|
6922
|
-
directoryRecord.
|
|
6923
|
-
directoryRecord.
|
|
6924
|
-
directoryRecord.
|
|
6925
|
-
directoryRecord.
|
|
6926
|
-
directoryRecord.
|
|
6927
|
-
directoryRecord.
|
|
6928
|
-
directoryRecord.
|
|
6929
|
-
directoryRecord.
|
|
6930
|
-
directoryRecord.
|
|
6931
|
-
directoryRecord.
|
|
6932
|
-
directoryRecord.
|
|
7049
|
+
directoryRecord.writeUint32(CENTRAL_FILE_HEADER_SIGNATURE);
|
|
7050
|
+
directoryRecord.writeUint16(versionMadeBy);
|
|
7051
|
+
directoryRecord.writeBytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
|
|
7052
|
+
directoryRecord.writeUint16(extraFieldLength);
|
|
7053
|
+
directoryRecord.writeUint16(getLength(rawComment));
|
|
7054
|
+
directoryRecord.writeUint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
|
|
7055
|
+
directoryRecord.writeUint16(internalFileAttributes);
|
|
7056
|
+
directoryRecord.writeUint32(externalFileAttributes);
|
|
7057
|
+
directoryRecord.writeUint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
|
|
7058
|
+
directoryRecord.writeBytes(rawFilename);
|
|
7059
|
+
directoryRecord.writeBytes(rawExtraFieldZip64);
|
|
7060
|
+
directoryRecord.writeBytes(rawExtraFieldAES);
|
|
7061
|
+
directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
7062
|
+
directoryRecord.writeBytes(rawExtraFieldNTFS);
|
|
7063
|
+
directoryRecord.writeBytes(rawExtraFieldUnix);
|
|
7064
|
+
directoryRecord.writeBytes(rawExtraField);
|
|
7065
|
+
directoryRecord.writeBytes(rawComment);
|
|
6933
7066
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
6934
7067
|
offset += directoryRecordLength;
|
|
6935
7068
|
if (options.onprogress) {
|
|
6936
7069
|
try {
|
|
6937
|
-
await options.onprogress(indexFileEntry + 1,
|
|
7070
|
+
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
6938
7071
|
} catch {
|
|
6939
7072
|
// ignored
|
|
6940
7073
|
}
|
|
@@ -6948,7 +7081,7 @@
|
|
|
6948
7081
|
}
|
|
6949
7082
|
|
|
6950
7083
|
async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
6951
|
-
const signCentralDirectory =
|
|
7084
|
+
const signCentralDirectory = getFunctionOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
|
|
6952
7085
|
if (signCentralDirectory) {
|
|
6953
7086
|
const signatureData = await signCentralDirectory(directoryArray);
|
|
6954
7087
|
const signatureDataLength = getLength(signatureData);
|
|
@@ -6956,9 +7089,9 @@
|
|
|
6956
7089
|
throw new Error(ERR_INVALID_SIGNATURE_DATA);
|
|
6957
7090
|
}
|
|
6958
7091
|
const signatureRecord = createRecordWriter(6 + signatureDataLength);
|
|
6959
|
-
signatureRecord.
|
|
6960
|
-
signatureRecord.
|
|
6961
|
-
signatureRecord.
|
|
7092
|
+
signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
|
|
7093
|
+
signatureRecord.writeUint16(signatureDataLength);
|
|
7094
|
+
signatureRecord.writeBytes(signatureData);
|
|
6962
7095
|
await writeData(zipWriter.writer, signatureRecord.array);
|
|
6963
7096
|
return 6 + signatureDataLength;
|
|
6964
7097
|
}
|
|
@@ -6969,7 +7102,7 @@
|
|
|
6969
7102
|
const { writer } = zipWriter;
|
|
6970
7103
|
const { directoryStart, signatureLength } = cdInfo;
|
|
6971
7104
|
let { directoryDataLength } = cdInfo;
|
|
6972
|
-
let
|
|
7105
|
+
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
6973
7106
|
let diskNumber = directoryStart.diskNumber;
|
|
6974
7107
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
6975
7108
|
let lastDiskNumber = getDiskNumber(writer);
|
|
@@ -6977,7 +7110,7 @@
|
|
|
6977
7110
|
lastDiskNumber++;
|
|
6978
7111
|
}
|
|
6979
7112
|
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
6980
|
-
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS ||
|
|
7113
|
+
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
6981
7114
|
if (zip64 === false) {
|
|
6982
7115
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
6983
7116
|
} else {
|
|
@@ -6994,37 +7127,37 @@
|
|
|
6994
7127
|
}
|
|
6995
7128
|
lastDiskNumber = getDiskNumber(writer);
|
|
6996
7129
|
if (zip64) {
|
|
6997
|
-
endOfdirectoryRecord.
|
|
6998
|
-
endOfdirectoryRecord.
|
|
6999
|
-
endOfdirectoryRecord.
|
|
7000
|
-
endOfdirectoryRecord.
|
|
7001
|
-
endOfdirectoryRecord.
|
|
7002
|
-
endOfdirectoryRecord.
|
|
7003
|
-
endOfdirectoryRecord.
|
|
7004
|
-
endOfdirectoryRecord.
|
|
7005
|
-
endOfdirectoryRecord.
|
|
7006
|
-
endOfdirectoryRecord.
|
|
7007
|
-
endOfdirectoryRecord.
|
|
7008
|
-
endOfdirectoryRecord.
|
|
7009
|
-
endOfdirectoryRecord.
|
|
7010
|
-
endOfdirectoryRecord.
|
|
7130
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7131
|
+
endOfdirectoryRecord.writeUint64(44);
|
|
7132
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
7133
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
7134
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7135
|
+
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
7136
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7137
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7138
|
+
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
7139
|
+
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
7140
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
7141
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7142
|
+
endOfdirectoryRecord.writeUint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
|
|
7143
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber + 1);
|
|
7011
7144
|
const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
|
|
7012
7145
|
if (supportZip64SplitFile) {
|
|
7013
7146
|
lastDiskNumber = MAX_16_BITS;
|
|
7014
7147
|
diskNumber = MAX_16_BITS;
|
|
7015
7148
|
}
|
|
7016
|
-
|
|
7149
|
+
fileEntriesLength = MAX_16_BITS;
|
|
7017
7150
|
directoryOffset = MAX_32_BITS;
|
|
7018
7151
|
directoryDataLength = MAX_32_BITS;
|
|
7019
7152
|
}
|
|
7020
|
-
endOfdirectoryRecord.
|
|
7021
|
-
endOfdirectoryRecord.
|
|
7022
|
-
endOfdirectoryRecord.
|
|
7023
|
-
endOfdirectoryRecord.
|
|
7024
|
-
endOfdirectoryRecord.
|
|
7025
|
-
endOfdirectoryRecord.
|
|
7026
|
-
endOfdirectoryRecord.
|
|
7027
|
-
endOfdirectoryRecord.
|
|
7153
|
+
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7154
|
+
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
7155
|
+
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
7156
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7157
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7158
|
+
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
7159
|
+
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
7160
|
+
endOfdirectoryRecord.writeUint16(commentLength);
|
|
7028
7161
|
await writeData(writer, endOfdirectoryRecord.array);
|
|
7029
7162
|
if (commentLength) {
|
|
7030
7163
|
await writeData(writer, comment);
|
|
@@ -7037,11 +7170,11 @@
|
|
|
7037
7170
|
let offset = 0;
|
|
7038
7171
|
return {
|
|
7039
7172
|
array,
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7173
|
+
writeUint8: value => { setUint8(view, offset, value); offset += 1; },
|
|
7174
|
+
writeUint16: value => { setUint16(view, offset, value); offset += 2; },
|
|
7175
|
+
writeUint32: value => { setUint32(view, offset, value); offset += 4; },
|
|
7176
|
+
writeUint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
|
|
7177
|
+
writeBytes: value => { arraySet(array, value, offset); offset += getLength(value); },
|
|
7045
7178
|
skip: count => offset += count
|
|
7046
7179
|
};
|
|
7047
7180
|
}
|
|
@@ -7065,6 +7198,71 @@
|
|
|
7065
7198
|
return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
|
|
7066
7199
|
}
|
|
7067
7200
|
|
|
7201
|
+
async function startsWithSplitZipSignature(reader) {
|
|
7202
|
+
const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
7203
|
+
return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
7204
|
+
}
|
|
7205
|
+
|
|
7206
|
+
async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
|
|
7207
|
+
const { writer } = zipWriter;
|
|
7208
|
+
const entryPositions = new Map();
|
|
7209
|
+
if (writer.closeDisk) {
|
|
7210
|
+
const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
|
|
7211
|
+
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
7212
|
+
let copiedLength = 0;
|
|
7213
|
+
for (const entry of sortedEntries) {
|
|
7214
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
7215
|
+
await copyData(zipWriter, reader, copiedLength, sourceOffset - copiedLength);
|
|
7216
|
+
if (exceedsAvailableSize(writer, await getLocalHeaderLength(reader, sourceOffset))) {
|
|
7217
|
+
await writer.closeDisk();
|
|
7218
|
+
}
|
|
7219
|
+
entryPositions.set(entry, {
|
|
7220
|
+
offset: getSegmentOffset(zipWriter, writer),
|
|
7221
|
+
diskNumberStart: getDiskNumber(writer)
|
|
7222
|
+
});
|
|
7223
|
+
copiedLength = sourceOffset;
|
|
7224
|
+
}
|
|
7225
|
+
await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
|
|
7226
|
+
} else {
|
|
7227
|
+
await copyData(zipWriter, reader, 0, directoryOffset);
|
|
7228
|
+
entries.forEach(entry => entryPositions.set(entry, {
|
|
7229
|
+
offset: splitZipSignatureLength + getSourceOffset(reader, entry),
|
|
7230
|
+
diskNumberStart: 0
|
|
7231
|
+
}));
|
|
7232
|
+
}
|
|
7233
|
+
return entryPositions;
|
|
7234
|
+
}
|
|
7235
|
+
|
|
7236
|
+
async function copyData(zipWriter, reader, offset, size) {
|
|
7237
|
+
if (size > 0) {
|
|
7238
|
+
const { writer } = zipWriter;
|
|
7239
|
+
await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
|
|
7240
|
+
writer.size += size;
|
|
7241
|
+
zipWriter.offset += size;
|
|
7242
|
+
}
|
|
7243
|
+
}
|
|
7244
|
+
|
|
7245
|
+
async function getLocalHeaderLength(reader, offset) {
|
|
7246
|
+
const headerArray = await readUint8Array(reader, offset, HEADER_SIZE);
|
|
7247
|
+
if (getLength(headerArray) < HEADER_SIZE) {
|
|
7248
|
+
return HEADER_SIZE;
|
|
7249
|
+
}
|
|
7250
|
+
const headerView = getDataView(headerArray);
|
|
7251
|
+
return HEADER_SIZE +
|
|
7252
|
+
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
7253
|
+
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
7254
|
+
}
|
|
7255
|
+
|
|
7256
|
+
function getSourceOffset(reader, { offset, diskNumberStart }) {
|
|
7257
|
+
return offset + (reader.getDiskOffset ? reader.getDiskOffset(diskNumberStart) : 0);
|
|
7258
|
+
}
|
|
7259
|
+
|
|
7260
|
+
function getSplitZipSignatureArray() {
|
|
7261
|
+
const signatureArray = new Uint8Array(SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
7262
|
+
setUint32(getDataView(signatureArray), 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
7263
|
+
return signatureArray;
|
|
7264
|
+
}
|
|
7265
|
+
|
|
7068
7266
|
async function writeData(writer, array) {
|
|
7069
7267
|
const { writable } = writer;
|
|
7070
7268
|
const streamWriter = writable.getWriter();
|
|
@@ -7116,6 +7314,21 @@
|
|
|
7116
7314
|
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
7117
7315
|
}
|
|
7118
7316
|
|
|
7317
|
+
function getDateOptionValue(zipWriter, options, name, defaultValue) {
|
|
7318
|
+
const date = getOptionValue(zipWriter, options, name, defaultValue);
|
|
7319
|
+
if (date === null) {
|
|
7320
|
+
return defaultValue;
|
|
7321
|
+
}
|
|
7322
|
+
if (date !== UNDEFINED_VALUE && (typeof date.getTime != FUNCTION_TYPE || Number.isNaN(date.getTime()))) {
|
|
7323
|
+
throw new Error(ERR_INVALID_DATE);
|
|
7324
|
+
}
|
|
7325
|
+
return date;
|
|
7326
|
+
}
|
|
7327
|
+
|
|
7328
|
+
function getFunctionOptionValue(zipWriter, options, name) {
|
|
7329
|
+
return checkFunctionOption(getOptionValue(zipWriter, options, name));
|
|
7330
|
+
}
|
|
7331
|
+
|
|
7119
7332
|
function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
|
|
7120
7333
|
const value = getAliasedValue(options, name, deprecatedName);
|
|
7121
7334
|
const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
|
|
@@ -7130,9 +7343,6 @@
|
|
|
7130
7343
|
return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
|
|
7131
7344
|
}
|
|
7132
7345
|
|
|
7133
|
-
function toNumber(value) {
|
|
7134
|
-
return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
|
|
7135
|
-
}
|
|
7136
7346
|
|
|
7137
7347
|
function getMaximumCompressedSize(uncompressedSize) {
|
|
7138
7348
|
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
@@ -7144,6 +7354,14 @@
|
|
|
7144
7354
|
: compressionMethod !== COMPRESSION_METHOD_STORE;
|
|
7145
7355
|
}
|
|
7146
7356
|
|
|
7357
|
+
function getUint16(view, offset) {
|
|
7358
|
+
return view.getUint16(offset, true);
|
|
7359
|
+
}
|
|
7360
|
+
|
|
7361
|
+
function getUint32(view, offset) {
|
|
7362
|
+
return view.getUint32(offset, true);
|
|
7363
|
+
}
|
|
7364
|
+
|
|
7147
7365
|
function setUint8(view, offset, value) {
|
|
7148
7366
|
view.setUint8(offset, value);
|
|
7149
7367
|
}
|
|
@@ -7187,9 +7405,9 @@
|
|
|
7187
7405
|
const headerRecord = createRecordWriter(HEADER_SIZE - 4);
|
|
7188
7406
|
const headerArray = headerRecord.array;
|
|
7189
7407
|
const headerView = getDataView(headerArray);
|
|
7190
|
-
headerRecord.
|
|
7191
|
-
headerRecord.
|
|
7192
|
-
headerRecord.
|
|
7408
|
+
headerRecord.writeUint16(version);
|
|
7409
|
+
headerRecord.writeUint16(bitFlag);
|
|
7410
|
+
headerRecord.writeUint16(compressionMethod);
|
|
7193
7411
|
if (rawLastModDate === UNDEFINED_VALUE) {
|
|
7194
7412
|
const dateArray = new Uint32Array(1);
|
|
7195
7413
|
const dateView = getDataView(dateArray);
|
|
@@ -7197,20 +7415,20 @@
|
|
|
7197
7415
|
setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
|
|
7198
7416
|
rawLastModDate = dateArray[0];
|
|
7199
7417
|
}
|
|
7200
|
-
headerRecord.
|
|
7418
|
+
headerRecord.writeUint32(rawLastModDate);
|
|
7201
7419
|
headerRecord.skip(4);
|
|
7202
7420
|
if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
|
|
7203
|
-
headerRecord.
|
|
7421
|
+
headerRecord.writeUint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
|
|
7204
7422
|
} else {
|
|
7205
7423
|
headerRecord.skip(4);
|
|
7206
7424
|
}
|
|
7207
7425
|
if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
|
|
7208
|
-
headerRecord.
|
|
7426
|
+
headerRecord.writeUint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
|
|
7209
7427
|
} else {
|
|
7210
7428
|
headerRecord.skip(4);
|
|
7211
7429
|
}
|
|
7212
|
-
headerRecord.
|
|
7213
|
-
headerRecord.
|
|
7430
|
+
headerRecord.writeUint16(getLength(rawFilename));
|
|
7431
|
+
headerRecord.writeUint16(extraFieldLength);
|
|
7214
7432
|
return {
|
|
7215
7433
|
headerArray,
|
|
7216
7434
|
headerView,
|
|
@@ -7275,6 +7493,7 @@
|
|
|
7275
7493
|
const ERR_ENTRY_EXISTS = "Entry filename already exists";
|
|
7276
7494
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
7277
7495
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
7496
|
+
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
7278
7497
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
7279
7498
|
const ERR_ABORTED = "The operation was aborted";
|
|
7280
7499
|
const ABORT_ERROR_NAME = "AbortError";
|
|
@@ -7307,13 +7526,14 @@
|
|
|
7307
7526
|
fs,
|
|
7308
7527
|
name,
|
|
7309
7528
|
data: params.data,
|
|
7310
|
-
options: params.options,
|
|
7529
|
+
options: params.options && Object.assign({}, params.options),
|
|
7311
7530
|
id: fs.entryIdCounter++,
|
|
7312
7531
|
parent,
|
|
7313
7532
|
children: [],
|
|
7314
7533
|
uncompressedSize: params.uncompressedSize || 0,
|
|
7315
7534
|
undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
|
|
7316
|
-
passThrough: params.passThrough
|
|
7535
|
+
passThrough: params.passThrough,
|
|
7536
|
+
defaultLastModDate: params.defaultLastModDate || new Date()
|
|
7317
7537
|
});
|
|
7318
7538
|
if (parent || !fs.root) {
|
|
7319
7539
|
fs.entries[zipEntry.id] = zipEntry;
|
|
@@ -7323,12 +7543,6 @@
|
|
|
7323
7543
|
}
|
|
7324
7544
|
}
|
|
7325
7545
|
|
|
7326
|
-
moveTo(target) {
|
|
7327
|
-
// deprecated
|
|
7328
|
-
const zipEntry = this;
|
|
7329
|
-
zipEntry.fs.move(zipEntry, target);
|
|
7330
|
-
}
|
|
7331
|
-
|
|
7332
7546
|
getFullname() {
|
|
7333
7547
|
return this.getRelativeName();
|
|
7334
7548
|
}
|
|
@@ -7360,6 +7574,11 @@
|
|
|
7360
7574
|
this.name = name;
|
|
7361
7575
|
}
|
|
7362
7576
|
}
|
|
7577
|
+
|
|
7578
|
+
setOptions(options) {
|
|
7579
|
+
const entryOptions = Object.assign({}, this.options, options);
|
|
7580
|
+
this.options = Object.fromEntries(Object.entries(entryOptions).filter(([, value]) => value !== UNDEFINED_VALUE));
|
|
7581
|
+
}
|
|
7363
7582
|
}
|
|
7364
7583
|
|
|
7365
7584
|
class ZipFileEntry extends ZipEntry {
|
|
@@ -7386,7 +7605,7 @@
|
|
|
7386
7605
|
const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
|
|
7387
7606
|
const dataSize = zipEntry.uncompressedSize || reader.size;
|
|
7388
7607
|
await Promise.all([initStream(reader), initStream(writer, dataSize)]);
|
|
7389
|
-
const
|
|
7608
|
+
const signal = checkSignalOption(options.signal);
|
|
7390
7609
|
const readable = createProgressReadable(zipEntry, reader, options, signal);
|
|
7391
7610
|
const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
|
|
7392
7611
|
zipEntry.uncompressedSize = reader.size;
|
|
@@ -7604,10 +7823,6 @@
|
|
|
7604
7823
|
});
|
|
7605
7824
|
}
|
|
7606
7825
|
|
|
7607
|
-
addData(name, params) {
|
|
7608
|
-
return addChild(this, name, params);
|
|
7609
|
-
}
|
|
7610
|
-
|
|
7611
7826
|
importBlob(blob, options) {
|
|
7612
7827
|
return this.importZip(new BlobReader(blob), options);
|
|
7613
7828
|
}
|
|
@@ -7721,7 +7936,7 @@
|
|
|
7721
7936
|
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
7722
7937
|
options.bufferedWrite = true;
|
|
7723
7938
|
}
|
|
7724
|
-
const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
|
|
7939
|
+
const [readers] = await Promise.all([initReaders(zipEntry, checkReaderOptions(options.readerOptions)), initStream(writer)]);
|
|
7725
7940
|
const zipWriter = new ZipWriter(writer, options);
|
|
7726
7941
|
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
|
|
7727
7942
|
await zipWriter.close(options.globalComment);
|
|
@@ -7731,12 +7946,13 @@
|
|
|
7731
7946
|
getExportedSize(options = {}) {
|
|
7732
7947
|
const zipEntry = this;
|
|
7733
7948
|
options = Object.assign({}, options);
|
|
7949
|
+
checkReaderOptions(options.readerOptions);
|
|
7734
7950
|
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
7735
7951
|
options.bufferedWrite = true;
|
|
7736
7952
|
}
|
|
7737
7953
|
const writeOrderGuaranteed = !options.bufferedWrite ||
|
|
7738
7954
|
(options.keepOrder !== false && zipEntry.children.every(child => !child.children.length));
|
|
7739
|
-
return getEntriesSize(options,
|
|
7955
|
+
return getEntriesSize(options, zipEntry.getChildren({ recursive: true }).filter(child => !isImplicitDirectory(child)).map(child => {
|
|
7740
7956
|
const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
|
|
7741
7957
|
return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
|
|
7742
7958
|
}), writeOrderGuaranteed, options.globalComment);
|
|
@@ -7775,7 +7991,7 @@
|
|
|
7775
7991
|
}
|
|
7776
7992
|
|
|
7777
7993
|
|
|
7778
|
-
class
|
|
7994
|
+
class ZipFS {
|
|
7779
7995
|
|
|
7780
7996
|
constructor() {
|
|
7781
7997
|
resetFS(this);
|
|
@@ -7891,10 +8107,6 @@
|
|
|
7891
8107
|
return this.root.addFile(file, options);
|
|
7892
8108
|
}
|
|
7893
8109
|
|
|
7894
|
-
addData(name, params) {
|
|
7895
|
-
return this.root.addData(name, params);
|
|
7896
|
-
}
|
|
7897
|
-
|
|
7898
8110
|
importBlob(blob, options) {
|
|
7899
8111
|
resetFS(this);
|
|
7900
8112
|
return this.root.importBlob(blob, options);
|
|
@@ -7962,7 +8174,7 @@
|
|
|
7962
8174
|
}
|
|
7963
8175
|
}
|
|
7964
8176
|
|
|
7965
|
-
const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
|
|
8177
|
+
const fs = { FS: ZipFS, ZipDirectoryEntry, ZipFileEntry };
|
|
7966
8178
|
|
|
7967
8179
|
function getTotalSize(entries, getEntrySize) {
|
|
7968
8180
|
let size = 0;
|
|
@@ -8106,7 +8318,7 @@
|
|
|
8106
8318
|
}
|
|
8107
8319
|
|
|
8108
8320
|
function forwardAbort(signal, abortController) {
|
|
8109
|
-
if (!signal) {
|
|
8321
|
+
if (!checkSignalOption(signal)) {
|
|
8110
8322
|
return () => { };
|
|
8111
8323
|
}
|
|
8112
8324
|
if (signal.aborted) {
|
|
@@ -8183,10 +8395,7 @@
|
|
|
8183
8395
|
});
|
|
8184
8396
|
}
|
|
8185
8397
|
if (isPassThrough(child, options)) {
|
|
8186
|
-
let
|
|
8187
|
-
if (compressionMethod === 0) {
|
|
8188
|
-
level = 0;
|
|
8189
|
-
}
|
|
8398
|
+
let encryptionStrength;
|
|
8190
8399
|
if (extraFieldAES) {
|
|
8191
8400
|
encryptionStrength = extraFieldAES.strength;
|
|
8192
8401
|
}
|
|
@@ -8196,13 +8405,12 @@
|
|
|
8196
8405
|
zipCrypto,
|
|
8197
8406
|
crc32,
|
|
8198
8407
|
uncompressedSize,
|
|
8199
|
-
level,
|
|
8200
8408
|
encryptionStrength,
|
|
8201
8409
|
compressionMethod
|
|
8202
8410
|
};
|
|
8203
8411
|
}
|
|
8204
8412
|
}
|
|
8205
|
-
const entryOptions = Object.assign({}, zipEntryMetadata, options,
|
|
8413
|
+
const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
|
|
8206
8414
|
if (!child.directory && entryOptions.passThrough && entryOptions.uncompressedSize === UNDEFINED_VALUE) {
|
|
8207
8415
|
throw new Error(ERR_INVALID_PASS_THROUGH);
|
|
8208
8416
|
}
|
|
@@ -8217,11 +8425,22 @@
|
|
|
8217
8425
|
return child.undeterminedSize ? UNDEFINED_VALUE : getExtractedSize(child, passThrough);
|
|
8218
8426
|
}
|
|
8219
8427
|
|
|
8428
|
+
function checkReaderOptions(readerOptions) {
|
|
8429
|
+
if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
|
|
8430
|
+
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
8431
|
+
}
|
|
8432
|
+
return readerOptions;
|
|
8433
|
+
}
|
|
8434
|
+
|
|
8220
8435
|
function isPassThrough(child, options) {
|
|
8221
8436
|
const { readerOptions } = options;
|
|
8222
8437
|
return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
|
|
8223
8438
|
}
|
|
8224
8439
|
|
|
8440
|
+
function isImplicitDirectory(child) {
|
|
8441
|
+
return child.directory && child.data === null;
|
|
8442
|
+
}
|
|
8443
|
+
|
|
8225
8444
|
function getUserExtraField(extraField) {
|
|
8226
8445
|
if (extraField) {
|
|
8227
8446
|
const userExtraField = new Map();
|
|
@@ -8239,7 +8458,7 @@
|
|
|
8239
8458
|
async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
8240
8459
|
const { onstart, onprogress, onend, onentryprogress } = options;
|
|
8241
8460
|
const selectedEntry = entry;
|
|
8242
|
-
const totalEntries = getTotalSize(entry.children, ()
|
|
8461
|
+
const totalEntries = getTotalSize(entry.children, child => isImplicitDirectory(child) ? 0 : 1);
|
|
8243
8462
|
let writtenSize = 0;
|
|
8244
8463
|
let writtenEntries = 0;
|
|
8245
8464
|
if (onstart) {
|
|
@@ -8268,6 +8487,9 @@
|
|
|
8268
8487
|
}
|
|
8269
8488
|
|
|
8270
8489
|
async function addChild(child) {
|
|
8490
|
+
if (isImplicitDirectory(child)) {
|
|
8491
|
+
return;
|
|
8492
|
+
}
|
|
8271
8493
|
const { name, entryOptions } = getChildEntryOptions(child, selectedEntry, options);
|
|
8272
8494
|
let entryWrittenSize = 0;
|
|
8273
8495
|
const entryMetadata = await zipWriter.add(name, readers.get(child), Object.assign(entryOptions, {
|
|
@@ -8301,7 +8523,7 @@
|
|
|
8301
8523
|
if (handle.kind == "file") {
|
|
8302
8524
|
const file = await handle.getFile();
|
|
8303
8525
|
addedEntries.push(
|
|
8304
|
-
parentEntry
|
|
8526
|
+
addChild(parentEntry, file.name, {
|
|
8305
8527
|
Reader: function () {
|
|
8306
8528
|
const readable = file.stream();
|
|
8307
8529
|
const size = file.size;
|
|
@@ -8335,10 +8557,11 @@
|
|
|
8335
8557
|
|
|
8336
8558
|
async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
8337
8559
|
const { onstart, onprogress, onend } = options;
|
|
8560
|
+
const readerOptions = checkReaderOptions(options.readerOptions);
|
|
8338
8561
|
const abortController = new AbortController();
|
|
8339
8562
|
const { signal } = abortController;
|
|
8340
8563
|
const releaseSignal = forwardAbort(options.signal, abortController);
|
|
8341
|
-
const getDataOptions = Object.assign({}, options,
|
|
8564
|
+
const getDataOptions = Object.assign({}, options, readerOptions, {
|
|
8342
8565
|
signal,
|
|
8343
8566
|
onstart: UNDEFINED_VALUE,
|
|
8344
8567
|
onprogress: UNDEFINED_VALUE,
|
|
@@ -8535,7 +8758,12 @@
|
|
|
8535
8758
|
exports.ERR_ABORTED = ERR_ABORTED;
|
|
8536
8759
|
exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
|
|
8537
8760
|
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
8761
|
+
exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
|
|
8538
8762
|
exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
|
|
8763
|
+
exports.ZipDirectoryEntry = ZipDirectoryEntry;
|
|
8764
|
+
exports.ZipEntry = ZipEntry;
|
|
8765
|
+
exports.ZipFS = ZipFS;
|
|
8766
|
+
exports.ZipFileEntry = ZipFileEntry;
|
|
8539
8767
|
exports.fs = fs;
|
|
8540
8768
|
|
|
8541
8769
|
}));
|