@zip.js/zip.js 2.11.4 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist/zip-core-external.js +427 -110
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +437 -107
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +492 -230
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +505 -227
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +492 -230
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +507 -229
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +508 -230
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +439 -109
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +439 -109
- package/dist/zip-native.min.js +1 -1
- package/dist/zip-web-worker-native.js +1 -1
- package/dist/zip-web-worker.js +1 -1
- package/dist/zip.js +440 -110
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +507 -229
- package/index-native.min.js +1 -1
- package/index.cjs +508 -230
- package/index.d.cts +468 -59
- package/index.d.ts +468 -59
- package/index.min.js +1 -1
- package/lib/core/codec-worker-web.js +10 -2
- package/lib/core/codec-worker.js +4 -3
- package/lib/core/configuration.js +20 -5
- package/lib/core/constants.js +2 -0
- package/lib/core/io.js +13 -5
- package/lib/core/options.js +16 -0
- package/lib/core/streams/codec-stream.js +6 -0
- package/lib/core/util/warnings.js +42 -0
- package/lib/core/version.js +1 -1
- package/lib/core/web-worker-base.js +4 -3
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-entry.js +49 -1
- package/lib/core/zip-fs.js +43 -132
- package/lib/core/zip-reader.js +106 -48
- package/lib/core/zip-writer.js +236 -54
- package/lib/zip-core-base.js +9 -3
- package/lib/zip-core-reader.js +2 -0
- package/lib/zip-core-writer.js +6 -1
- package/lib/zip-module-wasm-base.js +2 -2
- package/package.json +5 -3
package/dist/zip-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
|
}
|
|
@@ -2605,6 +2628,7 @@
|
|
|
2605
2628
|
constructor(chunkSize) {
|
|
2606
2629
|
const pendingChunks = [];
|
|
2607
2630
|
let pendingLength = 0;
|
|
2631
|
+
let outputSize = 0;
|
|
2608
2632
|
if (!Number.isFinite(chunkSize) || chunkSize < 1) {
|
|
2609
2633
|
chunkSize = DEFAULT_CHUNK_SIZE;
|
|
2610
2634
|
}
|
|
@@ -2613,15 +2637,20 @@
|
|
|
2613
2637
|
pendingChunks.push(chunk);
|
|
2614
2638
|
pendingLength += chunk.length;
|
|
2615
2639
|
while (pendingLength > chunkSize) {
|
|
2640
|
+
outputSize += chunkSize;
|
|
2616
2641
|
controller.enqueue(shiftChunk());
|
|
2617
2642
|
}
|
|
2618
2643
|
},
|
|
2619
2644
|
flush(controller) {
|
|
2620
2645
|
if (pendingLength) {
|
|
2646
|
+
outputSize += pendingLength;
|
|
2621
2647
|
controller.enqueue(concatChunks(pendingChunks, pendingLength));
|
|
2622
2648
|
}
|
|
2623
2649
|
}
|
|
2624
2650
|
});
|
|
2651
|
+
Object.defineProperty(this, "outputSize", {
|
|
2652
|
+
get: () => outputSize
|
|
2653
|
+
});
|
|
2625
2654
|
|
|
2626
2655
|
function shiftChunk() {
|
|
2627
2656
|
const result = new Uint8Array(chunkSize);
|
|
@@ -2822,7 +2851,7 @@
|
|
|
2822
2851
|
}
|
|
2823
2852
|
|
|
2824
2853
|
async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
|
|
2825
|
-
let codecStream;
|
|
2854
|
+
let codecStream, chunkStream;
|
|
2826
2855
|
try {
|
|
2827
2856
|
if (options.compressed && !options.format) {
|
|
2828
2857
|
const deflate = options.codecType.startsWith(CODEC_DEFLATE);
|
|
@@ -2845,9 +2874,10 @@
|
|
|
2845
2874
|
}
|
|
2846
2875
|
}
|
|
2847
2876
|
codecStream = new CodecStream(options, config);
|
|
2877
|
+
chunkStream = new ChunkStream(getChunkSize(config));
|
|
2848
2878
|
await readable
|
|
2849
2879
|
.pipeThrough(codecStream)
|
|
2850
|
-
.pipeThrough(
|
|
2880
|
+
.pipeThrough(chunkStream)
|
|
2851
2881
|
.pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
2852
2882
|
const {
|
|
2853
2883
|
crc32,
|
|
@@ -2861,7 +2891,7 @@
|
|
|
2861
2891
|
};
|
|
2862
2892
|
} catch (error) {
|
|
2863
2893
|
if (codecStream) {
|
|
2864
|
-
error.outputSize =
|
|
2894
|
+
error.outputSize = chunkStream ? chunkStream.outputSize : 0;
|
|
2865
2895
|
}
|
|
2866
2896
|
throw error;
|
|
2867
2897
|
} finally {
|
|
@@ -2970,11 +3000,17 @@
|
|
|
2970
3000
|
let resolveResult, rejectResult;
|
|
2971
3001
|
const result = new Promise((resolve, reject) => {
|
|
2972
3002
|
resolveResult = resolve;
|
|
2973
|
-
rejectResult =
|
|
3003
|
+
rejectResult = error => {
|
|
3004
|
+
if (error && error.outputSize === UNDEFINED_VALUE) {
|
|
3005
|
+
error.outputSize = workerData.outputSize;
|
|
3006
|
+
}
|
|
3007
|
+
reject(error);
|
|
3008
|
+
};
|
|
2974
3009
|
});
|
|
2975
3010
|
Object.assign(workerData, {
|
|
2976
3011
|
reader: null,
|
|
2977
3012
|
writer: null,
|
|
3013
|
+
outputSize: 0,
|
|
2978
3014
|
resolveResult,
|
|
2979
3015
|
rejectResult,
|
|
2980
3016
|
result
|
|
@@ -3258,8 +3294,10 @@
|
|
|
3258
3294
|
}
|
|
3259
3295
|
}
|
|
3260
3296
|
if (type == MESSAGE_DATA) {
|
|
3297
|
+
const chunk = new Uint8Array(value);
|
|
3261
3298
|
await writer.ready;
|
|
3262
|
-
await writer.write(
|
|
3299
|
+
await writer.write(chunk);
|
|
3300
|
+
workerData.outputSize += chunk.length;
|
|
3263
3301
|
if (!stale()) {
|
|
3264
3302
|
sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
|
|
3265
3303
|
}
|
|
@@ -3567,10 +3605,13 @@
|
|
|
3567
3605
|
|
|
3568
3606
|
|
|
3569
3607
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
3608
|
+
const MIN_SUCCESS_HTTP_STATUS = 200;
|
|
3609
|
+
const MAX_SUCCESS_HTTP_STATUS = 299;
|
|
3570
3610
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
3571
3611
|
const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
|
|
3572
3612
|
const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
|
|
3573
3613
|
const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
|
|
3614
|
+
const ERR_WRITER_SIZE_NOT_WRITABLE = "Invalid writer (size must be writable)";
|
|
3574
3615
|
|
|
3575
3616
|
const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
|
|
3576
3617
|
const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
|
|
@@ -3762,6 +3803,7 @@
|
|
|
3762
3803
|
const reader = this;
|
|
3763
3804
|
const { sourceBlob, size } = reader;
|
|
3764
3805
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
3806
|
+
// deno-lint-ignore valid-typeof
|
|
3765
3807
|
if (typeof sourceBlob.stream == FUNCTION_TYPE) {
|
|
3766
3808
|
if (!offset && readSize >= size) {
|
|
3767
3809
|
return toCompatibleReadable(sourceBlob.stream());
|
|
@@ -4168,7 +4210,7 @@
|
|
|
4168
4210
|
|
|
4169
4211
|
async function sendFetchRequest(method, { fetch: fetchFunction = fetch, options, url }, headers) {
|
|
4170
4212
|
const response = await fetchFunction(url, Object.assign({}, options, { method, headers }));
|
|
4171
|
-
if (response.status
|
|
4213
|
+
if (response.status >= MIN_SUCCESS_HTTP_STATUS && response.status <= MAX_SUCCESS_HTTP_STATUS) {
|
|
4172
4214
|
return response;
|
|
4173
4215
|
} else {
|
|
4174
4216
|
throw response.status == 416 ? new Error(ERR_HTTP_RANGE) : new Error(ERR_HTTP_STATUS + (response.statusText || response.status));
|
|
@@ -4179,7 +4221,7 @@
|
|
|
4179
4221
|
return new Promise((resolve, reject) => {
|
|
4180
4222
|
const request = new XMLHttpRequest();
|
|
4181
4223
|
request.addEventListener("load", () => {
|
|
4182
|
-
if (request.status
|
|
4224
|
+
if (request.status >= MIN_SUCCESS_HTTP_STATUS && request.status <= MAX_SUCCESS_HTTP_STATUS) {
|
|
4183
4225
|
const headers = [];
|
|
4184
4226
|
request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
|
|
4185
4227
|
const splitHeader = header.trim().split(/\s*:\s*/);
|
|
@@ -4483,8 +4525,10 @@
|
|
|
4483
4525
|
writable: toCompatibleWritable(writer)
|
|
4484
4526
|
};
|
|
4485
4527
|
}
|
|
4486
|
-
|
|
4487
|
-
writer.size = 0;
|
|
4528
|
+
try {
|
|
4529
|
+
writer.size = writer.size === UNDEFINED_VALUE ? 0 : writer.size;
|
|
4530
|
+
} catch {
|
|
4531
|
+
throw new Error(ERR_WRITER_SIZE_NOT_WRITABLE);
|
|
4488
4532
|
}
|
|
4489
4533
|
return writer;
|
|
4490
4534
|
}
|
|
@@ -4532,6 +4576,45 @@
|
|
|
4532
4576
|
}
|
|
4533
4577
|
}
|
|
4534
4578
|
|
|
4579
|
+
/*
|
|
4580
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
4581
|
+
|
|
4582
|
+
Redistribution and use in source and binary forms, with or without
|
|
4583
|
+
modification, are permitted provided that the following conditions are met:
|
|
4584
|
+
|
|
4585
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
4586
|
+
this list of conditions and the following disclaimer.
|
|
4587
|
+
|
|
4588
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
4589
|
+
notice, this list of conditions and the following disclaimer in
|
|
4590
|
+
the documentation and/or other materials provided with the distribution.
|
|
4591
|
+
|
|
4592
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
4593
|
+
derived from this software without specific prior written permission.
|
|
4594
|
+
|
|
4595
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
4596
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
4597
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
4598
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
4599
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
4600
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
4601
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
4602
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
4603
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
4604
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4605
|
+
*/
|
|
4606
|
+
|
|
4607
|
+
|
|
4608
|
+
function addWarning(warnings, reason, filename) {
|
|
4609
|
+
if (!warnings.some(warning => warning.reason == reason)) {
|
|
4610
|
+
const warning = { reason };
|
|
4611
|
+
if (filename !== UNDEFINED_VALUE) {
|
|
4612
|
+
warning.filename = filename;
|
|
4613
|
+
}
|
|
4614
|
+
warnings.push(warning);
|
|
4615
|
+
}
|
|
4616
|
+
}
|
|
4617
|
+
|
|
4535
4618
|
/*
|
|
4536
4619
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4537
4620
|
|
|
@@ -4560,6 +4643,7 @@
|
|
|
4560
4643
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
4561
4644
|
*/
|
|
4562
4645
|
|
|
4646
|
+
|
|
4563
4647
|
const PROPERTY_NAME_FILENAME = "filename";
|
|
4564
4648
|
const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
|
|
4565
4649
|
const PROPERTY_NAME_COMMENT = "comment";
|
|
@@ -4684,6 +4768,38 @@
|
|
|
4684
4768
|
|
|
4685
4769
|
}
|
|
4686
4770
|
|
|
4771
|
+
const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
|
|
4772
|
+
EXTRAFIELD_TYPE_ZIP64,
|
|
4773
|
+
EXTRAFIELD_TYPE_AES,
|
|
4774
|
+
EXTRAFIELD_TYPE_NTFS,
|
|
4775
|
+
EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
|
|
4776
|
+
EXTRAFIELD_TYPE_UNICODE_PATH,
|
|
4777
|
+
EXTRAFIELD_TYPE_UNICODE_COMMENT,
|
|
4778
|
+
EXTRAFIELD_TYPE_USDZ,
|
|
4779
|
+
EXTRAFIELD_TYPE_INFOZIP,
|
|
4780
|
+
EXTRAFIELD_TYPE_UNIX,
|
|
4781
|
+
EXTRAFIELD_TYPE_UNIX_TYPE1,
|
|
4782
|
+
EXTRAFIELD_TYPE_PKWARE_UNIX
|
|
4783
|
+
]);
|
|
4784
|
+
|
|
4785
|
+
function getUserExtraField(extraField) {
|
|
4786
|
+
if (extraField) {
|
|
4787
|
+
const userExtraField = new Map();
|
|
4788
|
+
extraField.forEach((field, type) => {
|
|
4789
|
+
if (!INTERPRETED_EXTRA_FIELD_TYPES.has(type)) {
|
|
4790
|
+
userExtraField.set(type, field.data);
|
|
4791
|
+
}
|
|
4792
|
+
});
|
|
4793
|
+
if (userExtraField.size) {
|
|
4794
|
+
return userExtraField;
|
|
4795
|
+
}
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4798
|
+
|
|
4799
|
+
function getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength) {
|
|
4800
|
+
return encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
4801
|
+
}
|
|
4802
|
+
|
|
4687
4803
|
/*
|
|
4688
4804
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
4689
4805
|
|
|
@@ -4743,6 +4859,8 @@
|
|
|
4743
4859
|
const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
|
|
4744
4860
|
const WARNING_DUPLICATE_FILENAME = "duplicate filename";
|
|
4745
4861
|
const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
|
|
4862
|
+
const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
|
|
4863
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = "mismatched local file header (filename)";
|
|
4746
4864
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
|
|
4747
4865
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
|
|
4748
4866
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
@@ -4813,7 +4931,7 @@
|
|
|
4813
4931
|
}
|
|
4814
4932
|
}
|
|
4815
4933
|
if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
|
|
4816
|
-
throwAmbiguousArchive(
|
|
4934
|
+
throwAmbiguousArchive(WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY);
|
|
4817
4935
|
}
|
|
4818
4936
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
4819
4937
|
let directoryDataLength = getUint32$1(endOfDirectoryView, 12);
|
|
@@ -5111,7 +5229,8 @@
|
|
|
5111
5229
|
const writer = new TransformStream();
|
|
5112
5230
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5113
5231
|
arrayBufferPromise.catch(() => { });
|
|
5114
|
-
await fileEntry.getData(writer, entry, zipReader.readRanges,
|
|
5232
|
+
await fileEntry.getData(writer, entry, zipReader.readRanges,
|
|
5233
|
+
Object.assign({}, options, { preventClose: false }));
|
|
5115
5234
|
return arrayBufferPromise;
|
|
5116
5235
|
};
|
|
5117
5236
|
offset = endOffset;
|
|
@@ -5192,49 +5311,101 @@
|
|
|
5192
5311
|
await reader.readable.cancel();
|
|
5193
5312
|
}
|
|
5194
5313
|
}
|
|
5314
|
+
|
|
5315
|
+
[SYMBOL_ASYNC_DISPOSE]() {
|
|
5316
|
+
return this.close();
|
|
5317
|
+
}
|
|
5195
5318
|
}
|
|
5196
5319
|
|
|
5197
5320
|
class ZipReaderStream {
|
|
5198
5321
|
|
|
5199
5322
|
constructor(options = {}) {
|
|
5200
|
-
|
|
5201
|
-
const
|
|
5323
|
+
let sourceController;
|
|
5324
|
+
const { readable, writable } = new TransformStream({
|
|
5325
|
+
start(controller) {
|
|
5326
|
+
sourceController = controller;
|
|
5327
|
+
}
|
|
5328
|
+
});
|
|
5329
|
+
const zipReader = new ZipReader(readable, options);
|
|
5330
|
+
const gen = zipReader.getEntriesGenerator();
|
|
5331
|
+
const pendingEntries = new Set();
|
|
5202
5332
|
this.readable = new ReadableStream({
|
|
5203
5333
|
async pull(controller) {
|
|
5204
5334
|
const { done, value } = await gen.next();
|
|
5205
5335
|
if (done)
|
|
5206
5336
|
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
|
-
})();
|
|
5337
|
+
const entryStream = createEntryStream(value, pendingEntries);
|
|
5226
5338
|
const chunk = {
|
|
5227
5339
|
...value,
|
|
5228
|
-
readable:
|
|
5340
|
+
readable: entryStream.readable
|
|
5229
5341
|
};
|
|
5230
5342
|
delete chunk.getData;
|
|
5343
|
+
Object.defineProperties(chunk, {
|
|
5344
|
+
localDirectory: {
|
|
5345
|
+
get: () => value.localDirectory,
|
|
5346
|
+
enumerable: true
|
|
5347
|
+
},
|
|
5348
|
+
warnings: {
|
|
5349
|
+
get: () => value.warnings,
|
|
5350
|
+
enumerable: true
|
|
5351
|
+
}
|
|
5352
|
+
});
|
|
5231
5353
|
controller.enqueue(chunk);
|
|
5354
|
+
},
|
|
5355
|
+
async cancel(reason) {
|
|
5356
|
+
const entryStreams = Array.from(pendingEntries);
|
|
5357
|
+
pendingEntries.clear();
|
|
5358
|
+
sourceController.error(reason);
|
|
5359
|
+
await Promise.allSettled(entryStreams.map(entryStream => entryStream.cancel(reason)));
|
|
5360
|
+
await Promise.allSettled([gen.return(), zipReader.close()]);
|
|
5232
5361
|
}
|
|
5233
5362
|
});
|
|
5234
5363
|
this.writable = writable;
|
|
5235
5364
|
}
|
|
5236
5365
|
}
|
|
5237
5366
|
|
|
5367
|
+
function createEntryStream(entry, pendingEntries) {
|
|
5368
|
+
const { readable, writable } = new TransformStream();
|
|
5369
|
+
let dataReader;
|
|
5370
|
+
const entryStream = {
|
|
5371
|
+
cancel: async reason => {
|
|
5372
|
+
pendingEntries.delete(entryStream);
|
|
5373
|
+
await (dataReader ? dataReader.cancel(reason) : readable.cancel(reason));
|
|
5374
|
+
}
|
|
5375
|
+
};
|
|
5376
|
+
entryStream.readable = new ReadableStream({
|
|
5377
|
+
async pull(controller) {
|
|
5378
|
+
if (!dataReader) {
|
|
5379
|
+
dataReader = readable.getReader();
|
|
5380
|
+
pendingEntries.add(entryStream);
|
|
5381
|
+
getData();
|
|
5382
|
+
}
|
|
5383
|
+
const { done, value } = await dataReader.read();
|
|
5384
|
+
if (done) {
|
|
5385
|
+
controller.close();
|
|
5386
|
+
} else {
|
|
5387
|
+
controller.enqueue(value);
|
|
5388
|
+
}
|
|
5389
|
+
},
|
|
5390
|
+
cancel: reason => entryStream.cancel(reason)
|
|
5391
|
+
}, { highWaterMark: 0 });
|
|
5392
|
+
return entryStream;
|
|
5393
|
+
|
|
5394
|
+
async function getData() {
|
|
5395
|
+
try {
|
|
5396
|
+
await entry.getData(writable, { preventClose: false });
|
|
5397
|
+
} catch (error) {
|
|
5398
|
+
try {
|
|
5399
|
+
await writable.abort(error);
|
|
5400
|
+
} catch {
|
|
5401
|
+
// ignored
|
|
5402
|
+
}
|
|
5403
|
+
} finally {
|
|
5404
|
+
pendingEntries.delete(entryStream);
|
|
5405
|
+
}
|
|
5406
|
+
}
|
|
5407
|
+
}
|
|
5408
|
+
|
|
5238
5409
|
async function isZipFile(reader, options = {}) {
|
|
5239
5410
|
reader = new GenericReader(reader);
|
|
5240
5411
|
await initStream(reader);
|
|
@@ -5294,7 +5465,9 @@
|
|
|
5294
5465
|
const dataView = getDataView(dataArray);
|
|
5295
5466
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
5296
5467
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
5297
|
-
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
5468
|
+
const passThrough = checkPassThroughOption(getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH));
|
|
5469
|
+
const passThroughCompression = Boolean(passThrough);
|
|
5470
|
+
const passThroughEncryption = passThrough === true;
|
|
5298
5471
|
checkPasswordOption(password, rawPassword);
|
|
5299
5472
|
password = password && password.length && password;
|
|
5300
5473
|
rawPassword = rawPassword && rawPassword.length && rawPassword;
|
|
@@ -5315,7 +5488,9 @@
|
|
|
5315
5488
|
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5316
5489
|
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5317
5490
|
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
5318
|
-
const
|
|
5491
|
+
const checkLocalFilenameOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_FILENAME);
|
|
5492
|
+
const checkLocalFilename = getCheckLocalFilename(
|
|
5493
|
+
checkLocalFilenameOption === UNDEFINED_VALUE ? checkLocalDirectoryOption : checkLocalFilenameOption, entryStrictness);
|
|
5319
5494
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
5320
5495
|
if (checkLocalFilename && (filenameLength || extraFieldLength)) {
|
|
5321
5496
|
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
@@ -5346,16 +5521,17 @@
|
|
|
5346
5521
|
if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
|
|
5347
5522
|
fileEntry.gid = gid;
|
|
5348
5523
|
}
|
|
5349
|
-
const
|
|
5524
|
+
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5525
|
+
const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
|
|
5350
5526
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
5351
|
-
if (!
|
|
5527
|
+
if (!passThroughEncryption) {
|
|
5352
5528
|
fileEntry.zipCrypto = zipCrypto;
|
|
5353
5529
|
}
|
|
5354
5530
|
if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
|
|
5355
5531
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
|
|
5356
5532
|
}
|
|
5357
|
-
const registeredCodec =
|
|
5358
|
-
if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !
|
|
5533
|
+
const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
5534
|
+
if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec && !passThroughCompression) {
|
|
5359
5535
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
5360
5536
|
}
|
|
5361
5537
|
if (encrypted) {
|
|
@@ -5372,15 +5548,16 @@
|
|
|
5372
5548
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5373
5549
|
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5374
5550
|
throwIfAborted(signal);
|
|
5375
|
-
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5376
5551
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
5377
5552
|
const checkOverlappingEntryOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
|
|
5378
5553
|
if (checkOverlappingEntryOnly) {
|
|
5379
5554
|
checkOverlappingEntry = true;
|
|
5380
5555
|
}
|
|
5381
5556
|
const { onstart, onprogress, onend } = options;
|
|
5382
|
-
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !
|
|
5383
|
-
const outputSize =
|
|
5557
|
+
const compressed = compressionMethod != COMPRESSION_METHOD_STORE && !passThroughCompression;
|
|
5558
|
+
const outputSize = passThroughCompression ?
|
|
5559
|
+
compressedSize - getEncryptionOverhead(encrypted, zipCrypto, extraFieldAES && extraFieldAES.strength) :
|
|
5560
|
+
uncompressedSize;
|
|
5384
5561
|
const deflate64 = compressionMethod == COMPRESSION_METHOD_DEFLATE_64;
|
|
5385
5562
|
let useCompressionStream = getOptionValue$1(zipEntry, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5386
5563
|
if (deflate64) {
|
|
@@ -5389,7 +5566,7 @@
|
|
|
5389
5566
|
const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
|
|
5390
5567
|
const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
|
|
5391
5568
|
getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
|
|
5392
|
-
checkCrc32Option) && !
|
|
5569
|
+
checkCrc32Option) && !passThroughCompression &&
|
|
5393
5570
|
(!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
|
|
5394
5571
|
const workerOptions = {
|
|
5395
5572
|
options: {
|
|
@@ -5443,10 +5620,10 @@
|
|
|
5443
5620
|
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5444
5621
|
({ writable } = writer);
|
|
5445
5622
|
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5446
|
-
writer.size += writtenSize;
|
|
5447
5623
|
if (writtenSize != outputSize) {
|
|
5448
|
-
throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
5624
|
+
throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
|
|
5449
5625
|
}
|
|
5626
|
+
writer.size += writtenSize;
|
|
5450
5627
|
}
|
|
5451
5628
|
} catch (error) {
|
|
5452
5629
|
if (error.outputSize !== UNDEFINED_VALUE) {
|
|
@@ -6112,7 +6289,7 @@
|
|
|
6112
6289
|
if (checkLocalFilename && !maskedLocalDirectory &&
|
|
6113
6290
|
(rawLocalFilename.length != rawFilename.length ||
|
|
6114
6291
|
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
6115
|
-
reportAmbiguity(reject, warnings,
|
|
6292
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME);
|
|
6116
6293
|
}
|
|
6117
6294
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
6118
6295
|
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
|
|
@@ -6137,16 +6314,6 @@
|
|
|
6137
6314
|
}
|
|
6138
6315
|
}
|
|
6139
6316
|
|
|
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
6317
|
function throwAmbiguousArchive(reason) {
|
|
6151
6318
|
const error = new Error(ERR_AMBIGUOUS_ARCHIVE);
|
|
6152
6319
|
error.reason = reason;
|
|
@@ -6226,7 +6393,9 @@
|
|
|
6226
6393
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
|
|
6227
6394
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
|
|
6228
6395
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
|
|
6396
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
|
|
6229
6397
|
WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
|
|
6398
|
+
WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
|
|
6230
6399
|
WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
|
|
6231
6400
|
WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
|
|
6232
6401
|
WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
|
|
@@ -6279,7 +6448,7 @@
|
|
|
6279
6448
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
6280
6449
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
6281
6450
|
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";
|
|
6451
|
+
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set to true (use 'compressed' instead)";
|
|
6283
6452
|
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
6284
6453
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
6285
6454
|
const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
|
|
@@ -6291,6 +6460,7 @@
|
|
|
6291
6460
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
6292
6461
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
6293
6462
|
const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
|
|
6463
|
+
const ERR_UNDEFINED_CRC32 = "Undefined CRC32";
|
|
6294
6464
|
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
6295
6465
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
6296
6466
|
const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
|
|
@@ -6304,14 +6474,21 @@
|
|
|
6304
6474
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
6305
6475
|
const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
|
|
6306
6476
|
const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
6477
|
+
const ERR_INVALID_ENTRY = "Invalid entry option (must be an entry returned by ZipReader#getEntries())";
|
|
6478
|
+
const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
|
|
6479
|
+
const WARNING_COMPRESSION_UNAVAILABLE = "compression unavailable";
|
|
6480
|
+
const WARNING_CLAMPED_LAST_MODIFICATION_DATE = "clamped last modification date";
|
|
6307
6481
|
|
|
6308
6482
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
6309
6483
|
const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
|
|
6310
6484
|
const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
|
|
6311
6485
|
const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
|
|
6486
|
+
const MIN_PRINTABLE_ASCII_CHARACTER_CODE = 0x20;
|
|
6487
|
+
const MAX_PRINTABLE_ASCII_CHARACTER_CODE = 0x7e;
|
|
6312
6488
|
const VENDOR_VERSION_AE_1 = 1;
|
|
6313
|
-
const INFOZIP_EXTRA_FIELD_TYPE
|
|
6489
|
+
const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
|
|
6314
6490
|
const UNIX_EXTRA_FIELD_TYPE = "unix";
|
|
6491
|
+
const LEVEL_BY_BITFLAG_LEVEL = [8, 9, 5, 3];
|
|
6315
6492
|
const MAX_LEVEL = 9;
|
|
6316
6493
|
|
|
6317
6494
|
let workers = 0;
|
|
@@ -6338,9 +6515,11 @@
|
|
|
6338
6515
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
6339
6516
|
pendingAddFileCalls: new Set(),
|
|
6340
6517
|
pendingErrors: [],
|
|
6518
|
+
warnings: [],
|
|
6341
6519
|
bufferedWrites: 0,
|
|
6342
6520
|
directWrites: 0,
|
|
6343
|
-
lastFileEntry: UNDEFINED_VALUE
|
|
6521
|
+
lastFileEntry: UNDEFINED_VALUE,
|
|
6522
|
+
archiveClosed: false
|
|
6344
6523
|
});
|
|
6345
6524
|
}
|
|
6346
6525
|
|
|
@@ -6505,6 +6684,9 @@
|
|
|
6505
6684
|
const zipWriter = this;
|
|
6506
6685
|
const { pendingAddFileCalls, writer } = this;
|
|
6507
6686
|
const { writable } = writer;
|
|
6687
|
+
if (zipWriter.archiveClosed) {
|
|
6688
|
+
return getWriterData(writer);
|
|
6689
|
+
}
|
|
6508
6690
|
if (!(comment instanceof Uint8Array)) {
|
|
6509
6691
|
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
6510
6692
|
}
|
|
@@ -6528,11 +6710,16 @@
|
|
|
6528
6710
|
throw error;
|
|
6529
6711
|
}
|
|
6530
6712
|
await closeFile(zipWriter, comment, options);
|
|
6713
|
+
zipWriter.archiveClosed = true;
|
|
6531
6714
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
6532
6715
|
if (!preventClose) {
|
|
6533
6716
|
await writable.getWriter().close();
|
|
6534
6717
|
}
|
|
6535
|
-
return writer
|
|
6718
|
+
return getWriterData(writer);
|
|
6719
|
+
}
|
|
6720
|
+
|
|
6721
|
+
[SYMBOL_ASYNC_DISPOSE]() {
|
|
6722
|
+
return this.close();
|
|
6536
6723
|
}
|
|
6537
6724
|
}
|
|
6538
6725
|
|
|
@@ -6611,6 +6798,10 @@
|
|
|
6611
6798
|
}
|
|
6612
6799
|
}
|
|
6613
6800
|
|
|
6801
|
+
function getWriterData(writer) {
|
|
6802
|
+
return writer.getData ? writer.getData() : writer.writable;
|
|
6803
|
+
}
|
|
6804
|
+
|
|
6614
6805
|
function watchPromiseError(zipWriter, promise) {
|
|
6615
6806
|
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
6616
6807
|
const watcher = {};
|
|
@@ -6629,6 +6820,14 @@
|
|
|
6629
6820
|
|
|
6630
6821
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
6631
6822
|
options = Object.assign({}, options);
|
|
6823
|
+
const entry = options[OPTION_ENTRY];
|
|
6824
|
+
if (entry !== UNDEFINED_VALUE) {
|
|
6825
|
+
const { entryOptions, passThroughOptions } = getSourceEntryOptions(entry,
|
|
6826
|
+
checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH)),
|
|
6827
|
+
getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE));
|
|
6828
|
+
delete options[OPTION_ENTRY];
|
|
6829
|
+
options = Object.assign(entryOptions, passThroughOptions, options);
|
|
6830
|
+
}
|
|
6632
6831
|
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6633
6832
|
name += DIRECTORY_SIGNATURE;
|
|
6634
6833
|
}
|
|
@@ -6693,21 +6892,33 @@
|
|
|
6693
6892
|
try {
|
|
6694
6893
|
const { resolvedOptions } = metadataInfo;
|
|
6695
6894
|
if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
|
|
6696
|
-
!resolvedOptions.
|
|
6895
|
+
!resolvedOptions.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
|
|
6697
6896
|
resolvedOptions.level = 0;
|
|
6897
|
+
addWarning(zipWriter.warnings, WARNING_COMPRESSION_UNAVAILABLE, name);
|
|
6698
6898
|
}
|
|
6699
6899
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
6700
6900
|
({ reader } = sizesInfo);
|
|
6701
6901
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
6702
6902
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
6903
|
+
let crc32 = options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32;
|
|
6904
|
+
const storesAE2 = sizesInfo.resolvedOptions.encrypted && !resolvedOptions.zipCrypto;
|
|
6905
|
+
if (resolvedOptions.passThroughCompression && !resolvedOptions.passThroughEncryption && storesAE2) {
|
|
6906
|
+
crc32 = UNDEFINED_VALUE;
|
|
6907
|
+
}
|
|
6908
|
+
if (resolvedOptions.passThroughCompression && reader && !storesAE2 && crc32 === UNDEFINED_VALUE) {
|
|
6909
|
+
throw new Error(ERR_UNDEFINED_CRC32);
|
|
6910
|
+
}
|
|
6703
6911
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
6704
6912
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
6705
|
-
crc32
|
|
6913
|
+
crc32,
|
|
6706
6914
|
offset: zipWriter.offset - diskOffset,
|
|
6707
6915
|
diskNumberStart: diskNumber,
|
|
6708
6916
|
[OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
|
|
6709
6917
|
});
|
|
6710
6918
|
const headerInfo = getHeaderInfo(options);
|
|
6919
|
+
if (headerInfo.lastModDateClamped) {
|
|
6920
|
+
addWarning(zipWriter.warnings, WARNING_CLAMPED_LAST_MODIFICATION_DATE, name);
|
|
6921
|
+
}
|
|
6711
6922
|
const dataDescriptorInfo = getDataDescriptorInfo(options);
|
|
6712
6923
|
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
6713
6924
|
fileEntry = await getFileEntry(zipWriter, name, reader, {
|
|
@@ -6734,6 +6945,95 @@
|
|
|
6734
6945
|
return new Entry(fileEntry);
|
|
6735
6946
|
}
|
|
6736
6947
|
|
|
6948
|
+
function getSourceEntryOptions(entry, passThrough, lastModDateOverride) {
|
|
6949
|
+
if (entry === null || typeof entry != OBJECT_TYPE || Array.isArray(entry)) {
|
|
6950
|
+
throw new Error(ERR_INVALID_ENTRY);
|
|
6951
|
+
}
|
|
6952
|
+
const {
|
|
6953
|
+
externalFileAttributes,
|
|
6954
|
+
versionMadeBy,
|
|
6955
|
+
comment,
|
|
6956
|
+
lastModDate,
|
|
6957
|
+
rawLastModDate,
|
|
6958
|
+
creationDate,
|
|
6959
|
+
lastAccessDate,
|
|
6960
|
+
uncompressedSize,
|
|
6961
|
+
encrypted,
|
|
6962
|
+
zipCrypto,
|
|
6963
|
+
crc32,
|
|
6964
|
+
compressionMethod,
|
|
6965
|
+
extraFieldAES,
|
|
6966
|
+
extraFieldUnix,
|
|
6967
|
+
internalFileAttributes,
|
|
6968
|
+
extraField,
|
|
6969
|
+
bitFlag,
|
|
6970
|
+
directory,
|
|
6971
|
+
uid,
|
|
6972
|
+
gid
|
|
6973
|
+
} = entry;
|
|
6974
|
+
const entryOptions = {
|
|
6975
|
+
externalFileAttributes,
|
|
6976
|
+
versionMadeBy,
|
|
6977
|
+
comment,
|
|
6978
|
+
lastModDate,
|
|
6979
|
+
creationDate,
|
|
6980
|
+
lastAccessDate,
|
|
6981
|
+
internalFileAttributes,
|
|
6982
|
+
directory
|
|
6983
|
+
};
|
|
6984
|
+
if (bitFlag && bitFlag.languageEncodingFlag) {
|
|
6985
|
+
entryOptions[OPTION_USE_UNICODE_FILE_NAMES] = true;
|
|
6986
|
+
}
|
|
6987
|
+
const userExtraField = getUserExtraField(extraField);
|
|
6988
|
+
if (userExtraField) {
|
|
6989
|
+
entryOptions[PROPERTY_NAME_EXTRA_FIELD] = userExtraField;
|
|
6990
|
+
}
|
|
6991
|
+
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
6992
|
+
Object.assign(entryOptions, {
|
|
6993
|
+
uid,
|
|
6994
|
+
gid,
|
|
6995
|
+
unixExtraFieldType: extraFieldUnix ? UNIX_EXTRA_FIELD_TYPE : INFOZIP_EXTRA_FIELD_TYPE
|
|
6996
|
+
});
|
|
6997
|
+
}
|
|
6998
|
+
const passThroughOptions = {};
|
|
6999
|
+
if (passThrough && !directory) {
|
|
7000
|
+
Object.assign(passThroughOptions, {
|
|
7001
|
+
uncompressedSize,
|
|
7002
|
+
crc32,
|
|
7003
|
+
compressionMethod
|
|
7004
|
+
});
|
|
7005
|
+
if (passThrough !== PASS_THROUGH_COMPRESSED) {
|
|
7006
|
+
Object.assign(passThroughOptions, {
|
|
7007
|
+
encrypted,
|
|
7008
|
+
zipCrypto,
|
|
7009
|
+
encryptionStrength: extraFieldAES ? extraFieldAES.strength : UNDEFINED_VALUE
|
|
7010
|
+
});
|
|
7011
|
+
}
|
|
7012
|
+
if (bitFlag) {
|
|
7013
|
+
passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
|
|
7014
|
+
passThroughOptions[OPTION_LEVEL] = LEVEL_BY_BITFLAG_LEVEL[bitFlag.level];
|
|
7015
|
+
}
|
|
7016
|
+
if (lastModDateOverride === UNDEFINED_VALUE) {
|
|
7017
|
+
passThroughOptions.rawLastModDate = rawLastModDate;
|
|
7018
|
+
} else if (passThrough !== PASS_THROUGH_COMPRESSED && zipCrypto && (!bitFlag || bitFlag.dataDescriptor) &&
|
|
7019
|
+
lastModDateOverride instanceof Date &&
|
|
7020
|
+
getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
|
|
7021
|
+
throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
|
|
7022
|
+
}
|
|
7023
|
+
}
|
|
7024
|
+
return { entryOptions, passThroughOptions };
|
|
7025
|
+
}
|
|
7026
|
+
|
|
7027
|
+
function getDosTimeHighByte(lastModDate) {
|
|
7028
|
+
let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
7029
|
+
if (dosLastModDate < MIN_DATE) {
|
|
7030
|
+
dosLastModDate = MIN_DATE;
|
|
7031
|
+
} else if (dosLastModDate > MAX_DATE) {
|
|
7032
|
+
dosLastModDate = MAX_DATE;
|
|
7033
|
+
}
|
|
7034
|
+
return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
|
|
7035
|
+
}
|
|
7036
|
+
|
|
6737
7037
|
function resolveAttributes(zipWriter, name, options) {
|
|
6738
7038
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
6739
7039
|
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
@@ -6748,7 +7048,7 @@
|
|
|
6748
7048
|
checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
|
|
6749
7049
|
checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
|
|
6750
7050
|
checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
|
|
6751
|
-
if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE
|
|
7051
|
+
if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
|
|
6752
7052
|
throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
|
|
6753
7053
|
}
|
|
6754
7054
|
if (unixExtraFieldType === UNIX_EXTRA_FIELD_TYPE &&
|
|
@@ -6756,7 +7056,7 @@
|
|
|
6756
7056
|
throw new Error(ERR_INVALID_UNIX_ID_SIZE);
|
|
6757
7057
|
}
|
|
6758
7058
|
if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
6759
|
-
unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE
|
|
7059
|
+
unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE;
|
|
6760
7060
|
}
|
|
6761
7061
|
let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
|
|
6762
7062
|
let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
|
|
@@ -6887,7 +7187,9 @@
|
|
|
6887
7187
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6888
7188
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6889
7189
|
const internalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
6890
|
-
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
7190
|
+
const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
|
|
7191
|
+
const passThroughCompression = Boolean(passThrough);
|
|
7192
|
+
const passThroughEncryption = passThrough === true;
|
|
6891
7193
|
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
6892
7194
|
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
6893
7195
|
checkPasswordOption(password, rawPassword);
|
|
@@ -6903,10 +7205,11 @@
|
|
|
6903
7205
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
6904
7206
|
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
6905
7207
|
throwIfAborted(signal);
|
|
6906
|
-
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
|
|
7208
|
+
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES,
|
|
7209
|
+
!isPrintableASCIIText(rawFilename) || !isPrintableASCIIText(rawComment));
|
|
6907
7210
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
6908
|
-
const registeredCodec =
|
|
6909
|
-
if (!
|
|
7211
|
+
const registeredCodec = passThroughCompression || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
7212
|
+
if (!passThroughCompression && compressionMethod !== UNDEFINED_VALUE &&
|
|
6910
7213
|
compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
|
|
6911
7214
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
6912
7215
|
}
|
|
@@ -6920,15 +7223,15 @@
|
|
|
6920
7223
|
level = 0;
|
|
6921
7224
|
}
|
|
6922
7225
|
}
|
|
6923
|
-
if (
|
|
6924
|
-
level =
|
|
7226
|
+
if (passThroughCompression) {
|
|
7227
|
+
level = toNumber(options[OPTION_LEVEL]);
|
|
6925
7228
|
}
|
|
6926
7229
|
let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
|
|
6927
7230
|
let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
|
|
6928
7231
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
6929
7232
|
dataDescriptor = false;
|
|
6930
7233
|
}
|
|
6931
|
-
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !
|
|
7234
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThroughEncryption)) {
|
|
6932
7235
|
dataDescriptor = true;
|
|
6933
7236
|
}
|
|
6934
7237
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -6952,7 +7255,8 @@
|
|
|
6952
7255
|
lastAccessDate,
|
|
6953
7256
|
creationDate,
|
|
6954
7257
|
internalFileAttributes,
|
|
6955
|
-
|
|
7258
|
+
passThroughCompression,
|
|
7259
|
+
passThroughEncryption,
|
|
6956
7260
|
password,
|
|
6957
7261
|
rawPassword,
|
|
6958
7262
|
encryptionStrength,
|
|
@@ -7013,7 +7317,7 @@
|
|
|
7013
7317
|
}
|
|
7014
7318
|
|
|
7015
7319
|
async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
|
|
7016
|
-
if (metadata.
|
|
7320
|
+
if (metadata.passThroughCompression && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
|
|
7017
7321
|
throw new Error(ERR_UNDEFINED_READER);
|
|
7018
7322
|
}
|
|
7019
7323
|
let contentSize;
|
|
@@ -7029,12 +7333,12 @@
|
|
|
7029
7333
|
}
|
|
7030
7334
|
|
|
7031
7335
|
function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
|
|
7032
|
-
const {
|
|
7336
|
+
const { passThroughCompression, passThroughEncryption, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
|
|
7033
7337
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
7034
7338
|
let maximumCompressedSize = 0;
|
|
7035
7339
|
let uncompressedSize = 0;
|
|
7036
7340
|
let unknownSize = false;
|
|
7037
|
-
if (
|
|
7341
|
+
if (passThroughCompression && hasContent) {
|
|
7038
7342
|
uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
|
|
7039
7343
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
7040
7344
|
throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
|
|
@@ -7045,17 +7349,17 @@
|
|
|
7045
7349
|
}
|
|
7046
7350
|
const zip64Enabled = zip64 === true;
|
|
7047
7351
|
const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
|
|
7048
|
-
if (hasContent &&
|
|
7352
|
+
if (hasContent && passThroughEncryption && !encrypted && getLength(password, rawPassword)) {
|
|
7049
7353
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
|
|
7050
7354
|
}
|
|
7051
|
-
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (
|
|
7355
|
+
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThroughEncryption && encrypted));
|
|
7052
7356
|
if (!hasContent) {
|
|
7053
7357
|
level = 0;
|
|
7054
7358
|
compressionMethod = COMPRESSION_METHOD_STORE;
|
|
7055
7359
|
}
|
|
7056
|
-
const encryptionOverhead = encryptedEntry
|
|
7360
|
+
const encryptionOverhead = getEncryptionOverhead(encryptedEntry, zipCrypto, encryptionStrength);
|
|
7057
7361
|
if (hasContent) {
|
|
7058
|
-
if (!
|
|
7362
|
+
if (!passThroughCompression) {
|
|
7059
7363
|
if (contentSize === UNDEFINED_VALUE) {
|
|
7060
7364
|
dataDescriptor = true;
|
|
7061
7365
|
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
@@ -7068,10 +7372,12 @@
|
|
|
7068
7372
|
}
|
|
7069
7373
|
} else {
|
|
7070
7374
|
options.uncompressedSize = uncompressedSize;
|
|
7071
|
-
maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
|
|
7375
|
+
maximumCompressedSize = contentSize === UNDEFINED_VALUE ?
|
|
7376
|
+
getMaximumCompressedSize(uncompressedSize) + encryptionOverhead :
|
|
7377
|
+
contentSize + (passThroughEncryption ? 0 : encryptionOverhead);
|
|
7072
7378
|
}
|
|
7073
7379
|
}
|
|
7074
|
-
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !
|
|
7380
|
+
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
|
|
7075
7381
|
if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
7076
7382
|
dataDescriptor = false;
|
|
7077
7383
|
}
|
|
@@ -7120,6 +7426,8 @@
|
|
|
7120
7426
|
const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
|
|
7121
7427
|
let offset = initialOffset;
|
|
7122
7428
|
let minimumEntrySize = INFINITY_VALUE;
|
|
7429
|
+
const entrySizes = [];
|
|
7430
|
+
const entriesAlreadyZip64 = new Set();
|
|
7123
7431
|
for (const entry of entries) {
|
|
7124
7432
|
let { name } = entry;
|
|
7125
7433
|
const { size } = entry;
|
|
@@ -7131,7 +7439,7 @@
|
|
|
7131
7439
|
({ name } = attributesInfo);
|
|
7132
7440
|
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
7133
7441
|
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
7134
|
-
!metadata.
|
|
7442
|
+
!metadata.passThroughCompression && !(await supportsDeflate(getConfiguration()))) {
|
|
7135
7443
|
metadata.level = 0;
|
|
7136
7444
|
}
|
|
7137
7445
|
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
@@ -7139,7 +7447,7 @@
|
|
|
7139
7447
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
7140
7448
|
}
|
|
7141
7449
|
const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
|
|
7142
|
-
if (hasContent && !metadata.
|
|
7450
|
+
if (hasContent && !metadata.passThroughCompression && isCompressed(sizes.compressionMethod, sizes.level)) {
|
|
7143
7451
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
7144
7452
|
}
|
|
7145
7453
|
const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
|
|
@@ -7159,10 +7467,15 @@
|
|
|
7159
7467
|
compressedSize
|
|
7160
7468
|
}));
|
|
7161
7469
|
const entrySize = entryInfo.metadataSize + compressedSize;
|
|
7470
|
+
entrySizes.push(entrySize);
|
|
7471
|
+
entriesAlreadyZip64.add(Boolean(entryOptions.zip64Enabled ||
|
|
7472
|
+
entryOptions.uncompressedSize >= MAX_32_BITS || compressedSize >= MAX_32_BITS));
|
|
7162
7473
|
minimumEntrySize = Math.min(minimumEntrySize, entrySize);
|
|
7163
7474
|
offset += entrySize;
|
|
7164
7475
|
}
|
|
7165
|
-
const layoutDependsOnWriteOrder = files.size > 1 && (usdz ||
|
|
7476
|
+
const layoutDependsOnWriteOrder = files.size > 1 && (usdz ||
|
|
7477
|
+
(offset - minimumEntrySize >= MAX_32_BITS &&
|
|
7478
|
+
(entriesAlreadyZip64.size > 1 || countEntriesBefore4GB(entrySizes, initialOffset, true) != countEntriesBefore4GB(entrySizes, initialOffset, false))));
|
|
7166
7479
|
if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
|
|
7167
7480
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
7168
7481
|
}
|
|
@@ -7180,6 +7493,20 @@
|
|
|
7180
7493
|
return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
7181
7494
|
}
|
|
7182
7495
|
|
|
7496
|
+
function countEntriesBefore4GB(entrySizes, initialOffset, largestFirst) {
|
|
7497
|
+
const ordered = entrySizes.slice().sort((first, second) => largestFirst ? second - first : first - second);
|
|
7498
|
+
let position = initialOffset;
|
|
7499
|
+
let count = 0;
|
|
7500
|
+
for (const entrySize of ordered) {
|
|
7501
|
+
if (position >= MAX_32_BITS) {
|
|
7502
|
+
break;
|
|
7503
|
+
}
|
|
7504
|
+
position += entrySize;
|
|
7505
|
+
count++;
|
|
7506
|
+
}
|
|
7507
|
+
return count;
|
|
7508
|
+
}
|
|
7509
|
+
|
|
7183
7510
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
7184
7511
|
const {
|
|
7185
7512
|
fileEntries,
|
|
@@ -7355,6 +7682,7 @@
|
|
|
7355
7682
|
localExtraFieldZip64Length,
|
|
7356
7683
|
rawExtraFieldExtendedTimestamp,
|
|
7357
7684
|
extraFieldExtendedTimestampFlag,
|
|
7685
|
+
extraFieldExtendedTimestampTime,
|
|
7358
7686
|
rawExtraFieldNTFS,
|
|
7359
7687
|
rawExtraFieldUnix,
|
|
7360
7688
|
rawExtraFieldAES,
|
|
@@ -7367,6 +7695,7 @@
|
|
|
7367
7695
|
password,
|
|
7368
7696
|
rawPassword,
|
|
7369
7697
|
level,
|
|
7698
|
+
useUnicodeFileNames,
|
|
7370
7699
|
zip64,
|
|
7371
7700
|
zip64Enabled,
|
|
7372
7701
|
zip64UncompressedSize,
|
|
@@ -7401,7 +7730,8 @@
|
|
|
7401
7730
|
msdosAttributesRaw,
|
|
7402
7731
|
msdosAttributes,
|
|
7403
7732
|
useCompressionStream,
|
|
7404
|
-
|
|
7733
|
+
passThroughCompression,
|
|
7734
|
+
passThroughEncryption,
|
|
7405
7735
|
format,
|
|
7406
7736
|
codecURI
|
|
7407
7737
|
} = options;
|
|
@@ -7412,9 +7742,9 @@
|
|
|
7412
7742
|
zip64Enabled,
|
|
7413
7743
|
directory: Boolean(directory),
|
|
7414
7744
|
executable: Boolean(executable),
|
|
7415
|
-
filenameUTF8:
|
|
7745
|
+
filenameUTF8: Boolean(useUnicodeFileNames),
|
|
7416
7746
|
rawFilename,
|
|
7417
|
-
commentUTF8:
|
|
7747
|
+
commentUTF8: Boolean(useUnicodeFileNames),
|
|
7418
7748
|
rawComment,
|
|
7419
7749
|
rawExtraFieldZip64,
|
|
7420
7750
|
localExtraFieldZip64Length,
|
|
@@ -7445,7 +7775,7 @@
|
|
|
7445
7775
|
uncompressedSize
|
|
7446
7776
|
} = options;
|
|
7447
7777
|
let compressedSize = 0;
|
|
7448
|
-
if (!
|
|
7778
|
+
if (!passThroughCompression) {
|
|
7449
7779
|
uncompressedSize = 0;
|
|
7450
7780
|
}
|
|
7451
7781
|
const { writable } = writer;
|
|
@@ -7462,9 +7792,9 @@
|
|
|
7462
7792
|
encryptionStrength,
|
|
7463
7793
|
zipCrypto: encrypted && zipCrypto,
|
|
7464
7794
|
passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
|
|
7465
|
-
computeCrc32: !
|
|
7466
|
-
compressed: compressed && !
|
|
7467
|
-
encrypted: encrypted && !
|
|
7795
|
+
computeCrc32: !passThroughCompression,
|
|
7796
|
+
compressed: compressed && !passThroughCompression,
|
|
7797
|
+
encrypted: encrypted && !passThroughEncryption,
|
|
7468
7798
|
useWebWorkers,
|
|
7469
7799
|
useCompressionStream,
|
|
7470
7800
|
transferStreams,
|
|
@@ -7479,7 +7809,7 @@
|
|
|
7479
7809
|
const result = await runWorker({ readable, writable }, workerOptions);
|
|
7480
7810
|
compressedSize = result.outputSize;
|
|
7481
7811
|
writer.size += compressedSize;
|
|
7482
|
-
if (!
|
|
7812
|
+
if (!passThroughCompression) {
|
|
7483
7813
|
uncompressedSize = result.inputSize;
|
|
7484
7814
|
if (!encrypted || zipCrypto) {
|
|
7485
7815
|
crc32 = result.crc32;
|
|
@@ -7522,8 +7852,9 @@
|
|
|
7522
7852
|
headerArray,
|
|
7523
7853
|
headerView,
|
|
7524
7854
|
signature: crc32,
|
|
7525
|
-
crc32: encrypted && !zipCrypto && !
|
|
7855
|
+
crc32: encrypted && !zipCrypto && !passThroughCompression ? UNDEFINED_VALUE : crc32,
|
|
7526
7856
|
extraFieldExtendedTimestampFlag,
|
|
7857
|
+
extraFieldExtendedTimestampTime,
|
|
7527
7858
|
zip64UncompressedSize,
|
|
7528
7859
|
zip64CompressedSize
|
|
7529
7860
|
});
|
|
@@ -7548,7 +7879,7 @@
|
|
|
7548
7879
|
encryptionStrength,
|
|
7549
7880
|
extendedTimestamp,
|
|
7550
7881
|
ntfsTimestamp,
|
|
7551
|
-
|
|
7882
|
+
passThroughCompression,
|
|
7552
7883
|
encrypted,
|
|
7553
7884
|
zip64UncompressedSize,
|
|
7554
7885
|
zip64CompressedSize,
|
|
@@ -7559,7 +7890,7 @@
|
|
|
7559
7890
|
let { version, compressionMethod } = options;
|
|
7560
7891
|
const compressed = !directory && isCompressed(compressionMethod, level);
|
|
7561
7892
|
let rawLocalExtraFieldZip64;
|
|
7562
|
-
const uncompressedFile =
|
|
7893
|
+
const uncompressedFile = passThroughCompression || !compressed;
|
|
7563
7894
|
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
|
|
7564
7895
|
const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
|
|
7565
7896
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
@@ -7571,8 +7902,8 @@
|
|
|
7571
7902
|
if (zip64ExtraFieldComplete) {
|
|
7572
7903
|
extraFieldZip64.writeUint64(uncompressedSize);
|
|
7573
7904
|
if (uncompressedFile) {
|
|
7574
|
-
const encryptionOverhead = encrypted
|
|
7575
|
-
extraFieldZip64.writeUint64(
|
|
7905
|
+
const encryptionOverhead = getEncryptionOverhead(encrypted, zipCrypto, encryptionStrength);
|
|
7906
|
+
extraFieldZip64.writeUint64(passThroughCompression ? 0 : uncompressedSize + encryptionOverhead);
|
|
7576
7907
|
}
|
|
7577
7908
|
}
|
|
7578
7909
|
} else {
|
|
@@ -7591,6 +7922,7 @@
|
|
|
7591
7922
|
let rawExtraFieldNTFS;
|
|
7592
7923
|
let rawExtraFieldExtendedTimestamp;
|
|
7593
7924
|
let extraFieldExtendedTimestampFlag;
|
|
7925
|
+
let extraFieldExtendedTimestampTime;
|
|
7594
7926
|
if (extendedTimestamp) {
|
|
7595
7927
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
7596
7928
|
const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
|
|
@@ -7598,6 +7930,7 @@
|
|
|
7598
7930
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
7599
7931
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
7600
7932
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
7933
|
+
extraFieldExtendedTimestampTime = lastModTimeUnix;
|
|
7601
7934
|
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7602
7935
|
extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
|
|
7603
7936
|
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
@@ -7640,7 +7973,7 @@
|
|
|
7640
7973
|
let rawExtraFieldUnix;
|
|
7641
7974
|
try {
|
|
7642
7975
|
const { uid, gid, unixExtraFieldType } = options;
|
|
7643
|
-
if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE
|
|
7976
|
+
if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
7644
7977
|
const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
|
|
7645
7978
|
const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
|
|
7646
7979
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
@@ -7681,7 +8014,7 @@
|
|
|
7681
8014
|
}
|
|
7682
8015
|
if (encrypted && !zipCrypto) {
|
|
7683
8016
|
version = version > VERSION_AES ? version : VERSION_AES;
|
|
7684
|
-
if (
|
|
8017
|
+
if (passThroughCompression && crc32 !== UNDEFINED_VALUE) {
|
|
7685
8018
|
rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
|
|
7686
8019
|
}
|
|
7687
8020
|
setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
|
|
@@ -7743,12 +8076,14 @@
|
|
|
7743
8076
|
headerArray,
|
|
7744
8077
|
headerView,
|
|
7745
8078
|
lastModDate: storedLastModDate,
|
|
8079
|
+
lastModDateClamped: storedLastModDate === clampedLastModDate && dosLastModDate.getTime() != clampedLastModDate.getTime(),
|
|
7746
8080
|
rawLastModDate,
|
|
7747
8081
|
encrypted,
|
|
7748
8082
|
compressed,
|
|
7749
8083
|
version,
|
|
7750
8084
|
compressionMethod,
|
|
7751
8085
|
extraFieldExtendedTimestampFlag,
|
|
8086
|
+
extraFieldExtendedTimestampTime,
|
|
7752
8087
|
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
7753
8088
|
localExtraFieldZip64Length,
|
|
7754
8089
|
rawExtraFieldExtendedTimestamp,
|
|
@@ -7851,7 +8186,7 @@
|
|
|
7851
8186
|
}, {
|
|
7852
8187
|
zip64,
|
|
7853
8188
|
zipCrypto,
|
|
7854
|
-
|
|
8189
|
+
passThroughCompression,
|
|
7855
8190
|
dataDescriptor
|
|
7856
8191
|
}) {
|
|
7857
8192
|
const {
|
|
@@ -7862,7 +8197,7 @@
|
|
|
7862
8197
|
dataDescriptorView,
|
|
7863
8198
|
dataDescriptorOffset
|
|
7864
8199
|
} = dataDescriptorInfo;
|
|
7865
|
-
if ((!encrypted || zipCrypto ||
|
|
8200
|
+
if ((!encrypted || zipCrypto || passThroughCompression) && crc32 !== UNDEFINED_VALUE) {
|
|
7866
8201
|
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
7867
8202
|
if (dataDescriptor) {
|
|
7868
8203
|
setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
|
|
@@ -7893,9 +8228,9 @@
|
|
|
7893
8228
|
uncompressedSize,
|
|
7894
8229
|
zip64UncompressedSize,
|
|
7895
8230
|
zip64CompressedSize
|
|
7896
|
-
}, localHeaderView, { dataDescriptor,
|
|
8231
|
+
}, localHeaderView, { dataDescriptor, passThroughCompression }) {
|
|
7897
8232
|
if (!dataDescriptor) {
|
|
7898
|
-
if (!encrypted || (
|
|
8233
|
+
if (!encrypted || (passThroughCompression && crc32 !== UNDEFINED_VALUE)) {
|
|
7899
8234
|
setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
|
|
7900
8235
|
}
|
|
7901
8236
|
if (!zip64CompressedSize) {
|
|
@@ -7932,9 +8267,8 @@
|
|
|
7932
8267
|
rawExtraFieldUnix,
|
|
7933
8268
|
rawExtraField,
|
|
7934
8269
|
rawCentralExtraField,
|
|
7935
|
-
extendedTimestamp,
|
|
7936
8270
|
extraFieldExtendedTimestampFlag,
|
|
7937
|
-
|
|
8271
|
+
extraFieldExtendedTimestampTime,
|
|
7938
8272
|
zip64Enabled,
|
|
7939
8273
|
uncompressedSize,
|
|
7940
8274
|
compressedSize
|
|
@@ -7977,16 +8311,15 @@
|
|
|
7977
8311
|
fileEntry.zip64Offset = zip64Offset;
|
|
7978
8312
|
fileEntry.zip64DiskNumberStart = zip64DiskNumberStart;
|
|
7979
8313
|
let rawExtraFieldTimestamp;
|
|
7980
|
-
|
|
7981
|
-
|
|
8314
|
+
if (extraFieldExtendedTimestampTime === UNDEFINED_VALUE) {
|
|
8315
|
+
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
8316
|
+
} else {
|
|
7982
8317
|
const extraFieldTimestamp = createRecordWriter(9);
|
|
7983
8318
|
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
7984
8319
|
extraFieldTimestamp.writeUint16(5);
|
|
7985
8320
|
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
7986
|
-
extraFieldTimestamp.writeUint32(
|
|
8321
|
+
extraFieldTimestamp.writeUint32(extraFieldExtendedTimestampTime);
|
|
7987
8322
|
rawExtraFieldTimestamp = extraFieldTimestamp.array;
|
|
7988
|
-
} else {
|
|
7989
|
-
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
7990
8323
|
}
|
|
7991
8324
|
fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
|
|
7992
8325
|
const extraFieldLength = getLength(
|
|
@@ -8486,6 +8819,11 @@
|
|
|
8486
8819
|
};
|
|
8487
8820
|
}
|
|
8488
8821
|
|
|
8822
|
+
function isPrintableASCIIText(rawText) {
|
|
8823
|
+
return rawText.every(characterCode =>
|
|
8824
|
+
characterCode >= MIN_PRINTABLE_ASCII_CHARACTER_CODE && characterCode <= MAX_PRINTABLE_ASCII_CHARACTER_CODE);
|
|
8825
|
+
}
|
|
8826
|
+
|
|
8489
8827
|
function getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod) {
|
|
8490
8828
|
let bitFlag = 0;
|
|
8491
8829
|
if (useUnicodeFileNames) {
|
|
@@ -8647,7 +8985,7 @@
|
|
|
8647
8985
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
8648
8986
|
*/
|
|
8649
8987
|
|
|
8650
|
-
const VERSION = "2.
|
|
8988
|
+
const VERSION = "2.12.0";
|
|
8651
8989
|
|
|
8652
8990
|
/*
|
|
8653
8991
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9128,7 +9466,10 @@
|
|
|
9128
9466
|
const ERR_ENTRY_EXISTS = "Entry filename already exists";
|
|
9129
9467
|
const ERR_DUPLICATE_IMPORTED_ENTRY = "Duplicate entry filename in the imported zip file";
|
|
9130
9468
|
const ERR_INVALID_DUPLICATES = "Invalid duplicates option (must be \"throw\", \"keep-first\" or \"keep-last\")";
|
|
9131
|
-
const ERR_ANCESTOR_ENTRY = "Entry is
|
|
9469
|
+
const ERR_ANCESTOR_ENTRY = "Entry is an ancestor of target entry";
|
|
9470
|
+
const ERR_ROOT_DIRECTORY_NOT_MOVABLE = "Root directory cannot be moved";
|
|
9471
|
+
const ERR_TARGET_NOT_DIRECTORY = "Target entry is not a directory";
|
|
9472
|
+
const ERR_PARENT_NOT_DIRECTORY = "Parent entry is not a directory";
|
|
9132
9473
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
9133
9474
|
const DUPLICATES_THROW = "throw";
|
|
9134
9475
|
const DUPLICATES_KEEP_FIRST = "keep-first";
|
|
@@ -9136,22 +9477,8 @@
|
|
|
9136
9477
|
const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
|
|
9137
9478
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
9138
9479
|
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
9139
|
-
const
|
|
9480
|
+
const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
|
|
9140
9481
|
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
9482
|
|
|
9156
9483
|
class ZipEntry {
|
|
9157
9484
|
|
|
@@ -9523,6 +9850,7 @@
|
|
|
9523
9850
|
await initStream(reader);
|
|
9524
9851
|
zipReader = new ZipReader(reader, options);
|
|
9525
9852
|
}
|
|
9853
|
+
checkPassThroughValue(options.passThrough);
|
|
9526
9854
|
const duplicates = checkDuplicatesOption(options.duplicates);
|
|
9527
9855
|
const importedEntries = [];
|
|
9528
9856
|
const entries = await zipReader.getEntries(options);
|
|
@@ -9613,18 +9941,25 @@
|
|
|
9613
9941
|
|
|
9614
9942
|
async exportZip(writer, options = {}) {
|
|
9615
9943
|
const zipEntry = this;
|
|
9944
|
+
const zipWriterProvided = Boolean(writer) && typeof writer.add == FUNCTION_TYPE;
|
|
9616
9945
|
options = Object.assign({}, options);
|
|
9617
|
-
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
9946
|
+
if (!zipWriterProvided && options.bufferedWrite === UNDEFINED_VALUE) {
|
|
9618
9947
|
options.bufferedWrite = true;
|
|
9619
9948
|
}
|
|
9620
|
-
const [readers] = await Promise.all([
|
|
9621
|
-
|
|
9949
|
+
const [readers] = await Promise.all([
|
|
9950
|
+
initReaders(zipEntry, checkReaderOptions(options.readerOptions)),
|
|
9951
|
+
zipWriterProvided ? UNDEFINED_VALUE : initStream(writer)
|
|
9952
|
+
]);
|
|
9953
|
+
const zipWriter = zipWriterProvided ? writer : new ZipWriter(writer, options);
|
|
9622
9954
|
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
|
|
9955
|
+
if (zipWriterProvided) {
|
|
9956
|
+
return zipWriter;
|
|
9957
|
+
}
|
|
9623
9958
|
await zipWriter.close(options.globalComment);
|
|
9624
9959
|
return writer.getData ? writer.getData() : writer.writable;
|
|
9625
9960
|
}
|
|
9626
9961
|
|
|
9627
|
-
getExportedSize(options = {}) {
|
|
9962
|
+
async getExportedSize(options = {}) {
|
|
9628
9963
|
const zipEntry = this;
|
|
9629
9964
|
options = Object.assign({}, options);
|
|
9630
9965
|
checkReaderOptions(options.readerOptions);
|
|
@@ -9639,7 +9974,7 @@
|
|
|
9639
9974
|
const writeOrderGuaranteed = !options.bufferedWrite ||
|
|
9640
9975
|
(entries.every(entry => entry.options.keepOrder !== false) &&
|
|
9641
9976
|
children.every(child => isImplicitDirectory(child) || !child.children.length));
|
|
9642
|
-
return getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
|
|
9977
|
+
return await getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
|
|
9643
9978
|
}
|
|
9644
9979
|
|
|
9645
9980
|
getChildByName(name) {
|
|
@@ -9700,7 +10035,7 @@
|
|
|
9700
10035
|
|
|
9701
10036
|
move(entry, destination) {
|
|
9702
10037
|
if (entry == this.root) {
|
|
9703
|
-
throw new Error(
|
|
10038
|
+
throw new Error(ERR_ROOT_DIRECTORY_NOT_MOVABLE);
|
|
9704
10039
|
} else {
|
|
9705
10040
|
if (destination.directory) {
|
|
9706
10041
|
if (!destination.isDescendantOf(entry)) {
|
|
@@ -9721,7 +10056,7 @@
|
|
|
9721
10056
|
throw new Error(ERR_ANCESTOR_ENTRY);
|
|
9722
10057
|
}
|
|
9723
10058
|
} else {
|
|
9724
|
-
throw new Error(
|
|
10059
|
+
throw new Error(ERR_TARGET_NOT_DIRECTORY);
|
|
9725
10060
|
}
|
|
9726
10061
|
}
|
|
9727
10062
|
}
|
|
@@ -10034,70 +10369,11 @@
|
|
|
10034
10369
|
let zipEntryMetadata = {};
|
|
10035
10370
|
let passThroughOptions = {};
|
|
10036
10371
|
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
|
-
}
|
|
10372
|
+
const passThrough = isPassThrough(child, options);
|
|
10373
|
+
const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
|
|
10374
|
+
({ entryOptions: zipEntryMetadata, passThroughOptions } = getSourceEntryOptions(child.data, passThrough, lastModDateOverride));
|
|
10375
|
+
if (passThrough) {
|
|
10376
|
+
passThroughOptions.passThrough = true;
|
|
10101
10377
|
}
|
|
10102
10378
|
}
|
|
10103
10379
|
const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
|
|
@@ -10107,16 +10383,6 @@
|
|
|
10107
10383
|
return { name, entryOptions };
|
|
10108
10384
|
}
|
|
10109
10385
|
|
|
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
10386
|
function getDeterminedSize(child, passThrough) {
|
|
10121
10387
|
const { reader } = child;
|
|
10122
10388
|
if (reader && reader.size !== UNDEFINED_VALUE) {
|
|
@@ -10129,9 +10395,18 @@
|
|
|
10129
10395
|
if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
|
|
10130
10396
|
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
10131
10397
|
}
|
|
10398
|
+
if (readerOptions) {
|
|
10399
|
+
checkPassThroughValue(readerOptions.passThrough);
|
|
10400
|
+
}
|
|
10132
10401
|
return readerOptions;
|
|
10133
10402
|
}
|
|
10134
10403
|
|
|
10404
|
+
function checkPassThroughValue(passThrough) {
|
|
10405
|
+
if (checkPassThroughOption(passThrough) === PASS_THROUGH_COMPRESSED) {
|
|
10406
|
+
throw new Error(ERR_UNSUPPORTED_PASS_THROUGH_VALUE);
|
|
10407
|
+
}
|
|
10408
|
+
}
|
|
10409
|
+
|
|
10135
10410
|
function replaceContent(zipEntry, params) {
|
|
10136
10411
|
const { uncompressedSize } = params;
|
|
10137
10412
|
Object.assign(zipEntry, params, {
|
|
@@ -10160,20 +10435,6 @@
|
|
|
10160
10435
|
return child.directory && child.data === null;
|
|
10161
10436
|
}
|
|
10162
10437
|
|
|
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
10438
|
async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
10178
10439
|
const { onstart, onprogress, onend, onentryprogress } = options;
|
|
10179
10440
|
const selectedEntry = entry;
|
|
@@ -10276,6 +10537,7 @@
|
|
|
10276
10537
|
|
|
10277
10538
|
async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
10278
10539
|
const { onstart, onprogress, onend } = options;
|
|
10540
|
+
checkPassThroughValue(options.passThrough);
|
|
10279
10541
|
const readerOptions = checkReaderOptions(options.readerOptions);
|
|
10280
10542
|
const abortController = new AbortController();
|
|
10281
10543
|
const { signal } = abortController;
|
|
@@ -10351,7 +10613,7 @@
|
|
|
10351
10613
|
if (exportAborted || isExportAborted(signal.reason)) {
|
|
10352
10614
|
return;
|
|
10353
10615
|
}
|
|
10354
|
-
|
|
10616
|
+
throwIfAborted(signal);
|
|
10355
10617
|
}
|
|
10356
10618
|
try {
|
|
10357
10619
|
if (child.directory) {
|
|
@@ -10484,7 +10746,7 @@
|
|
|
10484
10746
|
}
|
|
10485
10747
|
return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
|
|
10486
10748
|
} else {
|
|
10487
|
-
throw new Error(
|
|
10749
|
+
throw new Error(ERR_PARENT_NOT_DIRECTORY);
|
|
10488
10750
|
}
|
|
10489
10751
|
}
|
|
10490
10752
|
|
|
@@ -10531,6 +10793,7 @@
|
|
|
10531
10793
|
exports.Data64URIWriter = Data64URIWriter;
|
|
10532
10794
|
exports.ERR_ABORTED = ERR_ABORTED;
|
|
10533
10795
|
exports.ERR_AMBIGUOUS_ARCHIVE = ERR_AMBIGUOUS_ARCHIVE;
|
|
10796
|
+
exports.ERR_ANCESTOR_ENTRY = ERR_ANCESTOR_ENTRY;
|
|
10534
10797
|
exports.ERR_BAD_FORMAT = ERR_BAD_FORMAT;
|
|
10535
10798
|
exports.ERR_CENTRAL_DIRECTORY_NOT_FOUND = ERR_CENTRAL_DIRECTORY_NOT_FOUND;
|
|
10536
10799
|
exports.ERR_DUPLICATED_NAME = ERR_DUPLICATED_NAME;
|
|
@@ -10544,7 +10807,9 @@
|
|
|
10544
10807
|
exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
|
|
10545
10808
|
exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
|
|
10546
10809
|
exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
|
|
10810
|
+
exports.ERR_HTTP_STATUS = ERR_HTTP_STATUS;
|
|
10547
10811
|
exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
|
|
10812
|
+
exports.ERR_INVALID_BASE_URI = ERR_INVALID_BASE_URI;
|
|
10548
10813
|
exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
|
|
10549
10814
|
exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
|
|
10550
10815
|
exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
|
|
@@ -10554,6 +10819,7 @@
|
|
|
10554
10819
|
exports.ERR_INVALID_DATE = ERR_INVALID_DATE;
|
|
10555
10820
|
exports.ERR_INVALID_DUPLICATES = ERR_INVALID_DUPLICATES;
|
|
10556
10821
|
exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
|
|
10822
|
+
exports.ERR_INVALID_ENTRY = ERR_INVALID_ENTRY;
|
|
10557
10823
|
exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
|
|
10558
10824
|
exports.ERR_INVALID_ENTRY_COMMENT_TYPE = ERR_INVALID_ENTRY_COMMENT_TYPE;
|
|
10559
10825
|
exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
|
|
@@ -10572,6 +10838,7 @@
|
|
|
10572
10838
|
exports.ERR_INVALID_PASSWORD = ERR_INVALID_PASSWORD;
|
|
10573
10839
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
10574
10840
|
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
10841
|
+
exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
|
|
10575
10842
|
exports.ERR_INVALID_READER = ERR_INVALID_READER;
|
|
10576
10843
|
exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
|
|
10577
10844
|
exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
|
|
@@ -10582,14 +10849,19 @@
|
|
|
10582
10849
|
exports.ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = ERR_INVALID_UNIX_EXTRA_FIELD_TYPE;
|
|
10583
10850
|
exports.ERR_INVALID_UNIX_ID_SIZE = ERR_INVALID_UNIX_ID_SIZE;
|
|
10584
10851
|
exports.ERR_INVALID_UNIX_MODE = ERR_INVALID_UNIX_MODE;
|
|
10852
|
+
exports.ERR_INVALID_URI = ERR_INVALID_URI;
|
|
10585
10853
|
exports.ERR_INVALID_VERSION = ERR_INVALID_VERSION;
|
|
10586
10854
|
exports.ERR_ITERATOR_COMPLETED_TOO_SOON = ERR_ITERATOR_COMPLETED_TOO_SOON;
|
|
10587
10855
|
exports.ERR_LOCAL_FILE_HEADER_NOT_FOUND = ERR_LOCAL_FILE_HEADER_NOT_FOUND;
|
|
10588
10856
|
exports.ERR_OVERLAPPING_ENTRY = ERR_OVERLAPPING_ENTRY;
|
|
10857
|
+
exports.ERR_PARENT_NOT_DIRECTORY = ERR_PARENT_NOT_DIRECTORY;
|
|
10589
10858
|
exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
|
|
10590
10859
|
exports.ERR_RESERVED_COMPRESSION_METHOD = ERR_RESERVED_COMPRESSION_METHOD;
|
|
10860
|
+
exports.ERR_ROOT_DIRECTORY_NOT_MOVABLE = ERR_ROOT_DIRECTORY_NOT_MOVABLE;
|
|
10591
10861
|
exports.ERR_SPLIT_ZIP_FILE = ERR_SPLIT_ZIP_FILE;
|
|
10862
|
+
exports.ERR_TARGET_NOT_DIRECTORY = ERR_TARGET_NOT_DIRECTORY;
|
|
10592
10863
|
exports.ERR_UNDEFINED_COMPRESSION_METHOD = ERR_UNDEFINED_COMPRESSION_METHOD;
|
|
10864
|
+
exports.ERR_UNDEFINED_CRC32 = ERR_UNDEFINED_CRC32;
|
|
10593
10865
|
exports.ERR_UNDEFINED_READER = ERR_UNDEFINED_READER;
|
|
10594
10866
|
exports.ERR_UNDEFINED_UNCOMPRESSED_SIZE = ERR_UNDEFINED_UNCOMPRESSED_SIZE;
|
|
10595
10867
|
exports.ERR_UNDETERMINED_SIZE = ERR_UNDETERMINED_SIZE;
|
|
@@ -10601,10 +10873,12 @@
|
|
|
10601
10873
|
exports.ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH;
|
|
10602
10874
|
exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
|
|
10603
10875
|
exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
|
|
10876
|
+
exports.ERR_UNSUPPORTED_PASS_THROUGH_VALUE = ERR_UNSUPPORTED_PASS_THROUGH_VALUE;
|
|
10604
10877
|
exports.ERR_UNSUPPORTED_SPLIT_USDZ = ERR_UNSUPPORTED_SPLIT_USDZ;
|
|
10605
10878
|
exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
|
|
10606
10879
|
exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
|
|
10607
10880
|
exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
|
|
10881
|
+
exports.ERR_WRITER_SIZE_NOT_WRITABLE = ERR_WRITER_SIZE_NOT_WRITABLE;
|
|
10608
10882
|
exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
|
|
10609
10883
|
exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
|
|
10610
10884
|
exports.HttpRangeReader = HttpRangeReader;
|
|
@@ -10618,13 +10892,17 @@
|
|
|
10618
10892
|
exports.Uint8ArrayWriter = Uint8ArrayWriter;
|
|
10619
10893
|
exports.VERSION = VERSION;
|
|
10620
10894
|
exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
|
|
10895
|
+
exports.WARNING_CLAMPED_LAST_MODIFICATION_DATE = WARNING_CLAMPED_LAST_MODIFICATION_DATE;
|
|
10621
10896
|
exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
|
|
10897
|
+
exports.WARNING_COMPRESSION_UNAVAILABLE = WARNING_COMPRESSION_UNAVAILABLE;
|
|
10622
10898
|
exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
|
|
10623
10899
|
exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
|
|
10624
10900
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
|
|
10625
10901
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
|
|
10626
10902
|
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
|
|
10903
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME = WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME;
|
|
10627
10904
|
exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
|
|
10905
|
+
exports.WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY;
|
|
10628
10906
|
exports.WARNING_PREPENDED_CENTRAL_DIRECTORY = WARNING_PREPENDED_CENTRAL_DIRECTORY;
|
|
10629
10907
|
exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
|
|
10630
10908
|
exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;
|