@zip.js/zip.js 2.6.32 → 2.6.34
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/dist/z-worker-fflate.js +1 -1
- package/dist/z-worker-pako.js +1 -1
- package/dist/z-worker.js +1 -1
- package/dist/zip-fs-full.js +2441 -2287
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +1970 -1816
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +1969 -1815
- package/dist/zip-full.min.js +1 -1
- package/dist/zip-no-worker-deflate.min.js +1 -1
- package/dist/zip-no-worker-inflate.min.js +1 -1
- package/dist/zip-no-worker.min.js +1 -1
- package/dist/zip.js +1971 -1817
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +3 -1
- package/index.cjs +2441 -2287
- package/index.d.ts +36 -7
- package/index.js +3 -1
- package/lib/core/codec-pool.js +6 -5
- package/lib/core/codec-worker.js +321 -0
- package/lib/core/configuration.js +11 -8
- package/lib/core/constants.js +11 -5
- package/lib/core/io.js +150 -51
- package/lib/core/streams/aes-crypto-stream.js +2 -0
- package/lib/core/streams/codec-stream.js +60 -13
- package/lib/core/streams/codecs/sjcl.js +1 -1
- package/lib/core/streams/stream-adapter.js +55 -0
- package/lib/core/streams/zip-crypto-stream.js +1 -0
- package/lib/core/streams/zip-entry-stream.js +1 -0
- package/lib/core/util/stream-codec-shim.js +2 -0
- package/lib/core/z-worker-core.js +23 -12
- package/lib/core/zip-entry.js +2 -1
- package/lib/core/zip-fs-core.js +1 -0
- package/lib/core/zip-reader.js +16 -12
- package/lib/core/zip-writer.js +102 -54
- package/lib/z-worker-inline.js +1 -1
- package/lib/zip.js +1 -1
- package/package.json +5 -5
- package/rollup-es5.config.dev.js +199 -0
- package/rollup-es5.config.js +243 -0
- package/tests/all/test-http-split-zip.js +37 -0
- package/tests/all/test-readable-stream.js +1 -2
- package/tests/all/test-readable-zip-stream.js +1 -1
- package/tests/all/test-split-zip.js +25 -22
- package/tests/tests-data.js +2 -1
- package/lib/core/codec-interface.js +0 -115
- package/lib/core/codec-pool-worker.js +0 -289
package/lib/core/zip-reader.js
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
/* global BigInt, Response, ReadableStream, WritableStream */
|
|
30
|
+
// deno-lint-ignore-file no-this-alias
|
|
30
31
|
|
|
31
32
|
import {
|
|
32
33
|
MAX_32_BITS,
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
COMPRESSION_METHOD_DEFLATE,
|
|
35
36
|
COMPRESSION_METHOD_STORE,
|
|
36
37
|
COMPRESSION_METHOD_AES,
|
|
38
|
+
SPLIT_ZIP_FILE_SIGNATURE,
|
|
37
39
|
LOCAL_FILE_HEADER_SIGNATURE,
|
|
38
40
|
CENTRAL_FILE_HEADER_SIGNATURE,
|
|
39
41
|
END_OF_CENTRAL_DIR_SIGNATURE,
|
|
@@ -54,7 +56,8 @@ import {
|
|
|
54
56
|
BITFLAG_DATA_DESCRIPTOR,
|
|
55
57
|
BITFLAG_LANG_ENCODING_FLAG,
|
|
56
58
|
FILE_ATTR_MSDOS_DIR_MASK,
|
|
57
|
-
DIRECTORY_SIGNATURE
|
|
59
|
+
DIRECTORY_SIGNATURE,
|
|
60
|
+
UNDEFINED_VALUE
|
|
58
61
|
} from "./constants.js";
|
|
59
62
|
import {
|
|
60
63
|
getConfiguration,
|
|
@@ -76,7 +79,6 @@ import { decodeText } from "./util/decode-text.js";
|
|
|
76
79
|
import { Crc32 } from "./streams/codecs/crc32.js";
|
|
77
80
|
import { Entry } from "./zip-entry.js";
|
|
78
81
|
|
|
79
|
-
const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
|
|
80
82
|
const ERR_BAD_FORMAT = "File format is not recognized";
|
|
81
83
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
82
84
|
const ERR_EOCDR_ZIP64_NOT_FOUND = "End of Zip64 central directory not found";
|
|
@@ -127,7 +129,7 @@ class ZipReader {
|
|
|
127
129
|
let { reader } = zipReader;
|
|
128
130
|
const { config } = zipReader;
|
|
129
131
|
await initStream(reader);
|
|
130
|
-
if (reader.size ===
|
|
132
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
131
133
|
if (Array.isArray(reader)) {
|
|
132
134
|
reader = new SplitZipReader(reader);
|
|
133
135
|
} else {
|
|
@@ -149,15 +151,16 @@ class ZipReader {
|
|
|
149
151
|
throw new Error(ERR_EOCDR_NOT_FOUND);
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
|
-
const { lastDiskNumber } = reader;
|
|
153
154
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
154
155
|
let directoryDataLength = getUint32(endOfDirectoryView, 12);
|
|
155
156
|
let directoryDataOffset = getUint32(endOfDirectoryView, 16);
|
|
156
157
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
157
158
|
const commentLength = getUint16(endOfDirectoryView, 20);
|
|
158
159
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
159
|
-
|
|
160
|
-
|
|
160
|
+
const lastDiskNumber = getUint16(endOfDirectoryView, 4);
|
|
161
|
+
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
162
|
+
let diskNumber = getUint16(endOfDirectoryView, 6);
|
|
163
|
+
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
161
164
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
162
165
|
}
|
|
163
166
|
let filesLength = getUint16(endOfDirectoryView, 8);
|
|
@@ -343,7 +346,7 @@ class ZipEntry {
|
|
|
343
346
|
compressedSize
|
|
344
347
|
} = zipEntry;
|
|
345
348
|
const localDirectory = zipEntry.localDirectory = {};
|
|
346
|
-
|
|
349
|
+
const dataArray = await readUint8Array(reader, offset, 30, diskNumberStart);
|
|
347
350
|
const dataView = getDataView(dataArray);
|
|
348
351
|
let password = getOptionValue(zipEntry, options, "password");
|
|
349
352
|
password = password && password.length && password;
|
|
@@ -359,8 +362,9 @@ class ZipEntry {
|
|
|
359
362
|
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
360
363
|
}
|
|
361
364
|
readCommonHeader(localDirectory, dataView, 4);
|
|
362
|
-
|
|
363
|
-
|
|
365
|
+
localDirectory.rawExtraField = localDirectory.extraFieldLength ?
|
|
366
|
+
await readUint8Array(reader, offset + 30 + localDirectory.filenameLength, localDirectory.extraFieldLength, diskNumberStart) :
|
|
367
|
+
new Uint8Array();
|
|
364
368
|
await readCommonFooter(zipEntry, localDirectory, dataView, 4);
|
|
365
369
|
Object.assign(fileEntry, {
|
|
366
370
|
lastAccessDate: localDirectory.lastAccessDate,
|
|
@@ -369,7 +373,7 @@ class ZipEntry {
|
|
|
369
373
|
const encrypted = zipEntry.encrypted && localDirectory.encrypted;
|
|
370
374
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
371
375
|
if (encrypted) {
|
|
372
|
-
if (!zipCrypto && extraFieldAES.strength ===
|
|
376
|
+
if (!zipCrypto && extraFieldAES.strength === UNDEFINED_VALUE) {
|
|
373
377
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
|
|
374
378
|
} else if (!password) {
|
|
375
379
|
throw new Error(ERR_ENCRYPTED);
|
|
@@ -386,7 +390,7 @@ class ZipEntry {
|
|
|
386
390
|
};
|
|
387
391
|
}
|
|
388
392
|
const { writable } = writer;
|
|
389
|
-
if (writable.size ===
|
|
393
|
+
if (writable.size === UNDEFINED_VALUE) {
|
|
390
394
|
writable.size = 0;
|
|
391
395
|
}
|
|
392
396
|
const signal = getOptionValue(zipEntry, options, "signal");
|
|
@@ -634,7 +638,7 @@ async function seekSignature(reader, signature, startOffset, minimumBytes, maxim
|
|
|
634
638
|
}
|
|
635
639
|
|
|
636
640
|
function getOptionValue(zipReader, options, name) {
|
|
637
|
-
return options[name] ===
|
|
641
|
+
return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
|
|
638
642
|
}
|
|
639
643
|
|
|
640
644
|
function getDate(timeRaw) {
|
package/lib/core/zip-writer.js
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
/* global BigInt, ReadableStream, WritableStream */
|
|
30
|
+
// deno-lint-ignore-file no-this-alias
|
|
30
31
|
|
|
31
32
|
import {
|
|
32
33
|
MAX_32_BITS,
|
|
@@ -34,19 +35,21 @@ import {
|
|
|
34
35
|
COMPRESSION_METHOD_DEFLATE,
|
|
35
36
|
COMPRESSION_METHOD_STORE,
|
|
36
37
|
COMPRESSION_METHOD_AES,
|
|
38
|
+
SPLIT_ZIP_FILE_SIGNATURE,
|
|
37
39
|
LOCAL_FILE_HEADER_SIGNATURE,
|
|
38
40
|
DATA_DESCRIPTOR_RECORD_SIGNATURE,
|
|
39
41
|
CENTRAL_FILE_HEADER_SIGNATURE,
|
|
40
42
|
END_OF_CENTRAL_DIR_SIGNATURE,
|
|
41
43
|
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE,
|
|
42
44
|
ZIP64_END_OF_CENTRAL_DIR_SIGNATURE,
|
|
43
|
-
ZIP64_TOTAL_NUMBER_OF_DISKS,
|
|
44
45
|
EXTRAFIELD_TYPE_AES,
|
|
45
46
|
EXTRAFIELD_TYPE_ZIP64,
|
|
46
47
|
EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
|
|
47
48
|
EXTRAFIELD_TYPE_NTFS,
|
|
48
49
|
EXTRAFIELD_TYPE_NTFS_TAG1,
|
|
49
50
|
END_OF_CENTRAL_DIR_LENGTH,
|
|
51
|
+
ZIP64_END_OF_CENTRAL_DIR_LENGTH,
|
|
52
|
+
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH,
|
|
50
53
|
ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH,
|
|
51
54
|
BITFLAG_ENCRYPTED,
|
|
52
55
|
BITFLAG_DATA_DESCRIPTOR,
|
|
@@ -57,7 +60,9 @@ import {
|
|
|
57
60
|
VERSION_AES,
|
|
58
61
|
DIRECTORY_SIGNATURE,
|
|
59
62
|
MIN_DATE,
|
|
60
|
-
MAX_DATE
|
|
63
|
+
MAX_DATE,
|
|
64
|
+
UNDEFINED_VALUE,
|
|
65
|
+
FUNCTION_TYPE
|
|
61
66
|
} from "./constants.js";
|
|
62
67
|
import {
|
|
63
68
|
getConfiguration,
|
|
@@ -69,7 +74,8 @@ import {
|
|
|
69
74
|
} from "./codec-pool.js";
|
|
70
75
|
import {
|
|
71
76
|
initStream,
|
|
72
|
-
BlobWriter
|
|
77
|
+
BlobWriter,
|
|
78
|
+
SplitZipWriter
|
|
73
79
|
} from "./io.js";
|
|
74
80
|
import { encodeText } from "./util/encode-text.js";
|
|
75
81
|
import { Entry } from "./zip-entry.js";
|
|
@@ -85,7 +91,7 @@ const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
|
85
91
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
|
|
86
92
|
|
|
87
93
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
88
|
-
const EXTRAFIELD_LENGTH_ZIP64 =
|
|
94
|
+
const EXTRAFIELD_LENGTH_ZIP64 = 28;
|
|
89
95
|
|
|
90
96
|
let workers = 0;
|
|
91
97
|
const pendingEntries = [];
|
|
@@ -93,14 +99,26 @@ const pendingEntries = [];
|
|
|
93
99
|
class ZipWriter {
|
|
94
100
|
|
|
95
101
|
constructor(writer, options = {}) {
|
|
102
|
+
if (writer.writable === UNDEFINED_VALUE && typeof writer.next == FUNCTION_TYPE) {
|
|
103
|
+
writer = new SplitZipWriter(writer);
|
|
104
|
+
}
|
|
96
105
|
if (writer instanceof WritableStream) {
|
|
97
106
|
writer = { writable: writer };
|
|
98
107
|
}
|
|
99
|
-
if (writer.writable.size ===
|
|
108
|
+
if (writer.writable.size === UNDEFINED_VALUE) {
|
|
100
109
|
writer.writable.size = 0;
|
|
101
110
|
}
|
|
111
|
+
const splitZipFile = writer instanceof SplitZipWriter;
|
|
112
|
+
if (!splitZipFile) {
|
|
113
|
+
Object.assign(writer, {
|
|
114
|
+
diskNumber: 0,
|
|
115
|
+
diskOffset: 0,
|
|
116
|
+
availableSize: Infinity
|
|
117
|
+
});
|
|
118
|
+
}
|
|
102
119
|
Object.assign(this, {
|
|
103
120
|
writer,
|
|
121
|
+
addSplitZipSignature: splitZipFile,
|
|
104
122
|
options,
|
|
105
123
|
config: getConfiguration(),
|
|
106
124
|
files: new Map(),
|
|
@@ -203,7 +221,7 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
203
221
|
const password = getOptionValue(zipWriter, options, "password");
|
|
204
222
|
const encryptionStrength = getOptionValue(zipWriter, options, "encryptionStrength") || 3;
|
|
205
223
|
const zipCrypto = getOptionValue(zipWriter, options, "zipCrypto");
|
|
206
|
-
if (password !==
|
|
224
|
+
if (password !== UNDEFINED_VALUE && encryptionStrength !== UNDEFINED_VALUE && (encryptionStrength < 1 || encryptionStrength > 3)) {
|
|
207
225
|
throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
|
|
208
226
|
}
|
|
209
227
|
let rawExtraField = new Uint8Array();
|
|
@@ -227,18 +245,18 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
227
245
|
});
|
|
228
246
|
}
|
|
229
247
|
let extendedTimestamp = getOptionValue(zipWriter, options, "extendedTimestamp");
|
|
230
|
-
if (extendedTimestamp ===
|
|
248
|
+
if (extendedTimestamp === UNDEFINED_VALUE) {
|
|
231
249
|
extendedTimestamp = true;
|
|
232
250
|
}
|
|
233
251
|
let maximumCompressedSize = 0;
|
|
234
252
|
let maximumEntrySize = 0;
|
|
235
253
|
let keepOrder = getOptionValue(zipWriter, options, "keepOrder");
|
|
236
|
-
if (keepOrder ===
|
|
254
|
+
if (keepOrder === UNDEFINED_VALUE) {
|
|
237
255
|
keepOrder = true;
|
|
238
256
|
}
|
|
239
257
|
let uncompressedSize = 0;
|
|
240
258
|
let msDosCompatible = getOptionValue(zipWriter, options, "msDosCompatible");
|
|
241
|
-
if (msDosCompatible ===
|
|
259
|
+
if (msDosCompatible === UNDEFINED_VALUE) {
|
|
242
260
|
msDosCompatible = true;
|
|
243
261
|
}
|
|
244
262
|
const internalFileAttribute = getOptionValue(zipWriter, options, "internalFileAttribute") || 0;
|
|
@@ -251,15 +269,16 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
251
269
|
};
|
|
252
270
|
}
|
|
253
271
|
await initStream(reader);
|
|
254
|
-
if (reader.size ===
|
|
272
|
+
if (reader.size === UNDEFINED_VALUE) {
|
|
255
273
|
options.dataDescriptor = true;
|
|
256
|
-
if (zip64 ===
|
|
274
|
+
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
257
275
|
zip64 = true;
|
|
276
|
+
maximumCompressedSize = MAX_32_BITS;
|
|
258
277
|
}
|
|
259
278
|
} else {
|
|
260
279
|
uncompressedSize = reader.size;
|
|
280
|
+
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
|
|
261
281
|
}
|
|
262
|
-
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
|
|
263
282
|
}
|
|
264
283
|
if (zipWriter.offset + zipWriter.pendingEntriesSize >= MAX_32_BITS ||
|
|
265
284
|
uncompressedSize >= MAX_32_BITS ||
|
|
@@ -278,10 +297,10 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
278
297
|
let dataDescriptorSignature = getOptionValue(zipWriter, options, "dataDescriptorSignature");
|
|
279
298
|
const signal = getOptionValue(zipWriter, options, "signal");
|
|
280
299
|
const useCompressionStream = getOptionValue(zipWriter, options, "useCompressionStream");
|
|
281
|
-
if (dataDescriptor ===
|
|
300
|
+
if (dataDescriptor === UNDEFINED_VALUE) {
|
|
282
301
|
dataDescriptor = true;
|
|
283
302
|
}
|
|
284
|
-
if (dataDescriptor && dataDescriptorSignature ===
|
|
303
|
+
if (dataDescriptor && dataDescriptorSignature === UNDEFINED_VALUE) {
|
|
285
304
|
dataDescriptorSignature = false;
|
|
286
305
|
}
|
|
287
306
|
options = Object.assign({}, options, {
|
|
@@ -364,10 +383,21 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
364
383
|
releaseLockWriter = () => delete zipWriter.lockWriter;
|
|
365
384
|
}
|
|
366
385
|
await initStream(fileWriter);
|
|
386
|
+
const { writable, diskNumber } = writer;
|
|
387
|
+
let { diskOffset } = writer;
|
|
388
|
+
if (zipWriter.addSplitZipSignature) {
|
|
389
|
+
delete zipWriter.addSplitZipSignature;
|
|
390
|
+
const signatureArray = new Uint8Array(4);
|
|
391
|
+
const signatureArrayView = new DataView(signatureArray.buffer);
|
|
392
|
+
setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
393
|
+
await writeData(writable, signatureArray);
|
|
394
|
+
zipWriter.offset += 4;
|
|
395
|
+
}
|
|
367
396
|
if (!bufferedWrite) {
|
|
368
397
|
await lockPreviousFileEntry;
|
|
369
398
|
}
|
|
370
399
|
writingEntryData = true;
|
|
400
|
+
fileEntry.diskNumberStart = diskNumber;
|
|
371
401
|
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, zipWriter.config, options);
|
|
372
402
|
writingEntryData = false;
|
|
373
403
|
files.set(name, fileEntry);
|
|
@@ -378,7 +408,6 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
378
408
|
await lockPreviousFileEntry;
|
|
379
409
|
await requestLockWriter();
|
|
380
410
|
writingBufferedEntryData = true;
|
|
381
|
-
const { writable } = writer;
|
|
382
411
|
if (!dataDescriptor) {
|
|
383
412
|
const arrayBuffer = await sliceAsArrayBuffer(blob, 0, 26);
|
|
384
413
|
const arrayBufferView = new DataView(arrayBuffer);
|
|
@@ -395,13 +424,18 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
395
424
|
await writeData(writable, new Uint8Array(arrayBuffer));
|
|
396
425
|
blob = blob.slice(arrayBuffer.byteLength);
|
|
397
426
|
}
|
|
427
|
+
fileEntry.diskNumberStart = writer.diskNumber;
|
|
428
|
+
diskOffset = writer.diskOffset;
|
|
398
429
|
await blob.stream().pipeTo(writable, { preventClose: true, signal });
|
|
430
|
+
writable.size += blob.size;
|
|
399
431
|
writingBufferedEntryData = false;
|
|
400
432
|
}
|
|
401
|
-
fileEntry.offset = zipWriter.offset;
|
|
433
|
+
fileEntry.offset = zipWriter.offset - diskOffset;
|
|
402
434
|
if (fileEntry.zip64) {
|
|
403
|
-
const
|
|
404
|
-
|
|
435
|
+
const { rawExtraFieldZip64, offset, diskNumberStart } = fileEntry;
|
|
436
|
+
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
437
|
+
setBigUint64(rawExtraFieldZip64View, 20, BigInt(offset));
|
|
438
|
+
setUint32(rawExtraFieldZip64View, 28, diskNumberStart);
|
|
405
439
|
} else if (fileEntry.offset >= MAX_32_BITS) {
|
|
406
440
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
407
441
|
}
|
|
@@ -445,7 +479,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
445
479
|
}
|
|
446
480
|
}
|
|
447
481
|
|
|
448
|
-
async function createFileEntry(reader, writer,
|
|
482
|
+
async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryInfo, config, options) {
|
|
449
483
|
const {
|
|
450
484
|
headerInfo,
|
|
451
485
|
dataDescriptorInfo
|
|
@@ -490,7 +524,7 @@ async function createFileEntry(reader, writer, pendingFileEntry, entryInfo, conf
|
|
|
490
524
|
useCompressionStream
|
|
491
525
|
} = options;
|
|
492
526
|
const fileEntry = {
|
|
493
|
-
lock
|
|
527
|
+
lock,
|
|
494
528
|
versionMadeBy,
|
|
495
529
|
zip64,
|
|
496
530
|
directory: Boolean(directory),
|
|
@@ -505,7 +539,8 @@ async function createFileEntry(reader, writer, pendingFileEntry, entryInfo, conf
|
|
|
505
539
|
extendedTimestamp,
|
|
506
540
|
msDosCompatible,
|
|
507
541
|
internalFileAttribute,
|
|
508
|
-
externalFileAttribute
|
|
542
|
+
externalFileAttribute,
|
|
543
|
+
diskNumberStart
|
|
509
544
|
};
|
|
510
545
|
let uncompressedSize = 0;
|
|
511
546
|
let signature;
|
|
@@ -748,7 +783,7 @@ function setEntryInfo(entryInfo, options) {
|
|
|
748
783
|
zipCrypto,
|
|
749
784
|
dataDescriptor
|
|
750
785
|
} = options;
|
|
751
|
-
if ((!encrypted || zipCrypto) && signature !==
|
|
786
|
+
if ((!encrypted || zipCrypto) && signature !== UNDEFINED_VALUE) {
|
|
752
787
|
setUint32(headerView, 10, signature);
|
|
753
788
|
if (dataDescriptor) {
|
|
754
789
|
setUint32(dataDescriptorView, dataDescriptorOffset, signature);
|
|
@@ -777,10 +812,12 @@ function setEntryInfo(entryInfo, options) {
|
|
|
777
812
|
}
|
|
778
813
|
|
|
779
814
|
async function closeFile(zipWriter, comment, options) {
|
|
780
|
-
const { files } = zipWriter;
|
|
815
|
+
const { files, writer } = zipWriter;
|
|
781
816
|
let offset = 0;
|
|
782
817
|
let directoryDataLength = 0;
|
|
783
|
-
|
|
818
|
+
const { diskOffset, writable } = writer;
|
|
819
|
+
let { diskNumber } = writer;
|
|
820
|
+
let directoryOffset = zipWriter.offset - diskOffset;
|
|
784
821
|
let filesLength = files.size;
|
|
785
822
|
for (const [, {
|
|
786
823
|
rawFilename,
|
|
@@ -809,7 +846,7 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
809
846
|
zip64 = true;
|
|
810
847
|
}
|
|
811
848
|
}
|
|
812
|
-
const directoryArray = new Uint8Array(directoryDataLength
|
|
849
|
+
const directoryArray = new Uint8Array(directoryDataLength);
|
|
813
850
|
const directoryView = getDataView(directoryArray);
|
|
814
851
|
for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
|
|
815
852
|
const {
|
|
@@ -828,7 +865,8 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
828
865
|
internalFileAttribute,
|
|
829
866
|
externalFileAttribute,
|
|
830
867
|
extendedTimestamp,
|
|
831
|
-
lastModDate
|
|
868
|
+
lastModDate,
|
|
869
|
+
diskNumberStart
|
|
832
870
|
} = fileEntry;
|
|
833
871
|
let rawExtraFieldExtendedTimestamp;
|
|
834
872
|
if (extendedTimestamp) {
|
|
@@ -847,17 +885,14 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
847
885
|
arraySet(directoryArray, headerArray, offset + 6);
|
|
848
886
|
setUint16(directoryView, offset + 30, extraFieldLength);
|
|
849
887
|
setUint16(directoryView, offset + 32, getLength(rawComment));
|
|
888
|
+
setUint16(directoryView, offset + 34, zip64 ? MAX_16_BITS : diskNumberStart);
|
|
850
889
|
setUint16(directoryView, offset + 36, internalFileAttribute);
|
|
851
890
|
if (externalFileAttribute) {
|
|
852
891
|
setUint32(directoryView, offset + 38, externalFileAttribute);
|
|
853
892
|
} else if (directory && msDosCompatible) {
|
|
854
893
|
setUint8(directoryView, offset + 38, FILE_ATTR_MSDOS_DIR_MASK);
|
|
855
894
|
}
|
|
856
|
-
|
|
857
|
-
setUint32(directoryView, offset + 42, MAX_32_BITS);
|
|
858
|
-
} else {
|
|
859
|
-
setUint32(directoryView, offset + 42, fileEntryOffset);
|
|
860
|
-
}
|
|
895
|
+
setUint32(directoryView, offset + 42, zip64 ? MAX_32_BITS : fileEntryOffset);
|
|
861
896
|
arraySet(directoryArray, rawFilename, offset + 46);
|
|
862
897
|
arraySet(directoryArray, rawExtraFieldZip64, offset + 46 + getLength(rawFilename));
|
|
863
898
|
arraySet(directoryArray, rawExtraFieldAES, offset + 46 + getLength(rawFilename, rawExtraFieldZip64));
|
|
@@ -874,39 +909,52 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
874
909
|
}
|
|
875
910
|
}
|
|
876
911
|
}
|
|
912
|
+
await initStream(writer);
|
|
913
|
+
await writeData(writable, directoryArray);
|
|
914
|
+
const endOfdirectoryArray = new Uint8Array(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
915
|
+
const endOfdirectoryView = getDataView(endOfdirectoryArray);
|
|
916
|
+
let lastDiskNumber = writer.diskNumber;
|
|
917
|
+
const { availableSize } = writer;
|
|
918
|
+
if (availableSize < endOfdirectoryArray.length) {
|
|
919
|
+
lastDiskNumber++;
|
|
920
|
+
}
|
|
921
|
+
offset = 0;
|
|
877
922
|
if (zip64) {
|
|
878
|
-
setUint32(
|
|
879
|
-
setBigUint64(
|
|
880
|
-
setUint16(
|
|
881
|
-
setUint16(
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
setBigUint64(
|
|
885
|
-
setBigUint64(
|
|
886
|
-
|
|
887
|
-
setBigUint64(
|
|
888
|
-
setUint32(
|
|
923
|
+
setUint32(endOfdirectoryView, 0, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
924
|
+
setBigUint64(endOfdirectoryView, 4, BigInt(44));
|
|
925
|
+
setUint16(endOfdirectoryView, 12, 45);
|
|
926
|
+
setUint16(endOfdirectoryView, 14, 45);
|
|
927
|
+
setUint32(endOfdirectoryView, 16, lastDiskNumber);
|
|
928
|
+
setUint32(endOfdirectoryView, 20, diskNumber);
|
|
929
|
+
setBigUint64(endOfdirectoryView, 24, BigInt(filesLength));
|
|
930
|
+
setBigUint64(endOfdirectoryView, 32, BigInt(filesLength));
|
|
931
|
+
setBigUint64(endOfdirectoryView, 40, BigInt(directoryDataLength));
|
|
932
|
+
setBigUint64(endOfdirectoryView, 48, BigInt(directoryOffset));
|
|
933
|
+
setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
934
|
+
setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength));
|
|
935
|
+
setUint32(endOfdirectoryView, 72, lastDiskNumber + 1);
|
|
936
|
+
diskNumber = MAX_16_BITS;
|
|
889
937
|
filesLength = MAX_16_BITS;
|
|
890
938
|
directoryOffset = MAX_32_BITS;
|
|
891
939
|
directoryDataLength = MAX_32_BITS;
|
|
892
|
-
offset +=
|
|
893
|
-
}
|
|
894
|
-
setUint32(
|
|
895
|
-
setUint16(
|
|
896
|
-
setUint16(
|
|
897
|
-
|
|
898
|
-
|
|
940
|
+
offset += ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
941
|
+
}
|
|
942
|
+
setUint32(endOfdirectoryView, offset, END_OF_CENTRAL_DIR_SIGNATURE);
|
|
943
|
+
setUint16(endOfdirectoryView, offset + 4, lastDiskNumber);
|
|
944
|
+
setUint16(endOfdirectoryView, offset + 6, diskNumber);
|
|
945
|
+
setUint16(endOfdirectoryView, offset + 8, filesLength);
|
|
946
|
+
setUint16(endOfdirectoryView, offset + 10, filesLength);
|
|
947
|
+
setUint32(endOfdirectoryView, offset + 12, directoryDataLength);
|
|
948
|
+
setUint32(endOfdirectoryView, offset + 16, directoryOffset);
|
|
899
949
|
const commentLength = getLength(comment);
|
|
900
950
|
if (commentLength) {
|
|
901
951
|
if (commentLength <= MAX_16_BITS) {
|
|
902
|
-
setUint16(
|
|
952
|
+
setUint16(endOfdirectoryView, offset + 20, commentLength);
|
|
903
953
|
} else {
|
|
904
954
|
throw new Error(ERR_INVALID_COMMENT);
|
|
905
955
|
}
|
|
906
956
|
}
|
|
907
|
-
|
|
908
|
-
await initStream(zipWriter.writer);
|
|
909
|
-
await writeData(writable, directoryArray);
|
|
957
|
+
await writeData(writable, endOfdirectoryArray);
|
|
910
958
|
if (commentLength) {
|
|
911
959
|
await writeData(writable, comment);
|
|
912
960
|
}
|
|
@@ -935,7 +983,7 @@ function getTimeNTFS(date) {
|
|
|
935
983
|
}
|
|
936
984
|
|
|
937
985
|
function getOptionValue(zipWriter, options, name) {
|
|
938
|
-
return options[name] ===
|
|
986
|
+
return options[name] === UNDEFINED_VALUE ? zipWriter.options[name] : options[name];
|
|
939
987
|
}
|
|
940
988
|
|
|
941
989
|
function getMaximumCompressedSize(uncompressedSize) {
|