@zip.js/zip.js 2.8.36 → 2.8.38
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 +4 -2
- package/dist/zip-core.js +356 -63
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core.js +301 -63
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-native.js +359 -66
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +357 -64
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +358 -65
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +359 -66
- 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 +357 -64
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +359 -66
- package/index-native.min.js +1 -1
- package/index.cjs +357 -64
- package/index.d.cts +126 -4
- package/index.d.ts +126 -4
- package/index.min.js +1 -1
- package/lib/core/codec-pool.js +21 -4
- package/lib/core/codec-registry.js +116 -0
- package/lib/core/codec-worker.js +94 -18
- package/lib/core/configuration.js +2 -0
- package/lib/core/constants.js +5 -1
- package/lib/core/options.js +2 -0
- package/lib/core/streams/codec-stream.js +6 -2
- package/lib/core/streams/zip-entry-stream.js +50 -16
- package/lib/core/streams/zlib-js/zlib-streams.min.js +1 -1
- package/lib/core/web-worker-base.js +30 -8
- 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 +29 -3
- package/lib/core/zip-writer.js +68 -25
- package/lib/zip-core-base.js +7 -0
- package/lib/zip-core-reader.js +2 -1
- 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
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
|
|
46
46
|
const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
|
|
47
47
|
const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
|
|
48
|
+
const ARCHIVE_EXTRA_DATA_SIGNATURE = 0x08064b50;
|
|
48
49
|
const CENTRAL_FILE_HEADER_SIGNATURE = 0x02014b50;
|
|
49
50
|
const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;
|
|
50
51
|
const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 0x06064b50;
|
|
@@ -76,6 +77,7 @@
|
|
|
76
77
|
const BITFLAG_LEVEL_FAST_MASK = 0b100;
|
|
77
78
|
const BITFLAG_LEVEL_SUPER_FAST_MASK = 0b110;
|
|
78
79
|
const BITFLAG_DATA_DESCRIPTOR = 0b1000;
|
|
80
|
+
const BITFLAG_STRONG_ENCRYPTION = 0b1000000;
|
|
79
81
|
const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
|
|
80
82
|
const FILE_ATTR_MSDOS_DIR_MASK = 0b10000;
|
|
81
83
|
const FILE_ATTR_MSDOS_READONLY_MASK = 0x01;
|
|
@@ -103,7 +105,7 @@
|
|
|
103
105
|
const HEADER_OFFSET_UNCOMPRESSED_SIZE = 18;
|
|
104
106
|
const LOCAL_HEADER_COMMON_OFFSET = 4;
|
|
105
107
|
|
|
106
|
-
const MAX_DATE = new Date(2107, 11, 31);
|
|
108
|
+
const MAX_DATE = new Date(2107, 11, 31, 23, 59, 58);
|
|
107
109
|
const MIN_DATE = new Date(1980, 0, 1);
|
|
108
110
|
|
|
109
111
|
const UNDEFINED_VALUE = undefined;
|
|
@@ -159,6 +161,7 @@
|
|
|
159
161
|
maxWorkers,
|
|
160
162
|
terminateWorkerTimeout: 5000,
|
|
161
163
|
workerStarvationTimeout: 5000,
|
|
164
|
+
workerStartupTimeout: 5000,
|
|
162
165
|
useWebWorkers: true,
|
|
163
166
|
useCompressionStream: true,
|
|
164
167
|
transferStreams: true,
|
|
@@ -1171,6 +1174,61 @@
|
|
|
1171
1174
|
return reader.readUint8Array(offset, size);
|
|
1172
1175
|
}
|
|
1173
1176
|
|
|
1177
|
+
/*
|
|
1178
|
+
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
1179
|
+
|
|
1180
|
+
Redistribution and use in source and binary forms, with or without
|
|
1181
|
+
modification, are permitted provided that the following conditions are met:
|
|
1182
|
+
|
|
1183
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
1184
|
+
this list of conditions and the following disclaimer.
|
|
1185
|
+
|
|
1186
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
1187
|
+
notice, this list of conditions and the following disclaimer in
|
|
1188
|
+
the documentation and/or other materials provided with the distribution.
|
|
1189
|
+
|
|
1190
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
1191
|
+
derived from this software without specific prior written permission.
|
|
1192
|
+
|
|
1193
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
1194
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
1195
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
1196
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
1197
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
1198
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
1199
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
1200
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
1201
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
1202
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
1203
|
+
*/
|
|
1204
|
+
|
|
1205
|
+
const ERR_INVALID_CODEC_MODULE = "Invalid codec module";
|
|
1206
|
+
|
|
1207
|
+
const registeredCodecs = new Map();
|
|
1208
|
+
const codecStreams = new Map();
|
|
1209
|
+
|
|
1210
|
+
function getRegisteredCodec(compressionMethod) {
|
|
1211
|
+
return registeredCodecs.get(compressionMethod);
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
function getCodecStreams(format) {
|
|
1215
|
+
return codecStreams.get(format);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
function setCodecStreams(format, streams) {
|
|
1219
|
+
const { CompressionStream, DecompressionStream } = streams;
|
|
1220
|
+
if (typeof CompressionStream != FUNCTION_TYPE && typeof DecompressionStream != FUNCTION_TYPE) {
|
|
1221
|
+
throw new Error(ERR_INVALID_CODEC_MODULE);
|
|
1222
|
+
}
|
|
1223
|
+
codecStreams.set(format, { CompressionStream, DecompressionStream });
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
async function ensureCodecStreams(format, codecURI) {
|
|
1227
|
+
if (!codecStreams.has(format) && codecURI) {
|
|
1228
|
+
setCodecStreams(format, await import(codecURI));
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1174
1232
|
/*
|
|
1175
1233
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
1176
1234
|
|
|
@@ -2663,6 +2721,7 @@
|
|
|
2663
2721
|
|
|
2664
2722
|
const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
|
|
2665
2723
|
const ERR_INVALID_COMPRESSED_DATA = "Invalid compressed data";
|
|
2724
|
+
const ERR_UNSUPPORTED_COMPRESSION$2 = "Compression method not supported";
|
|
2666
2725
|
const FORMAT_DEFLATE_RAW = "deflate-raw";
|
|
2667
2726
|
const FORMAT_DEFLATE64_RAW = "deflate64-raw";
|
|
2668
2727
|
const FORMAT_GZIP = "gzip";
|
|
@@ -2673,23 +2732,26 @@
|
|
|
2673
2732
|
|
|
2674
2733
|
constructor(options, { chunkSize, CompressionStreamZlib, CompressionStream }) {
|
|
2675
2734
|
super({});
|
|
2676
|
-
const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level, deflate64 } = options;
|
|
2735
|
+
const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level, deflate64, format } = options;
|
|
2677
2736
|
const stream = this;
|
|
2678
2737
|
let crc32Stream, encryptionStream, gzipCrc32Stream;
|
|
2679
2738
|
let readable = super.readable;
|
|
2680
|
-
const
|
|
2739
|
+
const codecStreams = format && getCodecStreams(format);
|
|
2740
|
+
const useGzipCrc32 = signed && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) &&
|
|
2681
2741
|
Boolean(useCompressionStream && CompressionStream);
|
|
2682
2742
|
if ((!encrypted || zipCrypto) && signed && !useGzipCrc32) {
|
|
2683
2743
|
crc32Stream = new Crc32Stream();
|
|
2684
2744
|
readable = pipeThrough(readable, crc32Stream);
|
|
2685
2745
|
}
|
|
2686
2746
|
if (compressed) {
|
|
2687
|
-
if (
|
|
2747
|
+
if (codecStreams) {
|
|
2748
|
+
readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.CompressionStream, format, { level, chunkSize }));
|
|
2749
|
+
} else if (useGzipCrc32) {
|
|
2688
2750
|
gzipCrc32Stream = new GzipToRawDeflateStream();
|
|
2689
2751
|
readable = pipeThroughBackpressured(readable, new CompressionStream(FORMAT_GZIP));
|
|
2690
2752
|
readable = pipeThrough(readable, gzipCrc32Stream);
|
|
2691
2753
|
} else {
|
|
2692
|
-
readable =
|
|
2754
|
+
readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamZlib);
|
|
2693
2755
|
}
|
|
2694
2756
|
}
|
|
2695
2757
|
if (encrypted) {
|
|
@@ -2758,7 +2820,7 @@
|
|
|
2758
2820
|
|
|
2759
2821
|
constructor(options, { chunkSize, DecompressionStreamZlib, DecompressionStream }) {
|
|
2760
2822
|
super({});
|
|
2761
|
-
const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream, deflate64 } = options;
|
|
2823
|
+
const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream, deflate64, format } = options;
|
|
2762
2824
|
let crc32Stream, decryptionStream;
|
|
2763
2825
|
let readable = super.readable;
|
|
2764
2826
|
if (encrypted) {
|
|
@@ -2770,7 +2832,12 @@
|
|
|
2770
2832
|
}
|
|
2771
2833
|
}
|
|
2772
2834
|
if (compressed) {
|
|
2773
|
-
|
|
2835
|
+
const codecStreams = format && getCodecStreams(format);
|
|
2836
|
+
if (codecStreams) {
|
|
2837
|
+
readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize }));
|
|
2838
|
+
} else {
|
|
2839
|
+
readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamZlib);
|
|
2840
|
+
}
|
|
2774
2841
|
readable = mapInflateStreamError(readable);
|
|
2775
2842
|
}
|
|
2776
2843
|
if ((!encrypted || zipCrypto) && signed) {
|
|
@@ -2788,6 +2855,25 @@
|
|
|
2788
2855
|
}
|
|
2789
2856
|
}
|
|
2790
2857
|
|
|
2858
|
+
const deflateRawSupportByStream = new Map();
|
|
2859
|
+
|
|
2860
|
+
function supportsDeflateRaw(StreamClass) {
|
|
2861
|
+
if (!StreamClass) {
|
|
2862
|
+
return false;
|
|
2863
|
+
}
|
|
2864
|
+
let supported = deflateRawSupportByStream.get(StreamClass);
|
|
2865
|
+
if (supported === UNDEFINED_VALUE) {
|
|
2866
|
+
try {
|
|
2867
|
+
new StreamClass(FORMAT_DEFLATE_RAW);
|
|
2868
|
+
supported = true;
|
|
2869
|
+
} catch {
|
|
2870
|
+
supported = false;
|
|
2871
|
+
}
|
|
2872
|
+
deflateRawSupportByStream.set(StreamClass, supported);
|
|
2873
|
+
}
|
|
2874
|
+
return supported;
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2791
2877
|
function setReadable(stream, readable, flush) {
|
|
2792
2878
|
readable = pipeThrough(readable, new TransformStream({ flush }));
|
|
2793
2879
|
Object.defineProperty(stream, "readable", {
|
|
@@ -2797,21 +2883,24 @@
|
|
|
2797
2883
|
});
|
|
2798
2884
|
}
|
|
2799
2885
|
|
|
2800
|
-
function
|
|
2801
|
-
|
|
2886
|
+
function createCodecStream(CodecStreamClass, format, options) {
|
|
2887
|
+
if (!CodecStreamClass) {
|
|
2888
|
+
throw new Error(ERR_UNSUPPORTED_COMPRESSION$2);
|
|
2889
|
+
}
|
|
2890
|
+
return new CodecStreamClass(format, options);
|
|
2891
|
+
}
|
|
2892
|
+
|
|
2893
|
+
function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamZlib) {
|
|
2894
|
+
const Stream = useCompressionStream && CompressionStreamNative ?
|
|
2895
|
+
CompressionStreamNative :
|
|
2896
|
+
CompressionStreamZlib || CompressionStreamNative;
|
|
2802
2897
|
const format = options.deflate64 ? FORMAT_DEFLATE64_RAW : FORMAT_DEFLATE_RAW;
|
|
2803
2898
|
let codecStream;
|
|
2804
2899
|
try {
|
|
2805
2900
|
codecStream = new Stream(format, options);
|
|
2806
2901
|
} catch (error) {
|
|
2807
|
-
if (useCompressionStream) {
|
|
2808
|
-
|
|
2809
|
-
codecStream = new CompressionStreamZlib(format, options);
|
|
2810
|
-
} else if (CompressionStream) {
|
|
2811
|
-
codecStream = new CompressionStream(format, options);
|
|
2812
|
-
} else {
|
|
2813
|
-
throw error;
|
|
2814
|
-
}
|
|
2902
|
+
if (useCompressionStream && CompressionStreamZlib && Stream != CompressionStreamZlib) {
|
|
2903
|
+
codecStream = new CompressionStreamZlib(format, options);
|
|
2815
2904
|
} else {
|
|
2816
2905
|
throw error;
|
|
2817
2906
|
}
|
|
@@ -3072,6 +3161,7 @@
|
|
|
3072
3161
|
const MODULE_WORKER_OPTIONS = { type: "module" };
|
|
3073
3162
|
const ERROR_EVENT_TYPE = "error";
|
|
3074
3163
|
const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
|
|
3164
|
+
const ERR_WORKER_STARTUP_TIMEOUT = "Worker startup timeout";
|
|
3075
3165
|
|
|
3076
3166
|
let webWorkerSupported, webWorkerSource, webWorkerURI, webWorkerOptions;
|
|
3077
3167
|
let transferStreamsSupported = true;
|
|
@@ -3175,7 +3265,7 @@
|
|
|
3175
3265
|
}
|
|
3176
3266
|
|
|
3177
3267
|
function createWebWorkerInterface(workerData, config) {
|
|
3178
|
-
const { baseURI, chunkSize } = config;
|
|
3268
|
+
const { baseURI, chunkSize, workerStartupTimeout } = config;
|
|
3179
3269
|
let { wasmURI } = config;
|
|
3180
3270
|
|
|
3181
3271
|
if (!workerData.interface) {
|
|
@@ -3192,9 +3282,26 @@
|
|
|
3192
3282
|
}
|
|
3193
3283
|
Object.assign(workerData, {
|
|
3194
3284
|
worker,
|
|
3285
|
+
workerAlive: false,
|
|
3195
3286
|
terminated: false,
|
|
3196
3287
|
interface: {
|
|
3197
|
-
run: () =>
|
|
3288
|
+
run: async () => {
|
|
3289
|
+
try {
|
|
3290
|
+
return await runWebWorker(workerData, { chunkSize, wasmURI, baseURI, workerStartupTimeout });
|
|
3291
|
+
} catch (error) {
|
|
3292
|
+
if (error && error.workerStartupFailed) {
|
|
3293
|
+
webWorkerSupported = false;
|
|
3294
|
+
const { reader } = workerData;
|
|
3295
|
+
if (reader) {
|
|
3296
|
+
reader.releaseLock();
|
|
3297
|
+
}
|
|
3298
|
+
workerData.reader = null;
|
|
3299
|
+
workerData.writer = null;
|
|
3300
|
+
return runWorker$1(workerData, config);
|
|
3301
|
+
}
|
|
3302
|
+
throw error;
|
|
3303
|
+
}
|
|
3304
|
+
}
|
|
3198
3305
|
}
|
|
3199
3306
|
});
|
|
3200
3307
|
}
|
|
@@ -3204,15 +3311,23 @@
|
|
|
3204
3311
|
async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
|
|
3205
3312
|
let codecStream;
|
|
3206
3313
|
try {
|
|
3207
|
-
if (!options.
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
config
|
|
3214
|
-
|
|
3215
|
-
|
|
3314
|
+
if (options.compressed && !options.format) {
|
|
3315
|
+
const deflate = options.codecType.startsWith(CODEC_DEFLATE);
|
|
3316
|
+
const ZlibStream = deflate ? config.CompressionStreamZlib : config.DecompressionStreamZlib;
|
|
3317
|
+
const NativeStream = deflate ? config.CompressionStream : config.DecompressionStream;
|
|
3318
|
+
if (!options.useCompressionStream) {
|
|
3319
|
+
try {
|
|
3320
|
+
await initModule(config);
|
|
3321
|
+
} catch {
|
|
3322
|
+
if (!ZlibStream || ZlibStream.requiresModule) {
|
|
3323
|
+
options.useCompressionStream = true;
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
} else if (ZlibStream && ZlibStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
|
|
3327
|
+
try {
|
|
3328
|
+
await initModule(config);
|
|
3329
|
+
} catch {
|
|
3330
|
+
// ignored
|
|
3216
3331
|
}
|
|
3217
3332
|
}
|
|
3218
3333
|
}
|
|
@@ -3281,6 +3396,10 @@
|
|
|
3281
3396
|
writer: writable.getWriter()
|
|
3282
3397
|
});
|
|
3283
3398
|
}
|
|
3399
|
+
const { workerStartupTimeout } = config;
|
|
3400
|
+
if (!workerData.workerAlive && Number.isFinite(workerStartupTimeout) && workerStartupTimeout >= 0) {
|
|
3401
|
+
workerData.startupTimeout = setTimeout(() => onStartupTimeout(workerData), workerStartupTimeout);
|
|
3402
|
+
}
|
|
3284
3403
|
try {
|
|
3285
3404
|
const resultValue = await result;
|
|
3286
3405
|
await closeWritable();
|
|
@@ -3393,28 +3512,68 @@
|
|
|
3393
3512
|
} else {
|
|
3394
3513
|
worker = new Worker(webWorkerURI, webWorkerOptions);
|
|
3395
3514
|
}
|
|
3396
|
-
worker.addEventListener(MESSAGE_EVENT_TYPE, event =>
|
|
3515
|
+
worker.addEventListener(MESSAGE_EVENT_TYPE, event => {
|
|
3516
|
+
workerData.workerAlive = true;
|
|
3517
|
+
clearStartupTimeout(workerData);
|
|
3518
|
+
onMessage(event, workerData);
|
|
3519
|
+
});
|
|
3397
3520
|
worker.addEventListener(ERROR_EVENT_TYPE, event => onWorkerError(event, workerData));
|
|
3398
3521
|
worker.addEventListener(MESSAGE_ERROR_EVENT_TYPE, event => onWorkerError(event, workerData));
|
|
3399
3522
|
return worker;
|
|
3400
3523
|
}
|
|
3401
3524
|
|
|
3525
|
+
function onStartupTimeout(workerData) {
|
|
3526
|
+
workerData.startupTimeout = null;
|
|
3527
|
+
if (workerData.workerAlive) {
|
|
3528
|
+
return;
|
|
3529
|
+
}
|
|
3530
|
+
const { rejectResult, writer } = workerData;
|
|
3531
|
+
terminateWorker$1(workerData);
|
|
3532
|
+
workerData.worker = null;
|
|
3533
|
+
if (rejectResult) {
|
|
3534
|
+
const error = new Error(ERR_WORKER_STARTUP_TIMEOUT);
|
|
3535
|
+
error.workerStartupFailed = true;
|
|
3536
|
+
rejectResult(error);
|
|
3537
|
+
if (writer) {
|
|
3538
|
+
writer.releaseLock();
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
|
|
3543
|
+
function clearStartupTimeout(workerData) {
|
|
3544
|
+
const { startupTimeout } = workerData;
|
|
3545
|
+
if (startupTimeout) {
|
|
3546
|
+
clearTimeout(startupTimeout);
|
|
3547
|
+
workerData.startupTimeout = null;
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
|
|
3402
3551
|
function onWorkerError(event, workerData) {
|
|
3403
3552
|
if (event.preventDefault) {
|
|
3404
3553
|
event.preventDefault();
|
|
3405
3554
|
}
|
|
3406
|
-
|
|
3555
|
+
clearStartupTimeout(workerData);
|
|
3556
|
+
const { workerAlive, rejectResult, writer, onTaskFinished } = workerData;
|
|
3407
3557
|
terminateWorker$1(workerData);
|
|
3558
|
+
if (!workerAlive) {
|
|
3559
|
+
workerData.worker = null;
|
|
3560
|
+
}
|
|
3408
3561
|
if (rejectResult) {
|
|
3409
|
-
|
|
3562
|
+
let error = event.error || new Error(event.message || ERROR_EVENT_TYPE);
|
|
3563
|
+
if (!workerAlive) {
|
|
3564
|
+
error = Object.assign(new Error(error.message || ERROR_EVENT_TYPE), { workerStartupFailed: true });
|
|
3565
|
+
}
|
|
3566
|
+
rejectResult(error);
|
|
3410
3567
|
if (writer) {
|
|
3411
3568
|
writer.releaseLock();
|
|
3412
3569
|
}
|
|
3413
|
-
|
|
3570
|
+
if (workerAlive) {
|
|
3571
|
+
onTaskFinished();
|
|
3572
|
+
}
|
|
3414
3573
|
}
|
|
3415
3574
|
}
|
|
3416
3575
|
|
|
3417
|
-
function sendMessage(message, { worker, writer, transferStreams }) {
|
|
3576
|
+
function sendMessage(message, { worker, writer, transferStreams, workerAlive }) {
|
|
3418
3577
|
try {
|
|
3419
3578
|
const { value, readable, writable } = message;
|
|
3420
3579
|
const transferables = [];
|
|
@@ -3422,7 +3581,7 @@
|
|
|
3422
3581
|
message.value = toExactUint8Array(value);
|
|
3423
3582
|
transferables.push(message.value.buffer);
|
|
3424
3583
|
}
|
|
3425
|
-
if (transferStreams && transferStreamsSupported) {
|
|
3584
|
+
if (transferStreams && transferStreamsSupported && workerAlive) {
|
|
3426
3585
|
if (readable) {
|
|
3427
3586
|
transferables.push(readable);
|
|
3428
3587
|
}
|
|
@@ -3541,11 +3700,18 @@
|
|
|
3541
3700
|
|
|
3542
3701
|
async function runWorker(stream, workerOptions) {
|
|
3543
3702
|
const { options, config } = workerOptions;
|
|
3544
|
-
const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options;
|
|
3703
|
+
const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted, format, codecURI } = options;
|
|
3545
3704
|
const { workerURI, maxWorkers } = config;
|
|
3705
|
+
if (format) {
|
|
3706
|
+
if (codecURI) {
|
|
3707
|
+
options.codecURI = resolveCodecURI(codecURI, config.baseURI);
|
|
3708
|
+
}
|
|
3709
|
+
await ensureCodecStreams(format, options.codecURI);
|
|
3710
|
+
}
|
|
3546
3711
|
workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
|
|
3547
3712
|
const streamCopy = !compressed && !signed && !encrypted;
|
|
3548
|
-
|
|
3713
|
+
const workerSupported = format === UNDEFINED_VALUE || Boolean(options.codecURI);
|
|
3714
|
+
workerOptions.useWebWorkers = !streamCopy && workerSupported && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
|
|
3549
3715
|
workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
|
|
3550
3716
|
options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
|
|
3551
3717
|
return (await getWorker()).run();
|
|
@@ -3585,6 +3751,14 @@
|
|
|
3585
3751
|
}
|
|
3586
3752
|
}
|
|
3587
3753
|
|
|
3754
|
+
function resolveCodecURI(codecURI, baseURI) {
|
|
3755
|
+
try {
|
|
3756
|
+
return new URL(codecURI, baseURI).toString();
|
|
3757
|
+
} catch {
|
|
3758
|
+
return codecURI;
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3761
|
+
|
|
3588
3762
|
function armStarvationTimeout() {
|
|
3589
3763
|
if (!starvationTimeout && pendingRequests.length && Number.isFinite(starvationDelay) && starvationDelay >= 0) {
|
|
3590
3764
|
starvationTimeout = setTimeout(onWorkerStarvation, starvationDelay);
|
|
@@ -3903,6 +4077,7 @@
|
|
|
3903
4077
|
const OPTION_PREVENT_CLOSE = "preventClose";
|
|
3904
4078
|
const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
|
|
3905
4079
|
const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
|
|
4080
|
+
const OPTION_NTFS_TIMESTAMP = "ntfsTimestamp";
|
|
3906
4081
|
const OPTION_KEEP_ORDER = "keepOrder";
|
|
3907
4082
|
const OPTION_LEVEL = "level";
|
|
3908
4083
|
const OPTION_BUFFERED_WRITE = "bufferedWrite";
|
|
@@ -3962,6 +4137,7 @@
|
|
|
3962
4137
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
3963
4138
|
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
3964
4139
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4140
|
+
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
3965
4141
|
const CHARSET_UTF8 = "utf-8";
|
|
3966
4142
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
3967
4143
|
const CHARSET_CP437 = "cp437";
|
|
@@ -4039,6 +4215,7 @@
|
|
|
4039
4215
|
let prependedDataLength = 0;
|
|
4040
4216
|
let startOffset;
|
|
4041
4217
|
let zip64EndOfDirectory;
|
|
4218
|
+
let zip64EndOfDirectoryVersion2;
|
|
4042
4219
|
const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
|
|
4043
4220
|
if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
|
|
4044
4221
|
directoryDataOffset += getDiskOffset$1(reader, diskNumber);
|
|
@@ -4068,6 +4245,7 @@
|
|
|
4068
4245
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
4069
4246
|
}
|
|
4070
4247
|
zip64EndOfDirectory = true;
|
|
4248
|
+
zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
|
|
4071
4249
|
if (lastDiskNumber == MAX_16_BITS) {
|
|
4072
4250
|
lastDiskNumber = getUint32(endOfDirectoryView, 16);
|
|
4073
4251
|
} else if (checkAmbiguity && lastDiskNumber != getUint32(endOfDirectoryView, 16)) {
|
|
@@ -4147,6 +4325,9 @@
|
|
|
4147
4325
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4148
4326
|
const fileEntry = new ZipEntry$1(reader, config, zipReader.options);
|
|
4149
4327
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4328
|
+
if (indexFile == 0 && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4329
|
+
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
4330
|
+
}
|
|
4150
4331
|
throw new Error(ERR_CENTRAL_DIRECTORY_NOT_FOUND);
|
|
4151
4332
|
}
|
|
4152
4333
|
readCommonHeader(fileEntry, directoryView, offset + 6);
|
|
@@ -4334,7 +4515,8 @@
|
|
|
4334
4515
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
|
|
4335
4516
|
}
|
|
4336
4517
|
}
|
|
4337
|
-
|
|
4518
|
+
const registeredCodec = passThrough ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
4519
|
+
if ((compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE && compressionMethod != COMPRESSION_METHOD_DEFLATE_64 && !registeredCodec) && !passThrough) {
|
|
4338
4520
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION$1);
|
|
4339
4521
|
}
|
|
4340
4522
|
if (dataArray.length < HEADER_SIZE || getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
@@ -4373,7 +4555,10 @@
|
|
|
4373
4555
|
fileEntry.zipCrypto = zipCrypto;
|
|
4374
4556
|
}
|
|
4375
4557
|
if (encrypted) {
|
|
4376
|
-
if (
|
|
4558
|
+
if ((localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
|
|
4559
|
+
throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
|
|
4560
|
+
}
|
|
4561
|
+
if (!zipCrypto && (extraFieldAES.strength < 1 || extraFieldAES.strength > 3)) {
|
|
4377
4562
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
|
|
4378
4563
|
} else if (!password && !rawPassword) {
|
|
4379
4564
|
throw new Error(ERR_ENCRYPTED);
|
|
@@ -4412,6 +4597,8 @@
|
|
|
4412
4597
|
useCompressionStream,
|
|
4413
4598
|
transferStreams: getOptionValue$1(zipEntry, options, OPTION_TRANSFER_STREAMS),
|
|
4414
4599
|
deflate64,
|
|
4600
|
+
format: registeredCodec ? registeredCodec.format : UNDEFINED_VALUE,
|
|
4601
|
+
codecURI: registeredCodec ? registeredCodec.codecURI : UNDEFINED_VALUE,
|
|
4415
4602
|
checkPasswordOnly
|
|
4416
4603
|
},
|
|
4417
4604
|
config,
|
|
@@ -4464,6 +4651,16 @@
|
|
|
4464
4651
|
}
|
|
4465
4652
|
};
|
|
4466
4653
|
|
|
4654
|
+
function detectEncryptedCentralDirectory(directoryView) {
|
|
4655
|
+
const maxOffset = Math.min(directoryView.byteLength, 1024) - 3;
|
|
4656
|
+
for (let offset = 0; offset < maxOffset; offset++) {
|
|
4657
|
+
if (getUint32(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
4658
|
+
return true;
|
|
4659
|
+
}
|
|
4660
|
+
}
|
|
4661
|
+
return false;
|
|
4662
|
+
}
|
|
4663
|
+
|
|
4467
4664
|
function readCommonHeader(directory, dataView, offset) {
|
|
4468
4665
|
const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
|
|
4469
4666
|
const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
|
|
@@ -4978,6 +5175,7 @@
|
|
|
4978
5175
|
ERR_BAD_FORMAT: ERR_BAD_FORMAT,
|
|
4979
5176
|
ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
|
|
4980
5177
|
ERR_ENCRYPTED: ERR_ENCRYPTED,
|
|
5178
|
+
ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
|
|
4981
5179
|
ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
|
|
4982
5180
|
ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
|
|
4983
5181
|
ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
@@ -5028,6 +5226,7 @@
|
|
|
5028
5226
|
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
5029
5227
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
5030
5228
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
5229
|
+
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
5031
5230
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
|
|
5032
5231
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
5033
5232
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
@@ -5326,7 +5525,11 @@
|
|
|
5326
5525
|
if (versionMadeBy > MAX_16_BITS) {
|
|
5327
5526
|
throw new Error(ERR_INVALID_VERSION);
|
|
5328
5527
|
}
|
|
5329
|
-
let externalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES
|
|
5528
|
+
let externalFileAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES);
|
|
5529
|
+
const externalFileAttributesProvided = externalFileAttributes !== UNDEFINED_VALUE;
|
|
5530
|
+
if (!externalFileAttributesProvided) {
|
|
5531
|
+
externalFileAttributes = 0;
|
|
5532
|
+
}
|
|
5330
5533
|
if (!options[PROPERTY_NAME_DIRECTORY] && name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
5331
5534
|
options[PROPERTY_NAME_DIRECTORY] = true;
|
|
5332
5535
|
}
|
|
@@ -5335,13 +5538,13 @@
|
|
|
5335
5538
|
if (!name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
5336
5539
|
name += DIRECTORY_SIGNATURE;
|
|
5337
5540
|
}
|
|
5338
|
-
if (
|
|
5541
|
+
if (!externalFileAttributesProvided) {
|
|
5339
5542
|
externalFileAttributes = FILE_ATTR_MSDOS_DIR_MASK;
|
|
5340
5543
|
if (!msDosCompatible) {
|
|
5341
5544
|
externalFileAttributes |= (FILE_ATTR_UNIX_TYPE_DIR | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_DEFAULT_MASK) << 16;
|
|
5342
5545
|
}
|
|
5343
5546
|
}
|
|
5344
|
-
} else if (!msDosCompatible &&
|
|
5547
|
+
} else if (!msDosCompatible && !externalFileAttributesProvided) {
|
|
5345
5548
|
if (executable) {
|
|
5346
5549
|
externalFileAttributes = (FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_DEFAULT_MASK) << 16;
|
|
5347
5550
|
} else {
|
|
@@ -5350,6 +5553,7 @@
|
|
|
5350
5553
|
}
|
|
5351
5554
|
let unixExternalUpper;
|
|
5352
5555
|
if (!msDosCompatible) {
|
|
5556
|
+
const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
|
|
5353
5557
|
unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
5354
5558
|
unixMode = unixMode === UNDEFINED_VALUE ? unixExternalUpper : (unixMode & MAX_16_BITS);
|
|
5355
5559
|
if (setuid) {
|
|
@@ -5367,10 +5571,12 @@
|
|
|
5367
5571
|
} else {
|
|
5368
5572
|
sticky = Boolean(unixMode & FILE_ATTR_UNIX_STICKY_MASK);
|
|
5369
5573
|
}
|
|
5370
|
-
if (
|
|
5371
|
-
|
|
5574
|
+
if (!externalFileAttributesProvided || unixModeProvided) {
|
|
5575
|
+
if (directory) {
|
|
5576
|
+
unixMode |= FILE_ATTR_UNIX_TYPE_DIR;
|
|
5577
|
+
}
|
|
5578
|
+
externalFileAttributes = ((unixMode & MAX_16_BITS) << 16) | (externalFileAttributes & MAX_16_BITS);
|
|
5372
5579
|
}
|
|
5373
|
-
externalFileAttributes = ((unixMode & MAX_16_BITS) << 16) | (externalFileAttributes & MAX_8_BITS);
|
|
5374
5580
|
}
|
|
5375
5581
|
({ msdosAttributesRaw, msdosAttributes } = normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes));
|
|
5376
5582
|
if (hasMsDosProvided) {
|
|
@@ -5430,6 +5636,7 @@
|
|
|
5430
5636
|
const encryptionStrength = getOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
5431
5637
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
5432
5638
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
5639
|
+
const ntfsTimestamp = getOptionValue(zipWriter, options, OPTION_NTFS_TIMESTAMP);
|
|
5433
5640
|
const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
|
|
5434
5641
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
5435
5642
|
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
@@ -5439,11 +5646,20 @@
|
|
|
5439
5646
|
const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
|
|
5440
5647
|
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
|
|
5441
5648
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
5649
|
+
const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
5442
5650
|
if (!passThrough && compressionMethod !== UNDEFINED_VALUE &&
|
|
5443
|
-
compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE) {
|
|
5651
|
+
compressionMethod !== COMPRESSION_METHOD_STORE && compressionMethod !== COMPRESSION_METHOD_DEFLATE && !registeredCodec) {
|
|
5444
5652
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
5445
5653
|
}
|
|
5446
5654
|
let level = getOptionValue(zipWriter, options, OPTION_LEVEL);
|
|
5655
|
+
if (zipWriter.options[OPTION_USDZ]) {
|
|
5656
|
+
if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
|
|
5657
|
+
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
|
|
5658
|
+
}
|
|
5659
|
+
if (level === UNDEFINED_VALUE && compressionMethod === UNDEFINED_VALUE) {
|
|
5660
|
+
level = 0;
|
|
5661
|
+
}
|
|
5662
|
+
}
|
|
5447
5663
|
let useCompressionStream = getOptionValue(zipWriter, options, OPTION_USE_COMPRESSION_STREAM);
|
|
5448
5664
|
let dataDescriptor = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR);
|
|
5449
5665
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
@@ -5455,7 +5671,7 @@
|
|
|
5455
5671
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
5456
5672
|
useCompressionStream = false;
|
|
5457
5673
|
}
|
|
5458
|
-
if (!useCompressionStream && (zipWriter.config.CompressionStream === UNDEFINED_VALUE && zipWriter.config.CompressionStreamZlib === UNDEFINED_VALUE)) {
|
|
5674
|
+
if (!useCompressionStream && !registeredCodec && (zipWriter.config.CompressionStream === UNDEFINED_VALUE && zipWriter.config.CompressionStreamZlib === UNDEFINED_VALUE)) {
|
|
5459
5675
|
level = 0;
|
|
5460
5676
|
}
|
|
5461
5677
|
const zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
@@ -5499,6 +5715,7 @@
|
|
|
5499
5715
|
encryptionStrength,
|
|
5500
5716
|
zipCrypto,
|
|
5501
5717
|
extendedTimestamp,
|
|
5718
|
+
ntfsTimestamp,
|
|
5502
5719
|
keepOrder,
|
|
5503
5720
|
useWebWorkers,
|
|
5504
5721
|
transferStreams,
|
|
@@ -5508,6 +5725,9 @@
|
|
|
5508
5725
|
signal,
|
|
5509
5726
|
useUnicodeFileNames,
|
|
5510
5727
|
compressionMethod,
|
|
5728
|
+
format: registeredCodec ? registeredCodec.format : UNDEFINED_VALUE,
|
|
5729
|
+
codecURI: registeredCodec ? registeredCodec.codecURI : UNDEFINED_VALUE,
|
|
5730
|
+
codecVersionNeeded: registeredCodec ? registeredCodec.versionNeeded : UNDEFINED_VALUE,
|
|
5511
5731
|
level,
|
|
5512
5732
|
useCompressionStream,
|
|
5513
5733
|
dataDescriptor,
|
|
@@ -5804,7 +6024,9 @@
|
|
|
5804
6024
|
msdosAttributesRaw,
|
|
5805
6025
|
msdosAttributes,
|
|
5806
6026
|
useCompressionStream,
|
|
5807
|
-
passThrough
|
|
6027
|
+
passThrough,
|
|
6028
|
+
format,
|
|
6029
|
+
codecURI
|
|
5808
6030
|
} = options;
|
|
5809
6031
|
const fileEntry = {
|
|
5810
6032
|
lock,
|
|
@@ -5864,7 +6086,9 @@
|
|
|
5864
6086
|
encrypted: encrypted && !passThrough,
|
|
5865
6087
|
useWebWorkers,
|
|
5866
6088
|
useCompressionStream,
|
|
5867
|
-
transferStreams
|
|
6089
|
+
transferStreams,
|
|
6090
|
+
format,
|
|
6091
|
+
codecURI
|
|
5868
6092
|
},
|
|
5869
6093
|
config,
|
|
5870
6094
|
streamOptions: { signal, size, onstart, onprogress, onend }
|
|
@@ -5936,6 +6160,7 @@
|
|
|
5936
6160
|
rawExtraField,
|
|
5937
6161
|
encryptionStrength,
|
|
5938
6162
|
extendedTimestamp,
|
|
6163
|
+
ntfsTimestamp,
|
|
5939
6164
|
passThrough,
|
|
5940
6165
|
encrypted,
|
|
5941
6166
|
zip64UncompressedSize,
|
|
@@ -5981,7 +6206,8 @@
|
|
|
5981
6206
|
let extraFieldExtendedTimestampFlag;
|
|
5982
6207
|
if (extendedTimestamp) {
|
|
5983
6208
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
5984
|
-
|
|
6209
|
+
const lastModTimeUnixInRange = inUnixTimeRange(lastModTimeUnix);
|
|
6210
|
+
if (lastModTimeUnixInRange) {
|
|
5985
6211
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
5986
6212
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
5987
6213
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
@@ -5999,19 +6225,26 @@
|
|
|
5999
6225
|
} else {
|
|
6000
6226
|
rawExtraFieldExtendedTimestamp = EMPTY_UINT8_ARRAY;
|
|
6001
6227
|
}
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6228
|
+
const writeExtraFieldNTFS = ntfsTimestamp === UNDEFINED_VALUE ?
|
|
6229
|
+
!lastModTimeUnixInRange || Boolean(lastAccessDate || creationDate) :
|
|
6230
|
+
ntfsTimestamp;
|
|
6231
|
+
if (writeExtraFieldNTFS) {
|
|
6232
|
+
try {
|
|
6233
|
+
const lastModTimeNTFS = getTimeNTFS(lastModDate);
|
|
6234
|
+
const extraFieldNTFS = createRecordWriter(36);
|
|
6235
|
+
extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS);
|
|
6236
|
+
extraFieldNTFS.uint16(32);
|
|
6237
|
+
extraFieldNTFS.skip(4);
|
|
6238
|
+
extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS_TAG1);
|
|
6239
|
+
extraFieldNTFS.uint16(24);
|
|
6240
|
+
extraFieldNTFS.uint64(lastModTimeNTFS);
|
|
6241
|
+
extraFieldNTFS.uint64(getTimeNTFS(lastAccessDate) || lastModTimeNTFS);
|
|
6242
|
+
extraFieldNTFS.uint64(getTimeNTFS(creationDate) || lastModTimeNTFS);
|
|
6243
|
+
rawExtraFieldNTFS = extraFieldNTFS.array;
|
|
6244
|
+
} catch {
|
|
6245
|
+
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
6246
|
+
}
|
|
6247
|
+
} else {
|
|
6015
6248
|
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
6016
6249
|
}
|
|
6017
6250
|
} else {
|
|
@@ -6049,6 +6282,10 @@
|
|
|
6049
6282
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
6050
6283
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
6051
6284
|
}
|
|
6285
|
+
const { codecVersionNeeded } = options;
|
|
6286
|
+
if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
|
|
6287
|
+
version = version > codecVersionNeeded ? version : codecVersionNeeded;
|
|
6288
|
+
}
|
|
6052
6289
|
if (zip64) {
|
|
6053
6290
|
version = version > VERSION_ZIP64 ? version : VERSION_ZIP64;
|
|
6054
6291
|
}
|
|
@@ -6062,6 +6299,7 @@
|
|
|
6062
6299
|
if (extraFieldLength > MAX_16_BITS) {
|
|
6063
6300
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
6064
6301
|
}
|
|
6302
|
+
const dosLastModDate = new Date(Math.ceil(lastModDate.getTime() / 2000) * 2000);
|
|
6065
6303
|
const {
|
|
6066
6304
|
headerArray,
|
|
6067
6305
|
headerView,
|
|
@@ -6071,7 +6309,7 @@
|
|
|
6071
6309
|
bitFlag: getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod),
|
|
6072
6310
|
compressionMethod,
|
|
6073
6311
|
uncompressedSize,
|
|
6074
|
-
lastModDate:
|
|
6312
|
+
lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
|
|
6075
6313
|
rawFilename,
|
|
6076
6314
|
zip64CompressedSize,
|
|
6077
6315
|
zip64UncompressedSize,
|