@zip.js/zip.js 2.11.4 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist/zip-core-external.js +427 -110
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +437 -107
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +492 -230
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +505 -227
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +492 -230
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +507 -229
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +508 -230
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +439 -109
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +439 -109
- 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 +440 -110
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +507 -229
- package/index-native.min.js +1 -1
- package/index.cjs +508 -230
- package/index.d.cts +468 -59
- package/index.d.ts +468 -59
- package/index.min.js +1 -1
- package/lib/core/codec-worker-web.js +10 -2
- package/lib/core/codec-worker.js +4 -3
- package/lib/core/configuration.js +20 -5
- package/lib/core/constants.js +2 -0
- package/lib/core/io.js +13 -5
- package/lib/core/options.js +16 -0
- package/lib/core/streams/codec-stream.js +6 -0
- package/lib/core/util/warnings.js +42 -0
- package/lib/core/version.js +1 -1
- package/lib/core/web-worker-base.js +4 -3
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-entry.js +49 -1
- package/lib/core/zip-fs.js +43 -132
- package/lib/core/zip-reader.js +106 -48
- package/lib/core/zip-writer.js +236 -54
- package/lib/zip-core-base.js +9 -3
- package/lib/zip-core-reader.js +2 -0
- package/lib/zip-core-writer.js +6 -1
- package/lib/zip-module-wasm-base.js +2 -2
- package/package.json +5 -3
package/dist/zip-core.js
CHANGED
|
@@ -134,6 +134,7 @@
|
|
|
134
134
|
const BOOLEAN_TYPE = "boolean";
|
|
135
135
|
|
|
136
136
|
const EMPTY_UINT8_ARRAY = new Uint8Array();
|
|
137
|
+
const SYMBOL_ASYNC_DISPOSE = Symbol.asyncDispose || Symbol();
|
|
137
138
|
|
|
138
139
|
/*
|
|
139
140
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
@@ -178,6 +179,7 @@
|
|
|
178
179
|
const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
|
|
179
180
|
const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
|
|
180
181
|
const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
|
|
182
|
+
const OPTION_CHECK_LOCAL_FILENAME = "checkLocalFilename";
|
|
181
183
|
const OPTION_CHECK_SIGNATURE = "checkSignature";
|
|
182
184
|
const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
183
185
|
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
@@ -208,15 +210,18 @@
|
|
|
208
210
|
const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
|
|
209
211
|
const OPTION_DECRYPT_CENTRAL_DIRECTORY = "decryptCentralDirectory";
|
|
210
212
|
const OPTION_SIGN_CENTRAL_DIRECTORY = "signCentralDirectory";
|
|
213
|
+
const OPTION_ENTRY = "entry";
|
|
211
214
|
const TEXT_TYPE_FILENAME = "filename";
|
|
212
215
|
const TEXT_TYPE_COMMENT = "comment";
|
|
213
216
|
const STRICTNESS_STRICT = "strict";
|
|
214
217
|
const STRICTNESS_BALANCED = "balanced";
|
|
215
218
|
const STRICTNESS_TOLERANT = "tolerant";
|
|
219
|
+
const PASS_THROUGH_COMPRESSED = "compressed";
|
|
216
220
|
|
|
217
221
|
const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
|
|
218
222
|
const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
|
|
219
223
|
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
224
|
+
const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
|
|
220
225
|
const ERR_ABORTED = "The operation was aborted";
|
|
221
226
|
const ABORT_ERROR_NAME = "AbortError";
|
|
222
227
|
|
|
@@ -246,6 +251,13 @@
|
|
|
246
251
|
}
|
|
247
252
|
}
|
|
248
253
|
|
|
254
|
+
function checkPassThroughOption(passThrough) {
|
|
255
|
+
if (passThrough !== UNDEFINED_VALUE && typeof passThrough != BOOLEAN_TYPE && passThrough !== PASS_THROUGH_COMPRESSED) {
|
|
256
|
+
throw new Error(ERR_INVALID_PASS_THROUGH_VALUE);
|
|
257
|
+
}
|
|
258
|
+
return passThrough;
|
|
259
|
+
}
|
|
260
|
+
|
|
249
261
|
function checkInteger(value, maxValue, errorMessage) {
|
|
250
262
|
if (!Number.isInteger(value) || value < 0 || value > maxValue) {
|
|
251
263
|
throw new Error(errorMessage);
|
|
@@ -295,6 +307,8 @@
|
|
|
295
307
|
const MINIMUM_CHUNK_SIZE = 64;
|
|
296
308
|
const MINIMUM_PROPERTY_VALUE = 1;
|
|
297
309
|
const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
|
|
310
|
+
const ERR_INVALID_BASE_URI = "Invalid baseURI (must be a string)";
|
|
311
|
+
const ERR_INVALID_URI = "Invalid URI (must be a string or a function returning a string)";
|
|
298
312
|
let maxWorkers = 2;
|
|
299
313
|
try {
|
|
300
314
|
if (typeof navigator != UNDEFINED_TYPE && navigator.hardwareConcurrency) {
|
|
@@ -319,9 +333,9 @@
|
|
|
319
333
|
};
|
|
320
334
|
|
|
321
335
|
const PROPERTY_NAME_MAX_WORKERS = "maxWorkers";
|
|
336
|
+
const PROPERTY_NAME_BASE_URI = "baseURI";
|
|
322
337
|
|
|
323
|
-
const
|
|
324
|
-
"baseURI",
|
|
338
|
+
const URI_PROPERTY_NAMES = [
|
|
325
339
|
"wasmURI",
|
|
326
340
|
"workerURI"
|
|
327
341
|
];
|
|
@@ -345,7 +359,8 @@
|
|
|
345
359
|
"DecompressionStreamFallback"
|
|
346
360
|
];
|
|
347
361
|
const CONFIGURABLE_PROPERTY_NAMES = [
|
|
348
|
-
|
|
362
|
+
PROPERTY_NAME_BASE_URI,
|
|
363
|
+
...URI_PROPERTY_NAMES,
|
|
349
364
|
...BOOLEAN_PROPERTY_NAMES,
|
|
350
365
|
...NUMBER_PROPERTY_NAMES,
|
|
351
366
|
...FUNCTION_PROPERTY_NAMES
|
|
@@ -389,6 +404,14 @@
|
|
|
389
404
|
}
|
|
390
405
|
} else if (FUNCTION_PROPERTY_NAMES.includes(propertyName)) {
|
|
391
406
|
checkFunctionOption(propertyValue);
|
|
407
|
+
} else if (propertyName == PROPERTY_NAME_BASE_URI) {
|
|
408
|
+
if (propertyValue && typeof propertyValue != STRING_TYPE) {
|
|
409
|
+
throw new Error(ERR_INVALID_BASE_URI);
|
|
410
|
+
}
|
|
411
|
+
} else if (URI_PROPERTY_NAMES.includes(propertyName)) {
|
|
412
|
+
if (propertyValue && typeof propertyValue != STRING_TYPE && typeof propertyValue != FUNCTION_TYPE) {
|
|
413
|
+
throw new Error(ERR_INVALID_URI);
|
|
414
|
+
}
|
|
392
415
|
}
|
|
393
416
|
return propertyValue;
|
|
394
417
|
}
|
|
@@ -2605,6 +2628,7 @@
|
|
|
2605
2628
|
constructor(chunkSize) {
|
|
2606
2629
|
const pendingChunks = [];
|
|
2607
2630
|
let pendingLength = 0;
|
|
2631
|
+
let outputSize = 0;
|
|
2608
2632
|
if (!Number.isFinite(chunkSize) || chunkSize < 1) {
|
|
2609
2633
|
chunkSize = DEFAULT_CHUNK_SIZE;
|
|
2610
2634
|
}
|
|
@@ -2613,15 +2637,20 @@
|
|
|
2613
2637
|
pendingChunks.push(chunk);
|
|
2614
2638
|
pendingLength += chunk.length;
|
|
2615
2639
|
while (pendingLength > chunkSize) {
|
|
2640
|
+
outputSize += chunkSize;
|
|
2616
2641
|
controller.enqueue(shiftChunk());
|
|
2617
2642
|
}
|
|
2618
2643
|
},
|
|
2619
2644
|
flush(controller) {
|
|
2620
2645
|
if (pendingLength) {
|
|
2646
|
+
outputSize += pendingLength;
|
|
2621
2647
|
controller.enqueue(concatChunks(pendingChunks, pendingLength));
|
|
2622
2648
|
}
|
|
2623
2649
|
}
|
|
2624
2650
|
});
|
|
2651
|
+
Object.defineProperty(this, "outputSize", {
|
|
2652
|
+
get: () => outputSize
|
|
2653
|
+
});
|
|
2625
2654
|
|
|
2626
2655
|
function shiftChunk() {
|
|
2627
2656
|
const result = new Uint8Array(chunkSize);
|
|
@@ -2822,7 +2851,7 @@
|
|
|
2822
2851
|
}
|
|
2823
2852
|
|
|
2824
2853
|
async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
|
|
2825
|
-
let codecStream;
|
|
2854
|
+
let codecStream, chunkStream;
|
|
2826
2855
|
try {
|
|
2827
2856
|
if (options.compressed && !options.format) {
|
|
2828
2857
|
const deflate = options.codecType.startsWith(CODEC_DEFLATE);
|
|
@@ -2845,9 +2874,10 @@
|
|
|
2845
2874
|
}
|
|
2846
2875
|
}
|
|
2847
2876
|
codecStream = new CodecStream(options, config);
|
|
2877
|
+
chunkStream = new ChunkStream(getChunkSize(config));
|
|
2848
2878
|
await readable
|
|
2849
2879
|
.pipeThrough(codecStream)
|
|
2850
|
-
.pipeThrough(
|
|
2880
|
+
.pipeThrough(chunkStream)
|
|
2851
2881
|
.pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
2852
2882
|
const {
|
|
2853
2883
|
crc32,
|
|
@@ -2861,7 +2891,7 @@
|
|
|
2861
2891
|
};
|
|
2862
2892
|
} catch (error) {
|
|
2863
2893
|
if (codecStream) {
|
|
2864
|
-
error.outputSize =
|
|
2894
|
+
error.outputSize = chunkStream ? chunkStream.outputSize : 0;
|
|
2865
2895
|
}
|
|
2866
2896
|
throw error;
|
|
2867
2897
|
} finally {
|
|
@@ -2970,11 +3000,17 @@
|
|
|
2970
3000
|
let resolveResult, rejectResult;
|
|
2971
3001
|
const result = new Promise((resolve, reject) => {
|
|
2972
3002
|
resolveResult = resolve;
|
|
2973
|
-
rejectResult =
|
|
3003
|
+
rejectResult = error => {
|
|
3004
|
+
if (error && error.outputSize === UNDEFINED_VALUE) {
|
|
3005
|
+
error.outputSize = workerData.outputSize;
|
|
3006
|
+
}
|
|
3007
|
+
reject(error);
|
|
3008
|
+
};
|
|
2974
3009
|
});
|
|
2975
3010
|
Object.assign(workerData, {
|
|
2976
3011
|
reader: null,
|
|
2977
3012
|
writer: null,
|
|
3013
|
+
outputSize: 0,
|
|
2978
3014
|
resolveResult,
|
|
2979
3015
|
rejectResult,
|
|
2980
3016
|
result
|
|
@@ -3258,8 +3294,10 @@
|
|
|
3258
3294
|
}
|
|
3259
3295
|
}
|
|
3260
3296
|
if (type == MESSAGE_DATA) {
|
|
3297
|
+
const chunk = new Uint8Array(value);
|
|
3261
3298
|
await writer.ready;
|
|
3262
|
-
await writer.write(
|
|
3299
|
+
await writer.write(chunk);
|
|
3300
|
+
workerData.outputSize += chunk.length;
|
|
3263
3301
|
if (!stale()) {
|
|
3264
3302
|
sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
|
|
3265
3303
|
}
|
|
@@ -3567,10 +3605,13 @@
|
|
|
3567
3605
|
|
|
3568
3606
|
|
|
3569
3607
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
3608
|
+
const MIN_SUCCESS_HTTP_STATUS = 200;
|
|
3609
|
+
const MAX_SUCCESS_HTTP_STATUS = 299;
|
|
3570
3610
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
3571
3611
|
const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
|
|
3572
3612
|
const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
|
|
3573
3613
|
const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
|
|
3614
|
+
const ERR_WRITER_SIZE_NOT_WRITABLE = "Invalid writer (size must be writable)";
|
|
3574
3615
|
|
|
3575
3616
|
const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
|
|
3576
3617
|
const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
|
|
@@ -3762,6 +3803,7 @@
|
|
|
3762
3803
|
const reader = this;
|
|
3763
3804
|
const { sourceBlob, size } = reader;
|
|
3764
3805
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
3806
|
+
// deno-lint-ignore valid-typeof
|
|
3765
3807
|
if (typeof sourceBlob.stream == FUNCTION_TYPE) {
|
|
3766
3808
|
if (!offset && readSize >= size) {
|
|
3767
3809
|
return toCompatibleReadable(sourceBlob.stream());
|
|
@@ -4148,7 +4190,7 @@
|
|
|
4148
4190
|
|
|
4149
4191
|
async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
|
|
4150
4192
|
const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
|
|
4151
|
-
if (response.status
|
|
4193
|
+
if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
|
|
4152
4194
|
return response;
|
|
4153
4195
|
} else {
|
|
4154
4196
|
throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
|
|
@@ -4159,7 +4201,7 @@
|
|
|
4159
4201
|
return new Promise((resolve, reject) => {
|
|
4160
4202
|
const request = new XMLHttpRequest();
|
|
4161
4203
|
request.addEventListener("load", () => {
|
|
4162
|
-
if (request.status
|
|
4204
|
+
if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
|
|
4163
4205
|
const headers = [];
|
|
4164
4206
|
request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
|
|
4165
4207
|
const splitHeader = header.trim().split(/\s*:\s*/);
|
|
@@ -4463,8 +4505,10 @@
|
|
|
4463
4505
|
writable: toCompatibleWritable(writer)
|
|
4464
4506
|
};
|
|
4465
4507
|
}
|
|
4466
|
-
|
|
4467
|
-
writer.size = 0;
|
|
4508
|
+
try {
|
|
4509
|
+
writer.size = writer.size === UNDEFINED_VALUE ? 0 : writer.size;
|
|
4510
|
+
} catch {
|
|
4511
|
+
throw new Error(ERR_WRITER_SIZE_NOT_WRITABLE);
|
|
4468
4512
|
}
|
|
4469
4513
|
return writer;
|
|
4470
4514
|
}
|
|
@@ -4512,6 +4556,45 @@
|
|
|
4512
4556
|
}
|
|
4513
4557
|
}
|
|
4514
4558
|
|
|
4559
|
+
/*
|
|
4560
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
4561
|
+
|
|
4562
|
+
Redistribution and use in source and binary forms, with or without
|
|
4563
|
+
modification, are permitted provided that the following conditions are met:
|
|
4564
|
+
|
|
4565
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
4566
|
+
this list of conditions and the following disclaimer.
|
|
4567
|
+
|
|
4568
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
4569
|
+
notice, this list of conditions and the following disclaimer in
|
|
4570
|
+
the documentation and/or other materials provided with the distribution.
|
|
4571
|
+
|
|
4572
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
4573
|
+
derived from this software without specific prior written permission.
|
|
4574
|
+
|
|
4575
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4576
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4577
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4578
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4579
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4580
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4581
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4582
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4583
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4584
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4585
|
+
*/
|
|
4586
|
+
|
|
4587
|
+
|
|
4588
|
+
function addWarning(warnings, reason, filename) {
|
|
4589
|
+
if (!warnings.some(warning => warning.reason == reason)) {
|
|
4590
|
+
const warning = { reason };
|
|
4591
|
+
if (filename !== UNDEFINED_VALUE) {
|
|
4592
|
+
warning.filename = filename;
|
|
4593
|
+
}
|
|
4594
|
+
warnings.push(warning);
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
|
|
4515
4598
|
/*
|
|
4516
4599
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4517
4600
|
|
|
@@ -4540,6 +4623,7 @@
|
|
|
4540
4623
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4541
4624
|
*/
|
|
4542
4625
|
|
|
4626
|
+
|
|
4543
4627
|
const PROPERTY_NAME_FILENAME = "filename";
|
|
4544
4628
|
const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
|
|
4545
4629
|
const PROPERTY_NAME_COMMENT = "comment";
|
|
@@ -4664,6 +4748,38 @@
|
|
|
4664
4748
|
|
|
4665
4749
|
}
|
|
4666
4750
|
|
|
4751
|
+
const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
|
|
4752
|
+
EXTRAFIELD_TYPE_ZIP64,
|
|
4753
|
+
EXTRAFIELD_TYPE_AES,
|
|
4754
|
+
EXTRAFIELD_TYPE_NTFS,
|
|
4755
|
+
EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
|
|
4756
|
+
EXTRAFIELD_TYPE_UNICODE_PATH,
|
|
4757
|
+
EXTRAFIELD_TYPE_UNICODE_COMMENT,
|
|
4758
|
+
EXTRAFIELD_TYPE_USDZ,
|
|
4759
|
+
EXTRAFIELD_TYPE_INFOZIP,
|
|
4760
|
+
EXTRAFIELD_TYPE_UNIX,
|
|
4761
|
+
EXTRAFIELD_TYPE_UNIX_TYPE1,
|
|
4762
|
+
EXTRAFIELD_TYPE_PKWARE_UNIX
|
|
4763
|
+
]);
|
|
4764
|
+
|
|
4765
|
+
function getUserExtraField(extraField) {
|
|
4766
|
+
if (extraField) {
|
|
4767
|
+
const userExtraField = new Map();
|
|
4768
|
+
extraField.forEach((field, type) => {
|
|
4769
|
+
if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
|
|
4770
|
+
userExtraField.set(type, field.data);
|
|
4771
|
+
}
|
|
4772
|
+
});
|
|
4773
|
+
if (userExtraField.size) {
|
|
4774
|
+
return userExtraField;
|
|
4775
|
+
}
|
|
4776
|
+
}
|
|
4777
|
+
}
|
|
4778
|
+
|
|
4779
|
+
function getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength) {
|
|
4780
|
+
return encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
4781
|
+
}
|
|
4782
|
+
|
|
4667
4783
|
/*
|
|
4668
4784
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4669
4785
|
|
|
@@ -4723,6 +4839,8 @@
|
|
|
4723
4839
|
const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
|
|
4724
4840
|
const WARNING_DUPLICATE_FILENAME = "duplicate filename";
|
|
4725
4841
|
const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
|
|
4842
|
+
const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
|
|
4843
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = "mismatched local file header (filename)";
|
|
4726
4844
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
|
|
4727
4845
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
|
|
4728
4846
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
@@ -4793,7 +4911,7 @@
|
|
|
4793
4911
|
}
|
|
4794
4912
|
}
|
|
4795
4913
|
if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
|
|
4796
|
-
throwAmbiguousArchive(
|
|
4914
|
+
throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
|
|
4797
4915
|
}
|
|
4798
4916
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
4799
4917
|
let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
|
|
@@ -5091,7 +5209,8 @@
|
|
|
5091
5209
|
const writer = new TransformStream();
|
|
5092
5210
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5093
5211
|
arrayBufferPromise.catch(() => { });
|
|
5094
|
-
await fileEntry.getData(writer, entry, zipReader.readRanges,
|
|
5212
|
+
await fileEntry.getData(writer, entry, zipReader.readRanges,
|
|
5213
|
+
Object.assign({}, options, { preventClose: false }));
|
|
5095
5214
|
return arrayBufferPromise;
|
|
5096
5215
|
};
|
|
5097
5216
|
offset = endOffset;
|
|
@@ -5172,49 +5291,101 @@
|
|
|
5172
5291
|
await reader.readable.cancel();
|
|
5173
5292
|
}
|
|
5174
5293
|
}
|
|
5294
|
+
|
|
5295
|
+
[SYMBOL_ASYNC_DISPOSE]() {
|
|
5296
|
+
return this.close();
|
|
5297
|
+
}
|
|
5175
5298
|
}
|
|
5176
5299
|
|
|
5177
5300
|
class ZipReaderStream {
|
|
5178
5301
|
|
|
5179
5302
|
constructor(options = {}) {
|
|
5180
|
-
|
|
5181
|
-
const
|
|
5303
|
+
let sourceController;
|
|
5304
|
+
const { readable, writable } = new TransformStream({
|
|
5305
|
+
start(controller) {
|
|
5306
|
+
sourceController = controller;
|
|
5307
|
+
}
|
|
5308
|
+
});
|
|
5309
|
+
const zipReader = new ZipReader(readable, options);
|
|
5310
|
+
const gen = zipReader.getEntriesGenerator();
|
|
5311
|
+
const pendingEntries = new Set();
|
|
5182
5312
|
this.readable = new ReadableStream({
|
|
5183
5313
|
async pull(controller) {
|
|
5184
5314
|
const { done, value } = await gen.next();
|
|
5185
5315
|
if (done)
|
|
5186
5316
|
return controller.close();
|
|
5187
|
-
const
|
|
5188
|
-
const { readable, writable } = new TransformStream();
|
|
5189
|
-
if (value.getData) {
|
|
5190
|
-
getData();
|
|
5191
|
-
return readable;
|
|
5192
|
-
}
|
|
5193
|
-
|
|
5194
|
-
async function getData() {
|
|
5195
|
-
try {
|
|
5196
|
-
await value.getData(writable);
|
|
5197
|
-
} catch (error) {
|
|
5198
|
-
try {
|
|
5199
|
-
await writable.abort(error);
|
|
5200
|
-
} catch {
|
|
5201
|
-
// ignored
|
|
5202
|
-
}
|
|
5203
|
-
}
|
|
5204
|
-
}
|
|
5205
|
-
})();
|
|
5317
|
+
const entryStream = createEntryStream(value, pendingEntries);
|
|
5206
5318
|
const chunk = {
|
|
5207
5319
|
...value,
|
|
5208
|
-
readable:
|
|
5320
|
+
readable: entryStream.readable
|
|
5209
5321
|
};
|
|
5210
5322
|
delete chunk.getData;
|
|
5323
|
+
Object.defineProperties(chunk, {
|
|
5324
|
+
localDirectory: {
|
|
5325
|
+
get: () => value.localDirectory,
|
|
5326
|
+
enumerable: true
|
|
5327
|
+
},
|
|
5328
|
+
warnings: {
|
|
5329
|
+
get: () => value.warnings,
|
|
5330
|
+
enumerable: true
|
|
5331
|
+
}
|
|
5332
|
+
});
|
|
5211
5333
|
controller.enqueue(chunk);
|
|
5334
|
+
},
|
|
5335
|
+
async cancel(reason) {
|
|
5336
|
+
const entryStreams = Array.from(pendingEntries);
|
|
5337
|
+
pendingEntries.clear();
|
|
5338
|
+
sourceController.error(reason);
|
|
5339
|
+
await Promise.allSettled(entryStreams.map(entryStream => entryStream.cancel(reason)));
|
|
5340
|
+
await Promise.allSettled([gen.return(), zipReader.close()]);
|
|
5212
5341
|
}
|
|
5213
5342
|
});
|
|
5214
5343
|
this.writable = writable;
|
|
5215
5344
|
}
|
|
5216
5345
|
}
|
|
5217
5346
|
|
|
5347
|
+
function createEntryStream(entry, pendingEntries) {
|
|
5348
|
+
const { readable, writable } = new TransformStream();
|
|
5349
|
+
let dataReader;
|
|
5350
|
+
const entryStream = {
|
|
5351
|
+
cancel: async reason => {
|
|
5352
|
+
pendingEntries.delete(entryStream);
|
|
5353
|
+
await (dataReader ? dataReader.cancel(reason) : readable.cancel(reason));
|
|
5354
|
+
}
|
|
5355
|
+
};
|
|
5356
|
+
entryStream.readable = new ReadableStream({
|
|
5357
|
+
async pull(controller) {
|
|
5358
|
+
if (!dataReader) {
|
|
5359
|
+
dataReader = readable.getReader();
|
|
5360
|
+
pendingEntries.add(entryStream);
|
|
5361
|
+
getData();
|
|
5362
|
+
}
|
|
5363
|
+
const { done, value } = await dataReader.read();
|
|
5364
|
+
if (done) {
|
|
5365
|
+
controller.close();
|
|
5366
|
+
} else {
|
|
5367
|
+
controller.enqueue(value);
|
|
5368
|
+
}
|
|
5369
|
+
},
|
|
5370
|
+
cancel: reason => entryStream.cancel(reason)
|
|
5371
|
+
}, { highWaterMark: 0 });
|
|
5372
|
+
return entryStream;
|
|
5373
|
+
|
|
5374
|
+
async function getData() {
|
|
5375
|
+
try {
|
|
5376
|
+
await entry.getData(writable, { preventClose: false });
|
|
5377
|
+
} catch (error) {
|
|
5378
|
+
try {
|
|
5379
|
+
await writable.abort(error);
|
|
5380
|
+
} catch {
|
|
5381
|
+
// ignored
|
|
5382
|
+
}
|
|
5383
|
+
} finally {
|
|
5384
|
+
pendingEntries.delete(entryStream);
|
|
5385
|
+
}
|
|
5386
|
+
}
|
|
5387
|
+
}
|
|
5388
|
+
|
|
5218
5389
|
async function isZipFile(reader, options = {}) {
|
|
5219
5390
|
reader = new GenericReader(reader);
|
|
5220
5391
|
await initStream(reader);
|
|
@@ -5274,7 +5445,9 @@
|
|
|
5274
5445
|
const dataView = getDataView(dataArray);
|
|
5275
5446
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
5276
5447
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
5277
|
-
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
5448
|
+
const passThrough = checkPassThroughOption(getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH));
|
|
5449
|
+
const passThroughCompression = Boolean(passThrough);
|
|
5450
|
+
const passThroughEncryption = passThrough === true;
|
|
5278
5451
|
checkPasswordOption(password, rawPassword);
|
|
5279
5452
|
password = password && password.length && password;
|
|
5280
5453
|
rawPassword = rawPassword && rawPassword.length && rawPassword;
|
|
@@ -5295,7 +5468,9 @@
|
|
|
5295
5468
|
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5296
5469
|
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5297
5470
|
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
5298
|
-
const
|
|
5471
|
+
const checkLocalFilenameOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_FILENAME);
|
|
5472
|
+
const checkLocalFilename = getCheckLocalFilename(
|
|
5473
|
+
checkLocalFilenameOption === UNDEFINED_VALUE ? checkLocalDirectoryOption : checkLocalFilenameOption, entryStrictness);
|
|
5299
5474
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
5300
5475
|
if (checkLocalFilename && (filenameLength || extraFieldLength)) {
|
|
5301
5476
|
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
@@ -5326,16 +5501,17 @@
|
|
|
5326
5501
|
if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
|
|
5327
5502
|
fileEntry.gid = gid;
|
|
5328
5503
|
}
|
|
5329
|
-
const
|
|
5504
|
+
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5505
|
+
const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
|
|
5330
5506
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
5331
|
-
if (!
|
|
5507
|
+
if (!passThroughEncryption) {
|
|
5332
5508
|
fileEntry.zipCrypto = zipCrypto;
|
|
5333
5509
|
}
|
|
5334
5510
|
if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
|
|
5335
5511
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
|
|
5336
5512
|
}
|
|
5337
|
-
const registeredCodec =
|
|
5338
|
-
if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !
|
|
5513
|
+
const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
5514
|
+
if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThroughCompression) {
|
|
5339
5515
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
5340
5516
|
}
|
|
5341
5517
|
if (encrypted) {
|
|
@@ -5352,15 +5528,16 @@
|
|
|
5352
5528
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5353
5529
|
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5354
5530
|
throwIfAborted(signal);
|
|
5355
|
-
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5356
5531
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
5357
5532
|
const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
|
|
5358
5533
|
if (checkOverlappingEntryOnly) {
|
|
5359
5534
|
checkOverlappingEntry = true;
|
|
5360
5535
|
}
|
|
5361
5536
|
const { onstart, onprogress, onend } = options;
|
|
5362
|
-
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !
|
|
5363
|
-
const outputSize =
|
|
5537
|
+
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThroughCompression;
|
|
5538
|
+
const outputSize = passThroughCompression ?
|
|
5539
|
+
compressedSize - getEncryptionOverhead(encrypted, zipCrypto, extraFieldAES && extraFieldAES.strength) :
|
|
5540
|
+
uncompressedSize;
|
|
5364
5541
|
const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
|
|
5365
5542
|
let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5366
5543
|
if (deflate64) {
|
|
@@ -5369,7 +5546,7 @@
|
|
|
5369
5546
|
const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
|
|
5370
5547
|
const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
|
|
5371
5548
|
getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
|
|
5372
|
-
checkCrc32Option) && !
|
|
5549
|
+
checkCrc32Option) && !passThroughCompression &&
|
|
5373
5550
|
(!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
|
|
5374
5551
|
const workerOptions = {
|
|
5375
5552
|
options: {
|
|
@@ -5423,10 +5600,10 @@
|
|
|
5423
5600
|
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5424
5601
|
({ writable } = writer);
|
|
5425
5602
|
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5426
|
-
writer.size += writtenSize;
|
|
5427
5603
|
if (writtenSize != outputSize) {
|
|
5428
|
-
throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
5604
|
+
throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
|
|
5429
5605
|
}
|
|
5606
|
+
writer.size += writtenSize;
|
|
5430
5607
|
}
|
|
5431
5608
|
} catch (error) {
|
|
5432
5609
|
if (error.outputSize !== UNDEFINED_VALUE) {
|
|
@@ -6092,7 +6269,7 @@
|
|
|
6092
6269
|
if (checkLocalFilename && !maskedLocalDirectory &&
|
|
6093
6270
|
(rawLocalFilename.length != rawFilename.length ||
|
|
6094
6271
|
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
6095
|
-
reportAmbiguity(reject, warnings,
|
|
6272
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
|
|
6096
6273
|
}
|
|
6097
6274
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
6098
6275
|
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
|
|
@@ -6117,16 +6294,6 @@
|
|
|
6117
6294
|
}
|
|
6118
6295
|
}
|
|
6119
6296
|
|
|
6120
|
-
function addWarning(warnings, reason, filename) {
|
|
6121
|
-
if (!warnings.some(warning => warning.reason == reason)) {
|
|
6122
|
-
const warning = { reason };
|
|
6123
|
-
if (filename !== UNDEFINED_VALUE) {
|
|
6124
|
-
warning.filename = filename;
|
|
6125
|
-
}
|
|
6126
|
-
warnings.push(warning);
|
|
6127
|
-
}
|
|
6128
|
-
}
|
|
6129
|
-
|
|
6130
6297
|
function throwAmbiguousArchive(reason) {
|
|
6131
6298
|
const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
|
|
6132
6299
|
error.reason = reason;
|
|
@@ -6206,7 +6373,9 @@
|
|
|
6206
6373
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
|
|
6207
6374
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
|
|
6208
6375
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
|
|
6376
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
|
|
6209
6377
|
WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
|
|
6378
|
+
WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
|
|
6210
6379
|
WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
|
|
6211
6380
|
WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
|
|
6212
6381
|
WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
|
|
@@ -6259,7 +6428,7 @@
|
|
|
6259
6428
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
6260
6429
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
6261
6430
|
const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
|
|
6262
|
-
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
6431
|
+
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set to true (use 'compressed' instead)";
|
|
6263
6432
|
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
6264
6433
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
6265
6434
|
const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
|
|
@@ -6271,6 +6440,7 @@
|
|
|
6271
6440
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
6272
6441
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
6273
6442
|
const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
|
|
6443
|
+
const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
|
|
6274
6444
|
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
6275
6445
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
6276
6446
|
const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
|
|
@@ -6284,14 +6454,21 @@
|
|
|
6284
6454
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
6285
6455
|
const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
|
|
6286
6456
|
const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
6457
|
+
const ERR_INVALID_ENTRY = "Invalid entry option (must be an entry returned by ZipReader#getEntries())";
|
|
6458
|
+
const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
|
|
6459
|
+
const WARNING_COMPRESSION_UNAVAILABLE = "compression unavailable";
|
|
6460
|
+
const WARNING_CLAMPED_LAST_MODIFICATION_DATE = "clamped last modification date";
|
|
6287
6461
|
|
|
6288
6462
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
6289
6463
|
const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
|
|
6290
6464
|
const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
|
|
6291
6465
|
const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
|
|
6466
|
+
const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
|
|
6467
|
+
const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
|
|
6292
6468
|
const VENDOR_VERSION_AE_1 = 1;
|
|
6293
6469
|
const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
|
|
6294
6470
|
const UNIX_EXTRA_FIELD_TYPE = "unix";
|
|
6471
|
+
const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
|
|
6295
6472
|
const MAX_LEVEL = 9;
|
|
6296
6473
|
|
|
6297
6474
|
let workers = 0;
|
|
@@ -6318,9 +6495,11 @@
|
|
|
6318
6495
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
6319
6496
|
pendingAddFileCalls: new Set(),
|
|
6320
6497
|
pendingErrors: [],
|
|
6498
|
+
warnings: [],
|
|
6321
6499
|
bufferedWrites: 0,
|
|
6322
6500
|
directWrites: 0,
|
|
6323
|
-
lastFileEntry: UNDEFINED_VALUE
|
|
6501
|
+
lastFileEntry: UNDEFINED_VALUE,
|
|
6502
|
+
archiveClosed: false
|
|
6324
6503
|
});
|
|
6325
6504
|
}
|
|
6326
6505
|
|
|
@@ -6485,6 +6664,9 @@
|
|
|
6485
6664
|
const zipWriter = this;
|
|
6486
6665
|
const { pendingAddFileCalls, writer } = this;
|
|
6487
6666
|
const { writable } = writer;
|
|
6667
|
+
if (zipWriter.archiveClosed) {
|
|
6668
|
+
return getWriterData(writer);
|
|
6669
|
+
}
|
|
6488
6670
|
if (!(comment instanceof Uint8Array)) {
|
|
6489
6671
|
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
6490
6672
|
}
|
|
@@ -6508,11 +6690,16 @@
|
|
|
6508
6690
|
throw error;
|
|
6509
6691
|
}
|
|
6510
6692
|
await closeFile(zipWriter, comment, options);
|
|
6693
|
+
zipWriter.archiveClosed = true;
|
|
6511
6694
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
6512
6695
|
if (!preventClose) {
|
|
6513
6696
|
await writable.getWriter().close();
|
|
6514
6697
|
}
|
|
6515
|
-
return writer
|
|
6698
|
+
return getWriterData(writer);
|
|
6699
|
+
}
|
|
6700
|
+
|
|
6701
|
+
[SYMBOL_ASYNC_DISPOSE]() {
|
|
6702
|
+
return this.close();
|
|
6516
6703
|
}
|
|
6517
6704
|
}
|
|
6518
6705
|
|
|
@@ -6591,6 +6778,10 @@
|
|
|
6591
6778
|
}
|
|
6592
6779
|
}
|
|
6593
6780
|
|
|
6781
|
+
function getWriterData(writer) {
|
|
6782
|
+
return writer.getData ? writer.getData() : writer.writable;
|
|
6783
|
+
}
|
|
6784
|
+
|
|
6594
6785
|
function watchPromiseError(zipWriter, promise) {
|
|
6595
6786
|
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
6596
6787
|
const watcher = {};
|
|
@@ -6609,6 +6800,14 @@
|
|
|
6609
6800
|
|
|
6610
6801
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
6611
6802
|
options = Object.assign({}, options);
|
|
6803
|
+
const entry = options[OPTION_ENTRY];
|
|
6804
|
+
if (entry !== UNDEFINED_VALUE) {
|
|
6805
|
+
const { entryOptions, passThroughOptions } = getSourceEntryOptions(entry,
|
|
6806
|
+
checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH)),
|
|
6807
|
+
getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE));
|
|
6808
|
+
delete options[OPTION_ENTRY];
|
|
6809
|
+
options = Object.assign(entryOptions, passThroughOptions, options);
|
|
6810
|
+
}
|
|
6612
6811
|
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6613
6812
|
name += DIRECTORY_SIGNATURE;
|
|
6614
6813
|
}
|
|
@@ -6673,21 +6872,33 @@
|
|
|
6673
6872
|
try {
|
|
6674
6873
|
const { resolvedOptions } = metadataInfo;
|
|
6675
6874
|
if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
|
|
6676
|
-
!resolvedOptions.
|
|
6875
|
+
!resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
|
|
6677
6876
|
resolvedOptions.level = 0;
|
|
6877
|
+
addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
|
|
6678
6878
|
}
|
|
6679
6879
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
6680
6880
|
({ reader } = sizesInfo);
|
|
6681
6881
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
6682
6882
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
6883
|
+
let crc32 = options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32;
|
|
6884
|
+
const storesAE2 = sizesInfo.resolvedOptions.encrypted && !resolvedOptions.zipCrypto;
|
|
6885
|
+
if (resolvedOptions.passThroughCompression && !resolvedOptions.passThroughEncryption && storesAE2) {
|
|
6886
|
+
crc32 = UNDEFINED_VALUE;
|
|
6887
|
+
}
|
|
6888
|
+
if (resolvedOptions.passThroughCompression && reader && !storesAE2 && crc32 === UNDEFINED_VALUE) {
|
|
6889
|
+
throw new Error(ERR_UNDEFINED_CRC32);
|
|
6890
|
+
}
|
|
6683
6891
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
6684
6892
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
6685
|
-
crc32
|
|
6893
|
+
crc32,
|
|
6686
6894
|
offset: zipWriter.offset - diskOffset,
|
|
6687
6895
|
diskNumberStart: diskNumber,
|
|
6688
6896
|
[OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
|
|
6689
6897
|
});
|
|
6690
6898
|
const headerInfo = getHeaderInfo(options);
|
|
6899
|
+
if (headerInfo.lastModDateClamped) {
|
|
6900
|
+
addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
|
|
6901
|
+
}
|
|
6691
6902
|
const dataDescriptorInfo = getDataDescriptorInfo(options);
|
|
6692
6903
|
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
6693
6904
|
fileEntry = await getFileEntry(zipWriter, name, reader, {
|
|
@@ -6714,6 +6925,95 @@
|
|
|
6714
6925
|
return new Entry(fileEntry);
|
|
6715
6926
|
}
|
|
6716
6927
|
|
|
6928
|
+
function getSourceEntryOptions(entry, passThrough, lastModDateOverride) {
|
|
6929
|
+
if (entry === null || typeof entry != OBJECT_TYPE || Array.isArray(entry)) {
|
|
6930
|
+
throw new Error(ERR_INVALID_ENTRY);
|
|
6931
|
+
}
|
|
6932
|
+
const {
|
|
6933
|
+
externalFileAttributes,
|
|
6934
|
+
versionMadeBy,
|
|
6935
|
+
comment,
|
|
6936
|
+
lastModDate,
|
|
6937
|
+
rawLastModDate,
|
|
6938
|
+
creationDate,
|
|
6939
|
+
lastAccessDate,
|
|
6940
|
+
uncompressedSize,
|
|
6941
|
+
encrypted,
|
|
6942
|
+
zipCrypto,
|
|
6943
|
+
crc32,
|
|
6944
|
+
compressionMethod,
|
|
6945
|
+
extraFieldAES,
|
|
6946
|
+
extraFieldUnix,
|
|
6947
|
+
internalFileAttributes,
|
|
6948
|
+
extraField,
|
|
6949
|
+
bitFlag,
|
|
6950
|
+
directory,
|
|
6951
|
+
uid,
|
|
6952
|
+
gid
|
|
6953
|
+
} = entry;
|
|
6954
|
+
const entryOptions = {
|
|
6955
|
+
externalFileAttributes,
|
|
6956
|
+
versionMadeBy,
|
|
6957
|
+
comment,
|
|
6958
|
+
lastModDate,
|
|
6959
|
+
creationDate,
|
|
6960
|
+
lastAccessDate,
|
|
6961
|
+
internalFileAttributes,
|
|
6962
|
+
directory
|
|
6963
|
+
};
|
|
6964
|
+
if (bitFlag && bitFlag.languageEncodingFlag) {
|
|
6965
|
+
entryOptions[OPTION_USE_UNICODE_FILE_NAMES] = true;
|
|
6966
|
+
}
|
|
6967
|
+
const userExtraField = getUserExtraField(extraField);
|
|
6968
|
+
if (userExtraField) {
|
|
6969
|
+
entryOptions[PROPERTY_NAME_EXTRA_FIELD] = userExtraField;
|
|
6970
|
+
}
|
|
6971
|
+
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
6972
|
+
Object.assign(entryOptions, {
|
|
6973
|
+
uid,
|
|
6974
|
+
gid,
|
|
6975
|
+
unixExtraFieldType: extraFieldUnix ? UNIX_EXTRA_FIELD_TYPE : INFOZIP_EXTRA_FIELD_TYPE
|
|
6976
|
+
});
|
|
6977
|
+
}
|
|
6978
|
+
const passThroughOptions = {};
|
|
6979
|
+
if (passThrough && !directory) {
|
|
6980
|
+
Object.assign(passThroughOptions, {
|
|
6981
|
+
uncompressedSize,
|
|
6982
|
+
crc32,
|
|
6983
|
+
compressionMethod
|
|
6984
|
+
});
|
|
6985
|
+
if (passThrough !== PASS_THROUGH_COMPRESSED) {
|
|
6986
|
+
Object.assign(passThroughOptions, {
|
|
6987
|
+
encrypted,
|
|
6988
|
+
zipCrypto,
|
|
6989
|
+
encryptionStrength: extraFieldAES ? extraFieldAES.strength : UNDEFINED_VALUE
|
|
6990
|
+
});
|
|
6991
|
+
}
|
|
6992
|
+
if (bitFlag) {
|
|
6993
|
+
passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
|
|
6994
|
+
passThroughOptions[OPTION_LEVEL] = LEVEL_BY_BITFLAG_LEVEL[bitFlag.level];
|
|
6995
|
+
}
|
|
6996
|
+
if (lastModDateOverride === UNDEFINED_VALUE) {
|
|
6997
|
+
passThroughOptions.rawLastModDate = rawLastModDate;
|
|
6998
|
+
} else if (passThrough !== PASS_THROUGH_COMPRESSED && zipCrypto && (!bitFlag || bitFlag.dataDescriptor) &&
|
|
6999
|
+
lastModDateOverride instanceof Date &&
|
|
7000
|
+
getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
|
|
7001
|
+
throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
|
|
7002
|
+
}
|
|
7003
|
+
}
|
|
7004
|
+
return { entryOptions, passThroughOptions };
|
|
7005
|
+
}
|
|
7006
|
+
|
|
7007
|
+
function getDosTimeHighByte(lastModDate) {
|
|
7008
|
+
let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
7009
|
+
if (dosLastModDate < MIN_DATE) {
|
|
7010
|
+
dosLastModDate = MIN_DATE;
|
|
7011
|
+
} else if (dosLastModDate > MAX_DATE) {
|
|
7012
|
+
dosLastModDate = MAX_DATE;
|
|
7013
|
+
}
|
|
7014
|
+
return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
|
|
7015
|
+
}
|
|
7016
|
+
|
|
6717
7017
|
function resolveAttributes(zipWriter, name, options) {
|
|
6718
7018
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
6719
7019
|
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
@@ -6867,7 +7167,9 @@
|
|
|
6867
7167
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6868
7168
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6869
7169
|
const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
6870
|
-
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
7170
|
+
const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
|
|
7171
|
+
const passThroughCompression = Boolean(passThrough);
|
|
7172
|
+
const passThroughEncryption = passThrough === true;
|
|
6871
7173
|
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
6872
7174
|
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
6873
7175
|
checkPasswordOption(password, rawPassword);
|
|
@@ -6883,10 +7185,11 @@
|
|
|
6883
7185
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
6884
7186
|
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
6885
7187
|
throwIfAborted(signal);
|
|
6886
|
-
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
|
|
7188
|
+
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
|
|
7189
|
+
!isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
|
|
6887
7190
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
6888
|
-
const registeredCodec =
|
|
6889
|
-
if (!
|
|
7191
|
+
const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
7192
|
+
if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
|
|
6890
7193
|
compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
|
|
6891
7194
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
6892
7195
|
}
|
|
@@ -6900,15 +7203,15 @@
|
|
|
6900
7203
|
level = 0;
|
|
6901
7204
|
}
|
|
6902
7205
|
}
|
|
6903
|
-
if (
|
|
6904
|
-
level =
|
|
7206
|
+
if (passThroughCompression) {
|
|
7207
|
+
level = toNumber(options[OPTION_LEVEL]);
|
|
6905
7208
|
}
|
|
6906
7209
|
let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
|
|
6907
7210
|
let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
|
|
6908
7211
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
6909
7212
|
dataDescriptor = false;
|
|
6910
7213
|
}
|
|
6911
|
-
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !
|
|
7214
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
|
|
6912
7215
|
dataDescriptor = true;
|
|
6913
7216
|
}
|
|
6914
7217
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -6932,7 +7235,8 @@
|
|
|
6932
7235
|
lastAccessDate,
|
|
6933
7236
|
creationDate,
|
|
6934
7237
|
internalFileAttributes,
|
|
6935
|
-
|
|
7238
|
+
passThroughCompression,
|
|
7239
|
+
passThroughEncryption,
|
|
6936
7240
|
password,
|
|
6937
7241
|
rawPassword,
|
|
6938
7242
|
encryptionStrength,
|
|
@@ -6993,7 +7297,7 @@
|
|
|
6993
7297
|
}
|
|
6994
7298
|
|
|
6995
7299
|
async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
|
|
6996
|
-
if (metadata.
|
|
7300
|
+
if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
|
|
6997
7301
|
throw new Error(ERR_UNDEFINED_READER);
|
|
6998
7302
|
}
|
|
6999
7303
|
let contentSize;
|
|
@@ -7009,12 +7313,12 @@
|
|
|
7009
7313
|
}
|
|
7010
7314
|
|
|
7011
7315
|
function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
|
|
7012
|
-
const {
|
|
7316
|
+
const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
|
|
7013
7317
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
7014
7318
|
let maximumCompressedSize = 0;
|
|
7015
7319
|
let uncompressedSize = 0;
|
|
7016
7320
|
let unknownSize = false;
|
|
7017
|
-
if (
|
|
7321
|
+
if (passThroughCompression && hasContent) {
|
|
7018
7322
|
uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
|
|
7019
7323
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
7020
7324
|
throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
|
|
@@ -7025,17 +7329,17 @@
|
|
|
7025
7329
|
}
|
|
7026
7330
|
const zip64Enabled = zip64 === true;
|
|
7027
7331
|
const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
|
|
7028
|
-
if (hasContent &&
|
|
7332
|
+
if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
|
|
7029
7333
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
|
|
7030
7334
|
}
|
|
7031
|
-
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (
|
|
7335
|
+
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThroughEncryption && encrypted));
|
|
7032
7336
|
if (!hasContent) {
|
|
7033
7337
|
level = 0;
|
|
7034
7338
|
compressionMethod = COMPRESSION_METHOD_STORE;
|
|
7035
7339
|
}
|
|
7036
|
-
const encryptionOverhead = encryptedEntry
|
|
7340
|
+
const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
|
|
7037
7341
|
if (hasContent) {
|
|
7038
|
-
if (!
|
|
7342
|
+
if (!passThroughCompression) {
|
|
7039
7343
|
if (contentSize === UNDEFINED_VALUE) {
|
|
7040
7344
|
dataDescriptor = true;
|
|
7041
7345
|
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
@@ -7048,10 +7352,12 @@
|
|
|
7048
7352
|
}
|
|
7049
7353
|
} else {
|
|
7050
7354
|
options.uncompressedSize = uncompressedSize;
|
|
7051
|
-
maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
|
|
7355
|
+
maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
|
|
7356
|
+
getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
|
|
7357
|
+
contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
|
|
7052
7358
|
}
|
|
7053
7359
|
}
|
|
7054
|
-
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !
|
|
7360
|
+
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
|
|
7055
7361
|
if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
7056
7362
|
dataDescriptor = false;
|
|
7057
7363
|
}
|
|
@@ -7258,6 +7564,7 @@
|
|
|
7258
7564
|
localExtraFieldZip64Length,
|
|
7259
7565
|
rawExtraFieldExtendedTimestamp,
|
|
7260
7566
|
extraFieldExtendedTimestampFlag,
|
|
7567
|
+
extraFieldExtendedTimestampTime,
|
|
7261
7568
|
rawExtraFieldNTFS,
|
|
7262
7569
|
rawExtraFieldUnix,
|
|
7263
7570
|
rawExtraFieldAES,
|
|
@@ -7270,6 +7577,7 @@
|
|
|
7270
7577
|
password,
|
|
7271
7578
|
rawPassword,
|
|
7272
7579
|
level,
|
|
7580
|
+
useUnicodeFileNames,
|
|
7273
7581
|
zip64,
|
|
7274
7582
|
zip64Enabled,
|
|
7275
7583
|
zip64UncompressedSize,
|
|
@@ -7304,7 +7612,8 @@
|
|
|
7304
7612
|
msdosAttributesRaw,
|
|
7305
7613
|
msdosAttributes,
|
|
7306
7614
|
useCompressionStream,
|
|
7307
|
-
|
|
7615
|
+
passThroughCompression,
|
|
7616
|
+
passThroughEncryption,
|
|
7308
7617
|
format,
|
|
7309
7618
|
codecURI
|
|
7310
7619
|
} = options;
|
|
@@ -7315,9 +7624,9 @@
|
|
|
7315
7624
|
zip64Enabled,
|
|
7316
7625
|
directory: Boolean(directory),
|
|
7317
7626
|
executable: Boolean(executable),
|
|
7318
|
-
filenameUTF8:
|
|
7627
|
+
filenameUTF8: Boolean(useUnicodeFileNames),
|
|
7319
7628
|
rawFilename,
|
|
7320
|
-
commentUTF8:
|
|
7629
|
+
commentUTF8: Boolean(useUnicodeFileNames),
|
|
7321
7630
|
rawComment,
|
|
7322
7631
|
rawExtraFieldZip64,
|
|
7323
7632
|
localExtraFieldZip64Length,
|
|
@@ -7348,7 +7657,7 @@
|
|
|
7348
7657
|
uncompressedSize
|
|
7349
7658
|
} = options;
|
|
7350
7659
|
let compressedSize = 0;
|
|
7351
|
-
if (!
|
|
7660
|
+
if (!passThroughCompression) {
|
|
7352
7661
|
uncompressedSize = 0;
|
|
7353
7662
|
}
|
|
7354
7663
|
const { writable } = writer;
|
|
@@ -7365,9 +7674,9 @@
|
|
|
7365
7674
|
encryptionStrength,
|
|
7366
7675
|
zipCrypto: encrypted && zipCrypto,
|
|
7367
7676
|
passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
|
|
7368
|
-
computeCrc32: !
|
|
7369
|
-
compressed: compressed && !
|
|
7370
|
-
encrypted: encrypted && !
|
|
7677
|
+
computeCrc32: !passThroughCompression,
|
|
7678
|
+
compressed: compressed && !passThroughCompression,
|
|
7679
|
+
encrypted: encrypted && !passThroughEncryption,
|
|
7371
7680
|
useWebWorkers,
|
|
7372
7681
|
useCompressionStream,
|
|
7373
7682
|
transferStreams,
|
|
@@ -7382,7 +7691,7 @@
|
|
|
7382
7691
|
const result = await runWorker({ readable, writable }, workerOptions);
|
|
7383
7692
|
compressedSize = result.outputSize;
|
|
7384
7693
|
writer.size += compressedSize;
|
|
7385
|
-
if (!
|
|
7694
|
+
if (!passThroughCompression) {
|
|
7386
7695
|
uncompressedSize = result.inputSize;
|
|
7387
7696
|
if (!encrypted || zipCrypto) {
|
|
7388
7697
|
crc32 = result.crc32;
|
|
@@ -7425,8 +7734,9 @@
|
|
|
7425
7734
|
headerArray,
|
|
7426
7735
|
headerView,
|
|
7427
7736
|
signature: crc32,
|
|
7428
|
-
crc32: encrypted && !zipCrypto && !
|
|
7737
|
+
crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
|
|
7429
7738
|
extraFieldExtendedTimestampFlag,
|
|
7739
|
+
extraFieldExtendedTimestampTime,
|
|
7430
7740
|
zip64UncompressedSize,
|
|
7431
7741
|
zip64CompressedSize
|
|
7432
7742
|
});
|
|
@@ -7451,7 +7761,7 @@
|
|
|
7451
7761
|
encryptionStrength,
|
|
7452
7762
|
extendedTimestamp,
|
|
7453
7763
|
ntfsTimestamp,
|
|
7454
|
-
|
|
7764
|
+
passThroughCompression,
|
|
7455
7765
|
encrypted,
|
|
7456
7766
|
zip64UncompressedSize,
|
|
7457
7767
|
zip64CompressedSize,
|
|
@@ -7462,7 +7772,7 @@
|
|
|
7462
7772
|
let { version, compressionMethod } = options;
|
|
7463
7773
|
const compressed = !directory && isCompressed(compressionMethod, level);
|
|
7464
7774
|
let rawLocalExtraFieldZip64;
|
|
7465
|
-
const uncompressedFile =
|
|
7775
|
+
const uncompressedFile = passThroughCompression || !compressed;
|
|
7466
7776
|
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
|
|
7467
7777
|
const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
|
|
7468
7778
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
@@ -7474,8 +7784,8 @@
|
|
|
7474
7784
|
if (zip64ExtraFieldComplete) {
|
|
7475
7785
|
extraFieldZip64.writeUint64(uncompressedSize);
|
|
7476
7786
|
if (uncompressedFile) {
|
|
7477
|
-
const encryptionOverhead = encrypted
|
|
7478
|
-
extraFieldZip64.writeUint64(
|
|
7787
|
+
const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
|
|
7788
|
+
extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
|
|
7479
7789
|
}
|
|
7480
7790
|
}
|
|
7481
7791
|
} else {
|
|
@@ -7494,6 +7804,7 @@
|
|
|
7494
7804
|
let rawExtraFieldNTFS;
|
|
7495
7805
|
let rawExtraFieldExtendedTimestamp;
|
|
7496
7806
|
let extraFieldExtendedTimestampFlag;
|
|
7807
|
+
let extraFieldExtendedTimestampTime;
|
|
7497
7808
|
if (extendedTimestamp) {
|
|
7498
7809
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
7499
7810
|
const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
|
|
@@ -7501,6 +7812,7 @@
|
|
|
7501
7812
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
7502
7813
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
7503
7814
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
7815
|
+
extraFieldExtendedTimestampTime = lastModTimeUnix;
|
|
7504
7816
|
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7505
7817
|
extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
|
|
7506
7818
|
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
@@ -7584,7 +7896,7 @@
|
|
|
7584
7896
|
}
|
|
7585
7897
|
if (encrypted && !zipCrypto) {
|
|
7586
7898
|
version = version > VERSION_AES ? version : VERSION_AES;
|
|
7587
|
-
if (
|
|
7899
|
+
if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
|
|
7588
7900
|
rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
|
|
7589
7901
|
}
|
|
7590
7902
|
setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
|
|
@@ -7646,12 +7958,14 @@
|
|
|
7646
7958
|
headerArray,
|
|
7647
7959
|
headerView,
|
|
7648
7960
|
lastModDate: storedLastModDate,
|
|
7961
|
+
lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
|
|
7649
7962
|
rawLastModDate,
|
|
7650
7963
|
encrypted,
|
|
7651
7964
|
compressed,
|
|
7652
7965
|
version,
|
|
7653
7966
|
compressionMethod,
|
|
7654
7967
|
extraFieldExtendedTimestampFlag,
|
|
7968
|
+
extraFieldExtendedTimestampTime,
|
|
7655
7969
|
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
7656
7970
|
localExtraFieldZip64Length,
|
|
7657
7971
|
rawExtraFieldExtendedTimestamp,
|
|
@@ -7754,7 +8068,7 @@
|
|
|
7754
8068
|
}, {
|
|
7755
8069
|
zip64,
|
|
7756
8070
|
zipCrypto,
|
|
7757
|
-
|
|
8071
|
+
passThroughCompression,
|
|
7758
8072
|
dataDescriptor
|
|
7759
8073
|
}) {
|
|
7760
8074
|
const {
|
|
@@ -7765,7 +8079,7 @@
|
|
|
7765
8079
|
dataDescriptorView,
|
|
7766
8080
|
dataDescriptorOffset
|
|
7767
8081
|
} = dataDescriptorInfo;
|
|
7768
|
-
if ((!encrypted || zipCrypto ||
|
|
8082
|
+
if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
|
|
7769
8083
|
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
7770
8084
|
if (dataDescriptor) {
|
|
7771
8085
|
setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
|
|
@@ -7796,9 +8110,9 @@
|
|
|
7796
8110
|
uncompressedSize,
|
|
7797
8111
|
zip64UncompressedSize,
|
|
7798
8112
|
zip64CompressedSize
|
|
7799
|
-
}, localHeaderView, { dataDescriptor,
|
|
8113
|
+
}, localHeaderView, { dataDescriptor, passThroughCompression }) {
|
|
7800
8114
|
if (!dataDescriptor) {
|
|
7801
|
-
if (!encrypted || (
|
|
8115
|
+
if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
|
|
7802
8116
|
setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
|
|
7803
8117
|
}
|
|
7804
8118
|
if (!zip64CompressedSize) {
|
|
@@ -7835,9 +8149,8 @@
|
|
|
7835
8149
|
rawExtraFieldUnix,
|
|
7836
8150
|
rawExtraField,
|
|
7837
8151
|
rawCentralExtraField,
|
|
7838
|
-
extendedTimestamp,
|
|
7839
8152
|
extraFieldExtendedTimestampFlag,
|
|
7840
|
-
|
|
8153
|
+
extraFieldExtendedTimestampTime,
|
|
7841
8154
|
zip64Enabled,
|
|
7842
8155
|
uncompressedSize,
|
|
7843
8156
|
compressedSize
|
|
@@ -7880,16 +8193,15 @@
|
|
|
7880
8193
|
fileEntry.zip64Offset = zip64Offset;
|
|
7881
8194
|
fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
|
|
7882
8195
|
let rawExtraFieldTimestamp;
|
|
7883
|
-
|
|
7884
|
-
|
|
8196
|
+
if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
|
|
8197
|
+
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
8198
|
+
} else {
|
|
7885
8199
|
const extraFieldTimestamp = createRecordWriter(9);
|
|
7886
8200
|
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7887
8201
|
extraFieldTimestamp.writeUint16(5);
|
|
7888
8202
|
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7889
|
-
extraFieldTimestamp.writeUint32(
|
|
8203
|
+
extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
|
|
7890
8204
|
rawExtraFieldTimestamp = extraFieldTimestamp.array;
|
|
7891
|
-
} else {
|
|
7892
|
-
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
7893
8205
|
}
|
|
7894
8206
|
fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
|
|
7895
8207
|
const extraFieldLength = getLength(
|
|
@@ -8389,6 +8701,11 @@
|
|
|
8389
8701
|
};
|
|
8390
8702
|
}
|
|
8391
8703
|
|
|
8704
|
+
function isPrintableASCIIText(rawText) {
|
|
8705
|
+
return rawText.every(characterCode =>
|
|
8706
|
+
characterCode >= MIN_PRINTABLE_ASCII_CHARACTER_CODE && characterCode <= MAX_PRINTABLE_ASCII_CHARACTER_CODE);
|
|
8707
|
+
}
|
|
8708
|
+
|
|
8392
8709
|
function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
|
|
8393
8710
|
let bitFlag = 0;
|
|
8394
8711
|
if (useUnicodeFileNames) {
|
|
@@ -8550,7 +8867,7 @@
|
|
|
8550
8867
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
8551
8868
|
*/
|
|
8552
8869
|
|
|
8553
|
-
const VERSION = "2.
|
|
8870
|
+
const VERSION = "2.12.0";
|
|
8554
8871
|
|
|
8555
8872
|
/*
|
|
8556
8873
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9003,6 +9320,7 @@
|
|
|
9003
9320
|
exports.BlobWriter = BlobWriter;
|
|
9004
9321
|
exports.Data64URIReader = Data64URIReader;
|
|
9005
9322
|
exports.Data64URIWriter = Data64URIWriter;
|
|
9323
|
+
exports.ERR_ABORTED = ERR_ABORTED;
|
|
9006
9324
|
exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
|
|
9007
9325
|
exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
|
|
9008
9326
|
exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
|
|
@@ -9015,7 +9333,9 @@
|
|
|
9015
9333
|
exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
|
|
9016
9334
|
exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
|
|
9017
9335
|
exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
|
|
9336
|
+
exports.ERR_HTTP_STATUS = ERR_HTTP_STATUS;
|
|
9018
9337
|
exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
|
|
9338
|
+
exports.ERR_INVALID_BASE_URI = ERR_INVALID_BASE_URI;
|
|
9019
9339
|
exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
|
|
9020
9340
|
exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
|
|
9021
9341
|
exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
|
|
@@ -9024,6 +9344,7 @@
|
|
|
9024
9344
|
exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
|
|
9025
9345
|
exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
|
|
9026
9346
|
exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
|
|
9347
|
+
exports.ERR_INVALID_ENTRY = ERR_INVALID_ENTRY;
|
|
9027
9348
|
exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
|
|
9028
9349
|
exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
|
|
9029
9350
|
exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
|
|
@@ -9041,6 +9362,7 @@
|
|
|
9041
9362
|
exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
|
|
9042
9363
|
exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
|
|
9043
9364
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
9365
|
+
exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
|
|
9044
9366
|
exports.ERR_INVALID_READER = ERR_INVALID_READER;
|
|
9045
9367
|
exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
|
|
9046
9368
|
exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
|
|
@@ -9050,6 +9372,7 @@
|
|
|
9050
9372
|
exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
|
|
9051
9373
|
exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
|
|
9052
9374
|
exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
|
|
9375
|
+
exports.ERR_INVALID_URI = ERR_INVALID_URI;
|
|
9053
9376
|
exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
|
|
9054
9377
|
exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
|
|
9055
9378
|
exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
|
|
@@ -9057,6 +9380,7 @@
|
|
|
9057
9380
|
exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
|
|
9058
9381
|
exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
|
|
9059
9382
|
exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
|
|
9383
|
+
exports.ERR_UNDEFINED_CRC32 = ERR_UNDEFINED_CRC32;
|
|
9060
9384
|
exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
|
|
9061
9385
|
exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
|
|
9062
9386
|
exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
|
|
@@ -9072,6 +9396,8 @@
|
|
|
9072
9396
|
exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
|
|
9073
9397
|
exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
|
|
9074
9398
|
exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
|
|
9399
|
+
exports.ERR_WRITER_SIZE_NOT_WRITABLE = ERR_WRITER_SIZE_NOT_WRITABLE;
|
|
9400
|
+
exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
|
|
9075
9401
|
exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
|
|
9076
9402
|
exports.HttpRangeReader = HttpRangeReader;
|
|
9077
9403
|
exports.HttpReader = HttpReader;
|
|
@@ -9084,13 +9410,17 @@
|
|
|
9084
9410
|
exports.Uint8ArrayWriter = Uint8ArrayWriter;
|
|
9085
9411
|
exports.VERSION = VERSION;
|
|
9086
9412
|
exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
|
|
9413
|
+
exports.WARNING_CLAMPED_LAST_MODIFICATION_DATE = WARNING_CLAMPED_LAST_MODIFICATION_DATE;
|
|
9087
9414
|
exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
|
|
9415
|
+
exports.WARNING_COMPRESSION_UNAVAILABLE = WARNING_COMPRESSION_UNAVAILABLE;
|
|
9088
9416
|
exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
|
|
9089
9417
|
exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
|
|
9090
9418
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
|
|
9091
9419
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
|
|
9092
9420
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
|
|
9421
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME;
|
|
9093
9422
|
exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
|
|
9423
|
+
exports.WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY;
|
|
9094
9424
|
exports.WARNING_PREPENDED_CENTRAL_DIRECTORY = WARNING_PREPENDED_CENTRAL_DIRECTORY;
|
|
9095
9425
|
exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
|
|
9096
9426
|
exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;
|