@zip.js/zip.js 2.8.51 → 2.8.53
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 +8 -3
- package/deno.json +1 -1
- package/dist/zip-core-external.js +241 -95
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +243 -94
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +564 -199
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +551 -194
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +564 -199
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +567 -198
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +567 -198
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +243 -94
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +243 -94
- package/dist/zip-native.min.js +1 -1
- package/dist/zip.js +243 -94
- package/dist/zip.min.js +1 -1
- package/eslint.config.mjs +1 -1
- package/index-native.cjs +567 -198
- package/index-native.min.js +1 -1
- package/index.cjs +567 -198
- package/index.d.cts +551 -45
- package/index.d.ts +551 -45
- package/index.min.js +1 -1
- package/lib/core/codec-worker-web.js +13 -4
- package/lib/core/codec-worker.js +2 -0
- package/lib/core/constants.js +9 -0
- package/lib/core/io.js +43 -4
- package/lib/core/options.js +2 -0
- package/lib/core/util/compatible-streams.js +3 -8
- package/lib/core/zip-entry.js +16 -0
- package/lib/core/zip-fs.js +236 -107
- package/lib/core/zip-reader.js +106 -40
- package/lib/core/zip-writer.js +171 -41
- package/lib/zip-core-writer.js +3 -0
- package/package.json +9 -7
package/dist/zip-fs-core.js
CHANGED
|
@@ -89,6 +89,8 @@
|
|
|
89
89
|
const FILE_ATTR_MSDOS_ARCHIVE_MASK = 0x20;
|
|
90
90
|
const FILE_ATTR_UNIX_TYPE_MASK = 0o170000;
|
|
91
91
|
const FILE_ATTR_UNIX_TYPE_DIR = 0o040000;
|
|
92
|
+
const FILE_ATTR_UNIX_TYPE_SYMLINK = 0o120000;
|
|
93
|
+
const FILE_ATTR_UNIX_TYPE_FILE = 0o100000;
|
|
92
94
|
const FILE_ATTR_UNIX_EXECUTABLE_MASK = 0o111;
|
|
93
95
|
const FILE_ATTR_UNIX_DEFAULT_MASK = 0o644;
|
|
94
96
|
const FILE_ATTR_UNIX_SETUID_MASK = 0o4000;
|
|
@@ -99,6 +101,9 @@
|
|
|
99
101
|
const VERSION_ZIP64 = 0x2D;
|
|
100
102
|
const VERSION_AES = 0x33;
|
|
101
103
|
|
|
104
|
+
const VERSION_MADE_BY_MSDOS = 0x0014;
|
|
105
|
+
const VERSION_MADE_BY_UNIX = 0x0300;
|
|
106
|
+
|
|
102
107
|
const DIRECTORY_SIGNATURE = "/";
|
|
103
108
|
|
|
104
109
|
const HEADER_SIZE = 30;
|
|
@@ -257,8 +262,6 @@
|
|
|
257
262
|
*/
|
|
258
263
|
|
|
259
264
|
|
|
260
|
-
const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
|
|
261
|
-
|
|
262
265
|
function toCompatibleReadable(readable) {
|
|
263
266
|
if (readable instanceof ReadableStream) {
|
|
264
267
|
return readable;
|
|
@@ -281,12 +284,9 @@
|
|
|
281
284
|
|
|
282
285
|
function streamToBlob(readable, contentType) {
|
|
283
286
|
readable = toCompatibleReadable(readable);
|
|
287
|
+
const blobOptions = contentType ? { type: contentType } : {};
|
|
284
288
|
if (responseSupportsGlobalReadable()) {
|
|
285
|
-
|
|
286
|
-
if (contentType) {
|
|
287
|
-
options.headers = [[HTTP_HEADER_CONTENT_TYPE, contentType]];
|
|
288
|
-
}
|
|
289
|
-
return new Response(readable, options).blob();
|
|
289
|
+
return new Response(readable).blob().then(blob => contentType ? new Blob([blob], blobOptions) : blob);
|
|
290
290
|
}
|
|
291
291
|
const chunks = [];
|
|
292
292
|
return readable
|
|
@@ -295,7 +295,7 @@
|
|
|
295
295
|
chunks.push(chunk);
|
|
296
296
|
}
|
|
297
297
|
}))
|
|
298
|
-
.then(() => new Blob(chunks,
|
|
298
|
+
.then(() => new Blob(chunks, blobOptions));
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
function responseSupportsGlobalReadable() {
|
|
@@ -396,8 +396,10 @@
|
|
|
396
396
|
async pull(controller) {
|
|
397
397
|
const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
|
|
398
398
|
const data = await readUint8Array(reader, offset + chunkOffset, dataSize);
|
|
399
|
-
|
|
400
|
-
|
|
399
|
+
if (data.length) {
|
|
400
|
+
controller.enqueue(data);
|
|
401
|
+
}
|
|
402
|
+
if ((chunkOffset + chunkSize >= size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
|
|
401
403
|
controller.close();
|
|
402
404
|
} else {
|
|
403
405
|
chunkOffset += chunkSize;
|
|
@@ -475,6 +477,7 @@
|
|
|
475
477
|
constructor(contentType) {
|
|
476
478
|
super();
|
|
477
479
|
Object.assign(this, {
|
|
480
|
+
contentType,
|
|
478
481
|
data: "data:" + (contentType || "") + ";base64,",
|
|
479
482
|
pending: []
|
|
480
483
|
});
|
|
@@ -576,6 +579,7 @@
|
|
|
576
579
|
return transformStream.writable;
|
|
577
580
|
}
|
|
578
581
|
});
|
|
582
|
+
writer.contentType = contentType;
|
|
579
583
|
writer.blob = streamToBlob(transformStream.readable, contentType);
|
|
580
584
|
writer.blob.catch(() => { });
|
|
581
585
|
}
|
|
@@ -592,6 +596,26 @@
|
|
|
592
596
|
}
|
|
593
597
|
}
|
|
594
598
|
|
|
599
|
+
function getTextSize(text) {
|
|
600
|
+
let size = 0;
|
|
601
|
+
for (let indexCharacter = 0; indexCharacter < text.length; indexCharacter++) {
|
|
602
|
+
const characterCode = text.charCodeAt(indexCharacter);
|
|
603
|
+
if (characterCode < 0x80) {
|
|
604
|
+
size += 1;
|
|
605
|
+
} else if (characterCode < 0x800) {
|
|
606
|
+
size += 2;
|
|
607
|
+
} else if (characterCode < 0xd800 || characterCode >= 0xe000) {
|
|
608
|
+
size += 3;
|
|
609
|
+
} else if (characterCode < 0xdc00 && (text.charCodeAt(indexCharacter + 1) & 0xfc00) == 0xdc00) {
|
|
610
|
+
size += 4;
|
|
611
|
+
indexCharacter++;
|
|
612
|
+
} else {
|
|
613
|
+
size += 3;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return size;
|
|
617
|
+
}
|
|
618
|
+
|
|
595
619
|
class TextWriter extends BlobWriter {
|
|
596
620
|
|
|
597
621
|
constructor(encoding) {
|
|
@@ -1069,9 +1093,8 @@
|
|
|
1069
1093
|
|
|
1070
1094
|
async init() {
|
|
1071
1095
|
const reader = this;
|
|
1072
|
-
const { readers } = reader;
|
|
1073
1096
|
reader.lastDiskNumber = 0;
|
|
1074
|
-
await Promise.all(readers.map(
|
|
1097
|
+
const readers = reader.readers = await Promise.all(reader.readers.map(initDiskReader));
|
|
1075
1098
|
reader.diskOffsets = readers.map(diskReader => {
|
|
1076
1099
|
const diskOffset = reader.size;
|
|
1077
1100
|
reader.size += diskReader.size;
|
|
@@ -1248,6 +1271,10 @@
|
|
|
1248
1271
|
}
|
|
1249
1272
|
}
|
|
1250
1273
|
|
|
1274
|
+
function ownsWritable(writer) {
|
|
1275
|
+
return Boolean(writer && writer.getData);
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1251
1278
|
function isHttpFamily(url) {
|
|
1252
1279
|
const { baseURI } = getConfiguration();
|
|
1253
1280
|
const { protocol } = new URL(url, baseURI);
|
|
@@ -1262,6 +1289,16 @@
|
|
|
1262
1289
|
}
|
|
1263
1290
|
}
|
|
1264
1291
|
|
|
1292
|
+
async function initDiskReader(diskReader) {
|
|
1293
|
+
diskReader = new GenericReader(diskReader);
|
|
1294
|
+
await initStream(diskReader);
|
|
1295
|
+
if (diskReader.size === UNDEFINED_VALUE || !diskReader.readUint8Array) {
|
|
1296
|
+
diskReader = new BlobReader(await streamToBlob(diskReader.readable));
|
|
1297
|
+
await initStream(diskReader);
|
|
1298
|
+
}
|
|
1299
|
+
return diskReader;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1265
1302
|
function readUint8Array(reader, offset, size) {
|
|
1266
1303
|
return reader.readUint8Array(offset, size);
|
|
1267
1304
|
}
|
|
@@ -3783,6 +3820,8 @@
|
|
|
3783
3820
|
const PROPERTY_NAME_RAW_CREATION_DATE = "rawCreationDate";
|
|
3784
3821
|
const PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES = "internalFileAttributes";
|
|
3785
3822
|
const PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES = "externalFileAttributes";
|
|
3823
|
+
const PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES = "internalFileAttribute";
|
|
3824
|
+
const PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES = "externalFileAttribute";
|
|
3786
3825
|
const PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW = "msdosAttributesRaw";
|
|
3787
3826
|
const PROPERTY_NAME_MSDOS_ATTRIBUTES = "msdosAttributes";
|
|
3788
3827
|
const PROPERTY_NAME_MS_DOS_COMPATIBLE = "msDosCompatible";
|
|
@@ -3793,6 +3832,7 @@
|
|
|
3793
3832
|
const PROPERTY_NAME_ZIPCRYPTO = "zipCrypto";
|
|
3794
3833
|
const PROPERTY_NAME_DIRECTORY = "directory";
|
|
3795
3834
|
const PROPERTY_NAME_EXECUTABLE = "executable";
|
|
3835
|
+
const PROPERTY_NAME_SYMLINK = "symlink";
|
|
3796
3836
|
const PROPERTY_NAME_COMPRESSION_METHOD = "compressionMethod";
|
|
3797
3837
|
const PROPERTY_NAME_SIGNATURE = "signature";
|
|
3798
3838
|
const PROPERTY_NAME_CRC32 = "crc32";
|
|
@@ -3808,6 +3848,10 @@
|
|
|
3808
3848
|
const PROPERTY_NAME_SETGID = "setgid";
|
|
3809
3849
|
const PROPERTY_NAME_STICKY = "sticky";
|
|
3810
3850
|
const PROPERTY_NAME_BITFLAG = "bitFlag";
|
|
3851
|
+
const PROPERTY_NAME_RAW_BITFLAG = "rawBitFlag";
|
|
3852
|
+
const PROPERTY_NAME_FILENAME_LENGTH = "filenameLength";
|
|
3853
|
+
const PROPERTY_NAME_EXTRA_FIELD_LENGTH = "extraFieldLength";
|
|
3854
|
+
const PROPERTY_NAME_UNIX_EXTERNAL_UPPER = "unixExternalUpper";
|
|
3811
3855
|
const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
|
|
3812
3856
|
const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
|
|
3813
3857
|
const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
|
|
@@ -3836,6 +3880,8 @@
|
|
|
3836
3880
|
PROPERTY_NAME_DISK_NUMBER_START,
|
|
3837
3881
|
PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES,
|
|
3838
3882
|
PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES,
|
|
3883
|
+
PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES,
|
|
3884
|
+
PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES,
|
|
3839
3885
|
PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW,
|
|
3840
3886
|
PROPERTY_NAME_MSDOS_ATTRIBUTES,
|
|
3841
3887
|
PROPERTY_NAME_MS_DOS_COMPATIBLE,
|
|
@@ -3846,6 +3892,7 @@
|
|
|
3846
3892
|
PROPERTY_NAME_ZIPCRYPTO,
|
|
3847
3893
|
PROPERTY_NAME_DIRECTORY,
|
|
3848
3894
|
PROPERTY_NAME_EXECUTABLE,
|
|
3895
|
+
PROPERTY_NAME_SYMLINK,
|
|
3849
3896
|
PROPERTY_NAME_COMPRESSION_METHOD,
|
|
3850
3897
|
PROPERTY_NAME_SIGNATURE,
|
|
3851
3898
|
PROPERTY_NAME_CRC32,
|
|
@@ -3857,10 +3904,14 @@
|
|
|
3857
3904
|
PROPERTY_NAME_UID,
|
|
3858
3905
|
PROPERTY_NAME_GID,
|
|
3859
3906
|
PROPERTY_NAME_UNIX_MODE,
|
|
3907
|
+
PROPERTY_NAME_UNIX_EXTERNAL_UPPER,
|
|
3860
3908
|
PROPERTY_NAME_SETUID,
|
|
3861
3909
|
PROPERTY_NAME_SETGID,
|
|
3862
3910
|
PROPERTY_NAME_STICKY,
|
|
3863
3911
|
PROPERTY_NAME_BITFLAG,
|
|
3912
|
+
PROPERTY_NAME_RAW_BITFLAG,
|
|
3913
|
+
PROPERTY_NAME_FILENAME_LENGTH,
|
|
3914
|
+
PROPERTY_NAME_EXTRA_FIELD_LENGTH,
|
|
3864
3915
|
PROPERTY_NAME_FILENAME_UTF8,
|
|
3865
3916
|
PROPERTY_NAME_COMMENT_UTF8,
|
|
3866
3917
|
PROPERTY_NAME_RAW_EXTRA_FIELD,
|
|
@@ -3922,6 +3973,7 @@
|
|
|
3922
3973
|
const OPTION_CHECK_OVERLAPPING_ENTRY_ONLY = "checkOverlappingEntryOnly";
|
|
3923
3974
|
const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
|
|
3924
3975
|
const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
|
|
3976
|
+
const OPTION_CHECK_LOCAL_DIRECTORY = "checkLocalDirectory";
|
|
3925
3977
|
const OPTION_CHECK_SIGNATURE = "checkSignature";
|
|
3926
3978
|
const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
3927
3979
|
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
@@ -4053,7 +4105,7 @@
|
|
|
4053
4105
|
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
4054
4106
|
throw new Error(ERR_BAD_FORMAT);
|
|
4055
4107
|
}
|
|
4056
|
-
const strictness = getStrictness(
|
|
4108
|
+
const strictness = getStrictness(options, zipReader.options);
|
|
4057
4109
|
const checkAmbiguity = strictness == STRICTNESS_STRICT;
|
|
4058
4110
|
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
4059
4111
|
const maxAppendedDataSize = getMaxAppendedDataSize(getOptionValue$1(zipReader, options, OPTION_MAX_APPENDED_DATA_SIZE), strictness);
|
|
@@ -4275,6 +4327,7 @@
|
|
|
4275
4327
|
index: indexFile,
|
|
4276
4328
|
versionMadeBy,
|
|
4277
4329
|
msDosCompatible,
|
|
4330
|
+
zip64: false,
|
|
4278
4331
|
compressedSize: 0,
|
|
4279
4332
|
uncompressedSize: 0,
|
|
4280
4333
|
commentLength,
|
|
@@ -4308,15 +4361,18 @@
|
|
|
4308
4361
|
const setuid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETUID_MASK);
|
|
4309
4362
|
const setgid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETGID_MASK);
|
|
4310
4363
|
const sticky = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_STICKY_MASK);
|
|
4311
|
-
const
|
|
4364
|
+
const unixType = fileEntry.unixMode === UNDEFINED_VALUE ? unixExternalUpper : fileEntry.unixMode;
|
|
4365
|
+
const symlink = (unixType & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK;
|
|
4366
|
+
const executable = !symlink && ((fileEntry.unixMode !== UNDEFINED_VALUE)
|
|
4312
4367
|
? ((fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)
|
|
4313
|
-
: (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0));
|
|
4368
|
+
: (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)));
|
|
4314
4369
|
const modeIsDir = fileEntry.unixMode !== UNDEFINED_VALUE && ((fileEntry.unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
|
|
4315
4370
|
const upperIsDir = ((unixExternalUpper & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
|
|
4316
4371
|
Object.assign(fileEntry, {
|
|
4317
4372
|
setuid,
|
|
4318
4373
|
setgid,
|
|
4319
4374
|
sticky,
|
|
4375
|
+
symlink,
|
|
4320
4376
|
unixExternalUpper,
|
|
4321
4377
|
internalFileAttribute: fileEntry.internalFileAttributes,
|
|
4322
4378
|
externalFileAttribute: fileEntry.externalFileAttributes,
|
|
@@ -4382,6 +4438,10 @@
|
|
|
4382
4438
|
}
|
|
4383
4439
|
|
|
4384
4440
|
async close() {
|
|
4441
|
+
const { reader } = this;
|
|
4442
|
+
if (!reader.readUint8Array && reader.readable && !reader.readable.locked) {
|
|
4443
|
+
await reader.readable.cancel();
|
|
4444
|
+
}
|
|
4385
4445
|
}
|
|
4386
4446
|
}
|
|
4387
4447
|
|
|
@@ -4438,9 +4498,12 @@
|
|
|
4438
4498
|
extraFieldLength,
|
|
4439
4499
|
filenameLength
|
|
4440
4500
|
} = localDirectory;
|
|
4441
|
-
const
|
|
4501
|
+
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
4502
|
+
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
4503
|
+
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
4504
|
+
const checkLocalFilename = getCheckLocalFilename(checkLocalDirectoryOption, entryStrictness);
|
|
4442
4505
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
4443
|
-
if (
|
|
4506
|
+
if (checkLocalFilename && (filenameLength || extraFieldLength)) {
|
|
4444
4507
|
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
4445
4508
|
rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
|
|
4446
4509
|
localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
|
|
@@ -4449,17 +4512,26 @@
|
|
|
4449
4512
|
await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
|
|
4450
4513
|
EMPTY_UINT8_ARRAY;
|
|
4451
4514
|
}
|
|
4515
|
+
if (checkLocalFilename) {
|
|
4516
|
+
localDirectory.rawFilename = rawLocalFilename;
|
|
4517
|
+
}
|
|
4452
4518
|
readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
|
|
4453
|
-
if (
|
|
4454
|
-
|
|
4519
|
+
if (checkLocalDirectory) {
|
|
4520
|
+
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
|
|
4455
4521
|
}
|
|
4456
|
-
const { lastAccessDate, creationDate } = localDirectory;
|
|
4522
|
+
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
4457
4523
|
if (lastAccessDate) {
|
|
4458
4524
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
4459
4525
|
}
|
|
4460
4526
|
if (creationDate) {
|
|
4461
4527
|
fileEntry.creationDate = creationDate;
|
|
4462
4528
|
}
|
|
4529
|
+
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
4530
|
+
fileEntry.uid = uid;
|
|
4531
|
+
}
|
|
4532
|
+
if (gid !== UNDEFINED_VALUE && fileEntry.gid === UNDEFINED_VALUE) {
|
|
4533
|
+
fileEntry.gid = gid;
|
|
4534
|
+
}
|
|
4463
4535
|
const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
|
|
4464
4536
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
4465
4537
|
if (!passThrough) {
|
|
@@ -4566,7 +4638,7 @@
|
|
|
4566
4638
|
throw error;
|
|
4567
4639
|
}
|
|
4568
4640
|
} finally {
|
|
4569
|
-
const preventClose = getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
|
|
4641
|
+
const preventClose = !ownsWritable(writer) && getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
|
|
4570
4642
|
if (!preventClose && writable && !writable.locked) {
|
|
4571
4643
|
const writableWriter = writable.getWriter();
|
|
4572
4644
|
if (abortError) {
|
|
@@ -4695,10 +4767,12 @@
|
|
|
4695
4767
|
directory.extraFieldNTFS = extraFieldNTFS;
|
|
4696
4768
|
}
|
|
4697
4769
|
const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
|
|
4770
|
+
let unixIdsRead;
|
|
4698
4771
|
if (extraFieldUnix) {
|
|
4699
|
-
readExtraFieldUnix(extraFieldUnix, directory, false);
|
|
4772
|
+
unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
|
|
4700
4773
|
directory.extraFieldUnix = extraFieldUnix;
|
|
4701
|
-
}
|
|
4774
|
+
}
|
|
4775
|
+
if (!unixIdsRead) {
|
|
4702
4776
|
const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
|
|
4703
4777
|
if (extraFieldInfoZip) {
|
|
4704
4778
|
readExtraFieldUnix(extraFieldInfoZip, directory, true);
|
|
@@ -4801,7 +4875,7 @@
|
|
|
4801
4875
|
const creationDate = getDateNTFS(rawCreationDate);
|
|
4802
4876
|
const extraFieldData = { lastModDate, lastAccessDate, creationDate };
|
|
4803
4877
|
Object.assign(extraFieldNTFS, extraFieldData);
|
|
4804
|
-
Object.assign(directory, extraFieldData);
|
|
4878
|
+
Object.assign(directory, extraFieldData, { rawLastAccessDate, rawCreationDate });
|
|
4805
4879
|
}
|
|
4806
4880
|
}
|
|
4807
4881
|
|
|
@@ -4810,8 +4884,8 @@
|
|
|
4810
4884
|
return;
|
|
4811
4885
|
}
|
|
4812
4886
|
const extraFieldView = getDataView(extraField.data);
|
|
4813
|
-
const lastAccessDate = new Date(getUint32(extraFieldView, 0) * 1000);
|
|
4814
|
-
const lastModDate = new Date(getUint32(extraFieldView, 4) * 1000);
|
|
4887
|
+
const lastAccessDate = new Date((getUint32(extraFieldView, 0) | 0) * 1000);
|
|
4888
|
+
const lastModDate = new Date((getUint32(extraFieldView, 4) | 0) * 1000);
|
|
4815
4889
|
const extraFieldData = { lastAccessDate, lastModDate };
|
|
4816
4890
|
if (extraField.data.length >= 12) {
|
|
4817
4891
|
extraFieldData.uid = getUint16(extraFieldView, 8);
|
|
@@ -4845,6 +4919,7 @@
|
|
|
4845
4919
|
if (gid !== UNDEFINED_VALUE) {
|
|
4846
4920
|
directory.gid = gid;
|
|
4847
4921
|
}
|
|
4922
|
+
return uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE;
|
|
4848
4923
|
} catch {
|
|
4849
4924
|
// ignored
|
|
4850
4925
|
}
|
|
@@ -4917,26 +4992,25 @@
|
|
|
4917
4992
|
}
|
|
4918
4993
|
if (dataDescriptorLength) {
|
|
4919
4994
|
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
|
|
4920
|
-
const
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
if (extraFieldZip64) {
|
|
4927
|
-
readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
|
|
4928
|
-
readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
|
|
4929
|
-
} else {
|
|
4930
|
-
readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
|
|
4931
|
-
readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
|
|
4932
|
-
}
|
|
4933
|
-
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
|
|
4995
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
4996
|
+
let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
4997
|
+
getUint32(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
4998
|
+
if (signature) {
|
|
4999
|
+
const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
|
|
5000
|
+
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
|
|
4934
5001
|
if (matchCrc32 &&
|
|
4935
|
-
|
|
4936
|
-
|
|
5002
|
+
signedDataDescriptor.compressedSize == compressedSize &&
|
|
5003
|
+
signedDataDescriptor.uncompressedSize == uncompressedSize) {
|
|
4937
5004
|
dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
5005
|
+
} else {
|
|
5006
|
+
signature = false;
|
|
4938
5007
|
}
|
|
4939
5008
|
}
|
|
5009
|
+
if (dataDescriptorArray.length >= dataDescriptorLength) {
|
|
5010
|
+
const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
|
|
5011
|
+
localDataDescriptor.signature = signature;
|
|
5012
|
+
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
5013
|
+
}
|
|
4940
5014
|
}
|
|
4941
5015
|
const range = {
|
|
4942
5016
|
start: offset,
|
|
@@ -4953,6 +5027,20 @@
|
|
|
4953
5027
|
readRanges.set(index, range);
|
|
4954
5028
|
}
|
|
4955
5029
|
|
|
5030
|
+
function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
|
|
5031
|
+
const crc32 = getUint32(dataDescriptorView, offset);
|
|
5032
|
+
let compressedSize;
|
|
5033
|
+
let uncompressedSize;
|
|
5034
|
+
if (extraFieldZip64) {
|
|
5035
|
+
compressedSize = getBigUint64(dataDescriptorView, offset + 4);
|
|
5036
|
+
uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
|
|
5037
|
+
} else {
|
|
5038
|
+
compressedSize = getUint32(dataDescriptorView, offset + 4);
|
|
5039
|
+
uncompressedSize = getUint32(dataDescriptorView, offset + 8);
|
|
5040
|
+
}
|
|
5041
|
+
return { crc32, compressedSize, uncompressedSize };
|
|
5042
|
+
}
|
|
5043
|
+
|
|
4956
5044
|
function getDiskOffset$1(reader, diskNumber) {
|
|
4957
5045
|
return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
|
|
4958
5046
|
}
|
|
@@ -4961,14 +5049,40 @@
|
|
|
4961
5049
|
return value === STRICTNESS_STRICT || value === STRICTNESS_BALANCED || value === STRICTNESS_TOLERANT;
|
|
4962
5050
|
}
|
|
4963
5051
|
|
|
4964
|
-
function getStrictness(
|
|
4965
|
-
|
|
4966
|
-
|
|
5052
|
+
function getStrictness(options, inheritedOptions) {
|
|
5053
|
+
return resolveStrictness(options, resolveStrictness(inheritedOptions, STRICTNESS_BALANCED));
|
|
5054
|
+
}
|
|
5055
|
+
|
|
5056
|
+
function resolveStrictness(options, inheritedStrictness) {
|
|
5057
|
+
const strictness = options[OPTION_STRICTNESS];
|
|
5058
|
+
if (strictness !== UNDEFINED_VALUE) {
|
|
5059
|
+
if (!isStrictnessValue(strictness)) {
|
|
5060
|
+
throw new Error(ERR_INVALID_STRICTNESS);
|
|
5061
|
+
}
|
|
5062
|
+
return strictness;
|
|
5063
|
+
}
|
|
5064
|
+
const checkAmbiguity = options[OPTION_CHECK_AMBIGUITY];
|
|
5065
|
+
if (checkAmbiguity === UNDEFINED_VALUE) {
|
|
5066
|
+
return inheritedStrictness;
|
|
5067
|
+
}
|
|
5068
|
+
if (checkAmbiguity) {
|
|
5069
|
+
return STRICTNESS_STRICT;
|
|
5070
|
+
}
|
|
5071
|
+
return inheritedStrictness == STRICTNESS_TOLERANT ? STRICTNESS_TOLERANT : STRICTNESS_BALANCED;
|
|
5072
|
+
}
|
|
5073
|
+
|
|
5074
|
+
function getCheckLocalDirectory(checkLocalDirectory, strictness) {
|
|
5075
|
+
if (checkLocalDirectory === UNDEFINED_VALUE) {
|
|
5076
|
+
return strictness != STRICTNESS_TOLERANT;
|
|
4967
5077
|
}
|
|
4968
|
-
|
|
4969
|
-
|
|
5078
|
+
return Boolean(checkLocalDirectory);
|
|
5079
|
+
}
|
|
5080
|
+
|
|
5081
|
+
function getCheckLocalFilename(checkLocalFilename, strictness) {
|
|
5082
|
+
if (checkLocalFilename === UNDEFINED_VALUE) {
|
|
5083
|
+
return strictness == STRICTNESS_STRICT;
|
|
4970
5084
|
}
|
|
4971
|
-
return
|
|
5085
|
+
return Boolean(checkLocalFilename);
|
|
4972
5086
|
}
|
|
4973
5087
|
|
|
4974
5088
|
function getFilenameValidation(filenameValidation, strictness) {
|
|
@@ -5116,10 +5230,11 @@
|
|
|
5116
5230
|
return UNDEFINED_VALUE;
|
|
5117
5231
|
}
|
|
5118
5232
|
|
|
5119
|
-
function
|
|
5233
|
+
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
|
|
5120
5234
|
const { rawFilename } = zipEntry;
|
|
5121
|
-
if (
|
|
5122
|
-
rawLocalFilename.
|
|
5235
|
+
if (checkLocalFilename &&
|
|
5236
|
+
(rawLocalFilename.length != rawFilename.length ||
|
|
5237
|
+
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
5123
5238
|
throwAmbiguousArchive("mismatched local file header (filename)");
|
|
5124
5239
|
}
|
|
5125
5240
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
@@ -5235,11 +5350,13 @@
|
|
|
5235
5350
|
|
|
5236
5351
|
const ERR_DUPLICATED_NAME = "File already exists";
|
|
5237
5352
|
const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
|
|
5353
|
+
const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
|
|
5238
5354
|
const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
|
|
5239
5355
|
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
5240
5356
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
5241
5357
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
5242
5358
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
5359
|
+
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
5243
5360
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
|
|
5244
5361
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
5245
5362
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
@@ -5249,6 +5366,7 @@
|
|
|
5249
5366
|
const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
|
|
5250
5367
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
5251
5368
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
5369
|
+
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
5252
5370
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
5253
5371
|
const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
|
|
5254
5372
|
const ERR_INVALID_UID = "Invalid uid (must be integer 0..2^32-1)";
|
|
@@ -5301,6 +5419,10 @@
|
|
|
5301
5419
|
}
|
|
5302
5420
|
reader = new GenericReader(reader);
|
|
5303
5421
|
await initStream(reader);
|
|
5422
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
5423
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
5424
|
+
await initStream(reader);
|
|
5425
|
+
}
|
|
5304
5426
|
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5305
5427
|
const zipReader$1 = new ZipReader(reader.readable);
|
|
5306
5428
|
const entries = await zipReader$1.getEntries();
|
|
@@ -5449,6 +5571,9 @@
|
|
|
5449
5571
|
const zipWriter = this;
|
|
5450
5572
|
const { pendingAddFileCalls, writer } = this;
|
|
5451
5573
|
const { writable } = writer;
|
|
5574
|
+
if (!(comment instanceof Uint8Array)) {
|
|
5575
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
5576
|
+
}
|
|
5452
5577
|
if (getLength(comment) > MAX_16_BITS) {
|
|
5453
5578
|
throw new Error(ERR_INVALID_COMMENT);
|
|
5454
5579
|
}
|
|
@@ -5456,7 +5581,7 @@
|
|
|
5456
5581
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
5457
5582
|
}
|
|
5458
5583
|
await closeFile(zipWriter, comment, options);
|
|
5459
|
-
const preventClose = getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
5584
|
+
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
5460
5585
|
if (!preventClose) {
|
|
5461
5586
|
await writable.getWriter().close();
|
|
5462
5587
|
}
|
|
@@ -5483,8 +5608,6 @@
|
|
|
5483
5608
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
5484
5609
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
5485
5610
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
5486
|
-
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
5487
|
-
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
5488
5611
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
5489
5612
|
crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
|
|
5490
5613
|
offset: zipWriter.offset - diskOffset,
|
|
@@ -5498,14 +5621,20 @@
|
|
|
5498
5621
|
zipWriter.files.delete(name);
|
|
5499
5622
|
throw error;
|
|
5500
5623
|
}
|
|
5501
|
-
Object.assign(fileEntry, {
|
|
5624
|
+
Object.assign(fileEntry, {
|
|
5625
|
+
name,
|
|
5626
|
+
comment,
|
|
5627
|
+
extraField,
|
|
5628
|
+
[PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
|
|
5629
|
+
[PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
|
|
5630
|
+
});
|
|
5502
5631
|
return new Entry(fileEntry);
|
|
5503
5632
|
}
|
|
5504
5633
|
|
|
5505
5634
|
function resolveAttributes(zipWriter, name, options) {
|
|
5506
5635
|
name = name.trim();
|
|
5507
5636
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
5508
|
-
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ?
|
|
5637
|
+
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
5509
5638
|
const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
|
|
5510
5639
|
const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
|
|
5511
5640
|
const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
|
|
@@ -5539,7 +5668,7 @@
|
|
|
5539
5668
|
const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
|
|
5540
5669
|
if (hasUnixMetadata) {
|
|
5541
5670
|
msDosCompatible = false;
|
|
5542
|
-
versionMadeBy = (versionMadeBy &
|
|
5671
|
+
versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
|
|
5543
5672
|
} else if (hasMsDosProvided) {
|
|
5544
5673
|
msDosCompatible = true;
|
|
5545
5674
|
versionMadeBy = (versionMadeBy & MAX_8_BITS);
|
|
@@ -5553,7 +5682,7 @@
|
|
|
5553
5682
|
if (versionMadeBy > MAX_16_BITS) {
|
|
5554
5683
|
throw new Error(ERR_INVALID_VERSION);
|
|
5555
5684
|
}
|
|
5556
|
-
let externalFileAttributes =
|
|
5685
|
+
let externalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES);
|
|
5557
5686
|
const externalFileAttributesProvided = externalFileAttributes !== UNDEFINED_VALUE;
|
|
5558
5687
|
if (!externalFileAttributesProvided) {
|
|
5559
5688
|
externalFileAttributes = 0;
|
|
@@ -5579,11 +5708,10 @@
|
|
|
5579
5708
|
externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
|
|
5580
5709
|
}
|
|
5581
5710
|
}
|
|
5582
|
-
let unixExternalUpper;
|
|
5583
5711
|
if (!msDosCompatible) {
|
|
5584
5712
|
const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
|
|
5585
|
-
|
|
5586
|
-
unixMode = unixMode === UNDEFINED_VALUE ?
|
|
5713
|
+
const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
5714
|
+
unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
|
|
5587
5715
|
if (setuid) {
|
|
5588
5716
|
unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
|
|
5589
5717
|
} else {
|
|
@@ -5601,7 +5729,9 @@
|
|
|
5601
5729
|
}
|
|
5602
5730
|
if (!externalFileAttributesProvided || unixModeProvided) {
|
|
5603
5731
|
if (directory) {
|
|
5604
|
-
unixMode
|
|
5732
|
+
unixMode = (unixMode & ~FILE_ATTR_UNIX_TYPE_MASK) | FILE_ATTR_UNIX_TYPE_DIR;
|
|
5733
|
+
} else if (!(unixMode & FILE_ATTR_UNIX_TYPE_MASK)) {
|
|
5734
|
+
unixMode |= FILE_ATTR_UNIX_TYPE_FILE;
|
|
5605
5735
|
}
|
|
5606
5736
|
externalFileAttributes = ((unixMode & MAX_16_BITS) << 16) | (externalFileAttributes & MAX_16_BITS);
|
|
5607
5737
|
}
|
|
@@ -5610,17 +5740,20 @@
|
|
|
5610
5740
|
if (hasMsDosProvided) {
|
|
5611
5741
|
externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
|
|
5612
5742
|
}
|
|
5743
|
+
const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
5744
|
+
const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
|
|
5613
5745
|
return {
|
|
5614
5746
|
name,
|
|
5615
5747
|
resolvedOptions: {
|
|
5616
5748
|
versionMadeBy,
|
|
5617
|
-
msDosCompatible,
|
|
5749
|
+
msDosCompatible: Boolean(msDosCompatible),
|
|
5618
5750
|
externalFileAttributes,
|
|
5619
5751
|
unixExternalUpper,
|
|
5620
5752
|
uid,
|
|
5621
5753
|
gid,
|
|
5622
5754
|
unixMode,
|
|
5623
5755
|
unixExtraFieldType,
|
|
5756
|
+
symlink,
|
|
5624
5757
|
setuid,
|
|
5625
5758
|
setgid,
|
|
5626
5759
|
sticky,
|
|
@@ -5654,15 +5787,12 @@
|
|
|
5654
5787
|
const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
5655
5788
|
const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
5656
5789
|
const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
5657
|
-
const internalFileAttributes =
|
|
5790
|
+
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
5658
5791
|
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
5664
|
-
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
5665
|
-
}
|
|
5792
|
+
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
5793
|
+
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
5794
|
+
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
5795
|
+
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
5666
5796
|
}
|
|
5667
5797
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
5668
5798
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
@@ -5775,14 +5905,24 @@
|
|
|
5775
5905
|
}
|
|
5776
5906
|
|
|
5777
5907
|
async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
|
|
5908
|
+
if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
|
|
5909
|
+
throw new Error(ERR_UNDEFINED_READER);
|
|
5910
|
+
}
|
|
5911
|
+
let contentSize;
|
|
5912
|
+
if (reader) {
|
|
5913
|
+
reader = new GenericReader(reader);
|
|
5914
|
+
await initStream(reader);
|
|
5915
|
+
({ size: contentSize } = reader);
|
|
5916
|
+
}
|
|
5917
|
+
return Object.assign({ reader }, resolveEntrySizes(zipWriter, Boolean(reader), contentSize, metadata, options));
|
|
5918
|
+
}
|
|
5919
|
+
|
|
5920
|
+
function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
|
|
5778
5921
|
const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
|
|
5779
5922
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
5780
5923
|
let maximumCompressedSize = 0;
|
|
5781
5924
|
let uncompressedSize = 0;
|
|
5782
|
-
if (passThrough) {
|
|
5783
|
-
if (!reader) {
|
|
5784
|
-
throw new Error(ERR_UNDEFINED_READER);
|
|
5785
|
-
}
|
|
5925
|
+
if (passThrough && hasContent) {
|
|
5786
5926
|
uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
|
|
5787
5927
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
5788
5928
|
throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
|
|
@@ -5790,29 +5930,30 @@
|
|
|
5790
5930
|
}
|
|
5791
5931
|
const zip64Enabled = zip64 === true;
|
|
5792
5932
|
const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
|
|
5793
|
-
|
|
5794
|
-
|
|
5933
|
+
if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
|
|
5934
|
+
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
|
|
5935
|
+
}
|
|
5936
|
+
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
|
|
5937
|
+
if (!hasContent) {
|
|
5795
5938
|
level = 0;
|
|
5796
5939
|
compressionMethod = COMPRESSION_METHOD_STORE;
|
|
5797
5940
|
}
|
|
5798
5941
|
const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
5799
|
-
if (
|
|
5800
|
-
reader = new GenericReader(reader);
|
|
5801
|
-
await initStream(reader);
|
|
5942
|
+
if (hasContent) {
|
|
5802
5943
|
if (!passThrough) {
|
|
5803
|
-
if (
|
|
5944
|
+
if (contentSize === UNDEFINED_VALUE) {
|
|
5804
5945
|
dataDescriptor = true;
|
|
5805
5946
|
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
5806
5947
|
zip64 = true;
|
|
5807
5948
|
uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
|
|
5808
5949
|
}
|
|
5809
5950
|
} else {
|
|
5810
|
-
options.uncompressedSize = uncompressedSize =
|
|
5811
|
-
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize) + encryptionOverhead;
|
|
5951
|
+
options.uncompressedSize = uncompressedSize = contentSize;
|
|
5952
|
+
maximumCompressedSize = (isCompressed(compressionMethod, level) ? getMaximumCompressedSize(uncompressedSize) : uncompressedSize) + encryptionOverhead;
|
|
5812
5953
|
}
|
|
5813
5954
|
} else {
|
|
5814
5955
|
options.uncompressedSize = uncompressedSize;
|
|
5815
|
-
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize) + encryptionOverhead;
|
|
5956
|
+
maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
|
|
5816
5957
|
}
|
|
5817
5958
|
}
|
|
5818
5959
|
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
@@ -5826,7 +5967,7 @@
|
|
|
5826
5967
|
}
|
|
5827
5968
|
zip64 = zip64 || false;
|
|
5828
5969
|
return {
|
|
5829
|
-
|
|
5970
|
+
maximumCompressedSize,
|
|
5830
5971
|
resolvedOptions: {
|
|
5831
5972
|
dataDescriptor,
|
|
5832
5973
|
zip64,
|
|
@@ -5840,6 +5981,81 @@
|
|
|
5840
5981
|
};
|
|
5841
5982
|
}
|
|
5842
5983
|
|
|
5984
|
+
async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
|
|
5985
|
+
const zipWriter = { options: writerOptions, config: getConfiguration() };
|
|
5986
|
+
if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
|
|
5987
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
5988
|
+
}
|
|
5989
|
+
if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
|
|
5990
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
5991
|
+
}
|
|
5992
|
+
const commentLength = getLength(comment);
|
|
5993
|
+
if (commentLength > MAX_16_BITS) {
|
|
5994
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
5995
|
+
}
|
|
5996
|
+
const usdz = writerOptions[OPTION_USDZ];
|
|
5997
|
+
const files = new Map();
|
|
5998
|
+
let layoutDependsOnWriteOrder = Boolean(usdz);
|
|
5999
|
+
let offset = 0;
|
|
6000
|
+
for (const entry of entries) {
|
|
6001
|
+
let { name } = entry;
|
|
6002
|
+
const { size } = entry;
|
|
6003
|
+
const options = Object.assign({}, entry.options);
|
|
6004
|
+
name = name.trim();
|
|
6005
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6006
|
+
name += DIRECTORY_SIGNATURE;
|
|
6007
|
+
}
|
|
6008
|
+
const attributesInfo = resolveAttributes(zipWriter, name, options);
|
|
6009
|
+
({ name } = attributesInfo);
|
|
6010
|
+
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
6011
|
+
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
6012
|
+
!metadata.passThrough && !(await supportsDeflate(zipWriter.config))) {
|
|
6013
|
+
metadata.level = 0;
|
|
6014
|
+
}
|
|
6015
|
+
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
6016
|
+
if (hasContent && size === UNDEFINED_VALUE) {
|
|
6017
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
6018
|
+
}
|
|
6019
|
+
const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
|
|
6020
|
+
if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
|
|
6021
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
6022
|
+
}
|
|
6023
|
+
const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
|
|
6024
|
+
const headerInfo = getHeaderInfo(entryOptions);
|
|
6025
|
+
const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
|
|
6026
|
+
const entryInfo = {
|
|
6027
|
+
headerInfo,
|
|
6028
|
+
metadataSize: getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray)
|
|
6029
|
+
};
|
|
6030
|
+
if (usdz) {
|
|
6031
|
+
appendExtraFieldUSDZ(entryInfo, offset);
|
|
6032
|
+
}
|
|
6033
|
+
const compressedSize = hasContent ? maximumCompressedSize : 0;
|
|
6034
|
+
if (offset >= MAX_32_BITS) {
|
|
6035
|
+
layoutDependsOnWriteOrder = true;
|
|
6036
|
+
}
|
|
6037
|
+
files.set(name, Object.assign({}, entryOptions, headerInfo, {
|
|
6038
|
+
offset,
|
|
6039
|
+
diskNumberStart: 0,
|
|
6040
|
+
compressedSize
|
|
6041
|
+
}));
|
|
6042
|
+
offset += entryInfo.metadataSize + compressedSize;
|
|
6043
|
+
}
|
|
6044
|
+
if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
|
|
6045
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
6046
|
+
}
|
|
6047
|
+
const directoryDataLength = createDirectoryRecords(files);
|
|
6048
|
+
let zip64 = getOptionValue(zipWriter, writerOptions, PROPERTY_NAME_ZIP64);
|
|
6049
|
+
if (offset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || files.size >= MAX_16_BITS) {
|
|
6050
|
+
if (zip64 === false) {
|
|
6051
|
+
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
6052
|
+
} else {
|
|
6053
|
+
zip64 = true;
|
|
6054
|
+
}
|
|
6055
|
+
}
|
|
6056
|
+
return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
6057
|
+
}
|
|
6058
|
+
|
|
5843
6059
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
5844
6060
|
const {
|
|
5845
6061
|
files,
|
|
@@ -6054,6 +6270,7 @@
|
|
|
6054
6270
|
uid,
|
|
6055
6271
|
gid,
|
|
6056
6272
|
unixMode,
|
|
6273
|
+
symlink,
|
|
6057
6274
|
setuid,
|
|
6058
6275
|
setgid,
|
|
6059
6276
|
sticky,
|
|
@@ -6090,6 +6307,7 @@
|
|
|
6090
6307
|
uid,
|
|
6091
6308
|
gid,
|
|
6092
6309
|
unixMode,
|
|
6310
|
+
symlink: Boolean(symlink),
|
|
6093
6311
|
setuid,
|
|
6094
6312
|
setgid,
|
|
6095
6313
|
sticky,
|
|
@@ -6170,8 +6388,8 @@
|
|
|
6170
6388
|
rawLastModDate,
|
|
6171
6389
|
creationDate,
|
|
6172
6390
|
lastAccessDate,
|
|
6173
|
-
encrypted,
|
|
6174
|
-
zipCrypto,
|
|
6391
|
+
encrypted: Boolean(encrypted),
|
|
6392
|
+
zipCrypto: Boolean(zipCrypto),
|
|
6175
6393
|
size: metadataSize + compressedSize,
|
|
6176
6394
|
compressionMethod,
|
|
6177
6395
|
version,
|
|
@@ -6211,9 +6429,7 @@
|
|
|
6211
6429
|
crc32
|
|
6212
6430
|
} = options;
|
|
6213
6431
|
let { version, compressionMethod } = options;
|
|
6214
|
-
const compressed = !directory && (compressionMethod
|
|
6215
|
-
? (level === UNDEFINED_VALUE || level > 0)
|
|
6216
|
-
: compressionMethod !== COMPRESSION_METHOD_STORE);
|
|
6432
|
+
const compressed = !directory && isCompressed(compressionMethod, level);
|
|
6217
6433
|
let rawLocalExtraFieldZip64;
|
|
6218
6434
|
const uncompressedFile = passThrough || !compressed;
|
|
6219
6435
|
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || uncompressedFile));
|
|
@@ -6900,6 +7116,16 @@
|
|
|
6900
7116
|
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
6901
7117
|
}
|
|
6902
7118
|
|
|
7119
|
+
function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
|
|
7120
|
+
const value = getAliasedValue(options, name, deprecatedName);
|
|
7121
|
+
const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
|
|
7122
|
+
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
7123
|
+
}
|
|
7124
|
+
|
|
7125
|
+
function getAliasedValue(options, name, deprecatedName) {
|
|
7126
|
+
return options[name] === UNDEFINED_VALUE ? options[deprecatedName] : options[name];
|
|
7127
|
+
}
|
|
7128
|
+
|
|
6903
7129
|
function getNumberOptionValue(zipWriter, options, name, defaultValue) {
|
|
6904
7130
|
return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
|
|
6905
7131
|
}
|
|
@@ -6912,6 +7138,12 @@
|
|
|
6912
7138
|
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
6913
7139
|
}
|
|
6914
7140
|
|
|
7141
|
+
function isCompressed(compressionMethod, level) {
|
|
7142
|
+
return compressionMethod === UNDEFINED_VALUE
|
|
7143
|
+
? (level === UNDEFINED_VALUE || level > 0)
|
|
7144
|
+
: compressionMethod !== COMPRESSION_METHOD_STORE;
|
|
7145
|
+
}
|
|
7146
|
+
|
|
6915
7147
|
function setUint8(view, offset, value) {
|
|
6916
7148
|
view.setUint8(offset, value);
|
|
6917
7149
|
}
|
|
@@ -7042,6 +7274,7 @@
|
|
|
7042
7274
|
|
|
7043
7275
|
const ERR_ENTRY_EXISTS = "Entry filename already exists";
|
|
7044
7276
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
7277
|
+
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
7045
7278
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
7046
7279
|
const ERR_ABORTED = "The operation was aborted";
|
|
7047
7280
|
const ABORT_ERROR_NAME = "AbortError";
|
|
@@ -7079,6 +7312,7 @@
|
|
|
7079
7312
|
parent,
|
|
7080
7313
|
children: [],
|
|
7081
7314
|
uncompressedSize: params.uncompressedSize || 0,
|
|
7315
|
+
undeterminedSize: params.undeterminedSize || params.uncompressedSize === UNDEFINED_VALUE,
|
|
7082
7316
|
passThrough: params.passThrough
|
|
7083
7317
|
});
|
|
7084
7318
|
if (parent || !fs.root) {
|
|
@@ -7146,16 +7380,17 @@
|
|
|
7146
7380
|
|
|
7147
7381
|
async getData(writer, options = {}) {
|
|
7148
7382
|
const zipEntry = this;
|
|
7149
|
-
if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data)) {
|
|
7383
|
+
if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data && keepsContentType(writer, zipEntry.data))) {
|
|
7150
7384
|
return zipEntry.data;
|
|
7151
7385
|
} else {
|
|
7152
7386
|
const reader = zipEntry.reader = createReader(zipEntry.Reader, zipEntry.data, options);
|
|
7153
|
-
const
|
|
7154
|
-
await Promise.all([initStream(reader), initStream(writer,
|
|
7155
|
-
const { readable } = reader;
|
|
7387
|
+
const dataSize = zipEntry.uncompressedSize || reader.size;
|
|
7388
|
+
await Promise.all([initStream(reader), initStream(writer, dataSize)]);
|
|
7156
7389
|
const { signal } = options;
|
|
7390
|
+
const readable = createProgressReadable(zipEntry, reader, options, signal);
|
|
7391
|
+
const preventClose = !ownsWritable(writer) && Boolean(options.preventClose);
|
|
7157
7392
|
zipEntry.uncompressedSize = reader.size;
|
|
7158
|
-
await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable), { signal });
|
|
7393
|
+
await toCompatibleReadable(readable).pipeTo(toCompatibleWritable(writer.writable), { signal, preventClose, preventAbort: preventClose });
|
|
7159
7394
|
return writer.getData ? writer.getData() : writer.writable;
|
|
7160
7395
|
}
|
|
7161
7396
|
}
|
|
@@ -7286,7 +7521,7 @@
|
|
|
7286
7521
|
Reader: TextReader,
|
|
7287
7522
|
Writer: TextWriter,
|
|
7288
7523
|
options,
|
|
7289
|
-
uncompressedSize: text
|
|
7524
|
+
uncompressedSize: getTextSize(text)
|
|
7290
7525
|
});
|
|
7291
7526
|
}
|
|
7292
7527
|
|
|
@@ -7415,10 +7650,16 @@
|
|
|
7415
7650
|
}
|
|
7416
7651
|
|
|
7417
7652
|
async importZip(reader, options = {}) {
|
|
7418
|
-
|
|
7419
|
-
|
|
7653
|
+
let zipReader;
|
|
7654
|
+
if (reader && typeof reader.getEntries == FUNCTION_TYPE) {
|
|
7655
|
+
zipReader = reader;
|
|
7656
|
+
options = Object.assign({}, zipReader.options, options);
|
|
7657
|
+
} else {
|
|
7658
|
+
await initStream(reader);
|
|
7659
|
+
zipReader = new ZipReader(reader, options);
|
|
7660
|
+
}
|
|
7420
7661
|
const importedEntries = [];
|
|
7421
|
-
const entries = await zipReader.getEntries();
|
|
7662
|
+
const entries = await zipReader.getEntries(options);
|
|
7422
7663
|
for (const entry of entries) {
|
|
7423
7664
|
let parent = this;
|
|
7424
7665
|
try {
|
|
@@ -7440,7 +7681,7 @@
|
|
|
7440
7681
|
importedEntries.push(addChild(parent, name, {
|
|
7441
7682
|
data: entry,
|
|
7442
7683
|
Reader: getZipBlobReader(Object.assign({}, options)),
|
|
7443
|
-
uncompressedSize: entry.uncompressedSize,
|
|
7684
|
+
uncompressedSize: options.passThrough ? entry.compressedSize : entry.uncompressedSize,
|
|
7444
7685
|
passThrough: options.passThrough
|
|
7445
7686
|
}));
|
|
7446
7687
|
} else {
|
|
@@ -7482,11 +7723,25 @@
|
|
|
7482
7723
|
}
|
|
7483
7724
|
const [readers] = await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
|
|
7484
7725
|
const zipWriter = new ZipWriter(writer, options);
|
|
7485
|
-
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry],
|
|
7486
|
-
await zipWriter.close();
|
|
7726
|
+
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], getUncompressedSize), options, readers);
|
|
7727
|
+
await zipWriter.close(options.globalComment);
|
|
7487
7728
|
return writer.getData ? writer.getData() : writer.writable;
|
|
7488
7729
|
}
|
|
7489
7730
|
|
|
7731
|
+
getExportedSize(options = {}) {
|
|
7732
|
+
const zipEntry = this;
|
|
7733
|
+
options = Object.assign({}, options);
|
|
7734
|
+
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
7735
|
+
options.bufferedWrite = true;
|
|
7736
|
+
}
|
|
7737
|
+
const writeOrderGuaranteed = !options.bufferedWrite ||
|
|
7738
|
+
(options.keepOrder !== false && zipEntry.children.every(child => !child.children.length));
|
|
7739
|
+
return getEntriesSize(options, Array.from(zipEntry.getChildren({ recursive: true }), child => {
|
|
7740
|
+
const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
|
|
7741
|
+
return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
|
|
7742
|
+
}), writeOrderGuaranteed, options.globalComment);
|
|
7743
|
+
}
|
|
7744
|
+
|
|
7490
7745
|
getChildByName(name) {
|
|
7491
7746
|
const children = this.children;
|
|
7492
7747
|
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
@@ -7694,6 +7949,10 @@
|
|
|
7694
7949
|
return this.root.exportZip(writer, options);
|
|
7695
7950
|
}
|
|
7696
7951
|
|
|
7952
|
+
getExportedSize(options) {
|
|
7953
|
+
return this.root.getExportedSize(options);
|
|
7954
|
+
}
|
|
7955
|
+
|
|
7697
7956
|
isPasswordProtected() {
|
|
7698
7957
|
return this.root.isPasswordProtected();
|
|
7699
7958
|
}
|
|
@@ -7705,12 +7964,12 @@
|
|
|
7705
7964
|
|
|
7706
7965
|
const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
|
|
7707
7966
|
|
|
7708
|
-
function getTotalSize(entries,
|
|
7967
|
+
function getTotalSize(entries, getEntrySize) {
|
|
7709
7968
|
let size = 0;
|
|
7710
7969
|
const pendingEntries = Array.from(entries);
|
|
7711
7970
|
while (pendingEntries.length) {
|
|
7712
7971
|
const entry = pendingEntries.pop();
|
|
7713
|
-
size += entry
|
|
7972
|
+
size += getEntrySize(entry) || 0;
|
|
7714
7973
|
for (const child of entry.children) {
|
|
7715
7974
|
pendingEntries.push(child);
|
|
7716
7975
|
}
|
|
@@ -7718,6 +7977,15 @@
|
|
|
7718
7977
|
return size;
|
|
7719
7978
|
}
|
|
7720
7979
|
|
|
7980
|
+
function getUncompressedSize(entry) {
|
|
7981
|
+
return entry.uncompressedSize;
|
|
7982
|
+
}
|
|
7983
|
+
|
|
7984
|
+
function getExtractedSize(entry, passThrough) {
|
|
7985
|
+
const { data } = entry;
|
|
7986
|
+
return passThrough && data instanceof Entry ? data.compressedSize : entry.uncompressedSize;
|
|
7987
|
+
}
|
|
7988
|
+
|
|
7721
7989
|
function getReadableReader(readable) {
|
|
7722
7990
|
let consumed;
|
|
7723
7991
|
return function () {
|
|
@@ -7740,10 +8008,17 @@
|
|
|
7740
8008
|
|
|
7741
8009
|
async init() {
|
|
7742
8010
|
const zipBlobReader = this;
|
|
7743
|
-
|
|
7744
|
-
const
|
|
8011
|
+
const readerOptions = Object.assign({}, options, zipBlobReader.options);
|
|
8012
|
+
const { checkOverlappingEntry, checkOverlappingEntryOnly } = readerOptions;
|
|
8013
|
+
const data = await zipBlobReader.entry.getData(new BlobWriter(), Object.assign(readerOptions, {
|
|
8014
|
+
checkPasswordOnly: false,
|
|
8015
|
+
checkOverlappingEntry: checkOverlappingEntryOnly || checkOverlappingEntry,
|
|
8016
|
+
checkOverlappingEntryOnly: false,
|
|
8017
|
+
preventClose: false
|
|
8018
|
+
}));
|
|
7745
8019
|
zipBlobReader.data = data;
|
|
7746
8020
|
zipBlobReader.blobReader = new BlobReader(data);
|
|
8021
|
+
zipBlobReader.size = data.size;
|
|
7747
8022
|
super.init();
|
|
7748
8023
|
}
|
|
7749
8024
|
|
|
@@ -7757,6 +8032,30 @@
|
|
|
7757
8032
|
return Reader.prototype ? new Reader(data, options) : Reader(data, options);
|
|
7758
8033
|
}
|
|
7759
8034
|
|
|
8035
|
+
function keepsContentType(writer, data) {
|
|
8036
|
+
const { contentType } = writer;
|
|
8037
|
+
if (contentType === UNDEFINED_VALUE) {
|
|
8038
|
+
return true;
|
|
8039
|
+
} else if (writer.constructor == BlobWriter) {
|
|
8040
|
+
return data.type == contentType;
|
|
8041
|
+
} else if (writer.constructor == Data64URIWriter) {
|
|
8042
|
+
return data.startsWith(writer.data);
|
|
8043
|
+
} else {
|
|
8044
|
+
return true;
|
|
8045
|
+
}
|
|
8046
|
+
}
|
|
8047
|
+
|
|
8048
|
+
function createProgressReadable(zipEntry, reader, options, signal) {
|
|
8049
|
+
const { onstart, onprogress, onend } = options;
|
|
8050
|
+
const { readable } = reader;
|
|
8051
|
+
const coreReaderReportsProgress = zipEntry.data instanceof Entry;
|
|
8052
|
+
if (coreReaderReportsProgress || (!onstart && !onprogress && !onend)) {
|
|
8053
|
+
return readable;
|
|
8054
|
+
} else {
|
|
8055
|
+
return toCompatibleReadable(readable).pipeThrough(new ProgressWatcherStream({ onstart, onprogress, onend, size: reader.size }), { signal });
|
|
8056
|
+
}
|
|
8057
|
+
}
|
|
8058
|
+
|
|
7760
8059
|
async function initReaders(entry, options) {
|
|
7761
8060
|
const fileEntries = [];
|
|
7762
8061
|
const pendingEntries = [entry];
|
|
@@ -7789,6 +8088,7 @@
|
|
|
7789
8088
|
}
|
|
7790
8089
|
if (reader.size !== UNDEFINED_VALUE) {
|
|
7791
8090
|
child.uncompressedSize = reader.size;
|
|
8091
|
+
child.undeterminedSize = false;
|
|
7792
8092
|
}
|
|
7793
8093
|
}));
|
|
7794
8094
|
return readers;
|
|
@@ -7838,6 +8138,90 @@
|
|
|
7838
8138
|
return error;
|
|
7839
8139
|
}
|
|
7840
8140
|
|
|
8141
|
+
function getChildEntryOptions(child, selectedEntry, options) {
|
|
8142
|
+
const name = options.relativePath ? child.getRelativeName(selectedEntry) : child.getFullname();
|
|
8143
|
+
const childOptions = child.options || {};
|
|
8144
|
+
let zipEntryMetadata = {};
|
|
8145
|
+
let passThroughOptions = {};
|
|
8146
|
+
if (child.data instanceof Entry) {
|
|
8147
|
+
const {
|
|
8148
|
+
externalFileAttributes,
|
|
8149
|
+
versionMadeBy,
|
|
8150
|
+
comment,
|
|
8151
|
+
lastModDate,
|
|
8152
|
+
creationDate,
|
|
8153
|
+
lastAccessDate,
|
|
8154
|
+
uncompressedSize,
|
|
8155
|
+
encrypted,
|
|
8156
|
+
zipCrypto,
|
|
8157
|
+
crc32,
|
|
8158
|
+
compressionMethod,
|
|
8159
|
+
extraFieldAES,
|
|
8160
|
+
internalFileAttributes,
|
|
8161
|
+
extraField,
|
|
8162
|
+
uid,
|
|
8163
|
+
gid
|
|
8164
|
+
} = child.data;
|
|
8165
|
+
zipEntryMetadata = {
|
|
8166
|
+
externalFileAttributes,
|
|
8167
|
+
versionMadeBy,
|
|
8168
|
+
comment,
|
|
8169
|
+
lastModDate,
|
|
8170
|
+
creationDate,
|
|
8171
|
+
lastAccessDate,
|
|
8172
|
+
internalFileAttributes
|
|
8173
|
+
};
|
|
8174
|
+
const userExtraField = getUserExtraField(extraField);
|
|
8175
|
+
if (userExtraField) {
|
|
8176
|
+
zipEntryMetadata.extraField = userExtraField;
|
|
8177
|
+
}
|
|
8178
|
+
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
8179
|
+
Object.assign(zipEntryMetadata, {
|
|
8180
|
+
uid,
|
|
8181
|
+
gid,
|
|
8182
|
+
unixExtraFieldType: INFOZIP_EXTRA_FIELD_TYPE
|
|
8183
|
+
});
|
|
8184
|
+
}
|
|
8185
|
+
if (isPassThrough(child, options)) {
|
|
8186
|
+
let level, encryptionStrength;
|
|
8187
|
+
if (compressionMethod === 0) {
|
|
8188
|
+
level = 0;
|
|
8189
|
+
}
|
|
8190
|
+
if (extraFieldAES) {
|
|
8191
|
+
encryptionStrength = extraFieldAES.strength;
|
|
8192
|
+
}
|
|
8193
|
+
passThroughOptions = {
|
|
8194
|
+
passThrough: true,
|
|
8195
|
+
encrypted,
|
|
8196
|
+
zipCrypto,
|
|
8197
|
+
crc32,
|
|
8198
|
+
uncompressedSize,
|
|
8199
|
+
level,
|
|
8200
|
+
encryptionStrength,
|
|
8201
|
+
compressionMethod
|
|
8202
|
+
};
|
|
8203
|
+
}
|
|
8204
|
+
}
|
|
8205
|
+
const entryOptions = Object.assign({}, zipEntryMetadata, options, passThroughOptions, childOptions, { directory: child.directory });
|
|
8206
|
+
if (!child.directory && entryOptions.passThrough && entryOptions.uncompressedSize === UNDEFINED_VALUE) {
|
|
8207
|
+
throw new Error(ERR_INVALID_PASS_THROUGH);
|
|
8208
|
+
}
|
|
8209
|
+
return { name, entryOptions };
|
|
8210
|
+
}
|
|
8211
|
+
|
|
8212
|
+
function getDeterminedSize(child, passThrough) {
|
|
8213
|
+
const { reader } = child;
|
|
8214
|
+
if (reader && reader.size !== UNDEFINED_VALUE) {
|
|
8215
|
+
return reader.size;
|
|
8216
|
+
}
|
|
8217
|
+
return child.undeterminedSize ? UNDEFINED_VALUE : getExtractedSize(child, passThrough);
|
|
8218
|
+
}
|
|
8219
|
+
|
|
8220
|
+
function isPassThrough(child, options) {
|
|
8221
|
+
const { readerOptions } = options;
|
|
8222
|
+
return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
|
|
8223
|
+
}
|
|
8224
|
+
|
|
7841
8225
|
function getUserExtraField(extraField) {
|
|
7842
8226
|
if (extraField) {
|
|
7843
8227
|
const userExtraField = new Map();
|
|
@@ -7853,8 +8237,14 @@
|
|
|
7853
8237
|
}
|
|
7854
8238
|
|
|
7855
8239
|
async function exportZip(zipWriter, entry, totalSize, options, readers) {
|
|
8240
|
+
const { onstart, onprogress, onend, onentryprogress } = options;
|
|
7856
8241
|
const selectedEntry = entry;
|
|
7857
|
-
const
|
|
8242
|
+
const totalEntries = getTotalSize(entry.children, () => 1);
|
|
8243
|
+
let writtenSize = 0;
|
|
8244
|
+
let writtenEntries = 0;
|
|
8245
|
+
if (onstart) {
|
|
8246
|
+
await callHandler(onstart, totalSize);
|
|
8247
|
+
}
|
|
7858
8248
|
if (options.bufferedWrite) {
|
|
7859
8249
|
await processChildren(entry);
|
|
7860
8250
|
} else {
|
|
@@ -7862,6 +8252,9 @@
|
|
|
7862
8252
|
await addChild(child);
|
|
7863
8253
|
}
|
|
7864
8254
|
}
|
|
8255
|
+
if (onend) {
|
|
8256
|
+
await callHandler(onend, writtenSize);
|
|
8257
|
+
}
|
|
7865
8258
|
|
|
7866
8259
|
async function processChildren(entry) {
|
|
7867
8260
|
const results = await Promise.allSettled(entry.children.map(async child => {
|
|
@@ -7875,81 +8268,23 @@
|
|
|
7875
8268
|
}
|
|
7876
8269
|
|
|
7877
8270
|
async function addChild(child) {
|
|
7878
|
-
const name
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
externalFileAttributes,
|
|
7884
|
-
versionMadeBy,
|
|
7885
|
-
comment,
|
|
7886
|
-
lastModDate,
|
|
7887
|
-
creationDate,
|
|
7888
|
-
lastAccessDate,
|
|
7889
|
-
uncompressedSize,
|
|
7890
|
-
encrypted,
|
|
7891
|
-
zipCrypto,
|
|
7892
|
-
crc32,
|
|
7893
|
-
compressionMethod,
|
|
7894
|
-
extraFieldAES,
|
|
7895
|
-
internalFileAttributes,
|
|
7896
|
-
extraField,
|
|
7897
|
-
uid,
|
|
7898
|
-
gid
|
|
7899
|
-
} = child.data;
|
|
7900
|
-
zipEntryOptions = {
|
|
7901
|
-
externalFileAttributes,
|
|
7902
|
-
versionMadeBy,
|
|
7903
|
-
comment,
|
|
7904
|
-
lastModDate,
|
|
7905
|
-
creationDate,
|
|
7906
|
-
lastAccessDate,
|
|
7907
|
-
internalFileAttributes
|
|
7908
|
-
};
|
|
7909
|
-
const userExtraField = getUserExtraField(extraField);
|
|
7910
|
-
if (userExtraField) {
|
|
7911
|
-
zipEntryOptions.extraField = userExtraField;
|
|
7912
|
-
}
|
|
7913
|
-
if (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE) {
|
|
7914
|
-
Object.assign(zipEntryOptions, {
|
|
7915
|
-
uid,
|
|
7916
|
-
gid,
|
|
7917
|
-
unixExtraFieldType: options.unixExtraFieldType || INFOZIP_EXTRA_FIELD_TYPE
|
|
7918
|
-
});
|
|
7919
|
-
}
|
|
7920
|
-
if (child.passThrough) {
|
|
7921
|
-
let level, encryptionStrength;
|
|
7922
|
-
if (compressionMethod === 0) {
|
|
7923
|
-
level = 0;
|
|
7924
|
-
}
|
|
7925
|
-
if (extraFieldAES) {
|
|
7926
|
-
encryptionStrength = extraFieldAES.strength;
|
|
7927
|
-
}
|
|
7928
|
-
zipEntryOptions = Object.assign(zipEntryOptions, {
|
|
7929
|
-
passThrough: true,
|
|
7930
|
-
encrypted,
|
|
7931
|
-
zipCrypto,
|
|
7932
|
-
crc32,
|
|
7933
|
-
uncompressedSize,
|
|
7934
|
-
level,
|
|
7935
|
-
encryptionStrength,
|
|
7936
|
-
compressionMethod
|
|
7937
|
-
});
|
|
7938
|
-
}
|
|
7939
|
-
}
|
|
7940
|
-
await zipWriter.add(name, readers.get(child), Object.assign({}, options, zipEntryOptions, childOptions, {
|
|
7941
|
-
directory: child.directory,
|
|
8271
|
+
const { name, entryOptions } = getChildEntryOptions(child, selectedEntry, options);
|
|
8272
|
+
let entryWrittenSize = 0;
|
|
8273
|
+
const entryMetadata = await zipWriter.add(name, readers.get(child), Object.assign(entryOptions, {
|
|
8274
|
+
onstart: UNDEFINED_VALUE,
|
|
8275
|
+
onend: UNDEFINED_VALUE,
|
|
7942
8276
|
onprogress: async indexProgress => {
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
} catch {
|
|
7948
|
-
// ignored
|
|
7949
|
-
}
|
|
8277
|
+
writtenSize += indexProgress - entryWrittenSize;
|
|
8278
|
+
entryWrittenSize = indexProgress;
|
|
8279
|
+
if (onprogress) {
|
|
8280
|
+
await callHandler(onprogress, writtenSize, totalSize);
|
|
7950
8281
|
}
|
|
7951
8282
|
}
|
|
7952
8283
|
}));
|
|
8284
|
+
writtenEntries++;
|
|
8285
|
+
if (onentryprogress) {
|
|
8286
|
+
await callHandler(onentryprogress, writtenEntries, totalEntries, entryMetadata);
|
|
8287
|
+
}
|
|
7953
8288
|
}
|
|
7954
8289
|
}
|
|
7955
8290
|
|
|
@@ -7977,7 +8312,7 @@
|
|
|
7977
8312
|
})
|
|
7978
8313
|
);
|
|
7979
8314
|
} else if (handle.kind == "directory") {
|
|
7980
|
-
const directoryEntry = parentEntry.addDirectory(handle.name);
|
|
8315
|
+
const directoryEntry = parentEntry.addDirectory(handle.name, options);
|
|
7981
8316
|
addedEntries.push(directoryEntry);
|
|
7982
8317
|
for await (const childHandle of handle.values()) {
|
|
7983
8318
|
await addFile(directoryEntry, childHandle, addedEntries, entryName);
|
|
@@ -7999,15 +8334,29 @@
|
|
|
7999
8334
|
}
|
|
8000
8335
|
|
|
8001
8336
|
async function exportFileSystemHandle(zipEntry, directoryHandle, options) {
|
|
8002
|
-
const
|
|
8003
|
-
const writtenSizes = new Map();
|
|
8337
|
+
const { onstart, onprogress, onend } = options;
|
|
8004
8338
|
const abortController = new AbortController();
|
|
8005
8339
|
const { signal } = abortController;
|
|
8006
8340
|
const releaseSignal = forwardAbort(options.signal, abortController);
|
|
8341
|
+
const getDataOptions = Object.assign({}, options, options.readerOptions, {
|
|
8342
|
+
signal,
|
|
8343
|
+
onstart: UNDEFINED_VALUE,
|
|
8344
|
+
onprogress: UNDEFINED_VALUE,
|
|
8345
|
+
onend: UNDEFINED_VALUE,
|
|
8346
|
+
preventClose: false
|
|
8347
|
+
});
|
|
8348
|
+
const totalSize = getTotalSize([zipEntry], entry => getExtractedSize(entry, getDataOptions.passThrough));
|
|
8007
8349
|
const exportedEntryNames = [];
|
|
8008
8350
|
let exportAborted = false;
|
|
8351
|
+
let writtenSize = 0;
|
|
8009
8352
|
try {
|
|
8353
|
+
if (onstart) {
|
|
8354
|
+
await callHandler(onstart, totalSize);
|
|
8355
|
+
}
|
|
8010
8356
|
await exportChildren(zipEntry, directoryHandle);
|
|
8357
|
+
if (onend) {
|
|
8358
|
+
await callHandler(onend, writtenSize);
|
|
8359
|
+
}
|
|
8011
8360
|
} catch (error) {
|
|
8012
8361
|
try {
|
|
8013
8362
|
error.exportedEntryNames = exportedEntryNames;
|
|
@@ -8020,6 +8369,25 @@
|
|
|
8020
8369
|
}
|
|
8021
8370
|
return directoryHandle;
|
|
8022
8371
|
|
|
8372
|
+
function createProgressWritable(writable) {
|
|
8373
|
+
const writer = writable.getWriter();
|
|
8374
|
+
return new WritableStream({
|
|
8375
|
+
async write(chunk) {
|
|
8376
|
+
await writer.write(chunk);
|
|
8377
|
+
writtenSize += chunk.length;
|
|
8378
|
+
if (onprogress) {
|
|
8379
|
+
await callHandler(onprogress, writtenSize, totalSize);
|
|
8380
|
+
}
|
|
8381
|
+
},
|
|
8382
|
+
close() {
|
|
8383
|
+
return writer.close();
|
|
8384
|
+
},
|
|
8385
|
+
abort(reason) {
|
|
8386
|
+
return writer.abort(reason);
|
|
8387
|
+
}
|
|
8388
|
+
});
|
|
8389
|
+
}
|
|
8390
|
+
|
|
8023
8391
|
async function exportChildren(entry, parentHandle) {
|
|
8024
8392
|
if (options.concurrent) {
|
|
8025
8393
|
const results = await Promise.allSettled(entry.children.map(child => exportChild(child, parentHandle)));
|
|
@@ -8051,19 +8419,7 @@
|
|
|
8051
8419
|
const fileHandle = await parentHandle.getFileHandle(child.name, { create: true });
|
|
8052
8420
|
const writable = await fileHandle.createWritable();
|
|
8053
8421
|
try {
|
|
8054
|
-
await child.getData({ writable
|
|
8055
|
-
signal,
|
|
8056
|
-
onprogress: async progress => {
|
|
8057
|
-
if (options.onprogress) {
|
|
8058
|
-
writtenSizes.set(child.id, progress);
|
|
8059
|
-
try {
|
|
8060
|
-
await options.onprogress(Array.from(writtenSizes.values()).reduce((previousValue, currentValue) => previousValue + currentValue, 0), totalSize);
|
|
8061
|
-
} catch {
|
|
8062
|
-
// ignored
|
|
8063
|
-
}
|
|
8064
|
-
}
|
|
8065
|
-
}
|
|
8066
|
-
}));
|
|
8422
|
+
await child.getData({ writable: createProgressWritable(writable) }, getDataOptions);
|
|
8067
8423
|
} catch (error) {
|
|
8068
8424
|
throw exportAborted ? new Error(ERR_ABORT_EXPORT) : error;
|
|
8069
8425
|
}
|
|
@@ -8178,6 +8534,7 @@
|
|
|
8178
8534
|
|
|
8179
8535
|
exports.ERR_ABORTED = ERR_ABORTED;
|
|
8180
8536
|
exports.ERR_ENTRY_EXISTS = ERR_ENTRY_EXISTS;
|
|
8537
|
+
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
8181
8538
|
exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
|
|
8182
8539
|
exports.fs = fs;
|
|
8183
8540
|
|