@zip.js/zip.js 2.11.4 → 2.13.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 +549 -139
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +559 -136
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +615 -260
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +628 -257
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +615 -260
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +630 -259
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +631 -260
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +561 -138
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +561 -138
- 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 +562 -139
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +630 -259
- package/index-native.min.js +1 -1
- package/index.cjs +631 -260
- package/index.d.cts +474 -59
- package/index.d.ts +474 -59
- package/index.min.js +1 -1
- package/lib/core/codec-worker-web.js +72 -22
- package/lib/core/codec-worker.js +18 -5
- 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/error.js +35 -0
- package/lib/core/util/warnings.js +42 -0
- package/lib/core/version.js +1 -1
- package/lib/core/web-worker-base.js +46 -9
- 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 +45 -133
- package/lib/core/zip-reader.js +115 -52
- package/lib/core/zip-writer.js +244 -57
- 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/worker-message-property-names.js +1 -1
package/dist/zip-fs-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
|
}
|
|
@@ -466,6 +489,39 @@
|
|
|
466
489
|
return new DataView(array.buffer, array.byteOffset, array.byteLength);
|
|
467
490
|
}
|
|
468
491
|
|
|
492
|
+
/*
|
|
493
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
494
|
+
|
|
495
|
+
Redistribution and use in source and binary forms, with or without
|
|
496
|
+
modification, are permitted provided that the following conditions are met:
|
|
497
|
+
|
|
498
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
499
|
+
this list of conditions and the following disclaimer.
|
|
500
|
+
|
|
501
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
502
|
+
notice, this list of conditions and the following disclaimer in
|
|
503
|
+
the documentation and/or other materials provided with the distribution.
|
|
504
|
+
|
|
505
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
506
|
+
derived from this software without specific prior written permission.
|
|
507
|
+
|
|
508
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
509
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
510
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
511
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
512
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
513
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
514
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
515
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
516
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
517
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
518
|
+
*/
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
function isErrorObject(error) {
|
|
522
|
+
return Boolean(error) && typeof error == "object";
|
|
523
|
+
}
|
|
524
|
+
|
|
469
525
|
/*
|
|
470
526
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
471
527
|
|
|
@@ -2605,6 +2661,7 @@
|
|
|
2605
2661
|
constructor(chunkSize) {
|
|
2606
2662
|
const pendingChunks = [];
|
|
2607
2663
|
let pendingLength = 0;
|
|
2664
|
+
let outputSize = 0;
|
|
2608
2665
|
if (!Number.isFinite(chunkSize) || chunkSize < 1) {
|
|
2609
2666
|
chunkSize = DEFAULT_CHUNK_SIZE;
|
|
2610
2667
|
}
|
|
@@ -2613,15 +2670,20 @@
|
|
|
2613
2670
|
pendingChunks.push(chunk);
|
|
2614
2671
|
pendingLength += chunk.length;
|
|
2615
2672
|
while (pendingLength > chunkSize) {
|
|
2673
|
+
outputSize += chunkSize;
|
|
2616
2674
|
controller.enqueue(shiftChunk());
|
|
2617
2675
|
}
|
|
2618
2676
|
},
|
|
2619
2677
|
flush(controller) {
|
|
2620
2678
|
if (pendingLength) {
|
|
2679
|
+
outputSize += pendingLength;
|
|
2621
2680
|
controller.enqueue(concatChunks(pendingChunks, pendingLength));
|
|
2622
2681
|
}
|
|
2623
2682
|
}
|
|
2624
2683
|
});
|
|
2684
|
+
Object.defineProperty(this, "outputSize", {
|
|
2685
|
+
get: () => outputSize
|
|
2686
|
+
});
|
|
2625
2687
|
|
|
2626
2688
|
function shiftChunk() {
|
|
2627
2689
|
const result = new Uint8Array(chunkSize);
|
|
@@ -2727,7 +2789,9 @@
|
|
|
2727
2789
|
|
|
2728
2790
|
class CodecWorker {
|
|
2729
2791
|
|
|
2730
|
-
constructor(workerData, { readable, writable },
|
|
2792
|
+
constructor(workerData, { readable, writable }, workerOptions, onTaskFinished) {
|
|
2793
|
+
const { options, config, streamOptions, useWebWorkers, transferStreams, workerURI } = workerOptions;
|
|
2794
|
+
let { createWorker } = workerOptions;
|
|
2731
2795
|
const { signal } = streamOptions;
|
|
2732
2796
|
if (createWorkerFailed) {
|
|
2733
2797
|
createWorker = UNDEFINED_VALUE;
|
|
@@ -2740,6 +2804,7 @@
|
|
|
2740
2804
|
.pipeThrough(new ProgressWatcherStream(streamOptions), { signal }),
|
|
2741
2805
|
writable,
|
|
2742
2806
|
options: Object.assign({}, options),
|
|
2807
|
+
workerOptions,
|
|
2743
2808
|
workerURI,
|
|
2744
2809
|
createWorker,
|
|
2745
2810
|
transferStreams,
|
|
@@ -2821,8 +2886,8 @@
|
|
|
2821
2886
|
};
|
|
2822
2887
|
}
|
|
2823
2888
|
|
|
2824
|
-
async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
|
|
2825
|
-
let codecStream;
|
|
2889
|
+
async function runWorker$1({ options, readable, writable, onTaskFinished, workerOptions }, config) {
|
|
2890
|
+
let codecStream, chunkStream;
|
|
2826
2891
|
try {
|
|
2827
2892
|
if (options.compressed && !options.format) {
|
|
2828
2893
|
const deflate = options.codecType.startsWith(CODEC_DEFLATE);
|
|
@@ -2845,9 +2910,10 @@
|
|
|
2845
2910
|
}
|
|
2846
2911
|
}
|
|
2847
2912
|
codecStream = new CodecStream(options, config);
|
|
2913
|
+
chunkStream = new ChunkStream(getChunkSize(config));
|
|
2848
2914
|
await readable
|
|
2849
2915
|
.pipeThrough(codecStream)
|
|
2850
|
-
.pipeThrough(
|
|
2916
|
+
.pipeThrough(chunkStream)
|
|
2851
2917
|
.pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
2852
2918
|
const {
|
|
2853
2919
|
crc32,
|
|
@@ -2861,7 +2927,15 @@
|
|
|
2861
2927
|
};
|
|
2862
2928
|
} catch (error) {
|
|
2863
2929
|
if (codecStream) {
|
|
2864
|
-
|
|
2930
|
+
const outputSize = chunkStream ? chunkStream.outputSize : 0;
|
|
2931
|
+
workerOptions.outputSize = outputSize;
|
|
2932
|
+
if (isErrorObject(error)) {
|
|
2933
|
+
try {
|
|
2934
|
+
error.outputSize = outputSize;
|
|
2935
|
+
} catch {
|
|
2936
|
+
// ignored
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2865
2939
|
}
|
|
2866
2940
|
throw error;
|
|
2867
2941
|
} finally {
|
|
@@ -2970,11 +3044,23 @@
|
|
|
2970
3044
|
let resolveResult, rejectResult;
|
|
2971
3045
|
const result = new Promise((resolve, reject) => {
|
|
2972
3046
|
resolveResult = resolve;
|
|
2973
|
-
rejectResult =
|
|
3047
|
+
rejectResult = error => {
|
|
3048
|
+
const { outputSize, workerOptions } = workerData;
|
|
3049
|
+
workerOptions.outputSize = outputSize;
|
|
3050
|
+
if (isErrorObject(error) && error.outputSize === UNDEFINED_VALUE) {
|
|
3051
|
+
try {
|
|
3052
|
+
error.outputSize = outputSize;
|
|
3053
|
+
} catch {
|
|
3054
|
+
// ignored
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
reject(error);
|
|
3058
|
+
};
|
|
2974
3059
|
});
|
|
2975
3060
|
Object.assign(workerData, {
|
|
2976
3061
|
reader: null,
|
|
2977
3062
|
writer: null,
|
|
3063
|
+
outputSize: 0,
|
|
2978
3064
|
resolveResult,
|
|
2979
3065
|
rejectResult,
|
|
2980
3066
|
result
|
|
@@ -3235,21 +3321,15 @@
|
|
|
3235
3321
|
}
|
|
3236
3322
|
|
|
3237
3323
|
async function onMessage({ data }, workerData) {
|
|
3238
|
-
const { type, value, messageId, result, error } = data;
|
|
3324
|
+
const { type, value, messageId, result, error, errorValue } = data;
|
|
3239
3325
|
const { reader, writer, resolveResult, rejectResult, onTaskFinished, generation } = workerData;
|
|
3240
3326
|
const stale = () => workerData.generation != generation;
|
|
3241
3327
|
try {
|
|
3242
3328
|
if (error) {
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
Object.assign(responseError, { stack, code, name, outputSize });
|
|
3246
|
-
if (cause) {
|
|
3247
|
-
responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
|
|
3248
|
-
}
|
|
3249
|
-
if (codecImportFailed) {
|
|
3250
|
-
responseError.codecImportFailed = true;
|
|
3329
|
+
if (error.outputSize !== UNDEFINED_VALUE) {
|
|
3330
|
+
workerData.outputSize = error.outputSize;
|
|
3251
3331
|
}
|
|
3252
|
-
|
|
3332
|
+
fail(getResponseError(error, errorValue));
|
|
3253
3333
|
} else {
|
|
3254
3334
|
if (type == MESSAGE_PULL) {
|
|
3255
3335
|
const { value, done } = await reader.read();
|
|
@@ -3258,39 +3338,82 @@
|
|
|
3258
3338
|
}
|
|
3259
3339
|
}
|
|
3260
3340
|
if (type == MESSAGE_DATA) {
|
|
3341
|
+
const chunk = new Uint8Array(value);
|
|
3261
3342
|
await writer.ready;
|
|
3262
|
-
await writer.write(
|
|
3343
|
+
await writer.write(chunk);
|
|
3344
|
+
workerData.outputSize += chunk.length;
|
|
3263
3345
|
if (!stale()) {
|
|
3264
3346
|
sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
|
|
3265
3347
|
}
|
|
3266
3348
|
}
|
|
3267
3349
|
if (type == MESSAGE_CLOSE) {
|
|
3268
|
-
|
|
3350
|
+
succeed(result);
|
|
3269
3351
|
}
|
|
3270
3352
|
}
|
|
3271
3353
|
} catch (error) {
|
|
3272
3354
|
if (!stale()) {
|
|
3273
3355
|
terminateWorker$1(workerData);
|
|
3274
|
-
|
|
3356
|
+
fail(error);
|
|
3275
3357
|
}
|
|
3276
3358
|
}
|
|
3277
3359
|
|
|
3278
|
-
function
|
|
3279
|
-
if (stale()) {
|
|
3280
|
-
return;
|
|
3281
|
-
}
|
|
3282
|
-
if (error) {
|
|
3360
|
+
function fail(error) {
|
|
3361
|
+
if (!stale()) {
|
|
3283
3362
|
rejectResult(error);
|
|
3284
|
-
|
|
3363
|
+
releaseWriter();
|
|
3364
|
+
if (!(isErrorObject(error) && error.codecImportFailed)) {
|
|
3365
|
+
onTaskFinished();
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
|
|
3370
|
+
function succeed(result) {
|
|
3371
|
+
if (!stale()) {
|
|
3285
3372
|
resolveResult(result);
|
|
3373
|
+
releaseWriter();
|
|
3374
|
+
onTaskFinished();
|
|
3286
3375
|
}
|
|
3376
|
+
}
|
|
3377
|
+
|
|
3378
|
+
function releaseWriter() {
|
|
3287
3379
|
if (writer) {
|
|
3288
3380
|
writer.releaseLock();
|
|
3289
3381
|
}
|
|
3290
|
-
|
|
3291
|
-
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
|
|
3385
|
+
function getResponseError(errorData, errorValue) {
|
|
3386
|
+
const { message, stack, code, name, outputSize, cause, codecImportFailed } = errorData;
|
|
3387
|
+
let responseError;
|
|
3388
|
+
if (errorValue) {
|
|
3389
|
+
responseError = errorValue.value;
|
|
3390
|
+
} else {
|
|
3391
|
+
responseError = Object.assign(new Error(message), { stack, code, name });
|
|
3392
|
+
if (cause) {
|
|
3393
|
+
responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
|
|
3292
3394
|
}
|
|
3293
3395
|
}
|
|
3396
|
+
if (isErrorObject(responseError)) {
|
|
3397
|
+
try {
|
|
3398
|
+
if (outputSize !== UNDEFINED_VALUE) {
|
|
3399
|
+
responseError.outputSize = outputSize;
|
|
3400
|
+
}
|
|
3401
|
+
if (codecImportFailed) {
|
|
3402
|
+
responseError.codecImportFailed = true;
|
|
3403
|
+
}
|
|
3404
|
+
if (errorValue) {
|
|
3405
|
+
if (responseError.name !== name) {
|
|
3406
|
+
responseError.name = name;
|
|
3407
|
+
}
|
|
3408
|
+
if (responseError.code !== code) {
|
|
3409
|
+
responseError.code = code;
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
} catch {
|
|
3413
|
+
// ignored
|
|
3414
|
+
}
|
|
3415
|
+
}
|
|
3416
|
+
return responseError;
|
|
3294
3417
|
}
|
|
3295
3418
|
|
|
3296
3419
|
/*
|
|
@@ -3567,10 +3690,13 @@
|
|
|
3567
3690
|
|
|
3568
3691
|
|
|
3569
3692
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
3693
|
+
const MIN_SUCCESS_HTTP_STATUS = 200;
|
|
3694
|
+
const MAX_SUCCESS_HTTP_STATUS = 299;
|
|
3570
3695
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
3571
3696
|
const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
|
|
3572
3697
|
const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
|
|
3573
3698
|
const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
|
|
3699
|
+
const ERR_WRITER_SIZE_NOT_WRITABLE = "Invalid writer (size must be writable)";
|
|
3574
3700
|
|
|
3575
3701
|
const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
|
|
3576
3702
|
const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
|
|
@@ -3762,6 +3888,7 @@
|
|
|
3762
3888
|
const reader = this;
|
|
3763
3889
|
const { sourceBlob, size } = reader;
|
|
3764
3890
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
3891
|
+
// deno-lint-ignore valid-typeof
|
|
3765
3892
|
if (typeof sourceBlob.stream == FUNCTION_TYPE) {
|
|
3766
3893
|
if (!offset && readSize >= size) {
|
|
3767
3894
|
return toCompatibleReadable(sourceBlob.stream());
|
|
@@ -4168,7 +4295,7 @@
|
|
|
4168
4295
|
|
|
4169
4296
|
async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
|
|
4170
4297
|
const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
|
|
4171
|
-
if (response.status
|
|
4298
|
+
if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
|
|
4172
4299
|
return response;
|
|
4173
4300
|
} else {
|
|
4174
4301
|
throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
|
|
@@ -4179,7 +4306,7 @@
|
|
|
4179
4306
|
return new Promise((resolve, reject) => {
|
|
4180
4307
|
const request = new XMLHttpRequest();
|
|
4181
4308
|
request.addEventListener("load", () => {
|
|
4182
|
-
if (request.status
|
|
4309
|
+
if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
|
|
4183
4310
|
const headers = [];
|
|
4184
4311
|
request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
|
|
4185
4312
|
const splitHeader = header.trim().split(/\s*:\s*/);
|
|
@@ -4483,8 +4610,10 @@
|
|
|
4483
4610
|
writable: toCompatibleWritable(writer)
|
|
4484
4611
|
};
|
|
4485
4612
|
}
|
|
4486
|
-
|
|
4487
|
-
writer.size = 0;
|
|
4613
|
+
try {
|
|
4614
|
+
writer.size = writer.size === UNDEFINED_VALUE ? 0 : writer.size;
|
|
4615
|
+
} catch {
|
|
4616
|
+
throw new Error(ERR_WRITER_SIZE_NOT_WRITABLE);
|
|
4488
4617
|
}
|
|
4489
4618
|
return writer;
|
|
4490
4619
|
}
|
|
@@ -4532,6 +4661,45 @@
|
|
|
4532
4661
|
}
|
|
4533
4662
|
}
|
|
4534
4663
|
|
|
4664
|
+
/*
|
|
4665
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
4666
|
+
|
|
4667
|
+
Redistribution and use in source and binary forms, with or without
|
|
4668
|
+
modification, are permitted provided that the following conditions are met:
|
|
4669
|
+
|
|
4670
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
4671
|
+
this list of conditions and the following disclaimer.
|
|
4672
|
+
|
|
4673
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
4674
|
+
notice, this list of conditions and the following disclaimer in
|
|
4675
|
+
the documentation and/or other materials provided with the distribution.
|
|
4676
|
+
|
|
4677
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
4678
|
+
derived from this software without specific prior written permission.
|
|
4679
|
+
|
|
4680
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4681
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4682
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4683
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4684
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4685
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4686
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4687
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4688
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4689
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4690
|
+
*/
|
|
4691
|
+
|
|
4692
|
+
|
|
4693
|
+
function addWarning(warnings, reason, filename) {
|
|
4694
|
+
if (!warnings.some(warning => warning.reason == reason)) {
|
|
4695
|
+
const warning = { reason };
|
|
4696
|
+
if (filename !== UNDEFINED_VALUE) {
|
|
4697
|
+
warning.filename = filename;
|
|
4698
|
+
}
|
|
4699
|
+
warnings.push(warning);
|
|
4700
|
+
}
|
|
4701
|
+
}
|
|
4702
|
+
|
|
4535
4703
|
/*
|
|
4536
4704
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4537
4705
|
|
|
@@ -4560,6 +4728,7 @@
|
|
|
4560
4728
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4561
4729
|
*/
|
|
4562
4730
|
|
|
4731
|
+
|
|
4563
4732
|
const PROPERTY_NAME_FILENAME = "filename";
|
|
4564
4733
|
const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
|
|
4565
4734
|
const PROPERTY_NAME_COMMENT = "comment";
|
|
@@ -4684,6 +4853,38 @@
|
|
|
4684
4853
|
|
|
4685
4854
|
}
|
|
4686
4855
|
|
|
4856
|
+
const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
|
|
4857
|
+
EXTRAFIELD_TYPE_ZIP64,
|
|
4858
|
+
EXTRAFIELD_TYPE_AES,
|
|
4859
|
+
EXTRAFIELD_TYPE_NTFS,
|
|
4860
|
+
EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
|
|
4861
|
+
EXTRAFIELD_TYPE_UNICODE_PATH,
|
|
4862
|
+
EXTRAFIELD_TYPE_UNICODE_COMMENT,
|
|
4863
|
+
EXTRAFIELD_TYPE_USDZ,
|
|
4864
|
+
EXTRAFIELD_TYPE_INFOZIP,
|
|
4865
|
+
EXTRAFIELD_TYPE_UNIX,
|
|
4866
|
+
EXTRAFIELD_TYPE_UNIX_TYPE1,
|
|
4867
|
+
EXTRAFIELD_TYPE_PKWARE_UNIX
|
|
4868
|
+
]);
|
|
4869
|
+
|
|
4870
|
+
function getUserExtraField(extraField) {
|
|
4871
|
+
if (extraField) {
|
|
4872
|
+
const userExtraField = new Map();
|
|
4873
|
+
extraField.forEach((field, type) => {
|
|
4874
|
+
if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
|
|
4875
|
+
userExtraField.set(type, field.data);
|
|
4876
|
+
}
|
|
4877
|
+
});
|
|
4878
|
+
if (userExtraField.size) {
|
|
4879
|
+
return userExtraField;
|
|
4880
|
+
}
|
|
4881
|
+
}
|
|
4882
|
+
}
|
|
4883
|
+
|
|
4884
|
+
function getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength) {
|
|
4885
|
+
return encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
4886
|
+
}
|
|
4887
|
+
|
|
4687
4888
|
/*
|
|
4688
4889
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4689
4890
|
|
|
@@ -4743,6 +4944,8 @@
|
|
|
4743
4944
|
const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
|
|
4744
4945
|
const WARNING_DUPLICATE_FILENAME = "duplicate filename";
|
|
4745
4946
|
const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
|
|
4947
|
+
const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
|
|
4948
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = "mismatched local file header (filename)";
|
|
4746
4949
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
|
|
4747
4950
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
|
|
4748
4951
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
@@ -4813,7 +5016,7 @@
|
|
|
4813
5016
|
}
|
|
4814
5017
|
}
|
|
4815
5018
|
if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
|
|
4816
|
-
throwAmbiguousArchive(
|
|
5019
|
+
throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
|
|
4817
5020
|
}
|
|
4818
5021
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
4819
5022
|
let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
|
|
@@ -5111,7 +5314,8 @@
|
|
|
5111
5314
|
const writer = new TransformStream();
|
|
5112
5315
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5113
5316
|
arrayBufferPromise.catch(() => { });
|
|
5114
|
-
await fileEntry.getData(writer, entry, zipReader.readRanges,
|
|
5317
|
+
await fileEntry.getData(writer, entry, zipReader.readRanges,
|
|
5318
|
+
Object.assign({}, options, { preventClose: false }));
|
|
5115
5319
|
return arrayBufferPromise;
|
|
5116
5320
|
};
|
|
5117
5321
|
offset = endOffset;
|
|
@@ -5192,49 +5396,101 @@
|
|
|
5192
5396
|
await reader.readable.cancel();
|
|
5193
5397
|
}
|
|
5194
5398
|
}
|
|
5399
|
+
|
|
5400
|
+
[SYMBOL_ASYNC_DISPOSE]() {
|
|
5401
|
+
return this.close();
|
|
5402
|
+
}
|
|
5195
5403
|
}
|
|
5196
5404
|
|
|
5197
5405
|
class ZipReaderStream {
|
|
5198
5406
|
|
|
5199
5407
|
constructor(options = {}) {
|
|
5200
|
-
|
|
5201
|
-
const
|
|
5408
|
+
let sourceController;
|
|
5409
|
+
const { readable, writable } = new TransformStream({
|
|
5410
|
+
start(controller) {
|
|
5411
|
+
sourceController = controller;
|
|
5412
|
+
}
|
|
5413
|
+
});
|
|
5414
|
+
const zipReader = new ZipReader(readable, options);
|
|
5415
|
+
const gen = zipReader.getEntriesGenerator();
|
|
5416
|
+
const pendingEntries = new Set();
|
|
5202
5417
|
this.readable = new ReadableStream({
|
|
5203
5418
|
async pull(controller) {
|
|
5204
5419
|
const { done, value } = await gen.next();
|
|
5205
5420
|
if (done)
|
|
5206
5421
|
return controller.close();
|
|
5207
|
-
const
|
|
5208
|
-
const { readable, writable } = new TransformStream();
|
|
5209
|
-
if (value.getData) {
|
|
5210
|
-
getData();
|
|
5211
|
-
return readable;
|
|
5212
|
-
}
|
|
5213
|
-
|
|
5214
|
-
async function getData() {
|
|
5215
|
-
try {
|
|
5216
|
-
await value.getData(writable);
|
|
5217
|
-
} catch (error) {
|
|
5218
|
-
try {
|
|
5219
|
-
await writable.abort(error);
|
|
5220
|
-
} catch {
|
|
5221
|
-
// ignored
|
|
5222
|
-
}
|
|
5223
|
-
}
|
|
5224
|
-
}
|
|
5225
|
-
})();
|
|
5422
|
+
const entryStream = createEntryStream(value, pendingEntries);
|
|
5226
5423
|
const chunk = {
|
|
5227
5424
|
...value,
|
|
5228
|
-
readable:
|
|
5425
|
+
readable: entryStream.readable
|
|
5229
5426
|
};
|
|
5230
5427
|
delete chunk.getData;
|
|
5428
|
+
Object.defineProperties(chunk, {
|
|
5429
|
+
localDirectory: {
|
|
5430
|
+
get: () => value.localDirectory,
|
|
5431
|
+
enumerable: true
|
|
5432
|
+
},
|
|
5433
|
+
warnings: {
|
|
5434
|
+
get: () => value.warnings,
|
|
5435
|
+
enumerable: true
|
|
5436
|
+
}
|
|
5437
|
+
});
|
|
5231
5438
|
controller.enqueue(chunk);
|
|
5439
|
+
},
|
|
5440
|
+
async cancel(reason) {
|
|
5441
|
+
const entryStreams = Array.from(pendingEntries);
|
|
5442
|
+
pendingEntries.clear();
|
|
5443
|
+
sourceController.error(reason);
|
|
5444
|
+
await Promise.allSettled(entryStreams.map(entryStream => entryStream.cancel(reason)));
|
|
5445
|
+
await Promise.allSettled([gen.return(), zipReader.close()]);
|
|
5232
5446
|
}
|
|
5233
5447
|
});
|
|
5234
5448
|
this.writable = writable;
|
|
5235
5449
|
}
|
|
5236
5450
|
}
|
|
5237
5451
|
|
|
5452
|
+
function createEntryStream(entry, pendingEntries) {
|
|
5453
|
+
const { readable, writable } = new TransformStream();
|
|
5454
|
+
let dataReader;
|
|
5455
|
+
const entryStream = {
|
|
5456
|
+
cancel: async reason => {
|
|
5457
|
+
pendingEntries.delete(entryStream);
|
|
5458
|
+
await (dataReader ? dataReader.cancel(reason) : readable.cancel(reason));
|
|
5459
|
+
}
|
|
5460
|
+
};
|
|
5461
|
+
entryStream.readable = new ReadableStream({
|
|
5462
|
+
async pull(controller) {
|
|
5463
|
+
if (!dataReader) {
|
|
5464
|
+
dataReader = readable.getReader();
|
|
5465
|
+
pendingEntries.add(entryStream);
|
|
5466
|
+
getData();
|
|
5467
|
+
}
|
|
5468
|
+
const { done, value } = await dataReader.read();
|
|
5469
|
+
if (done) {
|
|
5470
|
+
controller.close();
|
|
5471
|
+
} else {
|
|
5472
|
+
controller.enqueue(value);
|
|
5473
|
+
}
|
|
5474
|
+
},
|
|
5475
|
+
cancel: reason => entryStream.cancel(reason)
|
|
5476
|
+
}, { highWaterMark: 0 });
|
|
5477
|
+
return entryStream;
|
|
5478
|
+
|
|
5479
|
+
async function getData() {
|
|
5480
|
+
try {
|
|
5481
|
+
await entry.getData(writable, { preventClose: false });
|
|
5482
|
+
} catch (error) {
|
|
5483
|
+
try {
|
|
5484
|
+
await writable.abort(error);
|
|
5485
|
+
} catch {
|
|
5486
|
+
// ignored
|
|
5487
|
+
}
|
|
5488
|
+
} finally {
|
|
5489
|
+
pendingEntries.delete(entryStream);
|
|
5490
|
+
}
|
|
5491
|
+
}
|
|
5492
|
+
}
|
|
5493
|
+
|
|
5238
5494
|
async function isZipFile(reader, options = {}) {
|
|
5239
5495
|
reader = new GenericReader(reader);
|
|
5240
5496
|
await initStream(reader);
|
|
@@ -5294,7 +5550,9 @@
|
|
|
5294
5550
|
const dataView = getDataView(dataArray);
|
|
5295
5551
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
5296
5552
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
5297
|
-
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
5553
|
+
const passThrough = checkPassThroughOption(getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH));
|
|
5554
|
+
const passThroughCompression = Boolean(passThrough);
|
|
5555
|
+
const passThroughEncryption = passThrough === true;
|
|
5298
5556
|
checkPasswordOption(password, rawPassword);
|
|
5299
5557
|
password = password && password.length && password;
|
|
5300
5558
|
rawPassword = rawPassword && rawPassword.length && rawPassword;
|
|
@@ -5315,7 +5573,9 @@
|
|
|
5315
5573
|
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5316
5574
|
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5317
5575
|
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
5318
|
-
const
|
|
5576
|
+
const checkLocalFilenameOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_FILENAME);
|
|
5577
|
+
const checkLocalFilename = getCheckLocalFilename(
|
|
5578
|
+
checkLocalFilenameOption === UNDEFINED_VALUE ? checkLocalDirectoryOption : checkLocalFilenameOption, entryStrictness);
|
|
5319
5579
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
5320
5580
|
if (checkLocalFilename && (filenameLength || extraFieldLength)) {
|
|
5321
5581
|
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
@@ -5346,16 +5606,17 @@
|
|
|
5346
5606
|
if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
|
|
5347
5607
|
fileEntry.gid = gid;
|
|
5348
5608
|
}
|
|
5349
|
-
const
|
|
5609
|
+
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5610
|
+
const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
|
|
5350
5611
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
5351
|
-
if (!
|
|
5612
|
+
if (!passThroughEncryption) {
|
|
5352
5613
|
fileEntry.zipCrypto = zipCrypto;
|
|
5353
5614
|
}
|
|
5354
5615
|
if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
|
|
5355
5616
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
|
|
5356
5617
|
}
|
|
5357
|
-
const registeredCodec =
|
|
5358
|
-
if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !
|
|
5618
|
+
const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
5619
|
+
if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThroughCompression) {
|
|
5359
5620
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
5360
5621
|
}
|
|
5361
5622
|
if (encrypted) {
|
|
@@ -5372,15 +5633,16 @@
|
|
|
5372
5633
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5373
5634
|
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5374
5635
|
throwIfAborted(signal);
|
|
5375
|
-
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5376
5636
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
5377
5637
|
const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
|
|
5378
5638
|
if (checkOverlappingEntryOnly) {
|
|
5379
5639
|
checkOverlappingEntry = true;
|
|
5380
5640
|
}
|
|
5381
5641
|
const { onstart, onprogress, onend } = options;
|
|
5382
|
-
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !
|
|
5383
|
-
const outputSize =
|
|
5642
|
+
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThroughCompression;
|
|
5643
|
+
const outputSize = passThroughCompression ?
|
|
5644
|
+
compressedSize - getEncryptionOverhead(encrypted, zipCrypto, extraFieldAES && extraFieldAES.strength) :
|
|
5645
|
+
uncompressedSize;
|
|
5384
5646
|
const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
|
|
5385
5647
|
let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5386
5648
|
if (deflate64) {
|
|
@@ -5389,7 +5651,7 @@
|
|
|
5389
5651
|
const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
|
|
5390
5652
|
const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
|
|
5391
5653
|
getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
|
|
5392
|
-
checkCrc32Option) && !
|
|
5654
|
+
checkCrc32Option) && !passThroughCompression &&
|
|
5393
5655
|
(!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
|
|
5394
5656
|
const workerOptions = {
|
|
5395
5657
|
options: {
|
|
@@ -5433,7 +5695,7 @@
|
|
|
5433
5695
|
readRanges
|
|
5434
5696
|
});
|
|
5435
5697
|
}
|
|
5436
|
-
let writable, abortError;
|
|
5698
|
+
let writable, abortError, aborted;
|
|
5437
5699
|
try {
|
|
5438
5700
|
if (!checkOverlappingEntryOnly) {
|
|
5439
5701
|
if (checkPasswordOnly) {
|
|
@@ -5443,24 +5705,28 @@
|
|
|
5443
5705
|
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5444
5706
|
({ writable } = writer);
|
|
5445
5707
|
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5446
|
-
writer.size += writtenSize;
|
|
5447
5708
|
if (writtenSize != outputSize) {
|
|
5448
|
-
throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
5709
|
+
throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
|
|
5449
5710
|
}
|
|
5711
|
+
writer.size += writtenSize;
|
|
5450
5712
|
}
|
|
5451
5713
|
} catch (error) {
|
|
5452
|
-
|
|
5714
|
+
const { outputSize: failedOutputSize } = workerOptions;
|
|
5715
|
+
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5716
|
+
writer.size += failedOutputSize;
|
|
5717
|
+
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5453
5718
|
writer.size += error.outputSize;
|
|
5454
5719
|
}
|
|
5455
|
-
if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
5720
|
+
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
5456
5721
|
abortError = error;
|
|
5722
|
+
aborted = true;
|
|
5457
5723
|
throw error;
|
|
5458
5724
|
}
|
|
5459
5725
|
} finally {
|
|
5460
5726
|
const preventClose = !ownsWritable(writer) && getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
|
|
5461
5727
|
if (!preventClose && writable && !writable.locked) {
|
|
5462
5728
|
const writableWriter = writable.getWriter();
|
|
5463
|
-
if (
|
|
5729
|
+
if (aborted) {
|
|
5464
5730
|
try {
|
|
5465
5731
|
await writableWriter.abort(abortError);
|
|
5466
5732
|
} catch {
|
|
@@ -6112,7 +6378,7 @@
|
|
|
6112
6378
|
if (checkLocalFilename && !maskedLocalDirectory &&
|
|
6113
6379
|
(rawLocalFilename.length != rawFilename.length ||
|
|
6114
6380
|
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
6115
|
-
reportAmbiguity(reject, warnings,
|
|
6381
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
|
|
6116
6382
|
}
|
|
6117
6383
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
6118
6384
|
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
|
|
@@ -6137,16 +6403,6 @@
|
|
|
6137
6403
|
}
|
|
6138
6404
|
}
|
|
6139
6405
|
|
|
6140
|
-
function addWarning(warnings, reason, filename) {
|
|
6141
|
-
if (!warnings.some(warning => warning.reason == reason)) {
|
|
6142
|
-
const warning = { reason };
|
|
6143
|
-
if (filename !== UNDEFINED_VALUE) {
|
|
6144
|
-
warning.filename = filename;
|
|
6145
|
-
}
|
|
6146
|
-
warnings.push(warning);
|
|
6147
|
-
}
|
|
6148
|
-
}
|
|
6149
|
-
|
|
6150
6406
|
function throwAmbiguousArchive(reason) {
|
|
6151
6407
|
const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
|
|
6152
6408
|
error.reason = reason;
|
|
@@ -6226,7 +6482,9 @@
|
|
|
6226
6482
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
|
|
6227
6483
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
|
|
6228
6484
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
|
|
6485
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
|
|
6229
6486
|
WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
|
|
6487
|
+
WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
|
|
6230
6488
|
WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
|
|
6231
6489
|
WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
|
|
6232
6490
|
WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
|
|
@@ -6279,7 +6537,7 @@
|
|
|
6279
6537
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
6280
6538
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
6281
6539
|
const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
|
|
6282
|
-
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
6540
|
+
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set to true (use 'compressed' instead)";
|
|
6283
6541
|
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
6284
6542
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
6285
6543
|
const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
|
|
@@ -6291,6 +6549,7 @@
|
|
|
6291
6549
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
6292
6550
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
6293
6551
|
const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
|
|
6552
|
+
const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
|
|
6294
6553
|
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
6295
6554
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
6296
6555
|
const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
|
|
@@ -6304,14 +6563,21 @@
|
|
|
6304
6563
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
6305
6564
|
const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
|
|
6306
6565
|
const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
6566
|
+
const ERR_INVALID_ENTRY = "Invalid entry option (must be an entry returned by ZipReader#getEntries())";
|
|
6567
|
+
const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
|
|
6568
|
+
const WARNING_COMPRESSION_UNAVAILABLE = "compression unavailable";
|
|
6569
|
+
const WARNING_CLAMPED_LAST_MODIFICATION_DATE = "clamped last modification date";
|
|
6307
6570
|
|
|
6308
6571
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
6309
6572
|
const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
|
|
6310
6573
|
const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
|
|
6311
6574
|
const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
|
|
6575
|
+
const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
|
|
6576
|
+
const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
|
|
6312
6577
|
const VENDOR_VERSION_AE_1 = 1;
|
|
6313
|
-
const INFOZIP_EXTRA_FIELD_TYPE
|
|
6578
|
+
const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
|
|
6314
6579
|
const UNIX_EXTRA_FIELD_TYPE = "unix";
|
|
6580
|
+
const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
|
|
6315
6581
|
const MAX_LEVEL = 9;
|
|
6316
6582
|
|
|
6317
6583
|
let workers = 0;
|
|
@@ -6338,9 +6604,11 @@
|
|
|
6338
6604
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
6339
6605
|
pendingAddFileCalls: new Set(),
|
|
6340
6606
|
pendingErrors: [],
|
|
6607
|
+
warnings: [],
|
|
6341
6608
|
bufferedWrites: 0,
|
|
6342
6609
|
directWrites: 0,
|
|
6343
|
-
lastFileEntry: UNDEFINED_VALUE
|
|
6610
|
+
lastFileEntry: UNDEFINED_VALUE,
|
|
6611
|
+
archiveClosed: false
|
|
6344
6612
|
});
|
|
6345
6613
|
}
|
|
6346
6614
|
|
|
@@ -6505,6 +6773,9 @@
|
|
|
6505
6773
|
const zipWriter = this;
|
|
6506
6774
|
const { pendingAddFileCalls, writer } = this;
|
|
6507
6775
|
const { writable } = writer;
|
|
6776
|
+
if (zipWriter.archiveClosed) {
|
|
6777
|
+
return getWriterData(writer);
|
|
6778
|
+
}
|
|
6508
6779
|
if (!(comment instanceof Uint8Array)) {
|
|
6509
6780
|
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
6510
6781
|
}
|
|
@@ -6515,7 +6786,7 @@
|
|
|
6515
6786
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6516
6787
|
}
|
|
6517
6788
|
await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
|
|
6518
|
-
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.
|
|
6789
|
+
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.failed && !watcher.observed);
|
|
6519
6790
|
if (unobservedWatchers.length) {
|
|
6520
6791
|
const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
|
|
6521
6792
|
unobservedWatchers.forEach(watcher => watcher.observed = true);
|
|
@@ -6528,11 +6799,16 @@
|
|
|
6528
6799
|
throw error;
|
|
6529
6800
|
}
|
|
6530
6801
|
await closeFile(zipWriter, comment, options);
|
|
6802
|
+
zipWriter.archiveClosed = true;
|
|
6531
6803
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
6532
6804
|
if (!preventClose) {
|
|
6533
6805
|
await writable.getWriter().close();
|
|
6534
6806
|
}
|
|
6535
|
-
return writer
|
|
6807
|
+
return getWriterData(writer);
|
|
6808
|
+
}
|
|
6809
|
+
|
|
6810
|
+
[SYMBOL_ASYNC_DISPOSE]() {
|
|
6811
|
+
return this.close();
|
|
6536
6812
|
}
|
|
6537
6813
|
}
|
|
6538
6814
|
|
|
@@ -6611,11 +6887,16 @@
|
|
|
6611
6887
|
}
|
|
6612
6888
|
}
|
|
6613
6889
|
|
|
6890
|
+
function getWriterData(writer) {
|
|
6891
|
+
return writer.getData ? writer.getData() : writer.writable;
|
|
6892
|
+
}
|
|
6893
|
+
|
|
6614
6894
|
function watchPromiseError(zipWriter, promise) {
|
|
6615
6895
|
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
6616
6896
|
const watcher = {};
|
|
6617
6897
|
watchedPromise.watcher = watcher;
|
|
6618
|
-
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE,
|
|
6898
|
+
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE,
|
|
6899
|
+
error => Object.assign(watcher, { failed: true, error }));
|
|
6619
6900
|
zipWriter.pendingErrors.push(watcher);
|
|
6620
6901
|
return watchedPromise;
|
|
6621
6902
|
}
|
|
@@ -6629,6 +6910,14 @@
|
|
|
6629
6910
|
|
|
6630
6911
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
6631
6912
|
options = Object.assign({}, options);
|
|
6913
|
+
const entry = options[OPTION_ENTRY];
|
|
6914
|
+
if (entry !== UNDEFINED_VALUE) {
|
|
6915
|
+
const { entryOptions, passThroughOptions } = getSourceEntryOptions(entry,
|
|
6916
|
+
checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH)),
|
|
6917
|
+
getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE));
|
|
6918
|
+
delete options[OPTION_ENTRY];
|
|
6919
|
+
options = Object.assign(entryOptions, passThroughOptions, options);
|
|
6920
|
+
}
|
|
6632
6921
|
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6633
6922
|
name += DIRECTORY_SIGNATURE;
|
|
6634
6923
|
}
|
|
@@ -6693,21 +6982,33 @@
|
|
|
6693
6982
|
try {
|
|
6694
6983
|
const { resolvedOptions } = metadataInfo;
|
|
6695
6984
|
if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
|
|
6696
|
-
!resolvedOptions.
|
|
6985
|
+
!resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
|
|
6697
6986
|
resolvedOptions.level = 0;
|
|
6987
|
+
addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
|
|
6698
6988
|
}
|
|
6699
6989
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
6700
6990
|
({ reader } = sizesInfo);
|
|
6701
6991
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
6702
6992
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
6993
|
+
let crc32 = options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32;
|
|
6994
|
+
const storesAE2 = sizesInfo.resolvedOptions.encrypted && !resolvedOptions.zipCrypto;
|
|
6995
|
+
if (resolvedOptions.passThroughCompression && !resolvedOptions.passThroughEncryption && storesAE2) {
|
|
6996
|
+
crc32 = UNDEFINED_VALUE;
|
|
6997
|
+
}
|
|
6998
|
+
if (resolvedOptions.passThroughCompression && reader && !storesAE2 && crc32 === UNDEFINED_VALUE) {
|
|
6999
|
+
throw new Error(ERR_UNDEFINED_CRC32);
|
|
7000
|
+
}
|
|
6703
7001
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
6704
7002
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
6705
|
-
crc32
|
|
7003
|
+
crc32,
|
|
6706
7004
|
offset: zipWriter.offset - diskOffset,
|
|
6707
7005
|
diskNumberStart: diskNumber,
|
|
6708
7006
|
[OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
|
|
6709
7007
|
});
|
|
6710
7008
|
const headerInfo = getHeaderInfo(options);
|
|
7009
|
+
if (headerInfo.lastModDateClamped) {
|
|
7010
|
+
addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
|
|
7011
|
+
}
|
|
6711
7012
|
const dataDescriptorInfo = getDataDescriptorInfo(options);
|
|
6712
7013
|
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
6713
7014
|
fileEntry = await getFileEntry(zipWriter, name, reader, {
|
|
@@ -6734,6 +7035,95 @@
|
|
|
6734
7035
|
return new Entry(fileEntry);
|
|
6735
7036
|
}
|
|
6736
7037
|
|
|
7038
|
+
function getSourceEntryOptions(entry, passThrough, lastModDateOverride) {
|
|
7039
|
+
if (entry === null || typeof entry != OBJECT_TYPE || Array.isArray(entry)) {
|
|
7040
|
+
throw new Error(ERR_INVALID_ENTRY);
|
|
7041
|
+
}
|
|
7042
|
+
const {
|
|
7043
|
+
externalFileAttributes,
|
|
7044
|
+
versionMadeBy,
|
|
7045
|
+
comment,
|
|
7046
|
+
lastModDate,
|
|
7047
|
+
rawLastModDate,
|
|
7048
|
+
creationDate,
|
|
7049
|
+
lastAccessDate,
|
|
7050
|
+
uncompressedSize,
|
|
7051
|
+
encrypted,
|
|
7052
|
+
zipCrypto,
|
|
7053
|
+
crc32,
|
|
7054
|
+
compressionMethod,
|
|
7055
|
+
extraFieldAES,
|
|
7056
|
+
extraFieldUnix,
|
|
7057
|
+
internalFileAttributes,
|
|
7058
|
+
extraField,
|
|
7059
|
+
bitFlag,
|
|
7060
|
+
directory,
|
|
7061
|
+
uid,
|
|
7062
|
+
gid
|
|
7063
|
+
} = entry;
|
|
7064
|
+
const entryOptions = {
|
|
7065
|
+
externalFileAttributes,
|
|
7066
|
+
versionMadeBy,
|
|
7067
|
+
comment,
|
|
7068
|
+
lastModDate,
|
|
7069
|
+
creationDate,
|
|
7070
|
+
lastAccessDate,
|
|
7071
|
+
internalFileAttributes,
|
|
7072
|
+
directory
|
|
7073
|
+
};
|
|
7074
|
+
if (bitFlag && bitFlag.languageEncodingFlag) {
|
|
7075
|
+
entryOptions[OPTION_USE_UNICODE_FILE_NAMES] = true;
|
|
7076
|
+
}
|
|
7077
|
+
const userExtraField = getUserExtraField(extraField);
|
|
7078
|
+
if (userExtraField) {
|
|
7079
|
+
entryOptions[PROPERTY_NAME_EXTRA_FIELD] = userExtraField;
|
|
7080
|
+
}
|
|
7081
|
+
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
7082
|
+
Object.assign(entryOptions, {
|
|
7083
|
+
uid,
|
|
7084
|
+
gid,
|
|
7085
|
+
unixExtraFieldType: extraFieldUnix ? UNIX_EXTRA_FIELD_TYPE : INFOZIP_EXTRA_FIELD_TYPE
|
|
7086
|
+
});
|
|
7087
|
+
}
|
|
7088
|
+
const passThroughOptions = {};
|
|
7089
|
+
if (passThrough && !directory) {
|
|
7090
|
+
Object.assign(passThroughOptions, {
|
|
7091
|
+
uncompressedSize,
|
|
7092
|
+
crc32,
|
|
7093
|
+
compressionMethod
|
|
7094
|
+
});
|
|
7095
|
+
if (passThrough !== PASS_THROUGH_COMPRESSED) {
|
|
7096
|
+
Object.assign(passThroughOptions, {
|
|
7097
|
+
encrypted,
|
|
7098
|
+
zipCrypto,
|
|
7099
|
+
encryptionStrength: extraFieldAES ? extraFieldAES.strength : UNDEFINED_VALUE
|
|
7100
|
+
});
|
|
7101
|
+
}
|
|
7102
|
+
if (bitFlag) {
|
|
7103
|
+
passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
|
|
7104
|
+
passThroughOptions[OPTION_LEVEL] = LEVEL_BY_BITFLAG_LEVEL[bitFlag.level];
|
|
7105
|
+
}
|
|
7106
|
+
if (lastModDateOverride === UNDEFINED_VALUE) {
|
|
7107
|
+
passThroughOptions.rawLastModDate = rawLastModDate;
|
|
7108
|
+
} else if (passThrough !== PASS_THROUGH_COMPRESSED && zipCrypto && (!bitFlag || bitFlag.dataDescriptor) &&
|
|
7109
|
+
lastModDateOverride instanceof Date &&
|
|
7110
|
+
getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
|
|
7111
|
+
throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
|
|
7112
|
+
}
|
|
7113
|
+
}
|
|
7114
|
+
return { entryOptions, passThroughOptions };
|
|
7115
|
+
}
|
|
7116
|
+
|
|
7117
|
+
function getDosTimeHighByte(lastModDate) {
|
|
7118
|
+
let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
7119
|
+
if (dosLastModDate < MIN_DATE) {
|
|
7120
|
+
dosLastModDate = MIN_DATE;
|
|
7121
|
+
} else if (dosLastModDate > MAX_DATE) {
|
|
7122
|
+
dosLastModDate = MAX_DATE;
|
|
7123
|
+
}
|
|
7124
|
+
return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
|
|
7125
|
+
}
|
|
7126
|
+
|
|
6737
7127
|
function resolveAttributes(zipWriter, name, options) {
|
|
6738
7128
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
6739
7129
|
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
@@ -6748,7 +7138,7 @@
|
|
|
6748
7138
|
checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
|
|
6749
7139
|
checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
|
|
6750
7140
|
checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
|
|
6751
|
-
if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE
|
|
7141
|
+
if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
|
|
6752
7142
|
throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
|
|
6753
7143
|
}
|
|
6754
7144
|
if (unixExtraFieldType === UNIX_EXTRA_FIELD_TYPE &&
|
|
@@ -6756,7 +7146,7 @@
|
|
|
6756
7146
|
throw new Error(ERR_INVALID_UNIX_ID_SIZE);
|
|
6757
7147
|
}
|
|
6758
7148
|
if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
6759
|
-
unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE
|
|
7149
|
+
unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE;
|
|
6760
7150
|
}
|
|
6761
7151
|
let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
|
|
6762
7152
|
let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
|
|
@@ -6887,7 +7277,9 @@
|
|
|
6887
7277
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6888
7278
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6889
7279
|
const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
6890
|
-
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
7280
|
+
const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
|
|
7281
|
+
const passThroughCompression = Boolean(passThrough);
|
|
7282
|
+
const passThroughEncryption = passThrough === true;
|
|
6891
7283
|
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
6892
7284
|
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
6893
7285
|
checkPasswordOption(password, rawPassword);
|
|
@@ -6903,10 +7295,11 @@
|
|
|
6903
7295
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
6904
7296
|
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
6905
7297
|
throwIfAborted(signal);
|
|
6906
|
-
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
|
|
7298
|
+
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
|
|
7299
|
+
!isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
|
|
6907
7300
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
6908
|
-
const registeredCodec =
|
|
6909
|
-
if (!
|
|
7301
|
+
const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
7302
|
+
if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
|
|
6910
7303
|
compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
|
|
6911
7304
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
6912
7305
|
}
|
|
@@ -6920,15 +7313,15 @@
|
|
|
6920
7313
|
level = 0;
|
|
6921
7314
|
}
|
|
6922
7315
|
}
|
|
6923
|
-
if (
|
|
6924
|
-
level =
|
|
7316
|
+
if (passThroughCompression) {
|
|
7317
|
+
level = toNumber(options[OPTION_LEVEL]);
|
|
6925
7318
|
}
|
|
6926
7319
|
let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
|
|
6927
7320
|
let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
|
|
6928
7321
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
6929
7322
|
dataDescriptor = false;
|
|
6930
7323
|
}
|
|
6931
|
-
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !
|
|
7324
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
|
|
6932
7325
|
dataDescriptor = true;
|
|
6933
7326
|
}
|
|
6934
7327
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -6952,7 +7345,8 @@
|
|
|
6952
7345
|
lastAccessDate,
|
|
6953
7346
|
creationDate,
|
|
6954
7347
|
internalFileAttributes,
|
|
6955
|
-
|
|
7348
|
+
passThroughCompression,
|
|
7349
|
+
passThroughEncryption,
|
|
6956
7350
|
password,
|
|
6957
7351
|
rawPassword,
|
|
6958
7352
|
encryptionStrength,
|
|
@@ -7013,7 +7407,7 @@
|
|
|
7013
7407
|
}
|
|
7014
7408
|
|
|
7015
7409
|
async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
|
|
7016
|
-
if (metadata.
|
|
7410
|
+
if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
|
|
7017
7411
|
throw new Error(ERR_UNDEFINED_READER);
|
|
7018
7412
|
}
|
|
7019
7413
|
let contentSize;
|
|
@@ -7029,12 +7423,12 @@
|
|
|
7029
7423
|
}
|
|
7030
7424
|
|
|
7031
7425
|
function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
|
|
7032
|
-
const {
|
|
7426
|
+
const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
|
|
7033
7427
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
7034
7428
|
let maximumCompressedSize = 0;
|
|
7035
7429
|
let uncompressedSize = 0;
|
|
7036
7430
|
let unknownSize = false;
|
|
7037
|
-
if (
|
|
7431
|
+
if (passThroughCompression && hasContent) {
|
|
7038
7432
|
uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
|
|
7039
7433
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
7040
7434
|
throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
|
|
@@ -7045,17 +7439,17 @@
|
|
|
7045
7439
|
}
|
|
7046
7440
|
const zip64Enabled = zip64 === true;
|
|
7047
7441
|
const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
|
|
7048
|
-
if (hasContent &&
|
|
7442
|
+
if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
|
|
7049
7443
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
|
|
7050
7444
|
}
|
|
7051
|
-
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (
|
|
7445
|
+
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThroughEncryption && encrypted));
|
|
7052
7446
|
if (!hasContent) {
|
|
7053
7447
|
level = 0;
|
|
7054
7448
|
compressionMethod = COMPRESSION_METHOD_STORE;
|
|
7055
7449
|
}
|
|
7056
|
-
const encryptionOverhead = encryptedEntry
|
|
7450
|
+
const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
|
|
7057
7451
|
if (hasContent) {
|
|
7058
|
-
if (!
|
|
7452
|
+
if (!passThroughCompression) {
|
|
7059
7453
|
if (contentSize === UNDEFINED_VALUE) {
|
|
7060
7454
|
dataDescriptor = true;
|
|
7061
7455
|
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
@@ -7068,10 +7462,12 @@
|
|
|
7068
7462
|
}
|
|
7069
7463
|
} else {
|
|
7070
7464
|
options.uncompressedSize = uncompressedSize;
|
|
7071
|
-
maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
|
|
7465
|
+
maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
|
|
7466
|
+
getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
|
|
7467
|
+
contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
|
|
7072
7468
|
}
|
|
7073
7469
|
}
|
|
7074
|
-
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !
|
|
7470
|
+
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
|
|
7075
7471
|
if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
7076
7472
|
dataDescriptor = false;
|
|
7077
7473
|
}
|
|
@@ -7120,6 +7516,8 @@
|
|
|
7120
7516
|
const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
|
|
7121
7517
|
let offset = initialOffset;
|
|
7122
7518
|
let minimumEntrySize = INFINITY_VALUE;
|
|
7519
|
+
const entrySizes = [];
|
|
7520
|
+
const entriesAlreadyZip64 = new Set();
|
|
7123
7521
|
for (const entry of entries) {
|
|
7124
7522
|
let { name } = entry;
|
|
7125
7523
|
const { size } = entry;
|
|
@@ -7131,7 +7529,7 @@
|
|
|
7131
7529
|
({ name } = attributesInfo);
|
|
7132
7530
|
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
7133
7531
|
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
7134
|
-
!metadata.
|
|
7532
|
+
!metadata.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
|
|
7135
7533
|
metadata.level = 0;
|
|
7136
7534
|
}
|
|
7137
7535
|
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
@@ -7139,7 +7537,7 @@
|
|
|
7139
7537
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
7140
7538
|
}
|
|
7141
7539
|
const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
|
|
7142
|
-
if (hasContent && !metadata.
|
|
7540
|
+
if (hasContent && !metadata.passThroughCompression && isCompressed(sizes.compressionMethod, sizes.level)) {
|
|
7143
7541
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
7144
7542
|
}
|
|
7145
7543
|
const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
|
|
@@ -7159,10 +7557,15 @@
|
|
|
7159
7557
|
compressedSize
|
|
7160
7558
|
}));
|
|
7161
7559
|
const entrySize = entryInfo.metadataSize + compressedSize;
|
|
7560
|
+
entrySizes.push(entrySize);
|
|
7561
|
+
entriesAlreadyZip64.add(Boolean(entryOptions.zip64Enabled ||
|
|
7562
|
+
entryOptions.uncompressedSize >= MAX_32_BITS || compressedSize >= MAX_32_BITS));
|
|
7162
7563
|
minimumEntrySize = Math.min(minimumEntrySize, entrySize);
|
|
7163
7564
|
offset += entrySize;
|
|
7164
7565
|
}
|
|
7165
|
-
const layoutDependsOnWriteOrder = files.size > 1 && (usdz ||
|
|
7566
|
+
const layoutDependsOnWriteOrder = files.size > 1 && (usdz ||
|
|
7567
|
+
(offset - minimumEntrySize >= MAX_32_BITS &&
|
|
7568
|
+
(entriesAlreadyZip64.size > 1 || countEntriesBefore4GB(entrySizes, initialOffset, true) != countEntriesBefore4GB(entrySizes, initialOffset, false))));
|
|
7166
7569
|
if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
|
|
7167
7570
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
7168
7571
|
}
|
|
@@ -7180,6 +7583,20 @@
|
|
|
7180
7583
|
return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
7181
7584
|
}
|
|
7182
7585
|
|
|
7586
|
+
function countEntriesBefore4GB(entrySizes, initialOffset, largestFirst) {
|
|
7587
|
+
const ordered = entrySizes.slice().sort((first, second) => largestFirst ? second - first : first - second);
|
|
7588
|
+
let position = initialOffset;
|
|
7589
|
+
let count = 0;
|
|
7590
|
+
for (const entrySize of ordered) {
|
|
7591
|
+
if (position >= MAX_32_BITS) {
|
|
7592
|
+
break;
|
|
7593
|
+
}
|
|
7594
|
+
position += entrySize;
|
|
7595
|
+
count++;
|
|
7596
|
+
}
|
|
7597
|
+
return count;
|
|
7598
|
+
}
|
|
7599
|
+
|
|
7183
7600
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
7184
7601
|
const {
|
|
7185
7602
|
fileEntries,
|
|
@@ -7355,6 +7772,7 @@
|
|
|
7355
7772
|
localExtraFieldZip64Length,
|
|
7356
7773
|
rawExtraFieldExtendedTimestamp,
|
|
7357
7774
|
extraFieldExtendedTimestampFlag,
|
|
7775
|
+
extraFieldExtendedTimestampTime,
|
|
7358
7776
|
rawExtraFieldNTFS,
|
|
7359
7777
|
rawExtraFieldUnix,
|
|
7360
7778
|
rawExtraFieldAES,
|
|
@@ -7367,6 +7785,7 @@
|
|
|
7367
7785
|
password,
|
|
7368
7786
|
rawPassword,
|
|
7369
7787
|
level,
|
|
7788
|
+
useUnicodeFileNames,
|
|
7370
7789
|
zip64,
|
|
7371
7790
|
zip64Enabled,
|
|
7372
7791
|
zip64UncompressedSize,
|
|
@@ -7401,7 +7820,8 @@
|
|
|
7401
7820
|
msdosAttributesRaw,
|
|
7402
7821
|
msdosAttributes,
|
|
7403
7822
|
useCompressionStream,
|
|
7404
|
-
|
|
7823
|
+
passThroughCompression,
|
|
7824
|
+
passThroughEncryption,
|
|
7405
7825
|
format,
|
|
7406
7826
|
codecURI
|
|
7407
7827
|
} = options;
|
|
@@ -7412,9 +7832,9 @@
|
|
|
7412
7832
|
zip64Enabled,
|
|
7413
7833
|
directory: Boolean(directory),
|
|
7414
7834
|
executable: Boolean(executable),
|
|
7415
|
-
filenameUTF8:
|
|
7835
|
+
filenameUTF8: Boolean(useUnicodeFileNames),
|
|
7416
7836
|
rawFilename,
|
|
7417
|
-
commentUTF8:
|
|
7837
|
+
commentUTF8: Boolean(useUnicodeFileNames),
|
|
7418
7838
|
rawComment,
|
|
7419
7839
|
rawExtraFieldZip64,
|
|
7420
7840
|
localExtraFieldZip64Length,
|
|
@@ -7445,7 +7865,7 @@
|
|
|
7445
7865
|
uncompressedSize
|
|
7446
7866
|
} = options;
|
|
7447
7867
|
let compressedSize = 0;
|
|
7448
|
-
if (!
|
|
7868
|
+
if (!passThroughCompression) {
|
|
7449
7869
|
uncompressedSize = 0;
|
|
7450
7870
|
}
|
|
7451
7871
|
const { writable } = writer;
|
|
@@ -7462,9 +7882,9 @@
|
|
|
7462
7882
|
encryptionStrength,
|
|
7463
7883
|
zipCrypto: encrypted && zipCrypto,
|
|
7464
7884
|
passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
|
|
7465
|
-
computeCrc32: !
|
|
7466
|
-
compressed: compressed && !
|
|
7467
|
-
encrypted: encrypted && !
|
|
7885
|
+
computeCrc32: !passThroughCompression,
|
|
7886
|
+
compressed: compressed && !passThroughCompression,
|
|
7887
|
+
encrypted: encrypted && !passThroughEncryption,
|
|
7468
7888
|
useWebWorkers,
|
|
7469
7889
|
useCompressionStream,
|
|
7470
7890
|
transferStreams,
|
|
@@ -7479,7 +7899,7 @@
|
|
|
7479
7899
|
const result = await runWorker({ readable, writable }, workerOptions);
|
|
7480
7900
|
compressedSize = result.outputSize;
|
|
7481
7901
|
writer.size += compressedSize;
|
|
7482
|
-
if (!
|
|
7902
|
+
if (!passThroughCompression) {
|
|
7483
7903
|
uncompressedSize = result.inputSize;
|
|
7484
7904
|
if (!encrypted || zipCrypto) {
|
|
7485
7905
|
crc32 = result.crc32;
|
|
@@ -7490,7 +7910,10 @@
|
|
|
7490
7910
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
7491
7911
|
}
|
|
7492
7912
|
} catch (error) {
|
|
7493
|
-
|
|
7913
|
+
const { outputSize: failedOutputSize } = workerOptions;
|
|
7914
|
+
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
7915
|
+
writer.size += failedOutputSize;
|
|
7916
|
+
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
7494
7917
|
writer.size += error.outputSize;
|
|
7495
7918
|
}
|
|
7496
7919
|
throw error;
|
|
@@ -7522,8 +7945,9 @@
|
|
|
7522
7945
|
headerArray,
|
|
7523
7946
|
headerView,
|
|
7524
7947
|
signature: crc32,
|
|
7525
|
-
crc32: encrypted && !zipCrypto && !
|
|
7948
|
+
crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
|
|
7526
7949
|
extraFieldExtendedTimestampFlag,
|
|
7950
|
+
extraFieldExtendedTimestampTime,
|
|
7527
7951
|
zip64UncompressedSize,
|
|
7528
7952
|
zip64CompressedSize
|
|
7529
7953
|
});
|
|
@@ -7548,7 +7972,7 @@
|
|
|
7548
7972
|
encryptionStrength,
|
|
7549
7973
|
extendedTimestamp,
|
|
7550
7974
|
ntfsTimestamp,
|
|
7551
|
-
|
|
7975
|
+
passThroughCompression,
|
|
7552
7976
|
encrypted,
|
|
7553
7977
|
zip64UncompressedSize,
|
|
7554
7978
|
zip64CompressedSize,
|
|
@@ -7559,7 +7983,7 @@
|
|
|
7559
7983
|
let { version, compressionMethod } = options;
|
|
7560
7984
|
const compressed = !directory && isCompressed(compressionMethod, level);
|
|
7561
7985
|
let rawLocalExtraFieldZip64;
|
|
7562
|
-
const uncompressedFile =
|
|
7986
|
+
const uncompressedFile = passThroughCompression || !compressed;
|
|
7563
7987
|
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
|
|
7564
7988
|
const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
|
|
7565
7989
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
@@ -7571,8 +7995,8 @@
|
|
|
7571
7995
|
if (zip64ExtraFieldComplete) {
|
|
7572
7996
|
extraFieldZip64.writeUint64(uncompressedSize);
|
|
7573
7997
|
if (uncompressedFile) {
|
|
7574
|
-
const encryptionOverhead = encrypted
|
|
7575
|
-
extraFieldZip64.writeUint64(
|
|
7998
|
+
const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
|
|
7999
|
+
extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
|
|
7576
8000
|
}
|
|
7577
8001
|
}
|
|
7578
8002
|
} else {
|
|
@@ -7591,6 +8015,7 @@
|
|
|
7591
8015
|
let rawExtraFieldNTFS;
|
|
7592
8016
|
let rawExtraFieldExtendedTimestamp;
|
|
7593
8017
|
let extraFieldExtendedTimestampFlag;
|
|
8018
|
+
let extraFieldExtendedTimestampTime;
|
|
7594
8019
|
if (extendedTimestamp) {
|
|
7595
8020
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
7596
8021
|
const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
|
|
@@ -7598,6 +8023,7 @@
|
|
|
7598
8023
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
7599
8024
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
7600
8025
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
8026
|
+
extraFieldExtendedTimestampTime = lastModTimeUnix;
|
|
7601
8027
|
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7602
8028
|
extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
|
|
7603
8029
|
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
@@ -7640,7 +8066,7 @@
|
|
|
7640
8066
|
let rawExtraFieldUnix;
|
|
7641
8067
|
try {
|
|
7642
8068
|
const { uid, gid, unixExtraFieldType } = options;
|
|
7643
|
-
if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE
|
|
8069
|
+
if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
7644
8070
|
const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
|
|
7645
8071
|
const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
|
|
7646
8072
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
@@ -7681,7 +8107,7 @@
|
|
|
7681
8107
|
}
|
|
7682
8108
|
if (encrypted && !zipCrypto) {
|
|
7683
8109
|
version = version > VERSION_AES ? version : VERSION_AES;
|
|
7684
|
-
if (
|
|
8110
|
+
if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
|
|
7685
8111
|
rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
|
|
7686
8112
|
}
|
|
7687
8113
|
setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
|
|
@@ -7743,12 +8169,14 @@
|
|
|
7743
8169
|
headerArray,
|
|
7744
8170
|
headerView,
|
|
7745
8171
|
lastModDate: storedLastModDate,
|
|
8172
|
+
lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
|
|
7746
8173
|
rawLastModDate,
|
|
7747
8174
|
encrypted,
|
|
7748
8175
|
compressed,
|
|
7749
8176
|
version,
|
|
7750
8177
|
compressionMethod,
|
|
7751
8178
|
extraFieldExtendedTimestampFlag,
|
|
8179
|
+
extraFieldExtendedTimestampTime,
|
|
7752
8180
|
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
7753
8181
|
localExtraFieldZip64Length,
|
|
7754
8182
|
rawExtraFieldExtendedTimestamp,
|
|
@@ -7851,7 +8279,7 @@
|
|
|
7851
8279
|
}, {
|
|
7852
8280
|
zip64,
|
|
7853
8281
|
zipCrypto,
|
|
7854
|
-
|
|
8282
|
+
passThroughCompression,
|
|
7855
8283
|
dataDescriptor
|
|
7856
8284
|
}) {
|
|
7857
8285
|
const {
|
|
@@ -7862,7 +8290,7 @@
|
|
|
7862
8290
|
dataDescriptorView,
|
|
7863
8291
|
dataDescriptorOffset
|
|
7864
8292
|
} = dataDescriptorInfo;
|
|
7865
|
-
if ((!encrypted || zipCrypto ||
|
|
8293
|
+
if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
|
|
7866
8294
|
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
7867
8295
|
if (dataDescriptor) {
|
|
7868
8296
|
setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
|
|
@@ -7893,9 +8321,9 @@
|
|
|
7893
8321
|
uncompressedSize,
|
|
7894
8322
|
zip64UncompressedSize,
|
|
7895
8323
|
zip64CompressedSize
|
|
7896
|
-
}, localHeaderView, { dataDescriptor,
|
|
8324
|
+
}, localHeaderView, { dataDescriptor, passThroughCompression }) {
|
|
7897
8325
|
if (!dataDescriptor) {
|
|
7898
|
-
if (!encrypted || (
|
|
8326
|
+
if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
|
|
7899
8327
|
setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
|
|
7900
8328
|
}
|
|
7901
8329
|
if (!zip64CompressedSize) {
|
|
@@ -7932,9 +8360,8 @@
|
|
|
7932
8360
|
rawExtraFieldUnix,
|
|
7933
8361
|
rawExtraField,
|
|
7934
8362
|
rawCentralExtraField,
|
|
7935
|
-
extendedTimestamp,
|
|
7936
8363
|
extraFieldExtendedTimestampFlag,
|
|
7937
|
-
|
|
8364
|
+
extraFieldExtendedTimestampTime,
|
|
7938
8365
|
zip64Enabled,
|
|
7939
8366
|
uncompressedSize,
|
|
7940
8367
|
compressedSize
|
|
@@ -7977,16 +8404,15 @@
|
|
|
7977
8404
|
fileEntry.zip64Offset = zip64Offset;
|
|
7978
8405
|
fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
|
|
7979
8406
|
let rawExtraFieldTimestamp;
|
|
7980
|
-
|
|
7981
|
-
|
|
8407
|
+
if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
|
|
8408
|
+
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
8409
|
+
} else {
|
|
7982
8410
|
const extraFieldTimestamp = createRecordWriter(9);
|
|
7983
8411
|
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7984
8412
|
extraFieldTimestamp.writeUint16(5);
|
|
7985
8413
|
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7986
|
-
extraFieldTimestamp.writeUint32(
|
|
8414
|
+
extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
|
|
7987
8415
|
rawExtraFieldTimestamp = extraFieldTimestamp.array;
|
|
7988
|
-
} else {
|
|
7989
|
-
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
7990
8416
|
}
|
|
7991
8417
|
fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
|
|
7992
8418
|
const extraFieldLength = getLength(
|
|
@@ -8486,6 +8912,11 @@
|
|
|
8486
8912
|
};
|
|
8487
8913
|
}
|
|
8488
8914
|
|
|
8915
|
+
function isPrintableASCIIText(rawText) {
|
|
8916
|
+
return rawText.every(characterCode =>
|
|
8917
|
+
characterCode >= MIN_PRINTABLE_ASCII_CHARACTER_CODE && characterCode <= MAX_PRINTABLE_ASCII_CHARACTER_CODE);
|
|
8918
|
+
}
|
|
8919
|
+
|
|
8489
8920
|
function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
|
|
8490
8921
|
let bitFlag = 0;
|
|
8491
8922
|
if (useUnicodeFileNames) {
|
|
@@ -8647,7 +9078,7 @@
|
|
|
8647
9078
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
8648
9079
|
*/
|
|
8649
9080
|
|
|
8650
|
-
const VERSION = "2.
|
|
9081
|
+
const VERSION = "2.13.0";
|
|
8651
9082
|
|
|
8652
9083
|
/*
|
|
8653
9084
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9128,7 +9559,10 @@
|
|
|
9128
9559
|
const ERR_ENTRY_EXISTS = "Entry filename already exists";
|
|
9129
9560
|
const ERR_DUPLICATE_IMPORTED_ENTRY = "Duplicate entry filename in the imported zip file";
|
|
9130
9561
|
const ERR_INVALID_DUPLICATES = "Invalid duplicates option (must be \"throw\", \"keep-first\" or \"keep-last\")";
|
|
9131
|
-
const ERR_ANCESTOR_ENTRY = "Entry is
|
|
9562
|
+
const ERR_ANCESTOR_ENTRY = "Entry is an ancestor of target entry";
|
|
9563
|
+
const ERR_ROOT_DIRECTORY_NOT_MOVABLE = "Root directory cannot be moved";
|
|
9564
|
+
const ERR_TARGET_NOT_DIRECTORY = "Target entry is not a directory";
|
|
9565
|
+
const ERR_PARENT_NOT_DIRECTORY = "Parent entry is not a directory";
|
|
9132
9566
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
9133
9567
|
const DUPLICATES_THROW = "throw";
|
|
9134
9568
|
const DUPLICATES_KEEP_FIRST = "keep-first";
|
|
@@ -9136,22 +9570,8 @@
|
|
|
9136
9570
|
const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
|
|
9137
9571
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
9138
9572
|
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
9139
|
-
const
|
|
9573
|
+
const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
|
|
9140
9574
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
9141
|
-
const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
|
|
9142
|
-
const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
|
|
9143
|
-
EXTRAFIELD_TYPE_ZIP64,
|
|
9144
|
-
EXTRAFIELD_TYPE_AES,
|
|
9145
|
-
EXTRAFIELD_TYPE_NTFS,
|
|
9146
|
-
EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
|
|
9147
|
-
EXTRAFIELD_TYPE_UNICODE_PATH,
|
|
9148
|
-
EXTRAFIELD_TYPE_UNICODE_COMMENT,
|
|
9149
|
-
EXTRAFIELD_TYPE_USDZ,
|
|
9150
|
-
EXTRAFIELD_TYPE_INFOZIP,
|
|
9151
|
-
EXTRAFIELD_TYPE_UNIX,
|
|
9152
|
-
EXTRAFIELD_TYPE_UNIX_TYPE1,
|
|
9153
|
-
EXTRAFIELD_TYPE_PKWARE_UNIX
|
|
9154
|
-
]);
|
|
9155
9575
|
|
|
9156
9576
|
class ZipEntry {
|
|
9157
9577
|
|
|
@@ -9283,7 +9703,7 @@
|
|
|
9283
9703
|
}));
|
|
9284
9704
|
return true;
|
|
9285
9705
|
} catch (error) {
|
|
9286
|
-
if (error.message == ERR_INVALID_PASSWORD) {
|
|
9706
|
+
if (isErrorObject(error) && error.message == ERR_INVALID_PASSWORD) {
|
|
9287
9707
|
return false;
|
|
9288
9708
|
} else {
|
|
9289
9709
|
throw error;
|
|
@@ -9523,6 +9943,7 @@
|
|
|
9523
9943
|
await initStream(reader);
|
|
9524
9944
|
zipReader = new ZipReader(reader, options);
|
|
9525
9945
|
}
|
|
9946
|
+
checkPassThroughValue(options.passThrough);
|
|
9526
9947
|
const duplicates = checkDuplicatesOption(options.duplicates);
|
|
9527
9948
|
const importedEntries = [];
|
|
9528
9949
|
const entries = await zipReader.getEntries(options);
|
|
@@ -9613,18 +10034,25 @@
|
|
|
9613
10034
|
|
|
9614
10035
|
async exportZip(writer, options = {}) {
|
|
9615
10036
|
const zipEntry = this;
|
|
10037
|
+
const zipWriterProvided = Boolean(writer) && typeof writer.add == FUNCTION_TYPE;
|
|
9616
10038
|
options = Object.assign({}, options);
|
|
9617
|
-
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
10039
|
+
if (!zipWriterProvided && options.bufferedWrite === UNDEFINED_VALUE) {
|
|
9618
10040
|
options.bufferedWrite = true;
|
|
9619
10041
|
}
|
|
9620
|
-
const [readers] = await Promise.all([
|
|
9621
|
-
|
|
10042
|
+
const [readers] = await Promise.all([
|
|
10043
|
+
initReaders(zipEntry, checkReaderOptions(options.readerOptions)),
|
|
10044
|
+
zipWriterProvided ? UNDEFINED_VALUE : initStream(writer)
|
|
10045
|
+
]);
|
|
10046
|
+
const zipWriter = zipWriterProvided ? writer : new ZipWriter(writer, options);
|
|
9622
10047
|
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
|
|
10048
|
+
if (zipWriterProvided) {
|
|
10049
|
+
return zipWriter;
|
|
10050
|
+
}
|
|
9623
10051
|
await zipWriter.close(options.globalComment);
|
|
9624
10052
|
return writer.getData ? writer.getData() : writer.writable;
|
|
9625
10053
|
}
|
|
9626
10054
|
|
|
9627
|
-
getExportedSize(options = {}) {
|
|
10055
|
+
async getExportedSize(options = {}) {
|
|
9628
10056
|
const zipEntry = this;
|
|
9629
10057
|
options = Object.assign({}, options);
|
|
9630
10058
|
checkReaderOptions(options.readerOptions);
|
|
@@ -9639,7 +10067,7 @@
|
|
|
9639
10067
|
const writeOrderGuaranteed = !options.bufferedWrite ||
|
|
9640
10068
|
(entries.every(entry => entry.options.keepOrder !== false) &&
|
|
9641
10069
|
children.every(child => isImplicitDirectory(child) || !child.children.length));
|
|
9642
|
-
return getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
|
|
10070
|
+
return await getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
|
|
9643
10071
|
}
|
|
9644
10072
|
|
|
9645
10073
|
getChildByName(name) {
|
|
@@ -9700,7 +10128,7 @@
|
|
|
9700
10128
|
|
|
9701
10129
|
move(entry, destination) {
|
|
9702
10130
|
if (entry == this.root) {
|
|
9703
|
-
throw new Error(
|
|
10131
|
+
throw new Error(ERR_ROOT_DIRECTORY_NOT_MOVABLE);
|
|
9704
10132
|
} else {
|
|
9705
10133
|
if (destination.directory) {
|
|
9706
10134
|
if (!destination.isDescendantOf(entry)) {
|
|
@@ -9721,7 +10149,7 @@
|
|
|
9721
10149
|
throw new Error(ERR_ANCESTOR_ENTRY);
|
|
9722
10150
|
}
|
|
9723
10151
|
} else {
|
|
9724
|
-
throw new Error(
|
|
10152
|
+
throw new Error(ERR_TARGET_NOT_DIRECTORY);
|
|
9725
10153
|
}
|
|
9726
10154
|
}
|
|
9727
10155
|
}
|
|
@@ -10034,70 +10462,11 @@
|
|
|
10034
10462
|
let zipEntryMetadata = {};
|
|
10035
10463
|
let passThroughOptions = {};
|
|
10036
10464
|
if (child.data instanceof Entry) {
|
|
10037
|
-
const
|
|
10038
|
-
|
|
10039
|
-
|
|
10040
|
-
|
|
10041
|
-
|
|
10042
|
-
rawLastModDate,
|
|
10043
|
-
creationDate,
|
|
10044
|
-
lastAccessDate,
|
|
10045
|
-
uncompressedSize,
|
|
10046
|
-
encrypted,
|
|
10047
|
-
zipCrypto,
|
|
10048
|
-
crc32,
|
|
10049
|
-
compressionMethod,
|
|
10050
|
-
extraFieldAES,
|
|
10051
|
-
internalFileAttributes,
|
|
10052
|
-
extraField,
|
|
10053
|
-
bitFlag,
|
|
10054
|
-
uid,
|
|
10055
|
-
gid
|
|
10056
|
-
} = child.data;
|
|
10057
|
-
zipEntryMetadata = {
|
|
10058
|
-
externalFileAttributes,
|
|
10059
|
-
versionMadeBy,
|
|
10060
|
-
comment,
|
|
10061
|
-
lastModDate,
|
|
10062
|
-
creationDate,
|
|
10063
|
-
lastAccessDate,
|
|
10064
|
-
internalFileAttributes
|
|
10065
|
-
};
|
|
10066
|
-
const userExtraField = getUserExtraField(extraField);
|
|
10067
|
-
if (userExtraField) {
|
|
10068
|
-
zipEntryMetadata.extraField = userExtraField;
|
|
10069
|
-
}
|
|
10070
|
-
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
10071
|
-
Object.assign(zipEntryMetadata, {
|
|
10072
|
-
uid,
|
|
10073
|
-
gid,
|
|
10074
|
-
unixExtraFieldType: INFOZIP_EXTRA_FIELD_TYPE
|
|
10075
|
-
});
|
|
10076
|
-
}
|
|
10077
|
-
if (isPassThrough(child, options)) {
|
|
10078
|
-
let encryptionStrength;
|
|
10079
|
-
if (extraFieldAES) {
|
|
10080
|
-
encryptionStrength = extraFieldAES.strength;
|
|
10081
|
-
}
|
|
10082
|
-
passThroughOptions = {
|
|
10083
|
-
passThrough: true,
|
|
10084
|
-
encrypted,
|
|
10085
|
-
zipCrypto,
|
|
10086
|
-
crc32,
|
|
10087
|
-
uncompressedSize,
|
|
10088
|
-
encryptionStrength,
|
|
10089
|
-
compressionMethod
|
|
10090
|
-
};
|
|
10091
|
-
if (bitFlag) {
|
|
10092
|
-
passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
|
|
10093
|
-
}
|
|
10094
|
-
const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
|
|
10095
|
-
if (lastModDateOverride === UNDEFINED_VALUE) {
|
|
10096
|
-
passThroughOptions.rawLastModDate = rawLastModDate;
|
|
10097
|
-
} else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
|
|
10098
|
-
getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
|
|
10099
|
-
throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
|
|
10100
|
-
}
|
|
10465
|
+
const passThrough = isPassThrough(child, options);
|
|
10466
|
+
const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
|
|
10467
|
+
({ entryOptions: zipEntryMetadata, passThroughOptions } = getSourceEntryOptions(child.data, passThrough, lastModDateOverride));
|
|
10468
|
+
if (passThrough) {
|
|
10469
|
+
passThroughOptions.passThrough = true;
|
|
10101
10470
|
}
|
|
10102
10471
|
}
|
|
10103
10472
|
const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
|
|
@@ -10107,16 +10476,6 @@
|
|
|
10107
10476
|
return { name, entryOptions };
|
|
10108
10477
|
}
|
|
10109
10478
|
|
|
10110
|
-
function getDosTimeHighByte(lastModDate) {
|
|
10111
|
-
let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
10112
|
-
if (dosLastModDate < MIN_DATE) {
|
|
10113
|
-
dosLastModDate = MIN_DATE;
|
|
10114
|
-
} else if (dosLastModDate > MAX_DATE) {
|
|
10115
|
-
dosLastModDate = MAX_DATE;
|
|
10116
|
-
}
|
|
10117
|
-
return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
|
|
10118
|
-
}
|
|
10119
|
-
|
|
10120
10479
|
function getDeterminedSize(child, passThrough) {
|
|
10121
10480
|
const { reader } = child;
|
|
10122
10481
|
if (reader && reader.size !== UNDEFINED_VALUE) {
|
|
@@ -10129,9 +10488,18 @@
|
|
|
10129
10488
|
if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
|
|
10130
10489
|
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
10131
10490
|
}
|
|
10491
|
+
if (readerOptions) {
|
|
10492
|
+
checkPassThroughValue(readerOptions.passThrough);
|
|
10493
|
+
}
|
|
10132
10494
|
return readerOptions;
|
|
10133
10495
|
}
|
|
10134
10496
|
|
|
10497
|
+
function checkPassThroughValue(passThrough) {
|
|
10498
|
+
if (checkPassThroughOption(passThrough) === PASS_THROUGH_COMPRESSED) {
|
|
10499
|
+
throw new Error(ERR_UNSUPPORTED_PASS_THROUGH_VALUE);
|
|
10500
|
+
}
|
|
10501
|
+
}
|
|
10502
|
+
|
|
10135
10503
|
function replaceContent(zipEntry, params) {
|
|
10136
10504
|
const { uncompressedSize } = params;
|
|
10137
10505
|
Object.assign(zipEntry, params, {
|
|
@@ -10160,20 +10528,6 @@
|
|
|
10160
10528
|
return child.directory && child.data === null;
|
|
10161
10529
|
}
|
|
10162
10530
|
|
|
10163
|
-
function getUserExtraField(extraField) {
|
|
10164
|
-
if (extraField) {
|
|
10165
|
-
const userExtraField = new Map();
|
|
10166
|
-
extraField.forEach((field, type) => {
|
|
10167
|
-
if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
|
|
10168
|
-
userExtraField.set(type, field.data);
|
|
10169
|
-
}
|
|
10170
|
-
});
|
|
10171
|
-
if (userExtraField.size) {
|
|
10172
|
-
return userExtraField;
|
|
10173
|
-
}
|
|
10174
|
-
}
|
|
10175
|
-
}
|
|
10176
|
-
|
|
10177
10531
|
async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
10178
10532
|
const { onstart, onprogress, onend, onentryprogress } = options;
|
|
10179
10533
|
const selectedEntry = entry;
|
|
@@ -10276,6 +10630,7 @@
|
|
|
10276
10630
|
|
|
10277
10631
|
async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
10278
10632
|
const { onstart, onprogress, onend } = options;
|
|
10633
|
+
checkPassThroughValue(options.passThrough);
|
|
10279
10634
|
const readerOptions = checkReaderOptions(options.readerOptions);
|
|
10280
10635
|
const abortController = new AbortController();
|
|
10281
10636
|
const { signal } = abortController;
|
|
@@ -10351,7 +10706,7 @@
|
|
|
10351
10706
|
if (exportAborted || isExportAborted(signal.reason)) {
|
|
10352
10707
|
return;
|
|
10353
10708
|
}
|
|
10354
|
-
|
|
10709
|
+
throwIfAborted(signal);
|
|
10355
10710
|
}
|
|
10356
10711
|
try {
|
|
10357
10712
|
if (child.directory) {
|
|
@@ -10484,7 +10839,7 @@
|
|
|
10484
10839
|
}
|
|
10485
10840
|
return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
|
|
10486
10841
|
} else {
|
|
10487
|
-
throw new Error(
|
|
10842
|
+
throw new Error(ERR_PARENT_NOT_DIRECTORY);
|
|
10488
10843
|
}
|
|
10489
10844
|
}
|
|
10490
10845
|
|
|
@@ -10531,6 +10886,7 @@
|
|
|
10531
10886
|
exports.Data64URIWriter = Data64URIWriter;
|
|
10532
10887
|
exports.ERR_ABORTED = ERR_ABORTED;
|
|
10533
10888
|
exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
|
|
10889
|
+
exports.ERR_ANCESTOR_ENTRY = ERR_ANCESTOR_ENTRY;
|
|
10534
10890
|
exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
|
|
10535
10891
|
exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
|
|
10536
10892
|
exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
|
|
@@ -10544,7 +10900,9 @@
|
|
|
10544
10900
|
exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
|
|
10545
10901
|
exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
|
|
10546
10902
|
exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
|
|
10903
|
+
exports.ERR_HTTP_STATUS = ERR_HTTP_STATUS;
|
|
10547
10904
|
exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
|
|
10905
|
+
exports.ERR_INVALID_BASE_URI = ERR_INVALID_BASE_URI;
|
|
10548
10906
|
exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
|
|
10549
10907
|
exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
|
|
10550
10908
|
exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
|
|
@@ -10554,6 +10912,7 @@
|
|
|
10554
10912
|
exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
|
|
10555
10913
|
exports.ERR_INVALID_DUPLICATES = ERR_INVALID_DUPLICATES;
|
|
10556
10914
|
exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
|
|
10915
|
+
exports.ERR_INVALID_ENTRY = ERR_INVALID_ENTRY;
|
|
10557
10916
|
exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
|
|
10558
10917
|
exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
|
|
10559
10918
|
exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
|
|
@@ -10572,6 +10931,7 @@
|
|
|
10572
10931
|
exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
|
|
10573
10932
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
10574
10933
|
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
10934
|
+
exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
|
|
10575
10935
|
exports.ERR_INVALID_READER = ERR_INVALID_READER;
|
|
10576
10936
|
exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
|
|
10577
10937
|
exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
|
|
@@ -10582,14 +10942,19 @@
|
|
|
10582
10942
|
exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
|
|
10583
10943
|
exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
|
|
10584
10944
|
exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
|
|
10945
|
+
exports.ERR_INVALID_URI = ERR_INVALID_URI;
|
|
10585
10946
|
exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
|
|
10586
10947
|
exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
|
|
10587
10948
|
exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
|
|
10588
10949
|
exports.ERR_OVERLAPPING_ENTRY = ERR_OVERLAPPING_ENTRY;
|
|
10950
|
+
exports.ERR_PARENT_NOT_DIRECTORY = ERR_PARENT_NOT_DIRECTORY;
|
|
10589
10951
|
exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
|
|
10590
10952
|
exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
|
|
10953
|
+
exports.ERR_ROOT_DIRECTORY_NOT_MOVABLE = ERR_ROOT_DIRECTORY_NOT_MOVABLE;
|
|
10591
10954
|
exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
|
|
10955
|
+
exports.ERR_TARGET_NOT_DIRECTORY = ERR_TARGET_NOT_DIRECTORY;
|
|
10592
10956
|
exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
|
|
10957
|
+
exports.ERR_UNDEFINED_CRC32 = ERR_UNDEFINED_CRC32;
|
|
10593
10958
|
exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
|
|
10594
10959
|
exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
|
|
10595
10960
|
exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
|
|
@@ -10601,10 +10966,12 @@
|
|
|
10601
10966
|
exports.ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH;
|
|
10602
10967
|
exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
|
|
10603
10968
|
exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
|
|
10969
|
+
exports.ERR_UNSUPPORTED_PASS_THROUGH_VALUE = ERR_UNSUPPORTED_PASS_THROUGH_VALUE;
|
|
10604
10970
|
exports.ERR_UNSUPPORTED_SPLIT_USDZ = ERR_UNSUPPORTED_SPLIT_USDZ;
|
|
10605
10971
|
exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
|
|
10606
10972
|
exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
|
|
10607
10973
|
exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
|
|
10974
|
+
exports.ERR_WRITER_SIZE_NOT_WRITABLE = ERR_WRITER_SIZE_NOT_WRITABLE;
|
|
10608
10975
|
exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
|
|
10609
10976
|
exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
|
|
10610
10977
|
exports.HttpRangeReader = HttpRangeReader;
|
|
@@ -10618,13 +10985,17 @@
|
|
|
10618
10985
|
exports.Uint8ArrayWriter = Uint8ArrayWriter;
|
|
10619
10986
|
exports.VERSION = VERSION;
|
|
10620
10987
|
exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
|
|
10988
|
+
exports.WARNING_CLAMPED_LAST_MODIFICATION_DATE = WARNING_CLAMPED_LAST_MODIFICATION_DATE;
|
|
10621
10989
|
exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
|
|
10990
|
+
exports.WARNING_COMPRESSION_UNAVAILABLE = WARNING_COMPRESSION_UNAVAILABLE;
|
|
10622
10991
|
exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
|
|
10623
10992
|
exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
|
|
10624
10993
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
|
|
10625
10994
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
|
|
10626
10995
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
|
|
10996
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME;
|
|
10627
10997
|
exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
|
|
10998
|
+
exports.WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY;
|
|
10628
10999
|
exports.WARNING_PREPENDED_CENTRAL_DIRECTORY = WARNING_PREPENDED_CENTRAL_DIRECTORY;
|
|
10629
11000
|
exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
|
|
10630
11001
|
exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;
|