@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-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 });
|
|
3394
|
+
}
|
|
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
|
|
3292
3414
|
}
|
|
3293
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());
|
|
@@ -4148,7 +4275,7 @@
|
|
|
4148
4275
|
|
|
4149
4276
|
async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
|
|
4150
4277
|
const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
|
|
4151
|
-
if (response.status
|
|
4278
|
+
if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
|
|
4152
4279
|
return response;
|
|
4153
4280
|
} else {
|
|
4154
4281
|
throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
|
|
@@ -4159,7 +4286,7 @@
|
|
|
4159
4286
|
return new Promise((resolve, reject) => {
|
|
4160
4287
|
const request = new XMLHttpRequest();
|
|
4161
4288
|
request.addEventListener("load", () => {
|
|
4162
|
-
if (request.status
|
|
4289
|
+
if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
|
|
4163
4290
|
const headers = [];
|
|
4164
4291
|
request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
|
|
4165
4292
|
const splitHeader = header.trim().split(/\s*:\s*/);
|
|
@@ -4463,8 +4590,10 @@
|
|
|
4463
4590
|
writable: toCompatibleWritable(writer)
|
|
4464
4591
|
};
|
|
4465
4592
|
}
|
|
4466
|
-
|
|
4467
|
-
writer.size = 0;
|
|
4593
|
+
try {
|
|
4594
|
+
writer.size = writer.size === UNDEFINED_VALUE ? 0 : writer.size;
|
|
4595
|
+
} catch {
|
|
4596
|
+
throw new Error(ERR_WRITER_SIZE_NOT_WRITABLE);
|
|
4468
4597
|
}
|
|
4469
4598
|
return writer;
|
|
4470
4599
|
}
|
|
@@ -4512,6 +4641,45 @@
|
|
|
4512
4641
|
}
|
|
4513
4642
|
}
|
|
4514
4643
|
|
|
4644
|
+
/*
|
|
4645
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
4646
|
+
|
|
4647
|
+
Redistribution and use in source and binary forms, with or without
|
|
4648
|
+
modification, are permitted provided that the following conditions are met:
|
|
4649
|
+
|
|
4650
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
4651
|
+
this list of conditions and the following disclaimer.
|
|
4652
|
+
|
|
4653
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
4654
|
+
notice, this list of conditions and the following disclaimer in
|
|
4655
|
+
the documentation and/or other materials provided with the distribution.
|
|
4656
|
+
|
|
4657
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
4658
|
+
derived from this software without specific prior written permission.
|
|
4659
|
+
|
|
4660
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4661
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4662
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4663
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4664
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4665
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4666
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4667
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4668
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4669
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4670
|
+
*/
|
|
4671
|
+
|
|
4672
|
+
|
|
4673
|
+
function addWarning(warnings, reason, filename) {
|
|
4674
|
+
if (!warnings.some(warning => warning.reason == reason)) {
|
|
4675
|
+
const warning = { reason };
|
|
4676
|
+
if (filename !== UNDEFINED_VALUE) {
|
|
4677
|
+
warning.filename = filename;
|
|
4678
|
+
}
|
|
4679
|
+
warnings.push(warning);
|
|
4680
|
+
}
|
|
4681
|
+
}
|
|
4682
|
+
|
|
4515
4683
|
/*
|
|
4516
4684
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4517
4685
|
|
|
@@ -4540,6 +4708,7 @@
|
|
|
4540
4708
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4541
4709
|
*/
|
|
4542
4710
|
|
|
4711
|
+
|
|
4543
4712
|
const PROPERTY_NAME_FILENAME = "filename";
|
|
4544
4713
|
const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
|
|
4545
4714
|
const PROPERTY_NAME_COMMENT = "comment";
|
|
@@ -4664,6 +4833,38 @@
|
|
|
4664
4833
|
|
|
4665
4834
|
}
|
|
4666
4835
|
|
|
4836
|
+
const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
|
|
4837
|
+
EXTRAFIELD_TYPE_ZIP64,
|
|
4838
|
+
EXTRAFIELD_TYPE_AES,
|
|
4839
|
+
EXTRAFIELD_TYPE_NTFS,
|
|
4840
|
+
EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
|
|
4841
|
+
EXTRAFIELD_TYPE_UNICODE_PATH,
|
|
4842
|
+
EXTRAFIELD_TYPE_UNICODE_COMMENT,
|
|
4843
|
+
EXTRAFIELD_TYPE_USDZ,
|
|
4844
|
+
EXTRAFIELD_TYPE_INFOZIP,
|
|
4845
|
+
EXTRAFIELD_TYPE_UNIX,
|
|
4846
|
+
EXTRAFIELD_TYPE_UNIX_TYPE1,
|
|
4847
|
+
EXTRAFIELD_TYPE_PKWARE_UNIX
|
|
4848
|
+
]);
|
|
4849
|
+
|
|
4850
|
+
function getUserExtraField(extraField) {
|
|
4851
|
+
if (extraField) {
|
|
4852
|
+
const userExtraField = new Map();
|
|
4853
|
+
extraField.forEach((field, type) => {
|
|
4854
|
+
if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
|
|
4855
|
+
userExtraField.set(type, field.data);
|
|
4856
|
+
}
|
|
4857
|
+
});
|
|
4858
|
+
if (userExtraField.size) {
|
|
4859
|
+
return userExtraField;
|
|
4860
|
+
}
|
|
4861
|
+
}
|
|
4862
|
+
}
|
|
4863
|
+
|
|
4864
|
+
function getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength) {
|
|
4865
|
+
return encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
4866
|
+
}
|
|
4867
|
+
|
|
4667
4868
|
/*
|
|
4668
4869
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4669
4870
|
|
|
@@ -4723,6 +4924,8 @@
|
|
|
4723
4924
|
const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
|
|
4724
4925
|
const WARNING_DUPLICATE_FILENAME = "duplicate filename";
|
|
4725
4926
|
const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
|
|
4927
|
+
const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
|
|
4928
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = "mismatched local file header (filename)";
|
|
4726
4929
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
|
|
4727
4930
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
|
|
4728
4931
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
@@ -4793,7 +4996,7 @@
|
|
|
4793
4996
|
}
|
|
4794
4997
|
}
|
|
4795
4998
|
if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
|
|
4796
|
-
throwAmbiguousArchive(
|
|
4999
|
+
throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
|
|
4797
5000
|
}
|
|
4798
5001
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
4799
5002
|
let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
|
|
@@ -5091,7 +5294,8 @@
|
|
|
5091
5294
|
const writer = new TransformStream();
|
|
5092
5295
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5093
5296
|
arrayBufferPromise.catch(() => { });
|
|
5094
|
-
await fileEntry.getData(writer, entry, zipReader.readRanges,
|
|
5297
|
+
await fileEntry.getData(writer, entry, zipReader.readRanges,
|
|
5298
|
+
Object.assign({}, options, { preventClose: false }));
|
|
5095
5299
|
return arrayBufferPromise;
|
|
5096
5300
|
};
|
|
5097
5301
|
offset = endOffset;
|
|
@@ -5172,49 +5376,101 @@
|
|
|
5172
5376
|
await reader.readable.cancel();
|
|
5173
5377
|
}
|
|
5174
5378
|
}
|
|
5379
|
+
|
|
5380
|
+
[SYMBOL_ASYNC_DISPOSE]() {
|
|
5381
|
+
return this.close();
|
|
5382
|
+
}
|
|
5175
5383
|
}
|
|
5176
5384
|
|
|
5177
5385
|
class ZipReaderStream {
|
|
5178
5386
|
|
|
5179
5387
|
constructor(options = {}) {
|
|
5180
|
-
|
|
5181
|
-
const
|
|
5388
|
+
let sourceController;
|
|
5389
|
+
const { readable, writable } = new TransformStream({
|
|
5390
|
+
start(controller) {
|
|
5391
|
+
sourceController = controller;
|
|
5392
|
+
}
|
|
5393
|
+
});
|
|
5394
|
+
const zipReader = new ZipReader(readable, options);
|
|
5395
|
+
const gen = zipReader.getEntriesGenerator();
|
|
5396
|
+
const pendingEntries = new Set();
|
|
5182
5397
|
this.readable = new ReadableStream({
|
|
5183
5398
|
async pull(controller) {
|
|
5184
5399
|
const { done, value } = await gen.next();
|
|
5185
5400
|
if (done)
|
|
5186
5401
|
return controller.close();
|
|
5187
|
-
const
|
|
5188
|
-
const { readable, writable } = new TransformStream();
|
|
5189
|
-
if (value.getData) {
|
|
5190
|
-
getData();
|
|
5191
|
-
return readable;
|
|
5192
|
-
}
|
|
5193
|
-
|
|
5194
|
-
async function getData() {
|
|
5195
|
-
try {
|
|
5196
|
-
await value.getData(writable);
|
|
5197
|
-
} catch (error) {
|
|
5198
|
-
try {
|
|
5199
|
-
await writable.abort(error);
|
|
5200
|
-
} catch {
|
|
5201
|
-
// ignored
|
|
5202
|
-
}
|
|
5203
|
-
}
|
|
5204
|
-
}
|
|
5205
|
-
})();
|
|
5402
|
+
const entryStream = createEntryStream(value, pendingEntries);
|
|
5206
5403
|
const chunk = {
|
|
5207
5404
|
...value,
|
|
5208
|
-
readable:
|
|
5405
|
+
readable: entryStream.readable
|
|
5209
5406
|
};
|
|
5210
5407
|
delete chunk.getData;
|
|
5408
|
+
Object.defineProperties(chunk, {
|
|
5409
|
+
localDirectory: {
|
|
5410
|
+
get: () => value.localDirectory,
|
|
5411
|
+
enumerable: true
|
|
5412
|
+
},
|
|
5413
|
+
warnings: {
|
|
5414
|
+
get: () => value.warnings,
|
|
5415
|
+
enumerable: true
|
|
5416
|
+
}
|
|
5417
|
+
});
|
|
5211
5418
|
controller.enqueue(chunk);
|
|
5419
|
+
},
|
|
5420
|
+
async cancel(reason) {
|
|
5421
|
+
const entryStreams = Array.from(pendingEntries);
|
|
5422
|
+
pendingEntries.clear();
|
|
5423
|
+
sourceController.error(reason);
|
|
5424
|
+
await Promise.allSettled(entryStreams.map(entryStream => entryStream.cancel(reason)));
|
|
5425
|
+
await Promise.allSettled([gen.return(), zipReader.close()]);
|
|
5212
5426
|
}
|
|
5213
5427
|
});
|
|
5214
5428
|
this.writable = writable;
|
|
5215
5429
|
}
|
|
5216
5430
|
}
|
|
5217
5431
|
|
|
5432
|
+
function createEntryStream(entry, pendingEntries) {
|
|
5433
|
+
const { readable, writable } = new TransformStream();
|
|
5434
|
+
let dataReader;
|
|
5435
|
+
const entryStream = {
|
|
5436
|
+
cancel: async reason => {
|
|
5437
|
+
pendingEntries.delete(entryStream);
|
|
5438
|
+
await (dataReader ? dataReader.cancel(reason) : readable.cancel(reason));
|
|
5439
|
+
}
|
|
5440
|
+
};
|
|
5441
|
+
entryStream.readable = new ReadableStream({
|
|
5442
|
+
async pull(controller) {
|
|
5443
|
+
if (!dataReader) {
|
|
5444
|
+
dataReader = readable.getReader();
|
|
5445
|
+
pendingEntries.add(entryStream);
|
|
5446
|
+
getData();
|
|
5447
|
+
}
|
|
5448
|
+
const { done, value } = await dataReader.read();
|
|
5449
|
+
if (done) {
|
|
5450
|
+
controller.close();
|
|
5451
|
+
} else {
|
|
5452
|
+
controller.enqueue(value);
|
|
5453
|
+
}
|
|
5454
|
+
},
|
|
5455
|
+
cancel: reason => entryStream.cancel(reason)
|
|
5456
|
+
}, { highWaterMark: 0 });
|
|
5457
|
+
return entryStream;
|
|
5458
|
+
|
|
5459
|
+
async function getData() {
|
|
5460
|
+
try {
|
|
5461
|
+
await entry.getData(writable, { preventClose: false });
|
|
5462
|
+
} catch (error) {
|
|
5463
|
+
try {
|
|
5464
|
+
await writable.abort(error);
|
|
5465
|
+
} catch {
|
|
5466
|
+
// ignored
|
|
5467
|
+
}
|
|
5468
|
+
} finally {
|
|
5469
|
+
pendingEntries.delete(entryStream);
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
}
|
|
5473
|
+
|
|
5218
5474
|
async function isZipFile(reader, options = {}) {
|
|
5219
5475
|
reader = new GenericReader(reader);
|
|
5220
5476
|
await initStream(reader);
|
|
@@ -5274,7 +5530,9 @@
|
|
|
5274
5530
|
const dataView = getDataView(dataArray);
|
|
5275
5531
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
5276
5532
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
5277
|
-
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
5533
|
+
const passThrough = checkPassThroughOption(getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH));
|
|
5534
|
+
const passThroughCompression = Boolean(passThrough);
|
|
5535
|
+
const passThroughEncryption = passThrough === true;
|
|
5278
5536
|
checkPasswordOption(password, rawPassword);
|
|
5279
5537
|
password = password && password.length && password;
|
|
5280
5538
|
rawPassword = rawPassword && rawPassword.length && rawPassword;
|
|
@@ -5295,7 +5553,9 @@
|
|
|
5295
5553
|
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5296
5554
|
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5297
5555
|
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
5298
|
-
const
|
|
5556
|
+
const checkLocalFilenameOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_FILENAME);
|
|
5557
|
+
const checkLocalFilename = getCheckLocalFilename(
|
|
5558
|
+
checkLocalFilenameOption === UNDEFINED_VALUE ? checkLocalDirectoryOption : checkLocalFilenameOption, entryStrictness);
|
|
5299
5559
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
5300
5560
|
if (checkLocalFilename && (filenameLength || extraFieldLength)) {
|
|
5301
5561
|
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
@@ -5326,16 +5586,17 @@
|
|
|
5326
5586
|
if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
|
|
5327
5587
|
fileEntry.gid = gid;
|
|
5328
5588
|
}
|
|
5329
|
-
const
|
|
5589
|
+
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5590
|
+
const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
|
|
5330
5591
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
5331
|
-
if (!
|
|
5592
|
+
if (!passThroughEncryption) {
|
|
5332
5593
|
fileEntry.zipCrypto = zipCrypto;
|
|
5333
5594
|
}
|
|
5334
5595
|
if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
|
|
5335
5596
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
|
|
5336
5597
|
}
|
|
5337
|
-
const registeredCodec =
|
|
5338
|
-
if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !
|
|
5598
|
+
const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
5599
|
+
if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThroughCompression) {
|
|
5339
5600
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
5340
5601
|
}
|
|
5341
5602
|
if (encrypted) {
|
|
@@ -5352,15 +5613,16 @@
|
|
|
5352
5613
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5353
5614
|
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5354
5615
|
throwIfAborted(signal);
|
|
5355
|
-
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5356
5616
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
5357
5617
|
const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
|
|
5358
5618
|
if (checkOverlappingEntryOnly) {
|
|
5359
5619
|
checkOverlappingEntry = true;
|
|
5360
5620
|
}
|
|
5361
5621
|
const { onstart, onprogress, onend } = options;
|
|
5362
|
-
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !
|
|
5363
|
-
const outputSize =
|
|
5622
|
+
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThroughCompression;
|
|
5623
|
+
const outputSize = passThroughCompression ?
|
|
5624
|
+
compressedSize - getEncryptionOverhead(encrypted, zipCrypto, extraFieldAES && extraFieldAES.strength) :
|
|
5625
|
+
uncompressedSize;
|
|
5364
5626
|
const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
|
|
5365
5627
|
let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5366
5628
|
if (deflate64) {
|
|
@@ -5369,7 +5631,7 @@
|
|
|
5369
5631
|
const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
|
|
5370
5632
|
const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
|
|
5371
5633
|
getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
|
|
5372
|
-
checkCrc32Option) && !
|
|
5634
|
+
checkCrc32Option) && !passThroughCompression &&
|
|
5373
5635
|
(!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
|
|
5374
5636
|
const workerOptions = {
|
|
5375
5637
|
options: {
|
|
@@ -5413,7 +5675,7 @@
|
|
|
5413
5675
|
readRanges
|
|
5414
5676
|
});
|
|
5415
5677
|
}
|
|
5416
|
-
let writable, abortError;
|
|
5678
|
+
let writable, abortError, aborted;
|
|
5417
5679
|
try {
|
|
5418
5680
|
if (!checkOverlappingEntryOnly) {
|
|
5419
5681
|
if (checkPasswordOnly) {
|
|
@@ -5423,24 +5685,28 @@
|
|
|
5423
5685
|
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5424
5686
|
({ writable } = writer);
|
|
5425
5687
|
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5426
|
-
writer.size += writtenSize;
|
|
5427
5688
|
if (writtenSize != outputSize) {
|
|
5428
|
-
throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
5689
|
+
throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
|
|
5429
5690
|
}
|
|
5691
|
+
writer.size += writtenSize;
|
|
5430
5692
|
}
|
|
5431
5693
|
} catch (error) {
|
|
5432
|
-
|
|
5694
|
+
const { outputSize: failedOutputSize } = workerOptions;
|
|
5695
|
+
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5696
|
+
writer.size += failedOutputSize;
|
|
5697
|
+
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5433
5698
|
writer.size += error.outputSize;
|
|
5434
5699
|
}
|
|
5435
|
-
if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
5700
|
+
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
5436
5701
|
abortError = error;
|
|
5702
|
+
aborted = true;
|
|
5437
5703
|
throw error;
|
|
5438
5704
|
}
|
|
5439
5705
|
} finally {
|
|
5440
5706
|
const preventClose = !ownsWritable(writer) && getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
|
|
5441
5707
|
if (!preventClose && writable && !writable.locked) {
|
|
5442
5708
|
const writableWriter = writable.getWriter();
|
|
5443
|
-
if (
|
|
5709
|
+
if (aborted) {
|
|
5444
5710
|
try {
|
|
5445
5711
|
await writableWriter.abort(abortError);
|
|
5446
5712
|
} catch {
|
|
@@ -6092,7 +6358,7 @@
|
|
|
6092
6358
|
if (checkLocalFilename && !maskedLocalDirectory &&
|
|
6093
6359
|
(rawLocalFilename.length != rawFilename.length ||
|
|
6094
6360
|
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
6095
|
-
reportAmbiguity(reject, warnings,
|
|
6361
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
|
|
6096
6362
|
}
|
|
6097
6363
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
6098
6364
|
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
|
|
@@ -6117,16 +6383,6 @@
|
|
|
6117
6383
|
}
|
|
6118
6384
|
}
|
|
6119
6385
|
|
|
6120
|
-
function addWarning(warnings, reason, filename) {
|
|
6121
|
-
if (!warnings.some(warning => warning.reason == reason)) {
|
|
6122
|
-
const warning = { reason };
|
|
6123
|
-
if (filename !== UNDEFINED_VALUE) {
|
|
6124
|
-
warning.filename = filename;
|
|
6125
|
-
}
|
|
6126
|
-
warnings.push(warning);
|
|
6127
|
-
}
|
|
6128
|
-
}
|
|
6129
|
-
|
|
6130
6386
|
function throwAmbiguousArchive(reason) {
|
|
6131
6387
|
const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
|
|
6132
6388
|
error.reason = reason;
|
|
@@ -6206,7 +6462,9 @@
|
|
|
6206
6462
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
|
|
6207
6463
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
|
|
6208
6464
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
|
|
6465
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
|
|
6209
6466
|
WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
|
|
6467
|
+
WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
|
|
6210
6468
|
WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
|
|
6211
6469
|
WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
|
|
6212
6470
|
WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
|
|
@@ -6259,7 +6517,7 @@
|
|
|
6259
6517
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
6260
6518
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
6261
6519
|
const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
|
|
6262
|
-
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
6520
|
+
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set to true (use 'compressed' instead)";
|
|
6263
6521
|
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
6264
6522
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
6265
6523
|
const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
|
|
@@ -6271,6 +6529,7 @@
|
|
|
6271
6529
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
6272
6530
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
6273
6531
|
const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
|
|
6532
|
+
const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
|
|
6274
6533
|
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
6275
6534
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
6276
6535
|
const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
|
|
@@ -6284,14 +6543,21 @@
|
|
|
6284
6543
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
6285
6544
|
const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
|
|
6286
6545
|
const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
6546
|
+
const ERR_INVALID_ENTRY = "Invalid entry option (must be an entry returned by ZipReader#getEntries())";
|
|
6547
|
+
const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
|
|
6548
|
+
const WARNING_COMPRESSION_UNAVAILABLE = "compression unavailable";
|
|
6549
|
+
const WARNING_CLAMPED_LAST_MODIFICATION_DATE = "clamped last modification date";
|
|
6287
6550
|
|
|
6288
6551
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
6289
6552
|
const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
|
|
6290
6553
|
const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
|
|
6291
6554
|
const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
|
|
6555
|
+
const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
|
|
6556
|
+
const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
|
|
6292
6557
|
const VENDOR_VERSION_AE_1 = 1;
|
|
6293
6558
|
const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
|
|
6294
6559
|
const UNIX_EXTRA_FIELD_TYPE = "unix";
|
|
6560
|
+
const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
|
|
6295
6561
|
const MAX_LEVEL = 9;
|
|
6296
6562
|
|
|
6297
6563
|
let workers = 0;
|
|
@@ -6318,9 +6584,11 @@
|
|
|
6318
6584
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
6319
6585
|
pendingAddFileCalls: new Set(),
|
|
6320
6586
|
pendingErrors: [],
|
|
6587
|
+
warnings: [],
|
|
6321
6588
|
bufferedWrites: 0,
|
|
6322
6589
|
directWrites: 0,
|
|
6323
|
-
lastFileEntry: UNDEFINED_VALUE
|
|
6590
|
+
lastFileEntry: UNDEFINED_VALUE,
|
|
6591
|
+
archiveClosed: false
|
|
6324
6592
|
});
|
|
6325
6593
|
}
|
|
6326
6594
|
|
|
@@ -6485,6 +6753,9 @@
|
|
|
6485
6753
|
const zipWriter = this;
|
|
6486
6754
|
const { pendingAddFileCalls, writer } = this;
|
|
6487
6755
|
const { writable } = writer;
|
|
6756
|
+
if (zipWriter.archiveClosed) {
|
|
6757
|
+
return getWriterData(writer);
|
|
6758
|
+
}
|
|
6488
6759
|
if (!(comment instanceof Uint8Array)) {
|
|
6489
6760
|
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
6490
6761
|
}
|
|
@@ -6495,7 +6766,7 @@
|
|
|
6495
6766
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6496
6767
|
}
|
|
6497
6768
|
await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
|
|
6498
|
-
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.
|
|
6769
|
+
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.failed && !watcher.observed);
|
|
6499
6770
|
if (unobservedWatchers.length) {
|
|
6500
6771
|
const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
|
|
6501
6772
|
unobservedWatchers.forEach(watcher => watcher.observed = true);
|
|
@@ -6508,11 +6779,16 @@
|
|
|
6508
6779
|
throw error;
|
|
6509
6780
|
}
|
|
6510
6781
|
await closeFile(zipWriter, comment, options);
|
|
6782
|
+
zipWriter.archiveClosed = true;
|
|
6511
6783
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
6512
6784
|
if (!preventClose) {
|
|
6513
6785
|
await writable.getWriter().close();
|
|
6514
6786
|
}
|
|
6515
|
-
return writer
|
|
6787
|
+
return getWriterData(writer);
|
|
6788
|
+
}
|
|
6789
|
+
|
|
6790
|
+
[SYMBOL_ASYNC_DISPOSE]() {
|
|
6791
|
+
return this.close();
|
|
6516
6792
|
}
|
|
6517
6793
|
}
|
|
6518
6794
|
|
|
@@ -6591,11 +6867,16 @@
|
|
|
6591
6867
|
}
|
|
6592
6868
|
}
|
|
6593
6869
|
|
|
6870
|
+
function getWriterData(writer) {
|
|
6871
|
+
return writer.getData ? writer.getData() : writer.writable;
|
|
6872
|
+
}
|
|
6873
|
+
|
|
6594
6874
|
function watchPromiseError(zipWriter, promise) {
|
|
6595
6875
|
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
6596
6876
|
const watcher = {};
|
|
6597
6877
|
watchedPromise.watcher = watcher;
|
|
6598
|
-
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE,
|
|
6878
|
+
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE,
|
|
6879
|
+
error => Object.assign(watcher, { failed: true, error }));
|
|
6599
6880
|
zipWriter.pendingErrors.push(watcher);
|
|
6600
6881
|
return watchedPromise;
|
|
6601
6882
|
}
|
|
@@ -6609,6 +6890,14 @@
|
|
|
6609
6890
|
|
|
6610
6891
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
6611
6892
|
options = Object.assign({}, options);
|
|
6893
|
+
const entry = options[OPTION_ENTRY];
|
|
6894
|
+
if (entry !== UNDEFINED_VALUE) {
|
|
6895
|
+
const { entryOptions, passThroughOptions } = getSourceEntryOptions(entry,
|
|
6896
|
+
checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH)),
|
|
6897
|
+
getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE));
|
|
6898
|
+
delete options[OPTION_ENTRY];
|
|
6899
|
+
options = Object.assign(entryOptions, passThroughOptions, options);
|
|
6900
|
+
}
|
|
6612
6901
|
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6613
6902
|
name += DIRECTORY_SIGNATURE;
|
|
6614
6903
|
}
|
|
@@ -6673,21 +6962,33 @@
|
|
|
6673
6962
|
try {
|
|
6674
6963
|
const { resolvedOptions } = metadataInfo;
|
|
6675
6964
|
if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
|
|
6676
|
-
!resolvedOptions.
|
|
6965
|
+
!resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
|
|
6677
6966
|
resolvedOptions.level = 0;
|
|
6967
|
+
addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
|
|
6678
6968
|
}
|
|
6679
6969
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
6680
6970
|
({ reader } = sizesInfo);
|
|
6681
6971
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
6682
6972
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
6973
|
+
let crc32 = options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32;
|
|
6974
|
+
const storesAE2 = sizesInfo.resolvedOptions.encrypted && !resolvedOptions.zipCrypto;
|
|
6975
|
+
if (resolvedOptions.passThroughCompression && !resolvedOptions.passThroughEncryption && storesAE2) {
|
|
6976
|
+
crc32 = UNDEFINED_VALUE;
|
|
6977
|
+
}
|
|
6978
|
+
if (resolvedOptions.passThroughCompression && reader && !storesAE2 && crc32 === UNDEFINED_VALUE) {
|
|
6979
|
+
throw new Error(ERR_UNDEFINED_CRC32);
|
|
6980
|
+
}
|
|
6683
6981
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
6684
6982
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
6685
|
-
crc32
|
|
6983
|
+
crc32,
|
|
6686
6984
|
offset: zipWriter.offset - diskOffset,
|
|
6687
6985
|
diskNumberStart: diskNumber,
|
|
6688
6986
|
[OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
|
|
6689
6987
|
});
|
|
6690
6988
|
const headerInfo = getHeaderInfo(options);
|
|
6989
|
+
if (headerInfo.lastModDateClamped) {
|
|
6990
|
+
addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
|
|
6991
|
+
}
|
|
6691
6992
|
const dataDescriptorInfo = getDataDescriptorInfo(options);
|
|
6692
6993
|
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
6693
6994
|
fileEntry = await getFileEntry(zipWriter, name, reader, {
|
|
@@ -6714,6 +7015,95 @@
|
|
|
6714
7015
|
return new Entry(fileEntry);
|
|
6715
7016
|
}
|
|
6716
7017
|
|
|
7018
|
+
function getSourceEntryOptions(entry, passThrough, lastModDateOverride) {
|
|
7019
|
+
if (entry === null || typeof entry != OBJECT_TYPE || Array.isArray(entry)) {
|
|
7020
|
+
throw new Error(ERR_INVALID_ENTRY);
|
|
7021
|
+
}
|
|
7022
|
+
const {
|
|
7023
|
+
externalFileAttributes,
|
|
7024
|
+
versionMadeBy,
|
|
7025
|
+
comment,
|
|
7026
|
+
lastModDate,
|
|
7027
|
+
rawLastModDate,
|
|
7028
|
+
creationDate,
|
|
7029
|
+
lastAccessDate,
|
|
7030
|
+
uncompressedSize,
|
|
7031
|
+
encrypted,
|
|
7032
|
+
zipCrypto,
|
|
7033
|
+
crc32,
|
|
7034
|
+
compressionMethod,
|
|
7035
|
+
extraFieldAES,
|
|
7036
|
+
extraFieldUnix,
|
|
7037
|
+
internalFileAttributes,
|
|
7038
|
+
extraField,
|
|
7039
|
+
bitFlag,
|
|
7040
|
+
directory,
|
|
7041
|
+
uid,
|
|
7042
|
+
gid
|
|
7043
|
+
} = entry;
|
|
7044
|
+
const entryOptions = {
|
|
7045
|
+
externalFileAttributes,
|
|
7046
|
+
versionMadeBy,
|
|
7047
|
+
comment,
|
|
7048
|
+
lastModDate,
|
|
7049
|
+
creationDate,
|
|
7050
|
+
lastAccessDate,
|
|
7051
|
+
internalFileAttributes,
|
|
7052
|
+
directory
|
|
7053
|
+
};
|
|
7054
|
+
if (bitFlag && bitFlag.languageEncodingFlag) {
|
|
7055
|
+
entryOptions[OPTION_USE_UNICODE_FILE_NAMES] = true;
|
|
7056
|
+
}
|
|
7057
|
+
const userExtraField = getUserExtraField(extraField);
|
|
7058
|
+
if (userExtraField) {
|
|
7059
|
+
entryOptions[PROPERTY_NAME_EXTRA_FIELD] = userExtraField;
|
|
7060
|
+
}
|
|
7061
|
+
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
7062
|
+
Object.assign(entryOptions, {
|
|
7063
|
+
uid,
|
|
7064
|
+
gid,
|
|
7065
|
+
unixExtraFieldType: extraFieldUnix ? UNIX_EXTRA_FIELD_TYPE : INFOZIP_EXTRA_FIELD_TYPE
|
|
7066
|
+
});
|
|
7067
|
+
}
|
|
7068
|
+
const passThroughOptions = {};
|
|
7069
|
+
if (passThrough && !directory) {
|
|
7070
|
+
Object.assign(passThroughOptions, {
|
|
7071
|
+
uncompressedSize,
|
|
7072
|
+
crc32,
|
|
7073
|
+
compressionMethod
|
|
7074
|
+
});
|
|
7075
|
+
if (passThrough !== PASS_THROUGH_COMPRESSED) {
|
|
7076
|
+
Object.assign(passThroughOptions, {
|
|
7077
|
+
encrypted,
|
|
7078
|
+
zipCrypto,
|
|
7079
|
+
encryptionStrength: extraFieldAES ? extraFieldAES.strength : UNDEFINED_VALUE
|
|
7080
|
+
});
|
|
7081
|
+
}
|
|
7082
|
+
if (bitFlag) {
|
|
7083
|
+
passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
|
|
7084
|
+
passThroughOptions[OPTION_LEVEL] = LEVEL_BY_BITFLAG_LEVEL[bitFlag.level];
|
|
7085
|
+
}
|
|
7086
|
+
if (lastModDateOverride === UNDEFINED_VALUE) {
|
|
7087
|
+
passThroughOptions.rawLastModDate = rawLastModDate;
|
|
7088
|
+
} else if (passThrough !== PASS_THROUGH_COMPRESSED && zipCrypto && (!bitFlag || bitFlag.dataDescriptor) &&
|
|
7089
|
+
lastModDateOverride instanceof Date &&
|
|
7090
|
+
getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
|
|
7091
|
+
throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
|
|
7092
|
+
}
|
|
7093
|
+
}
|
|
7094
|
+
return { entryOptions, passThroughOptions };
|
|
7095
|
+
}
|
|
7096
|
+
|
|
7097
|
+
function getDosTimeHighByte(lastModDate) {
|
|
7098
|
+
let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
7099
|
+
if (dosLastModDate < MIN_DATE) {
|
|
7100
|
+
dosLastModDate = MIN_DATE;
|
|
7101
|
+
} else if (dosLastModDate > MAX_DATE) {
|
|
7102
|
+
dosLastModDate = MAX_DATE;
|
|
7103
|
+
}
|
|
7104
|
+
return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
|
|
7105
|
+
}
|
|
7106
|
+
|
|
6717
7107
|
function resolveAttributes(zipWriter, name, options) {
|
|
6718
7108
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
6719
7109
|
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
@@ -6867,7 +7257,9 @@
|
|
|
6867
7257
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6868
7258
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6869
7259
|
const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
6870
|
-
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
7260
|
+
const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
|
|
7261
|
+
const passThroughCompression = Boolean(passThrough);
|
|
7262
|
+
const passThroughEncryption = passThrough === true;
|
|
6871
7263
|
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
6872
7264
|
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
6873
7265
|
checkPasswordOption(password, rawPassword);
|
|
@@ -6883,10 +7275,11 @@
|
|
|
6883
7275
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
6884
7276
|
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
6885
7277
|
throwIfAborted(signal);
|
|
6886
|
-
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
|
|
7278
|
+
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
|
|
7279
|
+
!isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
|
|
6887
7280
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
6888
|
-
const registeredCodec =
|
|
6889
|
-
if (!
|
|
7281
|
+
const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
7282
|
+
if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
|
|
6890
7283
|
compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
|
|
6891
7284
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
6892
7285
|
}
|
|
@@ -6900,15 +7293,15 @@
|
|
|
6900
7293
|
level = 0;
|
|
6901
7294
|
}
|
|
6902
7295
|
}
|
|
6903
|
-
if (
|
|
6904
|
-
level =
|
|
7296
|
+
if (passThroughCompression) {
|
|
7297
|
+
level = toNumber(options[OPTION_LEVEL]);
|
|
6905
7298
|
}
|
|
6906
7299
|
let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
|
|
6907
7300
|
let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
|
|
6908
7301
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
6909
7302
|
dataDescriptor = false;
|
|
6910
7303
|
}
|
|
6911
|
-
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !
|
|
7304
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
|
|
6912
7305
|
dataDescriptor = true;
|
|
6913
7306
|
}
|
|
6914
7307
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -6932,7 +7325,8 @@
|
|
|
6932
7325
|
lastAccessDate,
|
|
6933
7326
|
creationDate,
|
|
6934
7327
|
internalFileAttributes,
|
|
6935
|
-
|
|
7328
|
+
passThroughCompression,
|
|
7329
|
+
passThroughEncryption,
|
|
6936
7330
|
password,
|
|
6937
7331
|
rawPassword,
|
|
6938
7332
|
encryptionStrength,
|
|
@@ -6993,7 +7387,7 @@
|
|
|
6993
7387
|
}
|
|
6994
7388
|
|
|
6995
7389
|
async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
|
|
6996
|
-
if (metadata.
|
|
7390
|
+
if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
|
|
6997
7391
|
throw new Error(ERR_UNDEFINED_READER);
|
|
6998
7392
|
}
|
|
6999
7393
|
let contentSize;
|
|
@@ -7009,12 +7403,12 @@
|
|
|
7009
7403
|
}
|
|
7010
7404
|
|
|
7011
7405
|
function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
|
|
7012
|
-
const {
|
|
7406
|
+
const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
|
|
7013
7407
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
7014
7408
|
let maximumCompressedSize = 0;
|
|
7015
7409
|
let uncompressedSize = 0;
|
|
7016
7410
|
let unknownSize = false;
|
|
7017
|
-
if (
|
|
7411
|
+
if (passThroughCompression && hasContent) {
|
|
7018
7412
|
uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
|
|
7019
7413
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
7020
7414
|
throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
|
|
@@ -7025,17 +7419,17 @@
|
|
|
7025
7419
|
}
|
|
7026
7420
|
const zip64Enabled = zip64 === true;
|
|
7027
7421
|
const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
|
|
7028
|
-
if (hasContent &&
|
|
7422
|
+
if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
|
|
7029
7423
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
|
|
7030
7424
|
}
|
|
7031
|
-
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (
|
|
7425
|
+
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThroughEncryption && encrypted));
|
|
7032
7426
|
if (!hasContent) {
|
|
7033
7427
|
level = 0;
|
|
7034
7428
|
compressionMethod = COMPRESSION_METHOD_STORE;
|
|
7035
7429
|
}
|
|
7036
|
-
const encryptionOverhead = encryptedEntry
|
|
7430
|
+
const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
|
|
7037
7431
|
if (hasContent) {
|
|
7038
|
-
if (!
|
|
7432
|
+
if (!passThroughCompression) {
|
|
7039
7433
|
if (contentSize === UNDEFINED_VALUE) {
|
|
7040
7434
|
dataDescriptor = true;
|
|
7041
7435
|
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
@@ -7048,10 +7442,12 @@
|
|
|
7048
7442
|
}
|
|
7049
7443
|
} else {
|
|
7050
7444
|
options.uncompressedSize = uncompressedSize;
|
|
7051
|
-
maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
|
|
7445
|
+
maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
|
|
7446
|
+
getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
|
|
7447
|
+
contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
|
|
7052
7448
|
}
|
|
7053
7449
|
}
|
|
7054
|
-
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !
|
|
7450
|
+
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
|
|
7055
7451
|
if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
7056
7452
|
dataDescriptor = false;
|
|
7057
7453
|
}
|
|
@@ -7258,6 +7654,7 @@
|
|
|
7258
7654
|
localExtraFieldZip64Length,
|
|
7259
7655
|
rawExtraFieldExtendedTimestamp,
|
|
7260
7656
|
extraFieldExtendedTimestampFlag,
|
|
7657
|
+
extraFieldExtendedTimestampTime,
|
|
7261
7658
|
rawExtraFieldNTFS,
|
|
7262
7659
|
rawExtraFieldUnix,
|
|
7263
7660
|
rawExtraFieldAES,
|
|
@@ -7270,6 +7667,7 @@
|
|
|
7270
7667
|
password,
|
|
7271
7668
|
rawPassword,
|
|
7272
7669
|
level,
|
|
7670
|
+
useUnicodeFileNames,
|
|
7273
7671
|
zip64,
|
|
7274
7672
|
zip64Enabled,
|
|
7275
7673
|
zip64UncompressedSize,
|
|
@@ -7304,7 +7702,8 @@
|
|
|
7304
7702
|
msdosAttributesRaw,
|
|
7305
7703
|
msdosAttributes,
|
|
7306
7704
|
useCompressionStream,
|
|
7307
|
-
|
|
7705
|
+
passThroughCompression,
|
|
7706
|
+
passThroughEncryption,
|
|
7308
7707
|
format,
|
|
7309
7708
|
codecURI
|
|
7310
7709
|
} = options;
|
|
@@ -7315,9 +7714,9 @@
|
|
|
7315
7714
|
zip64Enabled,
|
|
7316
7715
|
directory: Boolean(directory),
|
|
7317
7716
|
executable: Boolean(executable),
|
|
7318
|
-
filenameUTF8:
|
|
7717
|
+
filenameUTF8: Boolean(useUnicodeFileNames),
|
|
7319
7718
|
rawFilename,
|
|
7320
|
-
commentUTF8:
|
|
7719
|
+
commentUTF8: Boolean(useUnicodeFileNames),
|
|
7321
7720
|
rawComment,
|
|
7322
7721
|
rawExtraFieldZip64,
|
|
7323
7722
|
localExtraFieldZip64Length,
|
|
@@ -7348,7 +7747,7 @@
|
|
|
7348
7747
|
uncompressedSize
|
|
7349
7748
|
} = options;
|
|
7350
7749
|
let compressedSize = 0;
|
|
7351
|
-
if (!
|
|
7750
|
+
if (!passThroughCompression) {
|
|
7352
7751
|
uncompressedSize = 0;
|
|
7353
7752
|
}
|
|
7354
7753
|
const { writable } = writer;
|
|
@@ -7365,9 +7764,9 @@
|
|
|
7365
7764
|
encryptionStrength,
|
|
7366
7765
|
zipCrypto: encrypted && zipCrypto,
|
|
7367
7766
|
passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
|
|
7368
|
-
computeCrc32: !
|
|
7369
|
-
compressed: compressed && !
|
|
7370
|
-
encrypted: encrypted && !
|
|
7767
|
+
computeCrc32: !passThroughCompression,
|
|
7768
|
+
compressed: compressed && !passThroughCompression,
|
|
7769
|
+
encrypted: encrypted && !passThroughEncryption,
|
|
7371
7770
|
useWebWorkers,
|
|
7372
7771
|
useCompressionStream,
|
|
7373
7772
|
transferStreams,
|
|
@@ -7382,7 +7781,7 @@
|
|
|
7382
7781
|
const result = await runWorker({ readable, writable }, workerOptions);
|
|
7383
7782
|
compressedSize = result.outputSize;
|
|
7384
7783
|
writer.size += compressedSize;
|
|
7385
|
-
if (!
|
|
7784
|
+
if (!passThroughCompression) {
|
|
7386
7785
|
uncompressedSize = result.inputSize;
|
|
7387
7786
|
if (!encrypted || zipCrypto) {
|
|
7388
7787
|
crc32 = result.crc32;
|
|
@@ -7393,7 +7792,10 @@
|
|
|
7393
7792
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
7394
7793
|
}
|
|
7395
7794
|
} catch (error) {
|
|
7396
|
-
|
|
7795
|
+
const { outputSize: failedOutputSize } = workerOptions;
|
|
7796
|
+
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
7797
|
+
writer.size += failedOutputSize;
|
|
7798
|
+
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
7397
7799
|
writer.size += error.outputSize;
|
|
7398
7800
|
}
|
|
7399
7801
|
throw error;
|
|
@@ -7425,8 +7827,9 @@
|
|
|
7425
7827
|
headerArray,
|
|
7426
7828
|
headerView,
|
|
7427
7829
|
signature: crc32,
|
|
7428
|
-
crc32: encrypted && !zipCrypto && !
|
|
7830
|
+
crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
|
|
7429
7831
|
extraFieldExtendedTimestampFlag,
|
|
7832
|
+
extraFieldExtendedTimestampTime,
|
|
7430
7833
|
zip64UncompressedSize,
|
|
7431
7834
|
zip64CompressedSize
|
|
7432
7835
|
});
|
|
@@ -7451,7 +7854,7 @@
|
|
|
7451
7854
|
encryptionStrength,
|
|
7452
7855
|
extendedTimestamp,
|
|
7453
7856
|
ntfsTimestamp,
|
|
7454
|
-
|
|
7857
|
+
passThroughCompression,
|
|
7455
7858
|
encrypted,
|
|
7456
7859
|
zip64UncompressedSize,
|
|
7457
7860
|
zip64CompressedSize,
|
|
@@ -7462,7 +7865,7 @@
|
|
|
7462
7865
|
let { version, compressionMethod } = options;
|
|
7463
7866
|
const compressed = !directory && isCompressed(compressionMethod, level);
|
|
7464
7867
|
let rawLocalExtraFieldZip64;
|
|
7465
|
-
const uncompressedFile =
|
|
7868
|
+
const uncompressedFile = passThroughCompression || !compressed;
|
|
7466
7869
|
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
|
|
7467
7870
|
const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
|
|
7468
7871
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
@@ -7474,8 +7877,8 @@
|
|
|
7474
7877
|
if (zip64ExtraFieldComplete) {
|
|
7475
7878
|
extraFieldZip64.writeUint64(uncompressedSize);
|
|
7476
7879
|
if (uncompressedFile) {
|
|
7477
|
-
const encryptionOverhead = encrypted
|
|
7478
|
-
extraFieldZip64.writeUint64(
|
|
7880
|
+
const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
|
|
7881
|
+
extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
|
|
7479
7882
|
}
|
|
7480
7883
|
}
|
|
7481
7884
|
} else {
|
|
@@ -7494,6 +7897,7 @@
|
|
|
7494
7897
|
let rawExtraFieldNTFS;
|
|
7495
7898
|
let rawExtraFieldExtendedTimestamp;
|
|
7496
7899
|
let extraFieldExtendedTimestampFlag;
|
|
7900
|
+
let extraFieldExtendedTimestampTime;
|
|
7497
7901
|
if (extendedTimestamp) {
|
|
7498
7902
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
7499
7903
|
const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
|
|
@@ -7501,6 +7905,7 @@
|
|
|
7501
7905
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
7502
7906
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
7503
7907
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
7908
|
+
extraFieldExtendedTimestampTime = lastModTimeUnix;
|
|
7504
7909
|
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7505
7910
|
extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
|
|
7506
7911
|
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
@@ -7584,7 +7989,7 @@
|
|
|
7584
7989
|
}
|
|
7585
7990
|
if (encrypted && !zipCrypto) {
|
|
7586
7991
|
version = version > VERSION_AES ? version : VERSION_AES;
|
|
7587
|
-
if (
|
|
7992
|
+
if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
|
|
7588
7993
|
rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
|
|
7589
7994
|
}
|
|
7590
7995
|
setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
|
|
@@ -7646,12 +8051,14 @@
|
|
|
7646
8051
|
headerArray,
|
|
7647
8052
|
headerView,
|
|
7648
8053
|
lastModDate: storedLastModDate,
|
|
8054
|
+
lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
|
|
7649
8055
|
rawLastModDate,
|
|
7650
8056
|
encrypted,
|
|
7651
8057
|
compressed,
|
|
7652
8058
|
version,
|
|
7653
8059
|
compressionMethod,
|
|
7654
8060
|
extraFieldExtendedTimestampFlag,
|
|
8061
|
+
extraFieldExtendedTimestampTime,
|
|
7655
8062
|
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
7656
8063
|
localExtraFieldZip64Length,
|
|
7657
8064
|
rawExtraFieldExtendedTimestamp,
|
|
@@ -7754,7 +8161,7 @@
|
|
|
7754
8161
|
}, {
|
|
7755
8162
|
zip64,
|
|
7756
8163
|
zipCrypto,
|
|
7757
|
-
|
|
8164
|
+
passThroughCompression,
|
|
7758
8165
|
dataDescriptor
|
|
7759
8166
|
}) {
|
|
7760
8167
|
const {
|
|
@@ -7765,7 +8172,7 @@
|
|
|
7765
8172
|
dataDescriptorView,
|
|
7766
8173
|
dataDescriptorOffset
|
|
7767
8174
|
} = dataDescriptorInfo;
|
|
7768
|
-
if ((!encrypted || zipCrypto ||
|
|
8175
|
+
if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
|
|
7769
8176
|
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
7770
8177
|
if (dataDescriptor) {
|
|
7771
8178
|
setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
|
|
@@ -7796,9 +8203,9 @@
|
|
|
7796
8203
|
uncompressedSize,
|
|
7797
8204
|
zip64UncompressedSize,
|
|
7798
8205
|
zip64CompressedSize
|
|
7799
|
-
}, localHeaderView, { dataDescriptor,
|
|
8206
|
+
}, localHeaderView, { dataDescriptor, passThroughCompression }) {
|
|
7800
8207
|
if (!dataDescriptor) {
|
|
7801
|
-
if (!encrypted || (
|
|
8208
|
+
if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
|
|
7802
8209
|
setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
|
|
7803
8210
|
}
|
|
7804
8211
|
if (!zip64CompressedSize) {
|
|
@@ -7835,9 +8242,8 @@
|
|
|
7835
8242
|
rawExtraFieldUnix,
|
|
7836
8243
|
rawExtraField,
|
|
7837
8244
|
rawCentralExtraField,
|
|
7838
|
-
extendedTimestamp,
|
|
7839
8245
|
extraFieldExtendedTimestampFlag,
|
|
7840
|
-
|
|
8246
|
+
extraFieldExtendedTimestampTime,
|
|
7841
8247
|
zip64Enabled,
|
|
7842
8248
|
uncompressedSize,
|
|
7843
8249
|
compressedSize
|
|
@@ -7880,16 +8286,15 @@
|
|
|
7880
8286
|
fileEntry.zip64Offset = zip64Offset;
|
|
7881
8287
|
fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
|
|
7882
8288
|
let rawExtraFieldTimestamp;
|
|
7883
|
-
|
|
7884
|
-
|
|
8289
|
+
if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
|
|
8290
|
+
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
8291
|
+
} else {
|
|
7885
8292
|
const extraFieldTimestamp = createRecordWriter(9);
|
|
7886
8293
|
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7887
8294
|
extraFieldTimestamp.writeUint16(5);
|
|
7888
8295
|
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7889
|
-
extraFieldTimestamp.writeUint32(
|
|
8296
|
+
extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
|
|
7890
8297
|
rawExtraFieldTimestamp = extraFieldTimestamp.array;
|
|
7891
|
-
} else {
|
|
7892
|
-
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
7893
8298
|
}
|
|
7894
8299
|
fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
|
|
7895
8300
|
const extraFieldLength = getLength(
|
|
@@ -8389,6 +8794,11 @@
|
|
|
8389
8794
|
};
|
|
8390
8795
|
}
|
|
8391
8796
|
|
|
8797
|
+
function isPrintableASCIIText(rawText) {
|
|
8798
|
+
return rawText.every(characterCode =>
|
|
8799
|
+
characterCode >= MIN_PRINTABLE_ASCII_CHARACTER_CODE && characterCode <= MAX_PRINTABLE_ASCII_CHARACTER_CODE);
|
|
8800
|
+
}
|
|
8801
|
+
|
|
8392
8802
|
function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
|
|
8393
8803
|
let bitFlag = 0;
|
|
8394
8804
|
if (useUnicodeFileNames) {
|
|
@@ -8550,7 +8960,7 @@
|
|
|
8550
8960
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
8551
8961
|
*/
|
|
8552
8962
|
|
|
8553
|
-
const VERSION = "2.
|
|
8963
|
+
const VERSION = "2.13.0";
|
|
8554
8964
|
|
|
8555
8965
|
/*
|
|
8556
8966
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9003,6 +9413,7 @@
|
|
|
9003
9413
|
exports.BlobWriter = BlobWriter;
|
|
9004
9414
|
exports.Data64URIReader = Data64URIReader;
|
|
9005
9415
|
exports.Data64URIWriter = Data64URIWriter;
|
|
9416
|
+
exports.ERR_ABORTED = ERR_ABORTED;
|
|
9006
9417
|
exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
|
|
9007
9418
|
exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
|
|
9008
9419
|
exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
|
|
@@ -9015,7 +9426,9 @@
|
|
|
9015
9426
|
exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
|
|
9016
9427
|
exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
|
|
9017
9428
|
exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
|
|
9429
|
+
exports.ERR_HTTP_STATUS = ERR_HTTP_STATUS;
|
|
9018
9430
|
exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
|
|
9431
|
+
exports.ERR_INVALID_BASE_URI = ERR_INVALID_BASE_URI;
|
|
9019
9432
|
exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
|
|
9020
9433
|
exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
|
|
9021
9434
|
exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
|
|
@@ -9024,6 +9437,7 @@
|
|
|
9024
9437
|
exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
|
|
9025
9438
|
exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
|
|
9026
9439
|
exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
|
|
9440
|
+
exports.ERR_INVALID_ENTRY = ERR_INVALID_ENTRY;
|
|
9027
9441
|
exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
|
|
9028
9442
|
exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
|
|
9029
9443
|
exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
|
|
@@ -9041,6 +9455,7 @@
|
|
|
9041
9455
|
exports.ERR_INVALID_MSDOS_DATA = ERR_INVALID_MSDOS_DATA;
|
|
9042
9456
|
exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
|
|
9043
9457
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
9458
|
+
exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
|
|
9044
9459
|
exports.ERR_INVALID_READER = ERR_INVALID_READER;
|
|
9045
9460
|
exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
|
|
9046
9461
|
exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
|
|
@@ -9050,6 +9465,7 @@
|
|
|
9050
9465
|
exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
|
|
9051
9466
|
exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
|
|
9052
9467
|
exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
|
|
9468
|
+
exports.ERR_INVALID_URI = ERR_INVALID_URI;
|
|
9053
9469
|
exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
|
|
9054
9470
|
exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
|
|
9055
9471
|
exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
|
|
@@ -9057,6 +9473,7 @@
|
|
|
9057
9473
|
exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
|
|
9058
9474
|
exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
|
|
9059
9475
|
exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
|
|
9476
|
+
exports.ERR_UNDEFINED_CRC32 = ERR_UNDEFINED_CRC32;
|
|
9060
9477
|
exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
|
|
9061
9478
|
exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
|
|
9062
9479
|
exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
|
|
@@ -9072,6 +9489,8 @@
|
|
|
9072
9489
|
exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
|
|
9073
9490
|
exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
|
|
9074
9491
|
exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
|
|
9492
|
+
exports.ERR_WRITER_SIZE_NOT_WRITABLE = ERR_WRITER_SIZE_NOT_WRITABLE;
|
|
9493
|
+
exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
|
|
9075
9494
|
exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
|
|
9076
9495
|
exports.HttpRangeReader = HttpRangeReader;
|
|
9077
9496
|
exports.HttpReader = HttpReader;
|
|
@@ -9084,13 +9503,17 @@
|
|
|
9084
9503
|
exports.Uint8ArrayWriter = Uint8ArrayWriter;
|
|
9085
9504
|
exports.VERSION = VERSION;
|
|
9086
9505
|
exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
|
|
9506
|
+
exports.WARNING_CLAMPED_LAST_MODIFICATION_DATE = WARNING_CLAMPED_LAST_MODIFICATION_DATE;
|
|
9087
9507
|
exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
|
|
9508
|
+
exports.WARNING_COMPRESSION_UNAVAILABLE = WARNING_COMPRESSION_UNAVAILABLE;
|
|
9088
9509
|
exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
|
|
9089
9510
|
exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
|
|
9090
9511
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
|
|
9091
9512
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
|
|
9092
9513
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
|
|
9514
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME;
|
|
9093
9515
|
exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
|
|
9516
|
+
exports.WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY;
|
|
9094
9517
|
exports.WARNING_PREPENDED_CENTRAL_DIRECTORY = WARNING_PREPENDED_CENTRAL_DIRECTORY;
|
|
9095
9518
|
exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
|
|
9096
9519
|
exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;
|