@zip.js/zip.js 2.7.63 → 2.7.65
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/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 +577 -282
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +579 -284
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +570 -278
- 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 +570 -278
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +2 -1
- package/index.cjs +577 -282
- package/index.d.ts +133 -80
- package/index.js +1 -0
- package/index.min.js +1 -1
- package/lib/core/codec-worker.js +11 -6
- package/lib/core/constants.js +22 -7
- package/lib/core/io.js +71 -51
- package/lib/core/streams/codec-stream.js +2 -3
- package/lib/core/z-worker-core.js +4 -2
- package/lib/core/zip-fs-core.js +9 -6
- package/lib/core/zip-reader.js +28 -14
- package/lib/core/zip-writer.js +463 -203
- package/lib/z-worker-inline.js +1 -1
- package/package.json +3 -3
package/lib/core/zip-writer.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global TransformStream, Response */
|
|
29
|
+
/* global TransformStream, Response, ReadableStream */
|
|
30
30
|
// deno-lint-ignore-file no-this-alias
|
|
31
31
|
|
|
32
32
|
import {
|
|
@@ -55,6 +55,9 @@ import {
|
|
|
55
55
|
BITFLAG_ENCRYPTED,
|
|
56
56
|
BITFLAG_DATA_DESCRIPTOR,
|
|
57
57
|
BITFLAG_LANG_ENCODING_FLAG,
|
|
58
|
+
BITFLAG_LEVEL_FAST_MASK,
|
|
59
|
+
BITFLAG_LEVEL_SUPER_FAST_MASK,
|
|
60
|
+
BITFLAG_LEVEL_MAX_MASK,
|
|
58
61
|
FILE_ATTR_MSDOS_DIR_MASK,
|
|
59
62
|
FILE_ATTR_UNIX_TYPE_DIR,
|
|
60
63
|
FILE_ATTR_UNIX_EXECUTABLE_MASK,
|
|
@@ -63,6 +66,10 @@ import {
|
|
|
63
66
|
VERSION_ZIP64,
|
|
64
67
|
VERSION_AES,
|
|
65
68
|
DIRECTORY_SIGNATURE,
|
|
69
|
+
HEADER_SIZE,
|
|
70
|
+
HEADER_OFFSET_SIGNATURE,
|
|
71
|
+
HEADER_OFFSET_COMPRESSED_SIZE,
|
|
72
|
+
HEADER_OFFSET_UNCOMPRESSED_SIZE,
|
|
66
73
|
MIN_DATE,
|
|
67
74
|
MAX_DATE,
|
|
68
75
|
UNDEFINED_VALUE
|
|
@@ -77,8 +84,8 @@ import {
|
|
|
77
84
|
} from "./codec-pool.js";
|
|
78
85
|
import {
|
|
79
86
|
initStream,
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
GenericWriter,
|
|
88
|
+
GenericReader
|
|
82
89
|
} from "./io.js";
|
|
83
90
|
import { encodeText } from "./util/encode-text.js";
|
|
84
91
|
import {
|
|
@@ -99,6 +106,9 @@ import {
|
|
|
99
106
|
PROPERTY_NAME_EXECUTABLE,
|
|
100
107
|
Entry
|
|
101
108
|
} from "./zip-entry.js";
|
|
109
|
+
import {
|
|
110
|
+
ZipReader
|
|
111
|
+
} from "./zip-reader.js";
|
|
102
112
|
|
|
103
113
|
const ERR_DUPLICATED_NAME = "File already exists";
|
|
104
114
|
const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
|
|
@@ -110,6 +120,7 @@ const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
|
|
|
110
120
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
111
121
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
|
|
112
122
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
123
|
+
const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
|
|
113
124
|
|
|
114
125
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
115
126
|
|
|
@@ -119,7 +130,7 @@ const pendingEntries = [];
|
|
|
119
130
|
class ZipWriter {
|
|
120
131
|
|
|
121
132
|
constructor(writer, options = {}) {
|
|
122
|
-
writer =
|
|
133
|
+
writer = new GenericWriter(writer);
|
|
123
134
|
const addSplitZipSignature =
|
|
124
135
|
writer.availableSize !== UNDEFINED_VALUE && writer.availableSize > 0 && writer.availableSize !== Infinity &&
|
|
125
136
|
writer.maxSize !== UNDEFINED_VALUE && writer.maxSize > 0 && writer.maxSize !== Infinity;
|
|
@@ -130,13 +141,106 @@ class ZipWriter {
|
|
|
130
141
|
config: getConfiguration(),
|
|
131
142
|
files: new Map(),
|
|
132
143
|
filenames: new Set(),
|
|
133
|
-
offset: options.offset === UNDEFINED_VALUE ? writer.writable.size : options.offset,
|
|
144
|
+
offset: options.offset === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options.offset,
|
|
134
145
|
pendingEntriesSize: 0,
|
|
135
146
|
pendingAddFileCalls: new Set(),
|
|
136
147
|
bufferedWrites: 0
|
|
137
148
|
});
|
|
138
149
|
}
|
|
139
150
|
|
|
151
|
+
async prependZip(reader) {
|
|
152
|
+
if (this.filenames.size) {
|
|
153
|
+
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
154
|
+
}
|
|
155
|
+
({ reader } = new GenericReader(reader));
|
|
156
|
+
const [zipEntriesReader, zipDataReader] = reader.readable.tee();
|
|
157
|
+
const zipReader = new ZipReader(new ReadableStream({
|
|
158
|
+
async start(controller) {
|
|
159
|
+
const reader = zipEntriesReader.getReader();
|
|
160
|
+
await readChunk();
|
|
161
|
+
|
|
162
|
+
async function readChunk() {
|
|
163
|
+
const { done, value } = await reader.read();
|
|
164
|
+
if (done) {
|
|
165
|
+
controller.close();
|
|
166
|
+
} else {
|
|
167
|
+
controller.enqueue(value);
|
|
168
|
+
await readChunk();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}));
|
|
173
|
+
const entries = await zipReader.getEntries();
|
|
174
|
+
await zipReader.close();
|
|
175
|
+
await zipDataReader.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
|
|
176
|
+
this.writer.size = this.offset = reader.size;
|
|
177
|
+
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
178
|
+
this.files = new Map(entries.map(entry => {
|
|
179
|
+
const {
|
|
180
|
+
version,
|
|
181
|
+
compressionMethod,
|
|
182
|
+
lastModDate,
|
|
183
|
+
lastAccessDate,
|
|
184
|
+
creationDate,
|
|
185
|
+
rawFilename,
|
|
186
|
+
bitFlag,
|
|
187
|
+
encrypted,
|
|
188
|
+
uncompressedSize,
|
|
189
|
+
compressedSize,
|
|
190
|
+
diskOffset,
|
|
191
|
+
diskNumber,
|
|
192
|
+
zip64
|
|
193
|
+
} = entry;
|
|
194
|
+
let {
|
|
195
|
+
rawExtraFieldZip64,
|
|
196
|
+
rawExtraFieldAES,
|
|
197
|
+
rawExtraFieldExtendedTimestamp,
|
|
198
|
+
rawExtraFieldNTFS,
|
|
199
|
+
rawExtraField,
|
|
200
|
+
} = entry;
|
|
201
|
+
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
202
|
+
rawExtraFieldZip64 = rawExtraFieldZip64 || new Uint8Array();
|
|
203
|
+
rawExtraFieldAES = rawExtraFieldAES || new Uint8Array();
|
|
204
|
+
rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || new Uint8Array();
|
|
205
|
+
rawExtraFieldNTFS = rawExtraFieldNTFS || new Uint8Array();
|
|
206
|
+
rawExtraField = rawExtraField || new Uint8Array();
|
|
207
|
+
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
|
|
208
|
+
const zip64UncompressedSize = zip64 && uncompressedSize > MAX_32_BITS;
|
|
209
|
+
const zip64CompressedSize = zip64 && compressedSize > MAX_32_BITS;
|
|
210
|
+
const {
|
|
211
|
+
headerArray,
|
|
212
|
+
headerView
|
|
213
|
+
} = getHeaderArrayData({
|
|
214
|
+
version,
|
|
215
|
+
bitflag: getBitflag(level, languageEncodingFlag, dataDescriptor, encrypted),
|
|
216
|
+
compressionMethod,
|
|
217
|
+
uncompressedSize,
|
|
218
|
+
compressedSize,
|
|
219
|
+
lastModDate,
|
|
220
|
+
rawFilename,
|
|
221
|
+
zip64CompressedSize,
|
|
222
|
+
zip64UncompressedSize,
|
|
223
|
+
extraFieldLength
|
|
224
|
+
});
|
|
225
|
+
Object.assign(entry, {
|
|
226
|
+
zip64UncompressedSize,
|
|
227
|
+
zip64CompressedSize,
|
|
228
|
+
zip64Offset: zip64 && this.offset - diskOffset > MAX_32_BITS,
|
|
229
|
+
zip64DiskNumberStart: zip64 && diskNumber > MAX_16_BITS,
|
|
230
|
+
rawExtraFieldZip64,
|
|
231
|
+
rawExtraFieldAES,
|
|
232
|
+
rawExtraFieldExtendedTimestamp,
|
|
233
|
+
rawExtraFieldNTFS,
|
|
234
|
+
rawExtraField,
|
|
235
|
+
extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
|
|
236
|
+
extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
|
|
237
|
+
headerArray,
|
|
238
|
+
headerView
|
|
239
|
+
});
|
|
240
|
+
return [entry.filename, entry];
|
|
241
|
+
}));
|
|
242
|
+
}
|
|
243
|
+
|
|
140
244
|
async add(name = "", reader, options = {}) {
|
|
141
245
|
const zipWriter = this;
|
|
142
246
|
const {
|
|
@@ -172,6 +276,22 @@ class ZipWriter {
|
|
|
172
276
|
}
|
|
173
277
|
}
|
|
174
278
|
|
|
279
|
+
remove(entry) {
|
|
280
|
+
const { filenames, files } = this;
|
|
281
|
+
if (typeof entry == "string") {
|
|
282
|
+
entry = files.get(entry);
|
|
283
|
+
}
|
|
284
|
+
if (entry && entry.filename !== UNDEFINED_VALUE) {
|
|
285
|
+
const { filename } = entry;
|
|
286
|
+
if (filenames.has(filename) && files.has(filename)) {
|
|
287
|
+
filenames.delete(filename);
|
|
288
|
+
files.delete(filename);
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
|
|
175
295
|
async close(comment = new Uint8Array(), options = {}) {
|
|
176
296
|
const zipWriter = this;
|
|
177
297
|
const { pendingAddFileCalls, writer } = this;
|
|
@@ -227,7 +347,8 @@ export {
|
|
|
227
347
|
ERR_INVALID_EXTRAFIELD_DATA,
|
|
228
348
|
ERR_INVALID_ENCRYPTION_STRENGTH,
|
|
229
349
|
ERR_UNSUPPORTED_FORMAT,
|
|
230
|
-
ERR_UNDEFINED_UNCOMPRESSED_SIZE
|
|
350
|
+
ERR_UNDEFINED_UNCOMPRESSED_SIZE,
|
|
351
|
+
ERR_ZIP_NOT_EMPTY
|
|
231
352
|
};
|
|
232
353
|
|
|
233
354
|
async function addFile(zipWriter, name, reader, options) {
|
|
@@ -308,7 +429,13 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
308
429
|
const useUnicodeFileNames = getOptionValue(zipWriter, options, "useUnicodeFileNames", true);
|
|
309
430
|
const useCompressionStream = getOptionValue(zipWriter, options, "useCompressionStream");
|
|
310
431
|
const compressionMethod = getOptionValue(zipWriter, options, "compressionMethod");
|
|
311
|
-
let dataDescriptor = getOptionValue(zipWriter, options, "dataDescriptor"
|
|
432
|
+
let dataDescriptor = getOptionValue(zipWriter, options, "dataDescriptor");
|
|
433
|
+
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
434
|
+
dataDescriptor = false;
|
|
435
|
+
}
|
|
436
|
+
if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
|
|
437
|
+
dataDescriptor = true;
|
|
438
|
+
}
|
|
312
439
|
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
313
440
|
if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(encryptionStrength >= 1 && encryptionStrength <= 3)) {
|
|
314
441
|
throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
|
|
@@ -344,7 +471,7 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
344
471
|
}
|
|
345
472
|
const zip64Enabled = zip64 === true;
|
|
346
473
|
if (reader) {
|
|
347
|
-
reader =
|
|
474
|
+
reader = new GenericReader(reader);
|
|
348
475
|
await initStream(reader);
|
|
349
476
|
if (!passThrough) {
|
|
350
477
|
if (reader.size === UNDEFINED_VALUE) {
|
|
@@ -354,10 +481,11 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
354
481
|
uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
|
|
355
482
|
}
|
|
356
483
|
} else {
|
|
357
|
-
uncompressedSize = reader.size;
|
|
484
|
+
options.uncompressedSize = uncompressedSize = reader.size;
|
|
358
485
|
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
|
|
359
486
|
}
|
|
360
487
|
} else {
|
|
488
|
+
options.uncompressedSize = uncompressedSize;
|
|
361
489
|
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
|
|
362
490
|
}
|
|
363
491
|
}
|
|
@@ -413,7 +541,10 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
413
541
|
passThrough,
|
|
414
542
|
encrypted: Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted),
|
|
415
543
|
signature,
|
|
416
|
-
compressionMethod
|
|
544
|
+
compressionMethod,
|
|
545
|
+
uncompressedSize,
|
|
546
|
+
offset: zipWriter.offset - diskOffset,
|
|
547
|
+
diskNumberStart: diskNumber,
|
|
417
548
|
});
|
|
418
549
|
const headerInfo = getHeaderInfo(options);
|
|
419
550
|
const dataDescriptorInfo = getDataDescriptorInfo(options);
|
|
@@ -465,8 +596,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
465
596
|
}
|
|
466
597
|
if ((options.bufferedWrite || zipWriter.writerLocked || (zipWriter.bufferedWrites && keepOrder) || !dataDescriptor) && !usdz) {
|
|
467
598
|
fileWriter = new TransformStream();
|
|
468
|
-
|
|
469
|
-
fileWriter.writable.size = 0;
|
|
599
|
+
fileWriter.size = 0;
|
|
470
600
|
bufferedWrite = true;
|
|
471
601
|
zipWriter.bufferedWrites++;
|
|
472
602
|
await initStream(writer);
|
|
@@ -475,19 +605,22 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
475
605
|
await requestLockWriter();
|
|
476
606
|
}
|
|
477
607
|
await initStream(fileWriter);
|
|
478
|
-
const { writable } = writer;
|
|
479
|
-
let { diskOffset } = writer;
|
|
608
|
+
const { writable, diskOffset } = writer;
|
|
480
609
|
if (zipWriter.addSplitZipSignature) {
|
|
481
610
|
delete zipWriter.addSplitZipSignature;
|
|
482
611
|
const signatureArray = new Uint8Array(4);
|
|
483
612
|
const signatureArrayView = getDataView(signatureArray);
|
|
484
613
|
setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
485
|
-
await writeData(
|
|
614
|
+
await writeData(writer, signatureArray);
|
|
486
615
|
zipWriter.offset += 4;
|
|
487
616
|
}
|
|
488
617
|
if (usdz) {
|
|
489
618
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
490
619
|
}
|
|
620
|
+
const {
|
|
621
|
+
localHeaderView,
|
|
622
|
+
localHeaderArray
|
|
623
|
+
} = headerInfo;
|
|
491
624
|
if (!bufferedWrite) {
|
|
492
625
|
await lockPreviousFileEntry;
|
|
493
626
|
await skipDiskIfNeeded(writable);
|
|
@@ -495,30 +628,38 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
495
628
|
const { diskNumber } = writer;
|
|
496
629
|
writingEntryData = true;
|
|
497
630
|
fileEntry.diskNumberStart = diskNumber;
|
|
631
|
+
if (bufferedWrite) {
|
|
632
|
+
blobPromise = new Response(fileWriter.readable).blob();
|
|
633
|
+
} else {
|
|
634
|
+
await writeData(fileWriter, localHeaderArray);
|
|
635
|
+
}
|
|
498
636
|
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, zipWriter.config, options);
|
|
637
|
+
const { zip64 } = fileEntry;
|
|
499
638
|
writingEntryData = false;
|
|
500
639
|
files.set(name, fileEntry);
|
|
501
640
|
fileEntry.filename = name;
|
|
502
641
|
if (bufferedWrite) {
|
|
503
|
-
await fileWriter.writable.getWriter().close();
|
|
504
|
-
let blob = await blobPromise;
|
|
505
|
-
await lockPreviousFileEntry;
|
|
642
|
+
const [blob] = await Promise.all([blobPromise, fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
506
643
|
await requestLockWriter();
|
|
507
644
|
writingBufferedEntryData = true;
|
|
508
|
-
|
|
509
|
-
|
|
645
|
+
fileEntry.diskNumberStart = writer.diskNumber;
|
|
646
|
+
fileEntry.offset = zipWriter.offset - writer.diskOffset;
|
|
647
|
+
if (zip64) {
|
|
648
|
+
updateZip64ExtraField(fileEntry);
|
|
510
649
|
}
|
|
650
|
+
updateLocalHeader(fileEntry, localHeaderView);
|
|
511
651
|
await skipDiskIfNeeded(writable);
|
|
512
|
-
|
|
513
|
-
diskOffset = writer.diskOffset;
|
|
652
|
+
await writeData(writer, localHeaderArray);
|
|
514
653
|
await blob.stream().pipeTo(writable, { preventClose: true, preventAbort: true, signal });
|
|
515
|
-
|
|
654
|
+
writer.size += fileWriter.size;
|
|
516
655
|
writingBufferedEntryData = false;
|
|
656
|
+
} else {
|
|
657
|
+
fileEntry.offset = zipWriter.offset - diskOffset;
|
|
658
|
+
if (zip64) {
|
|
659
|
+
updateZip64ExtraField(fileEntry);
|
|
660
|
+
}
|
|
517
661
|
}
|
|
518
|
-
fileEntry.offset
|
|
519
|
-
if (fileEntry.zip64) {
|
|
520
|
-
setZip64ExtraInfo(fileEntry, options);
|
|
521
|
-
} else if (fileEntry.offset > MAX_32_BITS) {
|
|
662
|
+
if (fileEntry.offset > MAX_32_BITS && !zip64) {
|
|
522
663
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
523
664
|
}
|
|
524
665
|
zipWriter.offset += fileEntry.size;
|
|
@@ -535,9 +676,9 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
535
676
|
}
|
|
536
677
|
}
|
|
537
678
|
if (bufferedWrite) {
|
|
538
|
-
zipWriter.offset += fileWriter.
|
|
679
|
+
zipWriter.offset += fileWriter.size;
|
|
539
680
|
} else {
|
|
540
|
-
zipWriter.offset = fileWriter.
|
|
681
|
+
zipWriter.offset = fileWriter.size;
|
|
541
682
|
}
|
|
542
683
|
}
|
|
543
684
|
files.delete(name);
|
|
@@ -583,14 +724,16 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
583
724
|
metadataSize
|
|
584
725
|
} = entryInfo;
|
|
585
726
|
const {
|
|
586
|
-
localHeaderArray,
|
|
587
727
|
headerArray,
|
|
728
|
+
headerView,
|
|
588
729
|
lastModDate,
|
|
589
730
|
rawLastModDate,
|
|
590
731
|
encrypted,
|
|
591
732
|
compressed,
|
|
592
733
|
version,
|
|
593
734
|
compressionMethod,
|
|
735
|
+
rawExtraFieldZip64,
|
|
736
|
+
localExtraFieldZip64Length,
|
|
594
737
|
rawExtraFieldExtendedTimestamp,
|
|
595
738
|
extraFieldExtendedTimestampFlag,
|
|
596
739
|
rawExtraFieldNTFS,
|
|
@@ -639,6 +782,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
639
782
|
rawFilename,
|
|
640
783
|
commentUTF8: true,
|
|
641
784
|
rawComment,
|
|
785
|
+
rawExtraFieldZip64,
|
|
786
|
+
localExtraFieldZip64Length,
|
|
642
787
|
rawExtraFieldExtendedTimestamp,
|
|
643
788
|
rawExtraFieldNTFS,
|
|
644
789
|
rawExtraFieldAES,
|
|
@@ -660,9 +805,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
660
805
|
const { writable } = writer;
|
|
661
806
|
if (reader) {
|
|
662
807
|
reader.chunkSize = getChunkSize(config);
|
|
663
|
-
await writeData(writable, localHeaderArray);
|
|
664
808
|
const readable = reader.readable;
|
|
665
|
-
const size =
|
|
809
|
+
const size = reader.size;
|
|
666
810
|
const workerOptions = {
|
|
667
811
|
options: {
|
|
668
812
|
codecType: CODEC_DEFLATE,
|
|
@@ -682,45 +826,31 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
682
826
|
config,
|
|
683
827
|
streamOptions: { signal, size, onstart, onprogress, onend }
|
|
684
828
|
};
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
if (zip64UncompressedSize) {
|
|
699
|
-
rawExtraFieldZip64Length += 8;
|
|
700
|
-
}
|
|
701
|
-
if (zip64CompressedSize) {
|
|
702
|
-
rawExtraFieldZip64Length += 8;
|
|
703
|
-
}
|
|
704
|
-
if (zip64Offset) {
|
|
705
|
-
rawExtraFieldZip64Length += 8;
|
|
706
|
-
}
|
|
707
|
-
if (zip64DiskNumberStart) {
|
|
708
|
-
rawExtraFieldZip64Length += 4;
|
|
829
|
+
try {
|
|
830
|
+
const result = await runWorker({ readable, writable }, workerOptions);
|
|
831
|
+
compressedSize = result.outputSize;
|
|
832
|
+
writer.size += compressedSize;
|
|
833
|
+
if (!passThrough) {
|
|
834
|
+
uncompressedSize = result.inputSize;
|
|
835
|
+
signature = result.signature;
|
|
836
|
+
}
|
|
837
|
+
} catch (error) {
|
|
838
|
+
if (error.outputSize !== UNDEFINED_VALUE) {
|
|
839
|
+
writer.size += error.outputSize;
|
|
840
|
+
}
|
|
841
|
+
throw error;
|
|
709
842
|
}
|
|
710
|
-
|
|
711
|
-
} else {
|
|
712
|
-
rawExtraFieldZip64 = new Uint8Array();
|
|
843
|
+
|
|
713
844
|
}
|
|
714
845
|
setEntryInfo({
|
|
715
846
|
signature,
|
|
716
|
-
rawExtraFieldZip64,
|
|
717
847
|
compressedSize,
|
|
718
848
|
uncompressedSize,
|
|
719
849
|
headerInfo,
|
|
720
850
|
dataDescriptorInfo
|
|
721
851
|
}, options);
|
|
722
852
|
if (dataDescriptor) {
|
|
723
|
-
await writeData(
|
|
853
|
+
await writeData(writer, dataDescriptorArray);
|
|
724
854
|
}
|
|
725
855
|
Object.assign(fileEntry, {
|
|
726
856
|
uncompressedSize,
|
|
@@ -735,8 +865,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
735
865
|
compressionMethod,
|
|
736
866
|
version,
|
|
737
867
|
headerArray,
|
|
868
|
+
headerView,
|
|
738
869
|
signature,
|
|
739
|
-
rawExtraFieldZip64,
|
|
740
870
|
extraFieldExtendedTimestampFlag,
|
|
741
871
|
zip64UncompressedSize,
|
|
742
872
|
zip64CompressedSize,
|
|
@@ -761,10 +891,62 @@ function getHeaderInfo(options) {
|
|
|
761
891
|
rawExtraField,
|
|
762
892
|
encryptionStrength,
|
|
763
893
|
extendedTimestamp,
|
|
764
|
-
|
|
894
|
+
passThrough,
|
|
895
|
+
encrypted,
|
|
896
|
+
zip64UncompressedSize,
|
|
897
|
+
zip64CompressedSize,
|
|
898
|
+
zip64Offset,
|
|
899
|
+
zip64DiskNumberStart,
|
|
900
|
+
uncompressedSize,
|
|
901
|
+
offset,
|
|
902
|
+
diskNumberStart
|
|
765
903
|
} = options;
|
|
766
904
|
let { version, compressionMethod } = options;
|
|
767
905
|
const compressed = !directory && (level > 0 || (level === UNDEFINED_VALUE && compressionMethod !== 0));
|
|
906
|
+
let rawExtraFieldZip64;
|
|
907
|
+
const uncompressedFile = passThrough || !compressed;
|
|
908
|
+
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || ((!zip64UncompressedSize && !zip64CompressedSize) || uncompressedFile));
|
|
909
|
+
if (zip64) {
|
|
910
|
+
let rawExtraFieldZip64Length = 4;
|
|
911
|
+
if (zip64UncompressedSize) {
|
|
912
|
+
rawExtraFieldZip64Length += 8;
|
|
913
|
+
}
|
|
914
|
+
if (zip64CompressedSize) {
|
|
915
|
+
rawExtraFieldZip64Length += 8;
|
|
916
|
+
}
|
|
917
|
+
if (zip64Offset) {
|
|
918
|
+
rawExtraFieldZip64Length += 8;
|
|
919
|
+
}
|
|
920
|
+
if (zip64DiskNumberStart) {
|
|
921
|
+
rawExtraFieldZip64Length += 4;
|
|
922
|
+
}
|
|
923
|
+
rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length);
|
|
924
|
+
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
925
|
+
setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
|
|
926
|
+
setUint16(rawExtraFieldZip64View, 2, getLength(rawExtraFieldZip64) - 4);
|
|
927
|
+
if (zip64ExtraFieldComplete) {
|
|
928
|
+
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
929
|
+
let rawExtraFieldZip64Offset = 4;
|
|
930
|
+
if (zip64UncompressedSize) {
|
|
931
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
|
|
932
|
+
rawExtraFieldZip64Offset += 8;
|
|
933
|
+
}
|
|
934
|
+
if (zip64CompressedSize && uncompressedFile) {
|
|
935
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
|
|
936
|
+
rawExtraFieldZip64Offset += 8;
|
|
937
|
+
}
|
|
938
|
+
if (zip64Offset) {
|
|
939
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
|
|
940
|
+
rawExtraFieldZip64Offset += 8;
|
|
941
|
+
}
|
|
942
|
+
if (zip64DiskNumberStart) {
|
|
943
|
+
setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
|
|
944
|
+
rawExtraFieldZip64Offset += 4;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
} else {
|
|
948
|
+
rawExtraFieldZip64 = new Uint8Array();
|
|
949
|
+
}
|
|
768
950
|
let rawExtraFieldAES;
|
|
769
951
|
if (encrypted && !zipCrypto) {
|
|
770
952
|
rawExtraFieldAES = new Uint8Array(getLength(EXTRAFIELD_DATA_AES) + 2);
|
|
@@ -813,71 +995,55 @@ function getHeaderInfo(options) {
|
|
|
813
995
|
} else {
|
|
814
996
|
rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array();
|
|
815
997
|
}
|
|
816
|
-
let bitFlag = 0;
|
|
817
|
-
if (useUnicodeFileNames) {
|
|
818
|
-
bitFlag = bitFlag | BITFLAG_LANG_ENCODING_FLAG;
|
|
819
|
-
}
|
|
820
|
-
if (dataDescriptor) {
|
|
821
|
-
bitFlag = bitFlag | BITFLAG_DATA_DESCRIPTOR;
|
|
822
|
-
}
|
|
823
998
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
824
999
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
825
1000
|
}
|
|
826
|
-
if (compressionMethod == COMPRESSION_METHOD_DEFLATE) {
|
|
827
|
-
if (level >= 1 && level < 3) {
|
|
828
|
-
bitFlag = bitFlag | 0b110;
|
|
829
|
-
}
|
|
830
|
-
if (level >= 3 && level < 5) {
|
|
831
|
-
bitFlag = bitFlag | 0b01;
|
|
832
|
-
}
|
|
833
|
-
if (level === 9) {
|
|
834
|
-
bitFlag = bitFlag | 0b10;
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
1001
|
if (zip64) {
|
|
838
1002
|
version = version > VERSION_ZIP64 ? version : VERSION_ZIP64;
|
|
839
1003
|
}
|
|
840
|
-
if (encrypted) {
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
rawExtraFieldAES[9] = compressionMethod;
|
|
845
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
const headerArray = new Uint8Array(26);
|
|
849
|
-
const headerView = getDataView(headerArray);
|
|
850
|
-
setUint16(headerView, 0, version);
|
|
851
|
-
setUint16(headerView, 2, bitFlag);
|
|
852
|
-
setUint16(headerView, 4, compressionMethod);
|
|
853
|
-
const dateArray = new Uint32Array(1);
|
|
854
|
-
const dateView = getDataView(dateArray);
|
|
855
|
-
let lastModDateMsDos;
|
|
856
|
-
if (lastModDate < MIN_DATE) {
|
|
857
|
-
lastModDateMsDos = MIN_DATE;
|
|
858
|
-
} else if (lastModDate > MAX_DATE) {
|
|
859
|
-
lastModDateMsDos = MAX_DATE;
|
|
860
|
-
} else {
|
|
861
|
-
lastModDateMsDos = lastModDate;
|
|
1004
|
+
if (encrypted && !zipCrypto) {
|
|
1005
|
+
version = version > VERSION_AES ? version : VERSION_AES;
|
|
1006
|
+
rawExtraFieldAES[9] = compressionMethod;
|
|
1007
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
862
1008
|
}
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
1009
|
+
const localExtraFieldZip64Length = zip64ExtraFieldComplete ? getLength(rawExtraFieldZip64) : 0;
|
|
1010
|
+
const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
|
|
1011
|
+
const {
|
|
1012
|
+
headerArray,
|
|
1013
|
+
headerView,
|
|
1014
|
+
rawLastModDate
|
|
1015
|
+
} = getHeaderArrayData({
|
|
1016
|
+
version,
|
|
1017
|
+
bitflag: getBitflag(level, useUnicodeFileNames, dataDescriptor, encrypted),
|
|
1018
|
+
compressionMethod,
|
|
1019
|
+
uncompressedSize,
|
|
1020
|
+
lastModDate: lastModDate < MIN_DATE ? MIN_DATE : lastModDate > MAX_DATE ? MAX_DATE : lastModDate,
|
|
1021
|
+
rawFilename,
|
|
1022
|
+
zip64CompressedSize,
|
|
1023
|
+
zip64UncompressedSize,
|
|
1024
|
+
extraFieldLength
|
|
1025
|
+
});
|
|
1026
|
+
let localHeaderOffset = HEADER_SIZE + 4;
|
|
1027
|
+
const localHeaderArray = new Uint8Array(localHeaderOffset + getLength(rawFilename) + extraFieldLength);
|
|
871
1028
|
const localHeaderView = getDataView(localHeaderArray);
|
|
872
1029
|
setUint32(localHeaderView, 0, LOCAL_FILE_HEADER_SIGNATURE);
|
|
873
1030
|
arraySet(localHeaderArray, headerArray, 4);
|
|
874
|
-
arraySet(localHeaderArray, rawFilename,
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
1031
|
+
arraySet(localHeaderArray, rawFilename, localHeaderOffset);
|
|
1032
|
+
localHeaderOffset += getLength(rawFilename);
|
|
1033
|
+
if (zip64ExtraFieldComplete) {
|
|
1034
|
+
arraySet(localHeaderArray, rawExtraFieldZip64, localHeaderOffset);
|
|
1035
|
+
}
|
|
1036
|
+
localHeaderOffset += localExtraFieldZip64Length;
|
|
1037
|
+
arraySet(localHeaderArray, rawExtraFieldAES, localHeaderOffset);
|
|
1038
|
+
localHeaderOffset += getLength(rawExtraFieldAES);
|
|
1039
|
+
arraySet(localHeaderArray, rawExtraFieldExtendedTimestamp, localHeaderOffset);
|
|
1040
|
+
localHeaderOffset += getLength(rawExtraFieldExtendedTimestamp);
|
|
1041
|
+
arraySet(localHeaderArray, rawExtraFieldNTFS, localHeaderOffset);
|
|
1042
|
+
localHeaderOffset += getLength(rawExtraFieldNTFS);
|
|
1043
|
+
arraySet(localHeaderArray, rawExtraField, localHeaderOffset);
|
|
879
1044
|
return {
|
|
880
1045
|
localHeaderArray,
|
|
1046
|
+
localHeaderView,
|
|
881
1047
|
headerArray,
|
|
882
1048
|
headerView,
|
|
883
1049
|
lastModDate,
|
|
@@ -887,6 +1053,8 @@ function getHeaderInfo(options) {
|
|
|
887
1053
|
version,
|
|
888
1054
|
compressionMethod,
|
|
889
1055
|
extraFieldExtendedTimestampFlag,
|
|
1056
|
+
rawExtraFieldZip64,
|
|
1057
|
+
localExtraFieldZip64Length,
|
|
890
1058
|
rawExtraFieldExtendedTimestamp,
|
|
891
1059
|
rawExtraFieldNTFS,
|
|
892
1060
|
rawExtraFieldAES,
|
|
@@ -915,12 +1083,11 @@ function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
|
|
|
915
1083
|
entryInfo.metadataSize += extraBytesLength;
|
|
916
1084
|
}
|
|
917
1085
|
|
|
918
|
-
function getDataDescriptorInfo(
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
} = options;
|
|
1086
|
+
function getDataDescriptorInfo({
|
|
1087
|
+
zip64,
|
|
1088
|
+
dataDescriptor,
|
|
1089
|
+
dataDescriptorSignature
|
|
1090
|
+
}) {
|
|
924
1091
|
let dataDescriptorArray = new Uint8Array();
|
|
925
1092
|
let dataDescriptorView, dataDescriptorOffset = 0;
|
|
926
1093
|
if (dataDescriptor) {
|
|
@@ -938,15 +1105,17 @@ function getDataDescriptorInfo(options) {
|
|
|
938
1105
|
};
|
|
939
1106
|
}
|
|
940
1107
|
|
|
941
|
-
function setEntryInfo(
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
1108
|
+
function setEntryInfo({
|
|
1109
|
+
signature,
|
|
1110
|
+
compressedSize,
|
|
1111
|
+
uncompressedSize,
|
|
1112
|
+
headerInfo,
|
|
1113
|
+
dataDescriptorInfo
|
|
1114
|
+
}, {
|
|
1115
|
+
zip64,
|
|
1116
|
+
zipCrypto,
|
|
1117
|
+
dataDescriptor
|
|
1118
|
+
}) {
|
|
950
1119
|
const {
|
|
951
1120
|
headerView,
|
|
952
1121
|
encrypted
|
|
@@ -955,40 +1124,20 @@ function setEntryInfo(entryInfo, options) {
|
|
|
955
1124
|
dataDescriptorView,
|
|
956
1125
|
dataDescriptorOffset
|
|
957
1126
|
} = dataDescriptorInfo;
|
|
958
|
-
const {
|
|
959
|
-
zip64,
|
|
960
|
-
zip64UncompressedSize,
|
|
961
|
-
zip64CompressedSize,
|
|
962
|
-
zipCrypto,
|
|
963
|
-
dataDescriptor
|
|
964
|
-
} = options;
|
|
965
1127
|
if ((!encrypted || zipCrypto) && signature !== UNDEFINED_VALUE) {
|
|
966
|
-
setUint32(headerView,
|
|
1128
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, signature);
|
|
967
1129
|
if (dataDescriptor) {
|
|
968
1130
|
setUint32(dataDescriptorView, dataDescriptorOffset, signature);
|
|
969
1131
|
}
|
|
970
1132
|
}
|
|
971
1133
|
if (zip64) {
|
|
972
|
-
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
973
|
-
setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
|
|
974
|
-
setUint16(rawExtraFieldZip64View, 2, getLength(rawExtraFieldZip64) - 4);
|
|
975
|
-
let rawExtraFieldZip64Offset = 4;
|
|
976
|
-
if (zip64UncompressedSize) {
|
|
977
|
-
setUint32(headerView, 18, MAX_32_BITS);
|
|
978
|
-
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
|
|
979
|
-
rawExtraFieldZip64Offset += 8;
|
|
980
|
-
}
|
|
981
|
-
if (zip64CompressedSize) {
|
|
982
|
-
setUint32(headerView, 14, MAX_32_BITS);
|
|
983
|
-
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
|
|
984
|
-
}
|
|
985
1134
|
if (dataDescriptor) {
|
|
986
1135
|
setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
|
|
987
1136
|
setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
|
|
988
1137
|
}
|
|
989
1138
|
} else {
|
|
990
|
-
setUint32(headerView,
|
|
991
|
-
setUint32(headerView,
|
|
1139
|
+
setUint32(headerView, HEADER_OFFSET_COMPRESSED_SIZE, compressedSize);
|
|
1140
|
+
setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
|
|
992
1141
|
if (dataDescriptor) {
|
|
993
1142
|
setUint32(dataDescriptorView, dataDescriptorOffset + 4, compressedSize);
|
|
994
1143
|
setUint32(dataDescriptorView, dataDescriptorOffset + 8, uncompressedSize);
|
|
@@ -996,36 +1145,72 @@ function setEntryInfo(entryInfo, options) {
|
|
|
996
1145
|
}
|
|
997
1146
|
}
|
|
998
1147
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1148
|
+
function updateLocalHeader({
|
|
1149
|
+
rawFilename,
|
|
1150
|
+
dataDescriptor,
|
|
1151
|
+
encrypted,
|
|
1152
|
+
zip64,
|
|
1153
|
+
localExtraFieldZip64Length,
|
|
1154
|
+
signature,
|
|
1155
|
+
compressedSize,
|
|
1156
|
+
uncompressedSize,
|
|
1157
|
+
offset,
|
|
1158
|
+
diskNumberStart,
|
|
1159
|
+
zip64UncompressedSize,
|
|
1160
|
+
zip64CompressedSize,
|
|
1161
|
+
zip64Offset,
|
|
1162
|
+
zip64DiskNumberStart
|
|
1163
|
+
}, localHeaderView) {
|
|
1164
|
+
if (!dataDescriptor) {
|
|
1165
|
+
if (!encrypted) {
|
|
1166
|
+
setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + 4, signature);
|
|
1167
|
+
}
|
|
1168
|
+
if (!zip64) {
|
|
1169
|
+
setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + 4, compressedSize);
|
|
1170
|
+
setUint32(localHeaderView, HEADER_OFFSET_UNCOMPRESSED_SIZE + 4, uncompressedSize);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
if (zip64) {
|
|
1174
|
+
if (localExtraFieldZip64Length) {
|
|
1175
|
+
let localHeaderOffset = HEADER_SIZE + 4 + getLength(rawFilename) + 4;
|
|
1176
|
+
if (zip64UncompressedSize) {
|
|
1177
|
+
setBigUint64(localHeaderView, localHeaderOffset, BigInt(uncompressedSize));
|
|
1178
|
+
localHeaderOffset += 8;
|
|
1179
|
+
}
|
|
1180
|
+
if (zip64CompressedSize) {
|
|
1181
|
+
setBigUint64(localHeaderView, localHeaderOffset, BigInt(compressedSize));
|
|
1182
|
+
localHeaderOffset += 8;
|
|
1183
|
+
}
|
|
1184
|
+
if (zip64Offset) {
|
|
1185
|
+
setBigUint64(localHeaderView, localHeaderOffset, BigInt(offset));
|
|
1186
|
+
localHeaderOffset += 8;
|
|
1187
|
+
}
|
|
1188
|
+
if (zip64DiskNumberStart) {
|
|
1189
|
+
setUint32(localHeaderView, localHeaderOffset, diskNumberStart);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1015
1192
|
}
|
|
1016
|
-
await writeData(writable, new Uint8Array(arrayBuffer));
|
|
1017
|
-
return entryData.slice(arrayBuffer.byteLength);
|
|
1018
1193
|
}
|
|
1019
1194
|
|
|
1020
|
-
function
|
|
1021
|
-
|
|
1022
|
-
|
|
1195
|
+
function updateZip64ExtraField({
|
|
1196
|
+
compressedSize,
|
|
1197
|
+
uncompressedSize,
|
|
1198
|
+
offset,
|
|
1199
|
+
diskNumberStart,
|
|
1200
|
+
zip64UncompressedSize,
|
|
1201
|
+
zip64CompressedSize,
|
|
1202
|
+
zip64Offset,
|
|
1203
|
+
zip64DiskNumberStart,
|
|
1204
|
+
rawExtraFieldZip64
|
|
1205
|
+
}) {
|
|
1023
1206
|
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
1024
1207
|
let rawExtraFieldZip64Offset = 4;
|
|
1025
1208
|
if (zip64UncompressedSize) {
|
|
1209
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
|
|
1026
1210
|
rawExtraFieldZip64Offset += 8;
|
|
1027
1211
|
}
|
|
1028
1212
|
if (zip64CompressedSize) {
|
|
1213
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
|
|
1029
1214
|
rawExtraFieldZip64Offset += 8;
|
|
1030
1215
|
}
|
|
1031
1216
|
if (zip64Offset) {
|
|
@@ -1039,7 +1224,7 @@ function setZip64ExtraInfo(fileEntry, options) {
|
|
|
1039
1224
|
|
|
1040
1225
|
async function closeFile(zipWriter, comment, options) {
|
|
1041
1226
|
const { files, writer } = zipWriter;
|
|
1042
|
-
const { diskOffset
|
|
1227
|
+
const { diskOffset } = writer;
|
|
1043
1228
|
let { diskNumber } = writer;
|
|
1044
1229
|
let offset = 0;
|
|
1045
1230
|
let directoryDataLength = 0;
|
|
@@ -1068,7 +1253,7 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
1068
1253
|
} else {
|
|
1069
1254
|
rawExtraFieldTimestamp = new Uint8Array();
|
|
1070
1255
|
}
|
|
1071
|
-
fileEntry.
|
|
1256
|
+
fileEntry.rawExtraFieldExtendedTimestamp = rawExtraFieldTimestamp;
|
|
1072
1257
|
directoryDataLength += 46 +
|
|
1073
1258
|
getLength(
|
|
1074
1259
|
rawFilename,
|
|
@@ -1089,12 +1274,13 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
1089
1274
|
rawFilename,
|
|
1090
1275
|
rawExtraFieldZip64,
|
|
1091
1276
|
rawExtraFieldAES,
|
|
1092
|
-
|
|
1277
|
+
rawExtraFieldExtendedTimestamp,
|
|
1093
1278
|
rawExtraFieldNTFS,
|
|
1094
1279
|
rawExtraField,
|
|
1095
1280
|
rawComment,
|
|
1096
1281
|
versionMadeBy,
|
|
1097
1282
|
headerArray,
|
|
1283
|
+
headerView,
|
|
1098
1284
|
zip64,
|
|
1099
1285
|
zip64UncompressedSize,
|
|
1100
1286
|
zip64CompressedSize,
|
|
@@ -1106,39 +1292,50 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
1106
1292
|
uncompressedSize,
|
|
1107
1293
|
compressedSize
|
|
1108
1294
|
} = fileEntry;
|
|
1109
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES,
|
|
1295
|
+
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
|
|
1110
1296
|
setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
|
|
1111
1297
|
setUint16(directoryView, offset + 4, versionMadeBy);
|
|
1112
|
-
const headerView = getDataView(headerArray);
|
|
1113
1298
|
if (!zip64UncompressedSize) {
|
|
1114
|
-
setUint32(headerView,
|
|
1299
|
+
setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
|
|
1115
1300
|
}
|
|
1116
1301
|
if (!zip64CompressedSize) {
|
|
1117
|
-
setUint32(headerView,
|
|
1302
|
+
setUint32(headerView, HEADER_OFFSET_COMPRESSED_SIZE, compressedSize);
|
|
1118
1303
|
}
|
|
1119
1304
|
arraySet(directoryArray, headerArray, offset + 6);
|
|
1120
|
-
|
|
1121
|
-
setUint16(directoryView,
|
|
1122
|
-
|
|
1123
|
-
setUint16(directoryView,
|
|
1305
|
+
let directoryOffset = offset + HEADER_SIZE + 4;
|
|
1306
|
+
setUint16(directoryView, directoryOffset, extraFieldLength);
|
|
1307
|
+
directoryOffset += 2;
|
|
1308
|
+
setUint16(directoryView, directoryOffset, getLength(rawComment));
|
|
1309
|
+
directoryOffset += 2;
|
|
1310
|
+
setUint16(directoryView, directoryOffset, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
|
|
1311
|
+
directoryOffset += 2;
|
|
1312
|
+
setUint16(directoryView, directoryOffset, internalFileAttributes);
|
|
1313
|
+
directoryOffset += 2;
|
|
1124
1314
|
if (externalFileAttributes) {
|
|
1125
|
-
setUint32(directoryView,
|
|
1315
|
+
setUint32(directoryView, directoryOffset, externalFileAttributes);
|
|
1126
1316
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
arraySet(directoryArray,
|
|
1131
|
-
|
|
1132
|
-
arraySet(directoryArray,
|
|
1133
|
-
|
|
1134
|
-
arraySet(directoryArray,
|
|
1135
|
-
|
|
1317
|
+
directoryOffset += 4;
|
|
1318
|
+
setUint32(directoryView, directoryOffset, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
|
|
1319
|
+
directoryOffset += 4;
|
|
1320
|
+
arraySet(directoryArray, rawFilename, directoryOffset);
|
|
1321
|
+
directoryOffset += getLength(rawFilename);
|
|
1322
|
+
arraySet(directoryArray, rawExtraFieldZip64, directoryOffset);
|
|
1323
|
+
directoryOffset += getLength(rawExtraFieldZip64);
|
|
1324
|
+
arraySet(directoryArray, rawExtraFieldAES, directoryOffset);
|
|
1325
|
+
directoryOffset += getLength(rawExtraFieldAES);
|
|
1326
|
+
arraySet(directoryArray, rawExtraFieldExtendedTimestamp, directoryOffset);
|
|
1327
|
+
directoryOffset += getLength(rawExtraFieldExtendedTimestamp);
|
|
1328
|
+
arraySet(directoryArray, rawExtraFieldNTFS, directoryOffset);
|
|
1329
|
+
directoryOffset += getLength(rawExtraFieldNTFS);
|
|
1330
|
+
arraySet(directoryArray, rawExtraField, directoryOffset);
|
|
1331
|
+
directoryOffset += getLength(rawExtraField);
|
|
1332
|
+
arraySet(directoryArray, rawComment, directoryOffset);
|
|
1136
1333
|
if (offset - directoryDiskOffset > writer.availableSize) {
|
|
1137
1334
|
writer.availableSize = 0;
|
|
1138
|
-
await writeData(
|
|
1335
|
+
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
1139
1336
|
directoryDiskOffset = offset;
|
|
1140
1337
|
}
|
|
1141
|
-
offset
|
|
1338
|
+
offset = directoryOffset;
|
|
1142
1339
|
if (options.onprogress) {
|
|
1143
1340
|
try {
|
|
1144
1341
|
await options.onprogress(indexFileEntry + 1, files.size, new Entry(fileEntry));
|
|
@@ -1148,7 +1345,7 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
1148
1345
|
}
|
|
1149
1346
|
}
|
|
1150
1347
|
}
|
|
1151
|
-
await writeData(
|
|
1348
|
+
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
1152
1349
|
let lastDiskNumber = writer.diskNumber;
|
|
1153
1350
|
const { availableSize } = writer;
|
|
1154
1351
|
if (availableSize < END_OF_CENTRAL_DIR_LENGTH) {
|
|
@@ -1204,17 +1401,18 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
1204
1401
|
throw new Error(ERR_INVALID_COMMENT);
|
|
1205
1402
|
}
|
|
1206
1403
|
}
|
|
1207
|
-
await writeData(
|
|
1404
|
+
await writeData(writer, endOfdirectoryArray);
|
|
1208
1405
|
if (commentLength) {
|
|
1209
|
-
await writeData(
|
|
1406
|
+
await writeData(writer, comment);
|
|
1210
1407
|
}
|
|
1211
1408
|
}
|
|
1212
1409
|
|
|
1213
|
-
async function writeData(
|
|
1410
|
+
async function writeData(writer, array) {
|
|
1411
|
+
const { writable } = writer;
|
|
1214
1412
|
const streamWriter = writable.getWriter();
|
|
1215
1413
|
try {
|
|
1216
1414
|
await streamWriter.ready;
|
|
1217
|
-
|
|
1415
|
+
writer.size += getLength(array);
|
|
1218
1416
|
await streamWriter.write(array);
|
|
1219
1417
|
} finally {
|
|
1220
1418
|
streamWriter.releaseLock();
|
|
@@ -1265,3 +1463,65 @@ function getLength(...arrayLikes) {
|
|
|
1265
1463
|
arrayLikes.forEach(arrayLike => arrayLike && (result += arrayLike.length));
|
|
1266
1464
|
return result;
|
|
1267
1465
|
}
|
|
1466
|
+
|
|
1467
|
+
function getHeaderArrayData({
|
|
1468
|
+
version,
|
|
1469
|
+
bitflag,
|
|
1470
|
+
compressionMethod,
|
|
1471
|
+
uncompressedSize,
|
|
1472
|
+
compressedSize,
|
|
1473
|
+
lastModDate,
|
|
1474
|
+
rawFilename,
|
|
1475
|
+
zip64CompressedSize,
|
|
1476
|
+
zip64UncompressedSize,
|
|
1477
|
+
extraFieldLength
|
|
1478
|
+
}) {
|
|
1479
|
+
const headerArray = new Uint8Array(HEADER_SIZE);
|
|
1480
|
+
const headerView = getDataView(headerArray);
|
|
1481
|
+
setUint16(headerView, 0, version);
|
|
1482
|
+
setUint16(headerView, 2, bitflag);
|
|
1483
|
+
setUint16(headerView, 4, compressionMethod);
|
|
1484
|
+
const dateArray = new Uint32Array(1);
|
|
1485
|
+
const dateView = getDataView(dateArray);
|
|
1486
|
+
setUint16(dateView, 0, (((lastModDate.getHours() << 6) | lastModDate.getMinutes()) << 5) | lastModDate.getSeconds() / 2);
|
|
1487
|
+
setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
|
|
1488
|
+
const rawLastModDate = dateArray[0];
|
|
1489
|
+
setUint32(headerView, 6, rawLastModDate);
|
|
1490
|
+
if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
|
|
1491
|
+
setUint32(headerView, HEADER_OFFSET_COMPRESSED_SIZE, zip64CompressedSize ? MAX_32_BITS : compressedSize);
|
|
1492
|
+
}
|
|
1493
|
+
if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
|
|
1494
|
+
setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
|
|
1495
|
+
}
|
|
1496
|
+
setUint16(headerView, 22, getLength(rawFilename));
|
|
1497
|
+
setUint16(headerView, 24, extraFieldLength);
|
|
1498
|
+
return {
|
|
1499
|
+
headerArray,
|
|
1500
|
+
headerView,
|
|
1501
|
+
rawLastModDate
|
|
1502
|
+
};
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
|
|
1506
|
+
function getBitflag(level, useUnicodeFileNames, dataDescriptor, encrypted) {
|
|
1507
|
+
let bitFlag = 0;
|
|
1508
|
+
if (useUnicodeFileNames) {
|
|
1509
|
+
bitFlag = bitFlag | BITFLAG_LANG_ENCODING_FLAG;
|
|
1510
|
+
}
|
|
1511
|
+
if (dataDescriptor) {
|
|
1512
|
+
bitFlag = bitFlag | BITFLAG_DATA_DESCRIPTOR;
|
|
1513
|
+
}
|
|
1514
|
+
if (level >= 0 && level < 2) {
|
|
1515
|
+
bitFlag = bitFlag | BITFLAG_LEVEL_SUPER_FAST_MASK;
|
|
1516
|
+
}
|
|
1517
|
+
if (level >= 3 && level < 6) {
|
|
1518
|
+
bitFlag = bitFlag | BITFLAG_LEVEL_FAST_MASK;
|
|
1519
|
+
}
|
|
1520
|
+
if (level == 9) {
|
|
1521
|
+
bitFlag = bitFlag | BITFLAG_LEVEL_MAX_MASK;
|
|
1522
|
+
}
|
|
1523
|
+
if (encrypted) {
|
|
1524
|
+
bitFlag = bitFlag | BITFLAG_ENCRYPTED;
|
|
1525
|
+
}
|
|
1526
|
+
return bitFlag;
|
|
1527
|
+
}
|