@zip.js/zip.js 2.8.52 → 2.8.54
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/README.md +1 -1
- package/deno.json +2 -1
- package/dist/zip-core-external.js +839 -528
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +847 -527
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +880 -557
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +829 -538
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +880 -557
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +895 -558
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +894 -557
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +849 -529
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +849 -529
- 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 +848 -528
- package/dist/zip.min.js +1 -1
- package/eslint.config.mjs +2 -1
- package/index-native.cjs +895 -558
- package/index-native.min.js +1 -1
- package/index.cjs +894 -557
- package/index.d.cts +672 -78
- package/index.d.ts +672 -78
- package/index.min.js +1 -1
- package/lib/core/codec-worker-web.js +13 -4
- package/lib/core/configuration.js +62 -21
- package/lib/core/constants.js +16 -1
- package/lib/core/io.js +44 -29
- package/lib/core/options.js +46 -2
- package/lib/core/streams/aes-crypto-stream.js +12 -12
- package/lib/core/util/decode-text.js +11 -2
- package/lib/core/web-worker-base.js +3 -2
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-entry.js +8 -0
- package/lib/core/zip-fs.js +38 -27
- package/lib/core/zip-reader.js +149 -60
- package/lib/core/zip-writer.js +329 -189
- package/lib/zip-core-base.js +6 -1
- package/lib/zip-core-reader.js +1 -0
- package/lib/zip-core-writer.js +5 -0
- package/package.json +11 -3
package/lib/core/zip-writer.js
CHANGED
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
*
|
|
54
54
|
* Scheduling:
|
|
55
55
|
* - The central directory order (i.e. the order in which entries are listed by getEntries()) is
|
|
56
|
-
* the insertion order of the `
|
|
56
|
+
* the insertion order of the `fileEntries` map. addFile() reserves each entry's slot synchronously in
|
|
57
57
|
* add() call order, before initializing the reader, so concurrent entries whose readers
|
|
58
58
|
* initialize at different speeds are still listed in call order.
|
|
59
|
-
* - `fileEntry.
|
|
59
|
+
* - `fileEntry.lockFileEntry` chains every entry to the previous one to reach getFileEntry(); awaiting it
|
|
60
60
|
* serializes the physical writes when `keepOrder` is set. The physical layout therefore follows
|
|
61
61
|
* the order in which the readers finish initializing, not necessarily the central directory
|
|
62
62
|
* order; each entry records its own `offset`, so the archive stays consistent either way.
|
|
@@ -86,6 +86,7 @@ import {
|
|
|
86
86
|
COMPRESSION_METHOD_STORE,
|
|
87
87
|
COMPRESSION_METHOD_AES,
|
|
88
88
|
SPLIT_ZIP_FILE_SIGNATURE,
|
|
89
|
+
SPLIT_ZIP_FILE_SIGNATURE_LENGTH,
|
|
89
90
|
LOCAL_FILE_HEADER_SIGNATURE,
|
|
90
91
|
DATA_DESCRIPTOR_RECORD_SIGNATURE,
|
|
91
92
|
DIGITAL_SIGNATURE_RECORD_SIGNATURE,
|
|
@@ -122,12 +123,15 @@ import {
|
|
|
122
123
|
FILE_ATTR_UNIX_TYPE_DIR,
|
|
123
124
|
FILE_ATTR_UNIX_TYPE_FILE,
|
|
124
125
|
FILE_ATTR_UNIX_TYPE_MASK,
|
|
126
|
+
FILE_ATTR_UNIX_TYPE_SYMLINK,
|
|
125
127
|
FILE_ATTR_UNIX_EXECUTABLE_MASK,
|
|
126
128
|
FILE_ATTR_UNIX_DEFAULT_MASK,
|
|
127
129
|
FILE_ATTR_UNIX_SETUID_MASK,
|
|
128
130
|
FILE_ATTR_UNIX_SETGID_MASK,
|
|
129
131
|
FILE_ATTR_UNIX_STICKY_MASK,
|
|
130
132
|
VERSION_DEFLATE,
|
|
133
|
+
VERSION_MADE_BY_MSDOS,
|
|
134
|
+
VERSION_MADE_BY_UNIX,
|
|
131
135
|
VERSION_ZIP64,
|
|
132
136
|
VERSION_AES,
|
|
133
137
|
DIRECTORY_SIGNATURE,
|
|
@@ -136,6 +140,8 @@ import {
|
|
|
136
140
|
HEADER_OFFSET_SIGNATURE,
|
|
137
141
|
HEADER_OFFSET_COMPRESSED_SIZE,
|
|
138
142
|
HEADER_OFFSET_UNCOMPRESSED_SIZE,
|
|
143
|
+
HEADER_OFFSET_FILENAME_LENGTH,
|
|
144
|
+
HEADER_OFFSET_EXTRAFIELD_LENGTH,
|
|
139
145
|
LOCAL_HEADER_COMMON_OFFSET,
|
|
140
146
|
MIN_DATE,
|
|
141
147
|
MAX_DATE,
|
|
@@ -143,6 +149,7 @@ import {
|
|
|
143
149
|
INFINITY_VALUE,
|
|
144
150
|
OBJECT_TYPE,
|
|
145
151
|
STRING_TYPE,
|
|
152
|
+
FUNCTION_TYPE,
|
|
146
153
|
EMPTY_UINT8_ARRAY
|
|
147
154
|
} from "./constants.js";
|
|
148
155
|
import { getConfiguration } from "./configuration.js";
|
|
@@ -155,13 +162,16 @@ import {
|
|
|
155
162
|
} from "./codec-pool.js";
|
|
156
163
|
import {
|
|
157
164
|
initStream,
|
|
165
|
+
createReadable,
|
|
166
|
+
readUint8Array,
|
|
158
167
|
GenericWriter,
|
|
159
168
|
GenericReader,
|
|
169
|
+
BlobReader,
|
|
160
170
|
ownsWritable
|
|
161
171
|
} from "./io.js";
|
|
162
172
|
import { encodeText } from "./util/encode-text.js";
|
|
163
173
|
import { getDataView } from "./util/array.js";
|
|
164
|
-
import { toCompatibleReadable } from "./util/compatible-streams.js";
|
|
174
|
+
import { toCompatibleReadable, streamToBlob } from "./util/compatible-streams.js";
|
|
165
175
|
import {
|
|
166
176
|
PROPERTY_NAME_LAST_MODIFICATION_DATE,
|
|
167
177
|
PROPERTY_NAME_LAST_ACCESS_DATE,
|
|
@@ -220,18 +230,28 @@ import {
|
|
|
220
230
|
OPTION_LOCAL_EXTRA_FIELD,
|
|
221
231
|
OPTION_SIGN_CENTRAL_DIRECTORY,
|
|
222
232
|
TEXT_TYPE_FILENAME,
|
|
223
|
-
TEXT_TYPE_COMMENT
|
|
233
|
+
TEXT_TYPE_COMMENT,
|
|
234
|
+
ERR_INVALID_PASSWORD_TYPE,
|
|
235
|
+
checkFunctionOption,
|
|
236
|
+
checkSignalOption,
|
|
237
|
+
checkPasswordOption,
|
|
238
|
+
toNumber
|
|
224
239
|
} from "./options.js";
|
|
225
240
|
|
|
226
241
|
const ERR_DUPLICATED_NAME = "File already exists";
|
|
227
242
|
const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
|
|
243
|
+
const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
|
|
228
244
|
const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
|
|
245
|
+
const ERR_INVALID_ENTRY_COMMENT_TYPE = "Invalid file entry comment (must be a string)";
|
|
246
|
+
const ERR_INVALID_DATE = "Invalid date (must be a valid Date instance)";
|
|
229
247
|
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
230
248
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
231
249
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
232
250
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
233
251
|
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
234
|
-
const
|
|
252
|
+
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
253
|
+
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
254
|
+
const ERR_INVALID_EXTRAFIELD_DATA_TYPE = "Invalid extra field data (must be a Uint8Array)";
|
|
235
255
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
236
256
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
237
257
|
const MIN_UNIX_TIME = -2147483648;
|
|
@@ -251,7 +271,6 @@ const ERR_INVALID_UNIX_ID_SIZE = "uid/gid must be 0..65535 for unixExtraFieldTyp
|
|
|
251
271
|
const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
|
|
252
272
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
253
273
|
const ERR_INVALID_LEVEL = "Invalid level (must be integer 0..9)";
|
|
254
|
-
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
255
274
|
const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
256
275
|
|
|
257
276
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
@@ -276,8 +295,7 @@ class ZipWriter {
|
|
|
276
295
|
writer,
|
|
277
296
|
addSplitZipSignature,
|
|
278
297
|
options,
|
|
279
|
-
|
|
280
|
-
files: new Map(),
|
|
298
|
+
fileEntries: new Map(),
|
|
281
299
|
filenames: new Set(),
|
|
282
300
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
283
301
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
@@ -293,15 +311,28 @@ class ZipWriter {
|
|
|
293
311
|
}
|
|
294
312
|
reader = new GenericReader(reader);
|
|
295
313
|
await initStream(reader);
|
|
314
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
315
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
316
|
+
await initStream(reader);
|
|
317
|
+
}
|
|
296
318
|
const { ZipReader } = await import("./zip-reader.js");
|
|
297
|
-
const zipReader = new ZipReader(reader
|
|
319
|
+
const zipReader = new ZipReader(reader);
|
|
298
320
|
const entries = await zipReader.getEntries();
|
|
299
321
|
await zipReader.close();
|
|
300
322
|
await initStream(this.writer);
|
|
301
|
-
|
|
302
|
-
|
|
323
|
+
const { directoryOffset } = zipReader;
|
|
324
|
+
let splitZipSignatureLength = 0;
|
|
325
|
+
if (this.addSplitZipSignature) {
|
|
326
|
+
delete this.addSplitZipSignature;
|
|
327
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
328
|
+
await writeData(this.writer, getSplitZipSignatureArray());
|
|
329
|
+
splitZipSignatureLength = SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
330
|
+
this.offset += splitZipSignatureLength;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
const entryPositions = await copyZipData(this, reader, entries, directoryOffset, splitZipSignatureLength);
|
|
303
334
|
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
304
|
-
this.
|
|
335
|
+
this.fileEntries = new Map(entries.map(entry => {
|
|
305
336
|
const {
|
|
306
337
|
version,
|
|
307
338
|
rawLastModDate,
|
|
@@ -356,11 +387,12 @@ class ZipWriter {
|
|
|
356
387
|
if (crc32 !== UNDEFINED_VALUE) {
|
|
357
388
|
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
358
389
|
}
|
|
390
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
359
391
|
Object.assign(entry, {
|
|
360
392
|
zip64UncompressedSize,
|
|
361
393
|
zip64CompressedSize,
|
|
362
|
-
|
|
363
|
-
diskNumberStart
|
|
394
|
+
offset,
|
|
395
|
+
diskNumberStart,
|
|
364
396
|
zip64DiskNumberStart: false,
|
|
365
397
|
rawExtraFieldZip64,
|
|
366
398
|
rawExtraFieldAES,
|
|
@@ -380,11 +412,8 @@ class ZipWriter {
|
|
|
380
412
|
async add(name = "", reader, options = {}) {
|
|
381
413
|
const zipWriter = this;
|
|
382
414
|
options = Object.assign({}, options);
|
|
383
|
-
const {
|
|
384
|
-
|
|
385
|
-
config
|
|
386
|
-
} = zipWriter;
|
|
387
|
-
if (workers < config.maxWorkers) {
|
|
415
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
416
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
388
417
|
workers++;
|
|
389
418
|
} else {
|
|
390
419
|
await new Promise(resolve => pendingEntries.push(resolve));
|
|
@@ -421,16 +450,16 @@ class ZipWriter {
|
|
|
421
450
|
}
|
|
422
451
|
|
|
423
452
|
remove(entry) {
|
|
424
|
-
const { filenames,
|
|
453
|
+
const { filenames, fileEntries } = this;
|
|
425
454
|
// deno-lint-ignore valid-typeof
|
|
426
455
|
if (typeof entry == STRING_TYPE) {
|
|
427
|
-
entry =
|
|
456
|
+
entry = fileEntries.get(entry);
|
|
428
457
|
}
|
|
429
458
|
if (entry && entry.filename !== UNDEFINED_VALUE) {
|
|
430
459
|
const { filename } = entry;
|
|
431
|
-
if (filenames.has(filename) &&
|
|
460
|
+
if (filenames.has(filename) && fileEntries.has(filename)) {
|
|
432
461
|
filenames.delete(filename);
|
|
433
|
-
|
|
462
|
+
fileEntries.delete(filename);
|
|
434
463
|
return true;
|
|
435
464
|
}
|
|
436
465
|
}
|
|
@@ -441,6 +470,9 @@ class ZipWriter {
|
|
|
441
470
|
const zipWriter = this;
|
|
442
471
|
const { pendingAddFileCalls, writer } = this;
|
|
443
472
|
const { writable } = writer;
|
|
473
|
+
if (!(comment instanceof Uint8Array)) {
|
|
474
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
475
|
+
}
|
|
444
476
|
if (getLength(comment) > MAX_16_BITS) {
|
|
445
477
|
throw new Error(ERR_INVALID_COMMENT);
|
|
446
478
|
}
|
|
@@ -524,10 +556,15 @@ export {
|
|
|
524
556
|
getEntriesSize,
|
|
525
557
|
ERR_DUPLICATED_NAME,
|
|
526
558
|
ERR_INVALID_COMMENT,
|
|
559
|
+
ERR_INVALID_COMMENT_TYPE,
|
|
527
560
|
ERR_INVALID_ENTRY_NAME,
|
|
528
561
|
ERR_INVALID_ENTRY_COMMENT,
|
|
562
|
+
ERR_INVALID_ENTRY_COMMENT_TYPE,
|
|
563
|
+
ERR_INVALID_DATE,
|
|
529
564
|
ERR_INVALID_VERSION,
|
|
565
|
+
ERR_INVALID_EXTRAFIELD,
|
|
530
566
|
ERR_INVALID_EXTRAFIELD_TYPE,
|
|
567
|
+
ERR_INVALID_EXTRAFIELD_DATA_TYPE,
|
|
531
568
|
ERR_INVALID_EXTRAFIELD_DATA,
|
|
532
569
|
ERR_INVALID_ENCRYPTION_STRENGTH,
|
|
533
570
|
ERR_UNSUPPORTED_ENCRYPTION_USDZ,
|
|
@@ -556,12 +593,12 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
556
593
|
const metadataInfo = resolveMetadata(zipWriter, name, options);
|
|
557
594
|
const { comment } = metadataInfo;
|
|
558
595
|
const extraField = options[PROPERTY_NAME_EXTRA_FIELD];
|
|
559
|
-
zipWriter.
|
|
596
|
+
zipWriter.fileEntries.set(name, UNDEFINED_VALUE);
|
|
560
597
|
let fileEntry;
|
|
561
598
|
try {
|
|
562
599
|
const { resolvedOptions } = metadataInfo;
|
|
563
600
|
if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
|
|
564
|
-
!resolvedOptions.passThrough && !(await supportsDeflate(
|
|
601
|
+
!resolvedOptions.passThrough && !(await supportsDeflate(getConfiguration()))) {
|
|
565
602
|
resolvedOptions.level = 0;
|
|
566
603
|
}
|
|
567
604
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
@@ -569,8 +606,6 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
569
606
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
570
607
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
571
608
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
572
|
-
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
573
|
-
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
574
609
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
575
610
|
crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
|
|
576
611
|
offset: zipWriter.offset - diskOffset,
|
|
@@ -581,17 +616,23 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
581
616
|
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
582
617
|
fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
|
|
583
618
|
} catch (error) {
|
|
584
|
-
zipWriter.
|
|
619
|
+
zipWriter.fileEntries.delete(name);
|
|
585
620
|
throw error;
|
|
586
621
|
}
|
|
587
|
-
Object.assign(fileEntry, {
|
|
622
|
+
Object.assign(fileEntry, {
|
|
623
|
+
name,
|
|
624
|
+
comment,
|
|
625
|
+
extraField,
|
|
626
|
+
[PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
|
|
627
|
+
[PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
|
|
628
|
+
});
|
|
588
629
|
return new Entry(fileEntry);
|
|
589
630
|
}
|
|
590
631
|
|
|
591
632
|
function resolveAttributes(zipWriter, name, options) {
|
|
592
633
|
name = name.trim();
|
|
593
634
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
594
|
-
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ?
|
|
635
|
+
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
595
636
|
const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
|
|
596
637
|
const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
|
|
597
638
|
const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
|
|
@@ -619,21 +660,21 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
619
660
|
if (unixExtraFieldType === UNDEFINED_VALUE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
620
661
|
unixExtraFieldType = INFOZIP_EXTRA_FIELD_TYPE;
|
|
621
662
|
}
|
|
622
|
-
let msdosAttributesRaw =
|
|
663
|
+
let msdosAttributesRaw = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
|
|
623
664
|
let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
|
|
624
|
-
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
|
|
665
|
+
const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType || executable;
|
|
625
666
|
const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
|
|
626
667
|
if (hasUnixMetadata) {
|
|
627
668
|
msDosCompatible = false;
|
|
628
|
-
versionMadeBy = (versionMadeBy &
|
|
669
|
+
versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
|
|
629
670
|
} else if (hasMsDosProvided) {
|
|
630
671
|
msDosCompatible = true;
|
|
631
672
|
versionMadeBy = (versionMadeBy & MAX_8_BITS);
|
|
632
673
|
}
|
|
633
|
-
if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
674
|
+
if (msdosAttributesRaw !== UNDEFINED_VALUE && (!Number.isInteger(msdosAttributesRaw) || msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
|
|
634
675
|
throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
|
|
635
676
|
}
|
|
636
|
-
if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
|
|
677
|
+
if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
|
|
637
678
|
throw new Error(ERR_INVALID_MSDOS_DATA);
|
|
638
679
|
}
|
|
639
680
|
if (versionMadeBy > MAX_16_BITS) {
|
|
@@ -665,11 +706,10 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
665
706
|
externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
|
|
666
707
|
}
|
|
667
708
|
}
|
|
668
|
-
let unixExternalUpper;
|
|
669
709
|
if (!msDosCompatible) {
|
|
670
710
|
const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
|
|
671
|
-
|
|
672
|
-
unixMode = unixMode === UNDEFINED_VALUE ?
|
|
711
|
+
const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
712
|
+
unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
|
|
673
713
|
if (setuid) {
|
|
674
714
|
unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
|
|
675
715
|
} else {
|
|
@@ -698,17 +738,20 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
698
738
|
if (hasMsDosProvided) {
|
|
699
739
|
externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
|
|
700
740
|
}
|
|
741
|
+
const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
742
|
+
const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
|
|
701
743
|
return {
|
|
702
744
|
name,
|
|
703
745
|
resolvedOptions: {
|
|
704
746
|
versionMadeBy,
|
|
705
|
-
msDosCompatible,
|
|
747
|
+
msDosCompatible: Boolean(msDosCompatible),
|
|
706
748
|
externalFileAttributes,
|
|
707
749
|
unixExternalUpper,
|
|
708
750
|
uid,
|
|
709
751
|
gid,
|
|
710
752
|
unixMode,
|
|
711
753
|
unixExtraFieldType,
|
|
754
|
+
symlink,
|
|
712
755
|
setuid,
|
|
713
756
|
setgid,
|
|
714
757
|
sticky,
|
|
@@ -719,7 +762,7 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
719
762
|
}
|
|
720
763
|
|
|
721
764
|
function resolveMetadata(zipWriter, name, options) {
|
|
722
|
-
const encode =
|
|
765
|
+
const encode = getFunctionOptionValue(zipWriter, options, OPTION_ENCODE_TEXT) || encodeText;
|
|
723
766
|
let rawFilename = encode(name, TEXT_TYPE_FILENAME);
|
|
724
767
|
if (rawFilename === UNDEFINED_VALUE) {
|
|
725
768
|
rawFilename = encodeText(name);
|
|
@@ -728,6 +771,10 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
728
771
|
throw new Error(ERR_INVALID_ENTRY_NAME);
|
|
729
772
|
}
|
|
730
773
|
const comment = options[PROPERTY_NAME_COMMENT] || "";
|
|
774
|
+
// deno-lint-ignore valid-typeof
|
|
775
|
+
if (typeof comment != STRING_TYPE) {
|
|
776
|
+
throw new Error(ERR_INVALID_ENTRY_COMMENT_TYPE);
|
|
777
|
+
}
|
|
731
778
|
let rawComment = encode(comment, TEXT_TYPE_COMMENT);
|
|
732
779
|
if (rawComment === UNDEFINED_VALUE) {
|
|
733
780
|
rawComment = encodeText(comment);
|
|
@@ -739,16 +786,14 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
739
786
|
if (version > MAX_16_BITS) {
|
|
740
787
|
throw new Error(ERR_INVALID_VERSION);
|
|
741
788
|
}
|
|
742
|
-
const lastModDate =
|
|
743
|
-
const lastAccessDate =
|
|
744
|
-
const creationDate =
|
|
789
|
+
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
790
|
+
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
791
|
+
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
745
792
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
746
793
|
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
747
794
|
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
748
795
|
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
749
|
-
|
|
750
|
-
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
751
|
-
}
|
|
796
|
+
checkPasswordOption(password, rawPassword);
|
|
752
797
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
753
798
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
754
799
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
@@ -757,9 +802,9 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
757
802
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
758
803
|
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
759
804
|
const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
|
|
760
|
-
const createTempStream =
|
|
805
|
+
const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
761
806
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
762
|
-
const signal = getOptionValue(zipWriter, options, OPTION_SIGNAL);
|
|
807
|
+
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
763
808
|
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
|
|
764
809
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
765
810
|
const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
@@ -839,18 +884,26 @@ function serializeExtraField(extraField) {
|
|
|
839
884
|
if (!extraField) {
|
|
840
885
|
return EMPTY_UINT8_ARRAY;
|
|
841
886
|
}
|
|
887
|
+
if (!(extraField instanceof Map)) {
|
|
888
|
+
throw new Error(ERR_INVALID_EXTRAFIELD);
|
|
889
|
+
}
|
|
842
890
|
let extraFieldSize = 0;
|
|
843
891
|
let offset = 0;
|
|
844
|
-
extraField.forEach(data => extraFieldSize += 4 + getLength(data));
|
|
845
|
-
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
846
|
-
const rawExtraFieldView = getDataView(rawExtraField);
|
|
847
892
|
extraField.forEach((data, type) => {
|
|
848
|
-
if (type > MAX_16_BITS) {
|
|
893
|
+
if (!Number.isInteger(type) || type < 0 || type > MAX_16_BITS) {
|
|
849
894
|
throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
|
|
850
895
|
}
|
|
896
|
+
if (!(data instanceof Uint8Array)) {
|
|
897
|
+
throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
|
|
898
|
+
}
|
|
851
899
|
if (getLength(data) > MAX_16_BITS) {
|
|
852
900
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
853
901
|
}
|
|
902
|
+
extraFieldSize += 4 + getLength(data);
|
|
903
|
+
});
|
|
904
|
+
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
905
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
906
|
+
extraField.forEach((data, type) => {
|
|
854
907
|
setUint16(rawExtraFieldView, offset, type);
|
|
855
908
|
setUint16(rawExtraFieldView, offset + 2, getLength(data));
|
|
856
909
|
arraySet(rawExtraField, data, offset + 4);
|
|
@@ -937,10 +990,13 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
937
990
|
}
|
|
938
991
|
|
|
939
992
|
async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
|
|
940
|
-
const zipWriter = { options: writerOptions
|
|
941
|
-
if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
|
|
993
|
+
const zipWriter = { options: writerOptions };
|
|
994
|
+
if (checkFunctionOption(writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY])) {
|
|
942
995
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
943
996
|
}
|
|
997
|
+
if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
|
|
998
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
999
|
+
}
|
|
944
1000
|
const commentLength = getLength(comment);
|
|
945
1001
|
if (commentLength > MAX_16_BITS) {
|
|
946
1002
|
throw new Error(ERR_INVALID_COMMENT);
|
|
@@ -961,7 +1017,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
961
1017
|
({ name } = attributesInfo);
|
|
962
1018
|
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
963
1019
|
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
964
|
-
!metadata.passThrough && !(await supportsDeflate(
|
|
1020
|
+
!metadata.passThrough && !(await supportsDeflate(getConfiguration()))) {
|
|
965
1021
|
metadata.level = 0;
|
|
966
1022
|
}
|
|
967
1023
|
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
@@ -1010,7 +1066,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
1010
1066
|
|
|
1011
1067
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
1012
1068
|
const {
|
|
1013
|
-
|
|
1069
|
+
fileEntries,
|
|
1014
1070
|
writer
|
|
1015
1071
|
} = zipWriter;
|
|
1016
1072
|
const {
|
|
@@ -1032,12 +1088,12 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1032
1088
|
let writerSizeBeforeEntry;
|
|
1033
1089
|
let flushedBufferedSize = 0;
|
|
1034
1090
|
let fileWriter;
|
|
1035
|
-
|
|
1091
|
+
fileEntries.set(name, fileEntry);
|
|
1036
1092
|
zipWriter.lastFileEntry = fileEntry;
|
|
1037
1093
|
try {
|
|
1038
1094
|
let lockPreviousFileEntry;
|
|
1039
1095
|
if (keepOrder) {
|
|
1040
|
-
lockPreviousFileEntry = previousFileEntry && previousFileEntry.
|
|
1096
|
+
lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
|
|
1041
1097
|
requestLockCurrentFileEntry();
|
|
1042
1098
|
}
|
|
1043
1099
|
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
|
|
@@ -1058,11 +1114,8 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1058
1114
|
const diskOffset = getDiskOffset(writer);
|
|
1059
1115
|
if (zipWriter.addSplitZipSignature) {
|
|
1060
1116
|
delete zipWriter.addSplitZipSignature;
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
1064
|
-
await writeData(writer, signatureArray);
|
|
1065
|
-
zipWriter.offset += 4;
|
|
1117
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
1118
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
1066
1119
|
}
|
|
1067
1120
|
if (usdz && !bufferedWrite) {
|
|
1068
1121
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -1080,11 +1133,11 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1080
1133
|
writerSizeBeforeEntry = writer.size;
|
|
1081
1134
|
await writeData(fileWriter, localHeaderArray);
|
|
1082
1135
|
}
|
|
1083
|
-
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo,
|
|
1136
|
+
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, getConfiguration(), options);
|
|
1084
1137
|
if (!bufferedWrite) {
|
|
1085
1138
|
writingEntryData = false;
|
|
1086
1139
|
}
|
|
1087
|
-
|
|
1140
|
+
fileEntries.set(name, fileEntry);
|
|
1088
1141
|
fileEntry.filename = name;
|
|
1089
1142
|
if (bufferedWrite) {
|
|
1090
1143
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
@@ -1125,7 +1178,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1125
1178
|
zipWriter.offset += flushedBufferedSize;
|
|
1126
1179
|
}
|
|
1127
1180
|
}
|
|
1128
|
-
|
|
1181
|
+
fileEntries.delete(name);
|
|
1129
1182
|
throw error;
|
|
1130
1183
|
} finally {
|
|
1131
1184
|
if (bufferedWrite) {
|
|
@@ -1147,7 +1200,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1147
1200
|
}
|
|
1148
1201
|
|
|
1149
1202
|
function requestLockCurrentFileEntry() {
|
|
1150
|
-
fileEntry.
|
|
1203
|
+
fileEntry.lockFileEntry = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
|
|
1151
1204
|
}
|
|
1152
1205
|
|
|
1153
1206
|
async function requestLockWriter() {
|
|
@@ -1167,7 +1220,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1167
1220
|
}
|
|
1168
1221
|
}
|
|
1169
1222
|
|
|
1170
|
-
async function createFileEntry(reader, writer, { diskNumberStart,
|
|
1223
|
+
async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry }, entryInfo, config, options) {
|
|
1171
1224
|
const {
|
|
1172
1225
|
headerInfo,
|
|
1173
1226
|
dataDescriptorInfo,
|
|
@@ -1222,6 +1275,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
1222
1275
|
uid,
|
|
1223
1276
|
gid,
|
|
1224
1277
|
unixMode,
|
|
1278
|
+
symlink,
|
|
1225
1279
|
setuid,
|
|
1226
1280
|
setgid,
|
|
1227
1281
|
sticky,
|
|
@@ -1234,7 +1288,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
1234
1288
|
codecURI
|
|
1235
1289
|
} = options;
|
|
1236
1290
|
const fileEntry = {
|
|
1237
|
-
|
|
1291
|
+
lockFileEntry,
|
|
1238
1292
|
versionMadeBy,
|
|
1239
1293
|
zip64,
|
|
1240
1294
|
directory: Boolean(directory),
|
|
@@ -1258,6 +1312,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
1258
1312
|
uid,
|
|
1259
1313
|
gid,
|
|
1260
1314
|
unixMode,
|
|
1315
|
+
symlink: Boolean(symlink),
|
|
1261
1316
|
setuid,
|
|
1262
1317
|
setgid,
|
|
1263
1318
|
sticky,
|
|
@@ -1275,7 +1330,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
1275
1330
|
}
|
|
1276
1331
|
const { writable } = writer;
|
|
1277
1332
|
if (reader) {
|
|
1278
|
-
const readable = toCompatibleReadable(
|
|
1333
|
+
const readable = toCompatibleReadable(createReadable(reader));
|
|
1279
1334
|
const size = reader.size;
|
|
1280
1335
|
const workerOptions = {
|
|
1281
1336
|
options: {
|
|
@@ -1338,8 +1393,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
1338
1393
|
rawLastModDate,
|
|
1339
1394
|
creationDate,
|
|
1340
1395
|
lastAccessDate,
|
|
1341
|
-
encrypted,
|
|
1342
|
-
zipCrypto,
|
|
1396
|
+
encrypted: Boolean(encrypted),
|
|
1397
|
+
zipCrypto: Boolean(zipCrypto),
|
|
1343
1398
|
size: metadataSize + compressedSize,
|
|
1344
1399
|
compressionMethod,
|
|
1345
1400
|
version,
|
|
@@ -1387,14 +1442,14 @@ function getHeaderInfo(options) {
|
|
|
1387
1442
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
1388
1443
|
const length = 4 + 16;
|
|
1389
1444
|
const extraFieldZip64 = createRecordWriter(length);
|
|
1390
|
-
extraFieldZip64.
|
|
1391
|
-
extraFieldZip64.
|
|
1445
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
1446
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
1392
1447
|
rawLocalExtraFieldZip64 = extraFieldZip64.array;
|
|
1393
1448
|
if (zip64ExtraFieldComplete) {
|
|
1394
|
-
extraFieldZip64.
|
|
1449
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
1395
1450
|
if (uncompressedFile) {
|
|
1396
1451
|
const encryptionOverhead = encrypted ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
1397
|
-
extraFieldZip64.
|
|
1452
|
+
extraFieldZip64.writeUint64(passThrough ? 0 : uncompressedSize + encryptionOverhead);
|
|
1398
1453
|
}
|
|
1399
1454
|
}
|
|
1400
1455
|
} else {
|
|
@@ -1403,8 +1458,8 @@ function getHeaderInfo(options) {
|
|
|
1403
1458
|
let rawExtraFieldAES;
|
|
1404
1459
|
if (encrypted && !zipCrypto) {
|
|
1405
1460
|
const extraFieldAES = createRecordWriter(getLength(EXTRAFIELD_DATA_AES) + 2);
|
|
1406
|
-
extraFieldAES.
|
|
1407
|
-
extraFieldAES.
|
|
1461
|
+
extraFieldAES.writeUint16(EXTRAFIELD_TYPE_AES);
|
|
1462
|
+
extraFieldAES.writeBytes(EXTRAFIELD_DATA_AES);
|
|
1408
1463
|
rawExtraFieldAES = extraFieldAES.array;
|
|
1409
1464
|
rawExtraFieldAES[8] = encryptionStrength;
|
|
1410
1465
|
} else {
|
|
@@ -1420,15 +1475,15 @@ function getHeaderInfo(options) {
|
|
|
1420
1475
|
const extraFieldTimestampLength = 9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0);
|
|
1421
1476
|
const extraFieldTimestamp = createRecordWriter(extraFieldTimestampLength);
|
|
1422
1477
|
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
1423
|
-
extraFieldTimestamp.
|
|
1424
|
-
extraFieldTimestamp.
|
|
1425
|
-
extraFieldTimestamp.
|
|
1426
|
-
extraFieldTimestamp.
|
|
1478
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
1479
|
+
extraFieldTimestamp.writeUint16(extraFieldTimestampLength - 4);
|
|
1480
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
1481
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
1427
1482
|
if (lastAccessDate) {
|
|
1428
|
-
extraFieldTimestamp.
|
|
1483
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(lastAccessDate)));
|
|
1429
1484
|
}
|
|
1430
1485
|
if (creationDate) {
|
|
1431
|
-
extraFieldTimestamp.
|
|
1486
|
+
extraFieldTimestamp.writeUint32(clampUnixTime(getTimeUnix(creationDate)));
|
|
1432
1487
|
}
|
|
1433
1488
|
rawExtraFieldExtendedTimestamp = extraFieldTimestamp.array;
|
|
1434
1489
|
} else {
|
|
@@ -1441,14 +1496,14 @@ function getHeaderInfo(options) {
|
|
|
1441
1496
|
try {
|
|
1442
1497
|
const lastModTimeNTFS = getTimeNTFS(lastModDate);
|
|
1443
1498
|
const extraFieldNTFS = createRecordWriter(36);
|
|
1444
|
-
extraFieldNTFS.
|
|
1445
|
-
extraFieldNTFS.
|
|
1499
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS);
|
|
1500
|
+
extraFieldNTFS.writeUint16(32);
|
|
1446
1501
|
extraFieldNTFS.skip(4);
|
|
1447
|
-
extraFieldNTFS.
|
|
1448
|
-
extraFieldNTFS.
|
|
1449
|
-
extraFieldNTFS.
|
|
1450
|
-
extraFieldNTFS.
|
|
1451
|
-
extraFieldNTFS.
|
|
1502
|
+
extraFieldNTFS.writeUint16(EXTRAFIELD_TYPE_NTFS_TAG1);
|
|
1503
|
+
extraFieldNTFS.writeUint16(24);
|
|
1504
|
+
extraFieldNTFS.writeUint64(lastModTimeNTFS);
|
|
1505
|
+
extraFieldNTFS.writeUint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
|
|
1506
|
+
extraFieldNTFS.writeUint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
|
|
1452
1507
|
rawExtraFieldNTFS = extraFieldNTFS.array;
|
|
1453
1508
|
} catch {
|
|
1454
1509
|
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
@@ -1467,20 +1522,20 @@ function getHeaderInfo(options) {
|
|
|
1467
1522
|
const gidBytes = packUnixId(gid);
|
|
1468
1523
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
1469
1524
|
const extraFieldUnix = createRecordWriter(4 + payloadLength);
|
|
1470
|
-
extraFieldUnix.
|
|
1471
|
-
extraFieldUnix.
|
|
1472
|
-
extraFieldUnix.
|
|
1473
|
-
extraFieldUnix.
|
|
1474
|
-
extraFieldUnix.
|
|
1475
|
-
extraFieldUnix.
|
|
1476
|
-
extraFieldUnix.
|
|
1525
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
|
|
1526
|
+
extraFieldUnix.writeUint16(payloadLength);
|
|
1527
|
+
extraFieldUnix.writeUint8(1);
|
|
1528
|
+
extraFieldUnix.writeUint8(uidBytes.length);
|
|
1529
|
+
extraFieldUnix.writeBytes(uidBytes);
|
|
1530
|
+
extraFieldUnix.writeUint8(gidBytes.length);
|
|
1531
|
+
extraFieldUnix.writeBytes(gidBytes);
|
|
1477
1532
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
1478
1533
|
} else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
1479
1534
|
const extraFieldUnix = createRecordWriter(8);
|
|
1480
|
-
extraFieldUnix.
|
|
1481
|
-
extraFieldUnix.
|
|
1482
|
-
extraFieldUnix.
|
|
1483
|
-
extraFieldUnix.
|
|
1535
|
+
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
|
|
1536
|
+
extraFieldUnix.writeUint16(4);
|
|
1537
|
+
extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
|
|
1538
|
+
extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
|
|
1484
1539
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
1485
1540
|
} else {
|
|
1486
1541
|
rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
|
|
@@ -1530,18 +1585,18 @@ function getHeaderInfo(options) {
|
|
|
1530
1585
|
const localHeader = createRecordWriter(HEADER_SIZE + getLength(rawFilename) + extraFieldLength);
|
|
1531
1586
|
const localHeaderArray = localHeader.array;
|
|
1532
1587
|
const localHeaderView = getDataView(localHeaderArray);
|
|
1533
|
-
localHeader.
|
|
1534
|
-
localHeader.
|
|
1535
|
-
localHeader.
|
|
1588
|
+
localHeader.writeUint32(LOCAL_FILE_HEADER_SIGNATURE);
|
|
1589
|
+
localHeader.writeBytes(headerArray);
|
|
1590
|
+
localHeader.writeBytes(rawFilename);
|
|
1536
1591
|
if (writeLocalExtraFieldZip64) {
|
|
1537
|
-
localHeader.
|
|
1538
|
-
}
|
|
1539
|
-
localHeader.
|
|
1540
|
-
localHeader.
|
|
1541
|
-
localHeader.
|
|
1542
|
-
localHeader.
|
|
1543
|
-
localHeader.
|
|
1544
|
-
localHeader.
|
|
1592
|
+
localHeader.writeBytes(rawLocalExtraFieldZip64);
|
|
1593
|
+
}
|
|
1594
|
+
localHeader.writeBytes(rawExtraFieldAES);
|
|
1595
|
+
localHeader.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
1596
|
+
localHeader.writeBytes(rawExtraFieldNTFS);
|
|
1597
|
+
localHeader.writeBytes(rawExtraFieldUnix);
|
|
1598
|
+
localHeader.writeBytes(rawExtraField);
|
|
1599
|
+
localHeader.writeBytes(rawLocalExtraField);
|
|
1545
1600
|
if (dataDescriptor) {
|
|
1546
1601
|
if (!zip64CompressedSize) {
|
|
1547
1602
|
setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, 0);
|
|
@@ -1731,7 +1786,7 @@ function updateLocalHeader({
|
|
|
1731
1786
|
|
|
1732
1787
|
|
|
1733
1788
|
async function closeFile(zipWriter, comment, options) {
|
|
1734
|
-
const directoryDataLength = createDirectoryRecords(zipWriter.
|
|
1789
|
+
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
1735
1790
|
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
1736
1791
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
1737
1792
|
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
@@ -1761,19 +1816,19 @@ function createDirectoryRecords(files) {
|
|
|
1761
1816
|
if (zip64Offset || zip64DiskNumberStart || zip64UncompressedSize || zip64CompressedSize) {
|
|
1762
1817
|
const length = 4 + (zip64UncompressedSize ? 8 : 0) + (zip64CompressedSize ? 8 : 0) + (zip64Offset ? 8 : 0) + (zip64DiskNumberStart ? 4 : 0);
|
|
1763
1818
|
const extraFieldZip64 = createRecordWriter(length);
|
|
1764
|
-
extraFieldZip64.
|
|
1765
|
-
extraFieldZip64.
|
|
1819
|
+
extraFieldZip64.writeUint16(EXTRAFIELD_TYPE_ZIP64);
|
|
1820
|
+
extraFieldZip64.writeUint16(length - 4);
|
|
1766
1821
|
if (zip64UncompressedSize) {
|
|
1767
|
-
extraFieldZip64.
|
|
1822
|
+
extraFieldZip64.writeUint64(uncompressedSize);
|
|
1768
1823
|
}
|
|
1769
1824
|
if (zip64CompressedSize) {
|
|
1770
|
-
extraFieldZip64.
|
|
1825
|
+
extraFieldZip64.writeUint64(compressedSize);
|
|
1771
1826
|
}
|
|
1772
1827
|
if (zip64Offset) {
|
|
1773
|
-
extraFieldZip64.
|
|
1828
|
+
extraFieldZip64.writeUint64(fileEntry.offset);
|
|
1774
1829
|
}
|
|
1775
1830
|
if (zip64DiskNumberStart) {
|
|
1776
|
-
extraFieldZip64.
|
|
1831
|
+
extraFieldZip64.writeUint32(fileEntry.diskNumberStart);
|
|
1777
1832
|
}
|
|
1778
1833
|
rawExtraFieldZip64 = extraFieldZip64.array;
|
|
1779
1834
|
} else {
|
|
@@ -1786,10 +1841,10 @@ function createDirectoryRecords(files) {
|
|
|
1786
1841
|
const lastModTimeUnix = getTimeUnix(lastModDate);
|
|
1787
1842
|
if (extendedTimestamp && inUnixTimeRange(lastModTimeUnix)) {
|
|
1788
1843
|
const extraFieldTimestamp = createRecordWriter(9);
|
|
1789
|
-
extraFieldTimestamp.
|
|
1790
|
-
extraFieldTimestamp.
|
|
1791
|
-
extraFieldTimestamp.
|
|
1792
|
-
extraFieldTimestamp.
|
|
1844
|
+
extraFieldTimestamp.writeUint16(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
1845
|
+
extraFieldTimestamp.writeUint16(5);
|
|
1846
|
+
extraFieldTimestamp.writeUint8(extraFieldExtendedTimestampFlag);
|
|
1847
|
+
extraFieldTimestamp.writeUint32(lastModTimeUnix);
|
|
1793
1848
|
rawExtraFieldTimestamp = extraFieldTimestamp.array;
|
|
1794
1849
|
} else {
|
|
1795
1850
|
rawExtraFieldTimestamp = EMPTY_UINT8_ARRAY;
|
|
@@ -1811,14 +1866,14 @@ function createDirectoryRecords(files) {
|
|
|
1811
1866
|
}
|
|
1812
1867
|
|
|
1813
1868
|
async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
1814
|
-
const {
|
|
1869
|
+
const { fileEntries, writer } = zipWriter;
|
|
1815
1870
|
const directoryArray = new Uint8Array(directoryDataLength);
|
|
1816
1871
|
await initStream(writer);
|
|
1817
1872
|
let offset = 0;
|
|
1818
1873
|
let directoryDiskOffset = 0;
|
|
1819
1874
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
1820
1875
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
1821
|
-
for (const [indexFileEntry, fileEntry] of Array.from(
|
|
1876
|
+
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
1822
1877
|
const {
|
|
1823
1878
|
offset: fileEntryOffset,
|
|
1824
1879
|
rawFilename,
|
|
@@ -1863,28 +1918,28 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
1863
1918
|
setUint16(headerView, HEADER_OFFSET_VERSION, VERSION_ZIP64);
|
|
1864
1919
|
}
|
|
1865
1920
|
const directoryRecord = createRecordWriter(directoryRecordLength);
|
|
1866
|
-
directoryRecord.
|
|
1867
|
-
directoryRecord.
|
|
1868
|
-
directoryRecord.
|
|
1869
|
-
directoryRecord.
|
|
1870
|
-
directoryRecord.
|
|
1871
|
-
directoryRecord.
|
|
1872
|
-
directoryRecord.
|
|
1873
|
-
directoryRecord.
|
|
1874
|
-
directoryRecord.
|
|
1875
|
-
directoryRecord.
|
|
1876
|
-
directoryRecord.
|
|
1877
|
-
directoryRecord.
|
|
1878
|
-
directoryRecord.
|
|
1879
|
-
directoryRecord.
|
|
1880
|
-
directoryRecord.
|
|
1881
|
-
directoryRecord.
|
|
1882
|
-
directoryRecord.
|
|
1921
|
+
directoryRecord.writeUint32(CENTRAL_FILE_HEADER_SIGNATURE);
|
|
1922
|
+
directoryRecord.writeUint16(versionMadeBy);
|
|
1923
|
+
directoryRecord.writeBytes(headerArray.subarray(0, HEADER_SIZE - 4 - 2));
|
|
1924
|
+
directoryRecord.writeUint16(extraFieldLength);
|
|
1925
|
+
directoryRecord.writeUint16(getLength(rawComment));
|
|
1926
|
+
directoryRecord.writeUint16(zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
|
|
1927
|
+
directoryRecord.writeUint16(internalFileAttributes);
|
|
1928
|
+
directoryRecord.writeUint32(externalFileAttributes);
|
|
1929
|
+
directoryRecord.writeUint32(zip64Offset ? MAX_32_BITS : fileEntryOffset);
|
|
1930
|
+
directoryRecord.writeBytes(rawFilename);
|
|
1931
|
+
directoryRecord.writeBytes(rawExtraFieldZip64);
|
|
1932
|
+
directoryRecord.writeBytes(rawExtraFieldAES);
|
|
1933
|
+
directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
1934
|
+
directoryRecord.writeBytes(rawExtraFieldNTFS);
|
|
1935
|
+
directoryRecord.writeBytes(rawExtraFieldUnix);
|
|
1936
|
+
directoryRecord.writeBytes(rawExtraField);
|
|
1937
|
+
directoryRecord.writeBytes(rawComment);
|
|
1883
1938
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
1884
1939
|
offset += directoryRecordLength;
|
|
1885
1940
|
if (options.onprogress) {
|
|
1886
1941
|
try {
|
|
1887
|
-
await options.onprogress(indexFileEntry + 1,
|
|
1942
|
+
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
1888
1943
|
} catch {
|
|
1889
1944
|
// ignored
|
|
1890
1945
|
}
|
|
@@ -1898,7 +1953,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
1898
1953
|
}
|
|
1899
1954
|
|
|
1900
1955
|
async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
1901
|
-
const signCentralDirectory =
|
|
1956
|
+
const signCentralDirectory = getFunctionOptionValue(zipWriter, options, OPTION_SIGN_CENTRAL_DIRECTORY);
|
|
1902
1957
|
if (signCentralDirectory) {
|
|
1903
1958
|
const signatureData = await signCentralDirectory(directoryArray);
|
|
1904
1959
|
const signatureDataLength = getLength(signatureData);
|
|
@@ -1906,9 +1961,9 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
|
1906
1961
|
throw new Error(ERR_INVALID_SIGNATURE_DATA);
|
|
1907
1962
|
}
|
|
1908
1963
|
const signatureRecord = createRecordWriter(6 + signatureDataLength);
|
|
1909
|
-
signatureRecord.
|
|
1910
|
-
signatureRecord.
|
|
1911
|
-
signatureRecord.
|
|
1964
|
+
signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
|
|
1965
|
+
signatureRecord.writeUint16(signatureDataLength);
|
|
1966
|
+
signatureRecord.writeBytes(signatureData);
|
|
1912
1967
|
await writeData(zipWriter.writer, signatureRecord.array);
|
|
1913
1968
|
return 6 + signatureDataLength;
|
|
1914
1969
|
}
|
|
@@ -1919,7 +1974,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
1919
1974
|
const { writer } = zipWriter;
|
|
1920
1975
|
const { directoryStart, signatureLength } = cdInfo;
|
|
1921
1976
|
let { directoryDataLength } = cdInfo;
|
|
1922
|
-
let
|
|
1977
|
+
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
1923
1978
|
let diskNumber = directoryStart.diskNumber;
|
|
1924
1979
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
1925
1980
|
let lastDiskNumber = getDiskNumber(writer);
|
|
@@ -1927,7 +1982,7 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
1927
1982
|
lastDiskNumber++;
|
|
1928
1983
|
}
|
|
1929
1984
|
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
1930
|
-
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS ||
|
|
1985
|
+
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
1931
1986
|
if (zip64 === false) {
|
|
1932
1987
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
1933
1988
|
} else {
|
|
@@ -1944,37 +1999,37 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
1944
1999
|
}
|
|
1945
2000
|
lastDiskNumber = getDiskNumber(writer);
|
|
1946
2001
|
if (zip64) {
|
|
1947
|
-
endOfdirectoryRecord.
|
|
1948
|
-
endOfdirectoryRecord.
|
|
1949
|
-
endOfdirectoryRecord.
|
|
1950
|
-
endOfdirectoryRecord.
|
|
1951
|
-
endOfdirectoryRecord.
|
|
1952
|
-
endOfdirectoryRecord.
|
|
1953
|
-
endOfdirectoryRecord.
|
|
1954
|
-
endOfdirectoryRecord.
|
|
1955
|
-
endOfdirectoryRecord.
|
|
1956
|
-
endOfdirectoryRecord.
|
|
1957
|
-
endOfdirectoryRecord.
|
|
1958
|
-
endOfdirectoryRecord.
|
|
1959
|
-
endOfdirectoryRecord.
|
|
1960
|
-
endOfdirectoryRecord.
|
|
2002
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
2003
|
+
endOfdirectoryRecord.writeUint64(44);
|
|
2004
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
2005
|
+
endOfdirectoryRecord.writeUint16(45);
|
|
2006
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
2007
|
+
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
2008
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
2009
|
+
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
2010
|
+
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
2011
|
+
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
2012
|
+
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
2013
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
2014
|
+
endOfdirectoryRecord.writeUint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength) + BigInt(signatureLength));
|
|
2015
|
+
endOfdirectoryRecord.writeUint32(lastDiskNumber + 1);
|
|
1961
2016
|
const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
|
|
1962
2017
|
if (supportZip64SplitFile) {
|
|
1963
2018
|
lastDiskNumber = MAX_16_BITS;
|
|
1964
2019
|
diskNumber = MAX_16_BITS;
|
|
1965
2020
|
}
|
|
1966
|
-
|
|
2021
|
+
fileEntriesLength = MAX_16_BITS;
|
|
1967
2022
|
directoryOffset = MAX_32_BITS;
|
|
1968
2023
|
directoryDataLength = MAX_32_BITS;
|
|
1969
2024
|
}
|
|
1970
|
-
endOfdirectoryRecord.
|
|
1971
|
-
endOfdirectoryRecord.
|
|
1972
|
-
endOfdirectoryRecord.
|
|
1973
|
-
endOfdirectoryRecord.
|
|
1974
|
-
endOfdirectoryRecord.
|
|
1975
|
-
endOfdirectoryRecord.
|
|
1976
|
-
endOfdirectoryRecord.
|
|
1977
|
-
endOfdirectoryRecord.
|
|
2025
|
+
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
2026
|
+
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
2027
|
+
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
2028
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
2029
|
+
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
2030
|
+
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
2031
|
+
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
2032
|
+
endOfdirectoryRecord.writeUint16(commentLength);
|
|
1978
2033
|
await writeData(writer, endOfdirectoryRecord.array);
|
|
1979
2034
|
if (commentLength) {
|
|
1980
2035
|
await writeData(writer, comment);
|
|
@@ -1987,11 +2042,11 @@ function createRecordWriter(length) {
|
|
|
1987
2042
|
let offset = 0;
|
|
1988
2043
|
return {
|
|
1989
2044
|
array,
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
2045
|
+
writeUint8: value => { setUint8(view, offset, value); offset += 1; },
|
|
2046
|
+
writeUint16: value => { setUint16(view, offset, value); offset += 2; },
|
|
2047
|
+
writeUint32: value => { setUint32(view, offset, value); offset += 4; },
|
|
2048
|
+
writeUint64: value => { setBigUint64(view, offset, BigInt(value)); offset += 8; },
|
|
2049
|
+
writeBytes: value => { arraySet(array, value, offset); offset += getLength(value); },
|
|
1995
2050
|
skip: count => offset += count
|
|
1996
2051
|
};
|
|
1997
2052
|
}
|
|
@@ -2015,6 +2070,71 @@ function getSegmentOffset(zipWriter, { diskNumber = 0, diskOffset = 0 }) {
|
|
|
2015
2070
|
return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
|
|
2016
2071
|
}
|
|
2017
2072
|
|
|
2073
|
+
async function startsWithSplitZipSignature(reader) {
|
|
2074
|
+
const signatureArray = await readUint8Array(reader, 0, SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
2075
|
+
return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZipSignatureLength) {
|
|
2079
|
+
const { writer } = zipWriter;
|
|
2080
|
+
const entryPositions = new Map();
|
|
2081
|
+
if (writer.closeDisk) {
|
|
2082
|
+
const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
|
|
2083
|
+
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
2084
|
+
let copiedLength = 0;
|
|
2085
|
+
for (const entry of sortedEntries) {
|
|
2086
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
2087
|
+
await copyData(zipWriter, reader, copiedLength, sourceOffset - copiedLength);
|
|
2088
|
+
if (exceedsAvailableSize(writer, await getLocalHeaderLength(reader, sourceOffset))) {
|
|
2089
|
+
await writer.closeDisk();
|
|
2090
|
+
}
|
|
2091
|
+
entryPositions.set(entry, {
|
|
2092
|
+
offset: getSegmentOffset(zipWriter, writer),
|
|
2093
|
+
diskNumberStart: getDiskNumber(writer)
|
|
2094
|
+
});
|
|
2095
|
+
copiedLength = sourceOffset;
|
|
2096
|
+
}
|
|
2097
|
+
await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
|
|
2098
|
+
} else {
|
|
2099
|
+
await copyData(zipWriter, reader, 0, directoryOffset);
|
|
2100
|
+
entries.forEach(entry => entryPositions.set(entry, {
|
|
2101
|
+
offset: splitZipSignatureLength + getSourceOffset(reader, entry),
|
|
2102
|
+
diskNumberStart: 0
|
|
2103
|
+
}));
|
|
2104
|
+
}
|
|
2105
|
+
return entryPositions;
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
async function copyData(zipWriter, reader, offset, size) {
|
|
2109
|
+
if (size > 0) {
|
|
2110
|
+
const { writer } = zipWriter;
|
|
2111
|
+
await createReadable(reader, { offset, size }).pipeTo(writer.writable, { preventClose: true, preventAbort: true });
|
|
2112
|
+
writer.size += size;
|
|
2113
|
+
zipWriter.offset += size;
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
|
|
2117
|
+
async function getLocalHeaderLength(reader, offset) {
|
|
2118
|
+
const headerArray = await readUint8Array(reader, offset, HEADER_SIZE);
|
|
2119
|
+
if (getLength(headerArray) < HEADER_SIZE) {
|
|
2120
|
+
return HEADER_SIZE;
|
|
2121
|
+
}
|
|
2122
|
+
const headerView = getDataView(headerArray);
|
|
2123
|
+
return HEADER_SIZE +
|
|
2124
|
+
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
2125
|
+
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2128
|
+
function getSourceOffset(reader, { offset, diskNumberStart }) {
|
|
2129
|
+
return offset + (reader.getDiskOffset ? reader.getDiskOffset(diskNumberStart) : 0);
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
function getSplitZipSignatureArray() {
|
|
2133
|
+
const signatureArray = new Uint8Array(SPLIT_ZIP_FILE_SIGNATURE_LENGTH);
|
|
2134
|
+
setUint32(getDataView(signatureArray), 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
2135
|
+
return signatureArray;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2018
2138
|
async function writeData(writer, array) {
|
|
2019
2139
|
const { writable } = writer;
|
|
2020
2140
|
const streamWriter = writable.getWriter();
|
|
@@ -2066,6 +2186,21 @@ function getOptionValue(zipWriter, options, name, defaultValue) {
|
|
|
2066
2186
|
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
2067
2187
|
}
|
|
2068
2188
|
|
|
2189
|
+
function getDateOptionValue(zipWriter, options, name, defaultValue) {
|
|
2190
|
+
const date = getOptionValue(zipWriter, options, name, defaultValue);
|
|
2191
|
+
if (date === null) {
|
|
2192
|
+
return defaultValue;
|
|
2193
|
+
}
|
|
2194
|
+
if (date !== UNDEFINED_VALUE && (typeof date.getTime != FUNCTION_TYPE || Number.isNaN(date.getTime()))) {
|
|
2195
|
+
throw new Error(ERR_INVALID_DATE);
|
|
2196
|
+
}
|
|
2197
|
+
return date;
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
function getFunctionOptionValue(zipWriter, options, name) {
|
|
2201
|
+
return checkFunctionOption(getOptionValue(zipWriter, options, name));
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2069
2204
|
function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
|
|
2070
2205
|
const value = getAliasedValue(options, name, deprecatedName);
|
|
2071
2206
|
const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
|
|
@@ -2080,9 +2215,6 @@ function getNumberOptionValue(zipWriter, options, name, defaultValue) {
|
|
|
2080
2215
|
return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
|
|
2081
2216
|
}
|
|
2082
2217
|
|
|
2083
|
-
function toNumber(value) {
|
|
2084
|
-
return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
|
|
2085
|
-
}
|
|
2086
2218
|
|
|
2087
2219
|
function getMaximumCompressedSize(uncompressedSize) {
|
|
2088
2220
|
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
@@ -2094,6 +2226,14 @@ function isCompressed(compressionMethod, level) {
|
|
|
2094
2226
|
: compressionMethod !== COMPRESSION_METHOD_STORE;
|
|
2095
2227
|
}
|
|
2096
2228
|
|
|
2229
|
+
function getUint16(view, offset) {
|
|
2230
|
+
return view.getUint16(offset, true);
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
function getUint32(view, offset) {
|
|
2234
|
+
return view.getUint32(offset, true);
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2097
2237
|
function setUint8(view, offset, value) {
|
|
2098
2238
|
view.setUint8(offset, value);
|
|
2099
2239
|
}
|
|
@@ -2137,9 +2277,9 @@ function getHeaderArrayData({
|
|
|
2137
2277
|
const headerRecord = createRecordWriter(HEADER_SIZE - 4);
|
|
2138
2278
|
const headerArray = headerRecord.array;
|
|
2139
2279
|
const headerView = getDataView(headerArray);
|
|
2140
|
-
headerRecord.
|
|
2141
|
-
headerRecord.
|
|
2142
|
-
headerRecord.
|
|
2280
|
+
headerRecord.writeUint16(version);
|
|
2281
|
+
headerRecord.writeUint16(bitFlag);
|
|
2282
|
+
headerRecord.writeUint16(compressionMethod);
|
|
2143
2283
|
if (rawLastModDate === UNDEFINED_VALUE) {
|
|
2144
2284
|
const dateArray = new Uint32Array(1);
|
|
2145
2285
|
const dateView = getDataView(dateArray);
|
|
@@ -2147,20 +2287,20 @@ function getHeaderArrayData({
|
|
|
2147
2287
|
setUint16(dateView, 2, ((((lastModDate.getFullYear() - 1980) << 4) | (lastModDate.getMonth() + 1)) << 5) | lastModDate.getDate());
|
|
2148
2288
|
rawLastModDate = dateArray[0];
|
|
2149
2289
|
}
|
|
2150
|
-
headerRecord.
|
|
2290
|
+
headerRecord.writeUint32(rawLastModDate);
|
|
2151
2291
|
headerRecord.skip(4);
|
|
2152
2292
|
if (zip64CompressedSize || compressedSize !== UNDEFINED_VALUE) {
|
|
2153
|
-
headerRecord.
|
|
2293
|
+
headerRecord.writeUint32(zip64CompressedSize ? MAX_32_BITS : compressedSize);
|
|
2154
2294
|
} else {
|
|
2155
2295
|
headerRecord.skip(4);
|
|
2156
2296
|
}
|
|
2157
2297
|
if (zip64UncompressedSize || uncompressedSize !== UNDEFINED_VALUE) {
|
|
2158
|
-
headerRecord.
|
|
2298
|
+
headerRecord.writeUint32(zip64UncompressedSize ? MAX_32_BITS : uncompressedSize);
|
|
2159
2299
|
} else {
|
|
2160
2300
|
headerRecord.skip(4);
|
|
2161
2301
|
}
|
|
2162
|
-
headerRecord.
|
|
2163
|
-
headerRecord.
|
|
2302
|
+
headerRecord.writeUint16(getLength(rawFilename));
|
|
2303
|
+
headerRecord.writeUint16(extraFieldLength);
|
|
2164
2304
|
return {
|
|
2165
2305
|
headerArray,
|
|
2166
2306
|
headerView,
|