@zip.js/zip.js 2.8.35 → 2.8.37
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 +3 -2
- package/dist/zip-core.js +246 -55
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core.js +198 -55
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-native.js +249 -58
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +247 -56
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +248 -57
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +249 -58
- 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 +247 -56
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +249 -58
- package/index-native.min.js +1 -1
- package/index.cjs +247 -56
- package/index.d.cts +112 -2
- package/index.d.ts +112 -2
- package/index.min.js +1 -1
- package/lib/core/codec-pool.js +19 -3
- package/lib/core/codec-registry.js +116 -0
- package/lib/core/constants.js +1 -1
- package/lib/core/io.js +47 -26
- package/lib/core/options.js +2 -0
- package/lib/core/streams/codec-stream.js +1 -1
- package/lib/core/streams/zip-entry-stream.js +22 -5
- package/lib/core/streams/zlib-js/zlib-streams.min.js +1 -1
- package/lib/core/web-worker-base.js +5 -1
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-reader.js +6 -2
- package/lib/core/zip-writer.js +53 -18
- package/lib/zip-core-base.js +7 -0
- package/lib/zip-core-writer.js +1 -0
- package/package.json +1 -1
- package/worker-message-property-names.js +1 -1
package/dist/zip-fs-core.js
CHANGED
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18;
|
|
104
104
|
const LOCAL_HEADER_COMMON_OFFSET = 4;
|
|
105
105
|
|
|
106
|
-
const MAX_DATE = new Date(2107, 11, 31);
|
|
106
|
+
const MAX_DATE = new Date(2107, 11, 31, 23, 59, 58);
|
|
107
107
|
const MIN_DATE = new Date(1980, 0, 1);
|
|
108
108
|
|
|
109
109
|
const UNDEFINED_VALUE = undefined;
|
|
@@ -268,6 +268,7 @@
|
|
|
268
268
|
const HTTP_METHOD_GET = "GET";
|
|
269
269
|
const HTTP_RANGE_UNIT = "bytes";
|
|
270
270
|
const DEFAULT_BUFFER_SIZE = 256 * 1024;
|
|
271
|
+
const DEFAULT_MAXIMUM_RANGE_SIZE = 16 * 1024 * 1024;
|
|
271
272
|
|
|
272
273
|
const PROPERTY_NAME_WRITABLE = "writable";
|
|
273
274
|
const DISK_BOUNDARY = Symbol();
|
|
@@ -580,6 +581,7 @@
|
|
|
580
581
|
forceRangeRequests,
|
|
581
582
|
combineSizeEocd,
|
|
582
583
|
checkResourceChanges = true,
|
|
584
|
+
maximumRangeSize = DEFAULT_MAXIMUM_RANGE_SIZE,
|
|
583
585
|
fetch
|
|
584
586
|
} = options;
|
|
585
587
|
options = Object.assign({}, options);
|
|
@@ -588,6 +590,7 @@
|
|
|
588
590
|
delete options.forceRangeRequests;
|
|
589
591
|
delete options.combineSizeEocd;
|
|
590
592
|
delete options.checkResourceChanges;
|
|
593
|
+
delete options.maximumRangeSize;
|
|
591
594
|
delete options.useXHR;
|
|
592
595
|
delete options.fetch;
|
|
593
596
|
Object.assign(httpReader, {
|
|
@@ -598,6 +601,7 @@
|
|
|
598
601
|
forceRangeRequests,
|
|
599
602
|
combineSizeEocd,
|
|
600
603
|
checkResourceChanges,
|
|
604
|
+
maximumRangeSize,
|
|
601
605
|
fetch
|
|
602
606
|
});
|
|
603
607
|
}
|
|
@@ -683,40 +687,31 @@
|
|
|
683
687
|
|
|
684
688
|
function createRangeReadable(httpReader, offset, size) {
|
|
685
689
|
let bodyReader;
|
|
690
|
+
let windowOffset = offset;
|
|
691
|
+
let windowRemainingLength = 0;
|
|
686
692
|
let remainingLength = size;
|
|
687
693
|
return new ReadableStream({
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
if (response.status != 206) {
|
|
691
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
692
|
-
}
|
|
693
|
-
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
694
|
-
if (contentRangeHeader) {
|
|
695
|
-
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
696
|
-
if (!Number.isNaN(rangeStart) && rangeStart != offset) {
|
|
697
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
checkResourceValidators(httpReader, response);
|
|
701
|
-
setResourceValidators(httpReader, response);
|
|
702
|
-
bodyReader = response.body.getReader();
|
|
694
|
+
start() {
|
|
695
|
+
return openWindow();
|
|
703
696
|
},
|
|
704
697
|
async pull(controller) {
|
|
698
|
+
if (!bodyReader) {
|
|
699
|
+
await openWindow();
|
|
700
|
+
}
|
|
705
701
|
const { value, done } = await bodyReader.read();
|
|
706
702
|
if (done) {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
703
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
704
|
+
}
|
|
705
|
+
const chunk = value.length > windowRemainingLength ? value.subarray(0, windowRemainingLength) : value;
|
|
706
|
+
windowRemainingLength -= chunk.length;
|
|
707
|
+
remainingLength -= chunk.length;
|
|
708
|
+
if (chunk.length) {
|
|
709
|
+
controller.enqueue(chunk);
|
|
710
|
+
}
|
|
711
|
+
if (!windowRemainingLength) {
|
|
712
|
+
await closeWindow();
|
|
717
713
|
if (!remainingLength) {
|
|
718
714
|
controller.close();
|
|
719
|
-
await bodyReader.cancel();
|
|
720
715
|
}
|
|
721
716
|
}
|
|
722
717
|
},
|
|
@@ -724,6 +719,32 @@
|
|
|
724
719
|
return bodyReader && bodyReader.cancel(reason);
|
|
725
720
|
}
|
|
726
721
|
});
|
|
722
|
+
|
|
723
|
+
async function openWindow() {
|
|
724
|
+
const windowLength = Math.min(httpReader.maximumRangeSize, remainingLength);
|
|
725
|
+
const response = await sendFetchRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, windowOffset, windowLength));
|
|
726
|
+
if (response.status != 206) {
|
|
727
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
728
|
+
}
|
|
729
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
730
|
+
if (contentRangeHeader) {
|
|
731
|
+
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
732
|
+
if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
|
|
733
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
checkResourceValidators(httpReader, response);
|
|
737
|
+
setResourceValidators(httpReader, response);
|
|
738
|
+
windowOffset += windowLength;
|
|
739
|
+
windowRemainingLength = windowLength;
|
|
740
|
+
bodyReader = response.body.getReader();
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
async function closeWindow() {
|
|
744
|
+
const currentBodyReader = bodyReader;
|
|
745
|
+
bodyReader = UNDEFINED_VALUE;
|
|
746
|
+
await currentBodyReader.cancel();
|
|
747
|
+
}
|
|
727
748
|
}
|
|
728
749
|
|
|
729
750
|
function getContentRangeSize(response) {
|
|
@@ -1150,6 +1171,61 @@
|
|
|
1150
1171
|
return reader.readUint8Array(offset, size);
|
|
1151
1172
|
}
|
|
1152
1173
|
|
|
1174
|
+
/*
|
|
1175
|
+
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
1176
|
+
|
|
1177
|
+
Redistribution and use in source and binary forms, with or without
|
|
1178
|
+
modification, are permitted provided that the following conditions are met:
|
|
1179
|
+
|
|
1180
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
1181
|
+
this list of conditions and the following disclaimer.
|
|
1182
|
+
|
|
1183
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
1184
|
+
notice, this list of conditions and the following disclaimer in
|
|
1185
|
+
the documentation and/or other materials provided with the distribution.
|
|
1186
|
+
|
|
1187
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
1188
|
+
derived from this software without specific prior written permission.
|
|
1189
|
+
|
|
1190
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
1191
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
1192
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
1193
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
1194
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
1195
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
1196
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
1197
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
1198
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
1199
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
1200
|
+
*/
|
|
1201
|
+
|
|
1202
|
+
const ERR_INVALID_CODEC_MODULE = "Invalid codec module";
|
|
1203
|
+
|
|
1204
|
+
const registeredCodecs = new Map();
|
|
1205
|
+
const codecStreams = new Map();
|
|
1206
|
+
|
|
1207
|
+
function getRegisteredCodec(compressionMethod) {
|
|
1208
|
+
return registeredCodecs.get(compressionMethod);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
function getCodecStreams(format) {
|
|
1212
|
+
return codecStreams.get(format);
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
function setCodecStreams(format, streams) {
|
|
1216
|
+
const { CompressionStream, DecompressionStream } = streams;
|
|
1217
|
+
if (typeof CompressionStream != FUNCTION_TYPE && typeof DecompressionStream != FUNCTION_TYPE) {
|
|
1218
|
+
throw new Error(ERR_INVALID_CODEC_MODULE);
|
|
1219
|
+
}
|
|
1220
|
+
codecStreams.set(format, { CompressionStream, DecompressionStream });
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
async function ensureCodecStreams(format, codecURI) {
|
|
1224
|
+
if (!codecStreams.has(format) && codecURI) {
|
|
1225
|
+
setCodecStreams(format, await import(codecURI));
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1153
1229
|
/*
|
|
1154
1230
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
1155
1231
|
|
|
@@ -2642,6 +2718,7 @@
|
|
|
2642
2718
|
|
|
2643
2719
|
const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
|
|
2644
2720
|
const ERR_INVALID_COMPRESSED_DATA = "Invalid compressed data";
|
|
2721
|
+
const ERR_UNSUPPORTED_COMPRESSION$2 = "Compression method not supported";
|
|
2645
2722
|
const FORMAT_DEFLATE_RAW = "deflate-raw";
|
|
2646
2723
|
const FORMAT_DEFLATE64_RAW = "deflate64-raw";
|
|
2647
2724
|
const FORMAT_GZIP = "gzip";
|
|
@@ -2652,18 +2729,21 @@
|
|
|
2652
2729
|
|
|
2653
2730
|
constructor(options, { chunkSize, CompressionStreamZlib, CompressionStream }) {
|
|
2654
2731
|
super({});
|
|
2655
|
-
const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level, deflate64 } = options;
|
|
2732
|
+
const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level, deflate64, format } = options;
|
|
2656
2733
|
const stream = this;
|
|
2657
2734
|
let crc32Stream, encryptionStream, gzipCrc32Stream;
|
|
2658
2735
|
let readable = super.readable;
|
|
2659
|
-
const
|
|
2736
|
+
const codecStreams = format && getCodecStreams(format);
|
|
2737
|
+
const useGzipCrc32 = signed && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) &&
|
|
2660
2738
|
Boolean(useCompressionStream && CompressionStream);
|
|
2661
2739
|
if ((!encrypted || zipCrypto) && signed && !useGzipCrc32) {
|
|
2662
2740
|
crc32Stream = new Crc32Stream();
|
|
2663
2741
|
readable = pipeThrough(readable, crc32Stream);
|
|
2664
2742
|
}
|
|
2665
2743
|
if (compressed) {
|
|
2666
|
-
if (
|
|
2744
|
+
if (codecStreams) {
|
|
2745
|
+
readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.CompressionStream, format, { level, chunkSize }));
|
|
2746
|
+
} else if (useGzipCrc32) {
|
|
2667
2747
|
gzipCrc32Stream = new GzipToRawDeflateStream();
|
|
2668
2748
|
readable = pipeThroughBackpressured(readable, new CompressionStream(FORMAT_GZIP));
|
|
2669
2749
|
readable = pipeThrough(readable, gzipCrc32Stream);
|
|
@@ -2737,7 +2817,7 @@
|
|
|
2737
2817
|
|
|
2738
2818
|
constructor(options, { chunkSize, DecompressionStreamZlib, DecompressionStream }) {
|
|
2739
2819
|
super({});
|
|
2740
|
-
const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream, deflate64 } = options;
|
|
2820
|
+
const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream, deflate64, format } = options;
|
|
2741
2821
|
let crc32Stream, decryptionStream;
|
|
2742
2822
|
let readable = super.readable;
|
|
2743
2823
|
if (encrypted) {
|
|
@@ -2749,7 +2829,12 @@
|
|
|
2749
2829
|
}
|
|
2750
2830
|
}
|
|
2751
2831
|
if (compressed) {
|
|
2752
|
-
|
|
2832
|
+
const codecStreams = format && getCodecStreams(format);
|
|
2833
|
+
if (codecStreams) {
|
|
2834
|
+
readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize }));
|
|
2835
|
+
} else {
|
|
2836
|
+
readable = pipeThroughCommpressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamZlib, DecompressionStream);
|
|
2837
|
+
}
|
|
2753
2838
|
readable = mapInflateStreamError(readable);
|
|
2754
2839
|
}
|
|
2755
2840
|
if ((!encrypted || zipCrypto) && signed) {
|
|
@@ -2776,6 +2861,13 @@
|
|
|
2776
2861
|
});
|
|
2777
2862
|
}
|
|
2778
2863
|
|
|
2864
|
+
function createCodecStream(CodecStreamClass, format, options) {
|
|
2865
|
+
if (!CodecStreamClass) {
|
|
2866
|
+
throw new Error(ERR_UNSUPPORTED_COMPRESSION$2);
|
|
2867
|
+
}
|
|
2868
|
+
return new CodecStreamClass(format, options);
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2779
2871
|
function pipeThroughCommpressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamZlib, CompressionStream) {
|
|
2780
2872
|
const Stream = useCompressionStream && CompressionStreamNative ? CompressionStreamNative : CompressionStreamZlib || CompressionStream;
|
|
2781
2873
|
const format = options.deflate64 ? FORMAT_DEFLATE64_RAW : FORMAT_DEFLATE_RAW;
|
|
@@ -2969,7 +3061,7 @@
|
|
|
2969
3061
|
constructor(chunkSize) {
|
|
2970
3062
|
const pendingChunks = [];
|
|
2971
3063
|
let pendingLength = 0;
|
|
2972
|
-
if (!(chunkSize
|
|
3064
|
+
if (!Number.isFinite(chunkSize) || chunkSize < 1) {
|
|
2973
3065
|
chunkSize = DEFAULT_CHUNK_SIZE;
|
|
2974
3066
|
}
|
|
2975
3067
|
super({
|
|
@@ -3520,11 +3612,18 @@
|
|
|
3520
3612
|
|
|
3521
3613
|
async function runWorker(stream, workerOptions) {
|
|
3522
3614
|
const { options, config } = workerOptions;
|
|
3523
|
-
const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options;
|
|
3615
|
+
const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted, format, codecURI } = options;
|
|
3524
3616
|
const { workerURI, maxWorkers } = config;
|
|
3617
|
+
if (format) {
|
|
3618
|
+
if (codecURI) {
|
|
3619
|
+
options.codecURI = resolveCodecURI(codecURI, config.baseURI);
|
|
3620
|
+
}
|
|
3621
|
+
await ensureCodecStreams(format, options.codecURI);
|
|
3622
|
+
}
|
|
3525
3623
|
workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
|
|
3526
3624
|
const streamCopy = !compressed && !signed && !encrypted;
|
|
3527
|
-
|
|
3625
|
+
const workerSupported = format === UNDEFINED_VALUE || Boolean(options.codecURI);
|
|
3626
|
+
workerOptions.useWebWorkers = !streamCopy && workerSupported && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
|
|
3528
3627
|
workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
|
|
3529
3628
|
options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
|
|
3530
3629
|
return (await getWorker()).run();
|
|
@@ -3564,6 +3663,14 @@
|
|
|
3564
3663
|
}
|
|
3565
3664
|
}
|
|
3566
3665
|
|
|
3666
|
+
function resolveCodecURI(codecURI, baseURI) {
|
|
3667
|
+
try {
|
|
3668
|
+
return new URL(codecURI, baseURI).toString();
|
|
3669
|
+
} catch {
|
|
3670
|
+
return codecURI;
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3567
3674
|
function armStarvationTimeout() {
|
|
3568
3675
|
if (!starvationTimeout && pendingRequests.length && Number.isFinite(starvationDelay) && starvationDelay >= 0) {
|
|
3569
3676
|
starvationTimeout = setTimeout(onWorkerStarvation, starvationDelay);
|
|
@@ -3882,6 +3989,7 @@
|
|
|
3882
3989
|
const OPTION_PREVENT_CLOSE = "preventClose";
|
|
3883
3990
|
const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
|
|
3884
3991
|
const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
|
|
3992
|
+
const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
|
|
3885
3993
|
const OPTION_KEEP_ORDER = "keepOrder";
|
|
3886
3994
|
const OPTION_LEVEL = "level";
|
|
3887
3995
|
const OPTION_BUFFERED_WRITE = "bufferedWrite";
|
|
@@ -4313,7 +4421,8 @@
|
|
|
4313
4421
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
|
|
4314
4422
|
}
|
|
4315
4423
|
}
|
|
4316
|
-
|
|
4424
|
+
const registeredCodec = passThrough ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
4425
|
+
if ((compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec) && !passThrough) {
|
|
4317
4426
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
|
|
4318
4427
|
}
|
|
4319
4428
|
if (dataArray.length < HEADER_SIZE || getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
@@ -4352,7 +4461,7 @@
|
|
|
4352
4461
|
fileEntry.zipCrypto = zipCrypto;
|
|
4353
4462
|
}
|
|
4354
4463
|
if (encrypted) {
|
|
4355
|
-
if (!zipCrypto && extraFieldAES.strength
|
|
4464
|
+
if (!zipCrypto && (extraFieldAES.strength < 1 || extraFieldAES.strength > 3)) {
|
|
4356
4465
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
|
|
4357
4466
|
} else if (!password && !rawPassword) {
|
|
4358
4467
|
throw new Error(ERR_ENCRYPTED);
|
|
@@ -4391,6 +4500,8 @@
|
|
|
4391
4500
|
useCompressionStream,
|
|
4392
4501
|
transferStreams: getOptionValue$1(zipEntry, options, OPTION_TRANSFER_STREAMS),
|
|
4393
4502
|
deflate64,
|
|
4503
|
+
format: registeredCodec ? registeredCodec.format : UNDEFINED_VALUE,
|
|
4504
|
+
codecURI: registeredCodec ? registeredCodec.codecURI : UNDEFINED_VALUE,
|
|
4394
4505
|
checkPasswordOnly
|
|
4395
4506
|
},
|
|
4396
4507
|
config,
|
|
@@ -5007,6 +5118,7 @@
|
|
|
5007
5118
|
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
5008
5119
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
5009
5120
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
5121
|
+
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
5010
5122
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
|
|
5011
5123
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
5012
5124
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
@@ -5409,6 +5521,7 @@
|
|
|
5409
5521
|
const encryptionStrength = getOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
5410
5522
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
5411
5523
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
5524
|
+
const ntfsTimestamp = getOptionValue(zipWriter, options, OPTION_NTFS_TIMESTAMP);
|
|
5412
5525
|
const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
|
|
5413
5526
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
5414
5527
|
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
@@ -5418,11 +5531,20 @@
|
|
|
5418
5531
|
const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
|
|
5419
5532
|
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
|
|
5420
5533
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
5534
|
+
const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
5421
5535
|
if (!passThrough && compressionMethod !== UNDEFINED_VALUE &&
|
|
5422
|
-
compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE) {
|
|
5536
|
+
compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
|
|
5423
5537
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
5424
5538
|
}
|
|
5425
5539
|
let level = getOptionValue(zipWriter, options, OPTION_LEVEL);
|
|
5540
|
+
if (zipWriter.options[OPTION_USDZ]) {
|
|
5541
|
+
if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
|
|
5542
|
+
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
|
|
5543
|
+
}
|
|
5544
|
+
if (level === UNDEFINED_VALUE && compressionMethod === UNDEFINED_VALUE) {
|
|
5545
|
+
level = 0;
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5426
5548
|
let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5427
5549
|
let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
|
|
5428
5550
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
@@ -5434,7 +5556,7 @@
|
|
|
5434
5556
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
5435
5557
|
useCompressionStream = false;
|
|
5436
5558
|
}
|
|
5437
|
-
if (!useCompressionStream && (zipWriter.config.CompressionStream === UNDEFINED_VALUE && zipWriter.config.CompressionStreamZlib === UNDEFINED_VALUE)) {
|
|
5559
|
+
if (!useCompressionStream && !registeredCodec && (zipWriter.config.CompressionStream === UNDEFINED_VALUE && zipWriter.config.CompressionStreamZlib === UNDEFINED_VALUE)) {
|
|
5438
5560
|
level = 0;
|
|
5439
5561
|
}
|
|
5440
5562
|
const zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
@@ -5478,6 +5600,7 @@
|
|
|
5478
5600
|
encryptionStrength,
|
|
5479
5601
|
zipCrypto,
|
|
5480
5602
|
extendedTimestamp,
|
|
5603
|
+
ntfsTimestamp,
|
|
5481
5604
|
keepOrder,
|
|
5482
5605
|
useWebWorkers,
|
|
5483
5606
|
transferStreams,
|
|
@@ -5487,6 +5610,9 @@
|
|
|
5487
5610
|
signal,
|
|
5488
5611
|
useUnicodeFileNames,
|
|
5489
5612
|
compressionMethod,
|
|
5613
|
+
format: registeredCodec ? registeredCodec.format : UNDEFINED_VALUE,
|
|
5614
|
+
codecURI: registeredCodec ? registeredCodec.codecURI : UNDEFINED_VALUE,
|
|
5615
|
+
codecVersionNeeded: registeredCodec ? registeredCodec.versionNeeded : UNDEFINED_VALUE,
|
|
5490
5616
|
level,
|
|
5491
5617
|
useCompressionStream,
|
|
5492
5618
|
dataDescriptor,
|
|
@@ -5783,7 +5909,9 @@
|
|
|
5783
5909
|
msdosAttributesRaw,
|
|
5784
5910
|
msdosAttributes,
|
|
5785
5911
|
useCompressionStream,
|
|
5786
|
-
passThrough
|
|
5912
|
+
passThrough,
|
|
5913
|
+
format,
|
|
5914
|
+
codecURI
|
|
5787
5915
|
} = options;
|
|
5788
5916
|
const fileEntry = {
|
|
5789
5917
|
lock,
|
|
@@ -5843,7 +5971,9 @@
|
|
|
5843
5971
|
encrypted: encrypted && !passThrough,
|
|
5844
5972
|
useWebWorkers,
|
|
5845
5973
|
useCompressionStream,
|
|
5846
|
-
transferStreams
|
|
5974
|
+
transferStreams,
|
|
5975
|
+
format,
|
|
5976
|
+
codecURI
|
|
5847
5977
|
},
|
|
5848
5978
|
config,
|
|
5849
5979
|
streamOptions: { signal, size, onstart, onprogress, onend }
|
|
@@ -5915,6 +6045,7 @@
|
|
|
5915
6045
|
rawExtraField,
|
|
5916
6046
|
encryptionStrength,
|
|
5917
6047
|
extendedTimestamp,
|
|
6048
|
+
ntfsTimestamp,
|
|
5918
6049
|
passThrough,
|
|
5919
6050
|
encrypted,
|
|
5920
6051
|
zip64UncompressedSize,
|
|
@@ -5960,7 +6091,8 @@
|
|
|
5960
6091
|
let extraFieldExtendedTimestampFlag;
|
|
5961
6092
|
if (extendedTimestamp) {
|
|
5962
6093
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
5963
|
-
|
|
6094
|
+
const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
|
|
6095
|
+
if (lastModTimeUnixInRange) {
|
|
5964
6096
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
5965
6097
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
5966
6098
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
@@ -5978,19 +6110,26 @@
|
|
|
5978
6110
|
} else {
|
|
5979
6111
|
rawExtraFieldExtendedTimestamp = EMPTY_UINT8_ARRAY;
|
|
5980
6112
|
}
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
6113
|
+
const writeExtraFieldNTFS = ntfsTimestamp === UNDEFINED_VALUE ?
|
|
6114
|
+
!lastModTimeUnixInRange || Boolean(lastAccessDate || creationDate) :
|
|
6115
|
+
ntfsTimestamp;
|
|
6116
|
+
if (writeExtraFieldNTFS) {
|
|
6117
|
+
try {
|
|
6118
|
+
const lastModTimeNTFS = getTimeNTFS(lastModDate);
|
|
6119
|
+
const extraFieldNTFS = createRecordWriter(36);
|
|
6120
|
+
extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS);
|
|
6121
|
+
extraFieldNTFS.uint16(32);
|
|
6122
|
+
extraFieldNTFS.skip(4);
|
|
6123
|
+
extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS_TAG1);
|
|
6124
|
+
extraFieldNTFS.uint16(24);
|
|
6125
|
+
extraFieldNTFS.uint64(lastModTimeNTFS);
|
|
6126
|
+
extraFieldNTFS.uint64(getTimeNTFS(lastAccessDate) || lastModTimeNTFS);
|
|
6127
|
+
extraFieldNTFS.uint64(getTimeNTFS(creationDate) || lastModTimeNTFS);
|
|
6128
|
+
rawExtraFieldNTFS = extraFieldNTFS.array;
|
|
6129
|
+
} catch {
|
|
6130
|
+
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
6131
|
+
}
|
|
6132
|
+
} else {
|
|
5994
6133
|
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
5995
6134
|
}
|
|
5996
6135
|
} else {
|
|
@@ -6028,6 +6167,10 @@
|
|
|
6028
6167
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
6029
6168
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
6030
6169
|
}
|
|
6170
|
+
const { codecVersionNeeded } = options;
|
|
6171
|
+
if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
|
|
6172
|
+
version = version > codecVersionNeeded ? version : codecVersionNeeded;
|
|
6173
|
+
}
|
|
6031
6174
|
if (zip64) {
|
|
6032
6175
|
version = version > VERSION_ZIP64 ? version : VERSION_ZIP64;
|
|
6033
6176
|
}
|