@zip.js/zip.js 2.8.57 → 2.8.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist/zip-core-external.js +458 -200
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +472 -199
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +481 -201
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +497 -193
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +481 -201
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +498 -202
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +499 -203
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +474 -201
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +474 -201
- 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 +475 -202
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +498 -202
- package/index-native.min.js +1 -1
- package/index.cjs +499 -203
- package/index.d.cts +297 -10
- package/index.d.ts +297 -10
- package/index.min.js +1 -1
- package/lib/core/constants.js +4 -0
- package/lib/core/options.js +2 -0
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-fs.js +27 -1
- package/lib/core/zip-reader.js +168 -38
- package/lib/core/zip-writer.js +290 -161
- package/lib/core/zlib-streams-inline.js +1 -1
- package/lib/zip-core-reader.js +16 -1
- package/package.json +1 -1
package/dist/zip-fs-core.js
CHANGED
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
const BITFLAG_LEVEL_FAST_MASK = 0b100;
|
|
83
83
|
const BITFLAG_LEVEL_SUPER_FAST_MASK = 0b110;
|
|
84
84
|
const BITFLAG_DATA_DESCRIPTOR = 0b1000;
|
|
85
|
+
const BITFLAG_COMPRESSED_PATCHED_DATA = 0b100000;
|
|
85
86
|
const BITFLAG_STRONG_ENCRYPTION = 0b1000000;
|
|
86
87
|
const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
|
|
87
88
|
const BITFLAG_MASKED_LOCAL_HEADERS = 0b10000000000000;
|
|
@@ -100,6 +101,7 @@
|
|
|
100
101
|
const FILE_ATTR_UNIX_SETGID_MASK = 0o2000;
|
|
101
102
|
const FILE_ATTR_UNIX_STICKY_MASK = 0o1000;
|
|
102
103
|
|
|
104
|
+
const VERSION_STORE = 0x0A;
|
|
103
105
|
const VERSION_DEFLATE = 0x14;
|
|
104
106
|
const VERSION_ZIP64 = 0x2D;
|
|
105
107
|
const VERSION_AES = 0x33;
|
|
@@ -198,6 +200,7 @@
|
|
|
198
200
|
const OPTION_USDZ = "usdz";
|
|
199
201
|
const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
|
|
200
202
|
const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
|
|
203
|
+
const OPTION_CENTRAL_EXTRA_FIELD = "centralExtraField";
|
|
201
204
|
const OPTION_STRICTNESS = "strictness";
|
|
202
205
|
const OPTION_FILENAME_VALIDATION = "filenameValidation";
|
|
203
206
|
const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
|
|
@@ -3608,6 +3611,8 @@
|
|
|
3608
3611
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3609
3612
|
*/
|
|
3610
3613
|
|
|
3614
|
+
|
|
3615
|
+
const ERR_WORKER_STARTUP_TIMEOUT = "Worker startup timeout";
|
|
3611
3616
|
let initModule = () => { };
|
|
3612
3617
|
|
|
3613
3618
|
async function supportsDeflate(config) {
|
|
@@ -4123,6 +4128,21 @@
|
|
|
4123
4128
|
const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
|
|
4124
4129
|
const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
|
|
4125
4130
|
const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
|
|
4131
|
+
const WARNING_UNSORTED_CENTRAL_DIRECTORY = "unsorted central directory";
|
|
4132
|
+
const WARNING_UNKNOWN_VERSION = "unknown version needed to extract";
|
|
4133
|
+
const WARNING_COMPRESSED_PATCHED_DATA = "compressed patched data";
|
|
4134
|
+
const WARNING_MALFORMED_EXTRA_FIELD = "malformed extra field";
|
|
4135
|
+
const WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = "unknown zip64 extensible data";
|
|
4136
|
+
const WARNING_WRAPPED_ENTRIES_COUNT = "wrapped entries count";
|
|
4137
|
+
const WARNING_APPENDED_DATA = "appended data";
|
|
4138
|
+
const WARNING_PREPENDED_DATA = "prepended data";
|
|
4139
|
+
const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
|
|
4140
|
+
const WARNING_DUPLICATE_FILENAME = "duplicate filename";
|
|
4141
|
+
const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
|
|
4142
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
|
|
4143
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
|
|
4144
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
4145
|
+
const MAX_KNOWN_VERSION = 63;
|
|
4126
4146
|
const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
|
|
4127
4147
|
const CHARSET_UTF8 = "utf-8";
|
|
4128
4148
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
@@ -4173,6 +4193,7 @@
|
|
|
4173
4193
|
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
4174
4194
|
throw new Error(ERR_BAD_FORMAT);
|
|
4175
4195
|
}
|
|
4196
|
+
const warnings = zipReader.warnings = [];
|
|
4176
4197
|
const strictness = getStrictness(options, zipReader.options);
|
|
4177
4198
|
const checkAmbiguity = strictness == STRICTNESS_STRICT;
|
|
4178
4199
|
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
@@ -4196,8 +4217,12 @@
|
|
|
4196
4217
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
4197
4218
|
const commentLength = getUint16$1(endOfDirectoryView, 20);
|
|
4198
4219
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
4199
|
-
|
|
4200
|
-
|
|
4220
|
+
const appendedDataLength = reader.size - appendedDataOffset;
|
|
4221
|
+
if (appendedDataLength > maxAppendedDataSize) {
|
|
4222
|
+
throwAmbiguousArchive(WARNING_APPENDED_DATA);
|
|
4223
|
+
}
|
|
4224
|
+
if (appendedDataLength > 0) {
|
|
4225
|
+
addWarning(warnings, WARNING_APPENDED_DATA);
|
|
4201
4226
|
}
|
|
4202
4227
|
let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
|
|
4203
4228
|
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
@@ -4251,23 +4276,23 @@
|
|
|
4251
4276
|
}
|
|
4252
4277
|
if (lastDiskNumber == MAX_16_BITS) {
|
|
4253
4278
|
lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
|
|
4254
|
-
} else if (
|
|
4255
|
-
|
|
4279
|
+
} else if (lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
|
|
4280
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4256
4281
|
}
|
|
4257
4282
|
if (diskNumber == MAX_16_BITS) {
|
|
4258
4283
|
diskNumber = getUint32$1(endOfDirectoryView, 20);
|
|
4259
|
-
} else if (
|
|
4260
|
-
|
|
4284
|
+
} else if (diskNumber != getUint32$1(endOfDirectoryView, 20)) {
|
|
4285
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4261
4286
|
}
|
|
4262
4287
|
if (filesLength == MAX_16_BITS) {
|
|
4263
4288
|
filesLength = getBigUint64(endOfDirectoryView, 32);
|
|
4264
|
-
} else if (
|
|
4265
|
-
|
|
4289
|
+
} else if (filesLength != getBigUint64(endOfDirectoryView, 32)) {
|
|
4290
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4266
4291
|
}
|
|
4267
4292
|
if (directoryDataLength == MAX_32_BITS) {
|
|
4268
4293
|
directoryDataLength = getBigUint64(endOfDirectoryView, 40);
|
|
4269
|
-
} else if (
|
|
4270
|
-
|
|
4294
|
+
} else if (directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
|
|
4295
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4271
4296
|
}
|
|
4272
4297
|
directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
4273
4298
|
}
|
|
@@ -4336,11 +4361,23 @@
|
|
|
4336
4361
|
declaredDirectoryDataLength = directoryArray.length;
|
|
4337
4362
|
decryptedDirectory = true;
|
|
4338
4363
|
}
|
|
4364
|
+
if (directoryEncryptionInfo && !decryptedDirectory &&
|
|
4365
|
+
(directoryArray.length < 4 || getUint32$1(directoryView, 0) == CENTRAL_FILE_HEADER_SIGNATURE)) {
|
|
4366
|
+
addWarning(warnings, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA);
|
|
4367
|
+
}
|
|
4339
4368
|
startOffset = directoryDataOffset;
|
|
4340
4369
|
const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
|
|
4341
4370
|
const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
|
|
4342
|
-
const filenames =
|
|
4371
|
+
const filenames = new Set();
|
|
4343
4372
|
let duplicateFilename;
|
|
4373
|
+
let previousEntryPosition = -1;
|
|
4374
|
+
const recoverWrappedFilesLength = !checkAmbiguity && !zip64EndOfDirectory;
|
|
4375
|
+
if (!filesLength && recoverWrappedFilesLength) {
|
|
4376
|
+
filesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
4377
|
+
if (filesLength) {
|
|
4378
|
+
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4344
4381
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4345
4382
|
const fileEntry = new ZipEntry$1(reader, zipReader.options);
|
|
4346
4383
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
@@ -4418,15 +4455,26 @@
|
|
|
4418
4455
|
filename,
|
|
4419
4456
|
comment
|
|
4420
4457
|
});
|
|
4421
|
-
readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)
|
|
4458
|
+
if (readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)) {
|
|
4459
|
+
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
4460
|
+
}
|
|
4422
4461
|
fileEntry.offset += prependedDataLength;
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4462
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
4463
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
4464
|
+
if (entryPosition < previousEntryPosition) {
|
|
4465
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
4466
|
+
}
|
|
4467
|
+
previousEntryPosition = entryPosition;
|
|
4468
|
+
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
4469
|
+
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
4470
|
+
}
|
|
4471
|
+
if ((fileEntry.rawBitFlag & BITFLAG_COMPRESSED_PATCHED_DATA) == BITFLAG_COMPRESSED_PATCHED_DATA) {
|
|
4472
|
+
addWarning(warnings, WARNING_COMPRESSED_PATCHED_DATA, filename);
|
|
4473
|
+
}
|
|
4474
|
+
if (filenames.has(fileEntry.filename)) {
|
|
4475
|
+
duplicateFilename = true;
|
|
4429
4476
|
}
|
|
4477
|
+
filenames.add(fileEntry.filename);
|
|
4430
4478
|
const unixExternalUpper = (fileEntry.externalFileAttributes >> 16) & MAX_16_BITS;
|
|
4431
4479
|
if (fileEntry.unixMode === UNDEFINED_VALUE && (unixExternalUpper & (FILE_ATTR_UNIX_DEFAULT_MASK | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_TYPE_DIR)) != 0) {
|
|
4432
4480
|
fileEntry.unixMode = unixExternalUpper;
|
|
@@ -4450,7 +4498,7 @@
|
|
|
4450
4498
|
internalFileAttribute: fileEntry.internalFileAttributes,
|
|
4451
4499
|
externalFileAttribute: fileEntry.externalFileAttributes,
|
|
4452
4500
|
executable,
|
|
4453
|
-
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) ||
|
|
4501
|
+
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE),
|
|
4454
4502
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
4455
4503
|
});
|
|
4456
4504
|
const entry = new Entry(fileEntry);
|
|
@@ -4463,6 +4511,13 @@
|
|
|
4463
4511
|
return arrayBufferPromise;
|
|
4464
4512
|
};
|
|
4465
4513
|
offset = endOffset;
|
|
4514
|
+
if (indexFile == filesLength - 1 && recoverWrappedFilesLength) {
|
|
4515
|
+
const wrappedFilesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
4516
|
+
if (wrappedFilesLength) {
|
|
4517
|
+
filesLength += wrappedFilesLength;
|
|
4518
|
+
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
4519
|
+
}
|
|
4520
|
+
}
|
|
4466
4521
|
const { onprogress } = options;
|
|
4467
4522
|
if (onprogress) {
|
|
4468
4523
|
try {
|
|
@@ -4487,18 +4542,22 @@
|
|
|
4487
4542
|
zipReader.digitalSignature = digitalSignature;
|
|
4488
4543
|
offsetAfterSignature = offset + 6 + digitalSignature.length;
|
|
4489
4544
|
}
|
|
4490
|
-
if (
|
|
4491
|
-
|
|
4545
|
+
if ((offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) ||
|
|
4546
|
+
(!decryptedDirectory && offset != directoryDataLength && offsetAfterSignature != directoryDataLength)) {
|
|
4547
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA);
|
|
4492
4548
|
}
|
|
4493
4549
|
if (duplicateFilename) {
|
|
4494
|
-
|
|
4550
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_DUPLICATE_FILENAME);
|
|
4495
4551
|
}
|
|
4496
4552
|
const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
|
|
4497
4553
|
const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
|
|
4498
4554
|
const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
|
|
4499
4555
|
startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
|
|
4500
4556
|
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
|
|
4501
|
-
throwAmbiguousArchive(
|
|
4557
|
+
throwAmbiguousArchive(WARNING_PREPENDED_DATA);
|
|
4558
|
+
}
|
|
4559
|
+
if (prependedDataLength || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
|
|
4560
|
+
addWarning(warnings, WARNING_PREPENDED_DATA);
|
|
4502
4561
|
}
|
|
4503
4562
|
if (extractPrependedData) {
|
|
4504
4563
|
zipReader.prependedData = startOffset > splitZipSignatureLength ?
|
|
@@ -4528,6 +4587,68 @@
|
|
|
4528
4587
|
}
|
|
4529
4588
|
}
|
|
4530
4589
|
|
|
4590
|
+
class ZipReaderStream {
|
|
4591
|
+
|
|
4592
|
+
constructor(options = {}) {
|
|
4593
|
+
const { readable, writable } = new TransformStream();
|
|
4594
|
+
const gen = new ZipReader(readable, options).getEntriesGenerator();
|
|
4595
|
+
this.readable = new ReadableStream({
|
|
4596
|
+
async pull(controller) {
|
|
4597
|
+
const { done, value } = await gen.next();
|
|
4598
|
+
if (done)
|
|
4599
|
+
return controller.close();
|
|
4600
|
+
const chunk = {
|
|
4601
|
+
...value,
|
|
4602
|
+
readable: (function () {
|
|
4603
|
+
const { readable, writable } = new TransformStream();
|
|
4604
|
+
if (value.getData) {
|
|
4605
|
+
getData();
|
|
4606
|
+
return readable;
|
|
4607
|
+
}
|
|
4608
|
+
|
|
4609
|
+
async function getData() {
|
|
4610
|
+
try {
|
|
4611
|
+
await value.getData(writable);
|
|
4612
|
+
} catch (error) {
|
|
4613
|
+
try {
|
|
4614
|
+
await writable.abort(error);
|
|
4615
|
+
} catch {
|
|
4616
|
+
// ignored
|
|
4617
|
+
}
|
|
4618
|
+
}
|
|
4619
|
+
}
|
|
4620
|
+
})()
|
|
4621
|
+
};
|
|
4622
|
+
delete chunk.getData;
|
|
4623
|
+
controller.enqueue(chunk);
|
|
4624
|
+
}
|
|
4625
|
+
});
|
|
4626
|
+
this.writable = writable;
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
|
|
4630
|
+
async function isZipFile(reader, options = {}) {
|
|
4631
|
+
reader = new GenericReader(reader);
|
|
4632
|
+
await initStream(reader);
|
|
4633
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
4634
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
4635
|
+
await initStream(reader);
|
|
4636
|
+
}
|
|
4637
|
+
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
4638
|
+
return false;
|
|
4639
|
+
}
|
|
4640
|
+
const strictness = getStrictness(options, {});
|
|
4641
|
+
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
4642
|
+
const maxAppendedDataSize = getMaxAppendedDataSize(options[OPTION_MAX_APPENDED_DATA_SIZE], strictness);
|
|
4643
|
+
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
4644
|
+
if (!endOfDirectoryInfo || (strictness == STRICTNESS_STRICT && endOfDirectoryReachingEndCount > 1)) {
|
|
4645
|
+
return false;
|
|
4646
|
+
}
|
|
4647
|
+
const commentLength = getUint16$1(getDataView(endOfDirectoryInfo), 20);
|
|
4648
|
+
const appendedDataOffset = endOfDirectoryInfo.offset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
4649
|
+
return reader.size - appendedDataOffset <= maxAppendedDataSize;
|
|
4650
|
+
}
|
|
4651
|
+
|
|
4531
4652
|
let ZipEntry$1 = class ZipEntry {
|
|
4532
4653
|
|
|
4533
4654
|
constructor(reader, options) {
|
|
@@ -4559,6 +4680,7 @@
|
|
|
4559
4680
|
dataDescriptor
|
|
4560
4681
|
} = bitFlag;
|
|
4561
4682
|
const localDirectory = fileEntry.localDirectory = {};
|
|
4683
|
+
const warnings = fileEntry.warnings = [];
|
|
4562
4684
|
const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
|
|
4563
4685
|
const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
|
|
4564
4686
|
const dataView = getDataView(dataArray);
|
|
@@ -4581,6 +4703,7 @@
|
|
|
4581
4703
|
extraFieldLength,
|
|
4582
4704
|
filenameLength
|
|
4583
4705
|
} = localDirectory;
|
|
4706
|
+
const dataOffset = localDirectory.dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
4584
4707
|
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
4585
4708
|
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
4586
4709
|
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
@@ -4598,10 +4721,10 @@
|
|
|
4598
4721
|
if (checkLocalFilename) {
|
|
4599
4722
|
localDirectory.rawFilename = rawLocalFilename;
|
|
4600
4723
|
}
|
|
4601
|
-
readCommonFooter(zipEntry, localDirectory, dataView, 4, true)
|
|
4602
|
-
|
|
4603
|
-
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
|
|
4724
|
+
if (readCommonFooter(zipEntry, localDirectory, dataView, 4, true)) {
|
|
4725
|
+
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD);
|
|
4604
4726
|
}
|
|
4727
|
+
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
4605
4728
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
4606
4729
|
if (lastAccessDate) {
|
|
4607
4730
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
@@ -4634,7 +4757,6 @@
|
|
|
4634
4757
|
throw new Error(ERR_ENCRYPTED);
|
|
4635
4758
|
}
|
|
4636
4759
|
}
|
|
4637
|
-
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
4638
4760
|
if (dataOffset + compressedSize > reader.size) {
|
|
4639
4761
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
4640
4762
|
}
|
|
@@ -4754,6 +4876,16 @@
|
|
|
4754
4876
|
return false;
|
|
4755
4877
|
}
|
|
4756
4878
|
|
|
4879
|
+
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
4880
|
+
let wrappedFilesLength = 0;
|
|
4881
|
+
while (offset + CENTRAL_FILE_HEADER_LENGTH <= directoryArray.length && getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4882
|
+
offset += CENTRAL_FILE_HEADER_LENGTH +
|
|
4883
|
+
getUint16$1(directoryView, offset + 28) + getUint16$1(directoryView, offset + 30) + getUint16$1(directoryView, offset + 32);
|
|
4884
|
+
wrappedFilesLength++;
|
|
4885
|
+
}
|
|
4886
|
+
return wrappedFilesLength % (MAX_16_BITS + 1) ? 0 : wrappedFilesLength;
|
|
4887
|
+
}
|
|
4888
|
+
|
|
4757
4889
|
function readDigitalSignature(signatureRecordArray) {
|
|
4758
4890
|
if (signatureRecordArray.length >= 6) {
|
|
4759
4891
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -4818,6 +4950,7 @@
|
|
|
4818
4950
|
const extraField = directory.extraField = new Map();
|
|
4819
4951
|
const rawExtraFieldView = getDataView(rawExtraField);
|
|
4820
4952
|
let offsetExtraField = 0;
|
|
4953
|
+
let malformedExtraField = false;
|
|
4821
4954
|
try {
|
|
4822
4955
|
while (offsetExtraField < rawExtraField.length) {
|
|
4823
4956
|
const type = getUint16$1(rawExtraFieldView, offsetExtraField);
|
|
@@ -4829,7 +4962,10 @@
|
|
|
4829
4962
|
offsetExtraField += 4 + size;
|
|
4830
4963
|
}
|
|
4831
4964
|
} catch {
|
|
4832
|
-
|
|
4965
|
+
malformedExtraField = true;
|
|
4966
|
+
}
|
|
4967
|
+
if (offsetExtraField > rawExtraField.length) {
|
|
4968
|
+
malformedExtraField = true;
|
|
4833
4969
|
}
|
|
4834
4970
|
const compressionMethod = getUint16$1(dataView, offset + 4);
|
|
4835
4971
|
Object.assign(directory, {
|
|
@@ -4897,6 +5033,7 @@
|
|
|
4897
5033
|
if (extraFieldUSDZ) {
|
|
4898
5034
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
4899
5035
|
}
|
|
5036
|
+
return malformedExtraField;
|
|
4900
5037
|
}
|
|
4901
5038
|
|
|
4902
5039
|
function readExtraFieldZip64(extraFieldZip64, directory) {
|
|
@@ -4926,10 +5063,11 @@
|
|
|
4926
5063
|
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
4927
5064
|
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
4928
5065
|
const nameCrc32 = getUint32$1(extraFieldView, 1);
|
|
5066
|
+
const version = getUint8(extraFieldView, 0);
|
|
4929
5067
|
Object.assign(extraFieldUnicode, {
|
|
4930
|
-
version
|
|
5068
|
+
version,
|
|
4931
5069
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
4932
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5070
|
+
valid: version == 1 && !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
4933
5071
|
});
|
|
4934
5072
|
if (extraFieldUnicode.valid) {
|
|
4935
5073
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -5357,27 +5495,46 @@
|
|
|
5357
5495
|
return UNDEFINED_VALUE;
|
|
5358
5496
|
}
|
|
5359
5497
|
|
|
5360
|
-
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
|
|
5498
|
+
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, warnings) {
|
|
5361
5499
|
const { rawFilename } = zipEntry;
|
|
5500
|
+
const reject = !warnings;
|
|
5362
5501
|
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
5363
5502
|
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
5364
5503
|
if (checkLocalFilename && !maskedLocalDirectory &&
|
|
5365
5504
|
(rawLocalFilename.length != rawFilename.length ||
|
|
5366
5505
|
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
5367
|
-
|
|
5506
|
+
reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
|
|
5368
5507
|
}
|
|
5369
5508
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
5370
|
-
|
|
5509
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
|
|
5371
5510
|
}
|
|
5372
5511
|
if (localDirectory.compressionMethod != zipEntry.compressionMethod) {
|
|
5373
|
-
|
|
5512
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD);
|
|
5374
5513
|
}
|
|
5375
5514
|
if (!localDirectory.bitFlag.dataDescriptor && !maskedLocalDirectory &&
|
|
5376
5515
|
(localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
|
|
5377
5516
|
(localDirectory.crc32 != zipEntry.crc32 ||
|
|
5378
5517
|
localDirectory.compressedSize != zipEntry.compressedSize ||
|
|
5379
5518
|
localDirectory.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
5380
|
-
|
|
5519
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
5520
|
+
}
|
|
5521
|
+
}
|
|
5522
|
+
|
|
5523
|
+
function reportAmbiguity(reject, warnings, reason) {
|
|
5524
|
+
if (reject) {
|
|
5525
|
+
throwAmbiguousArchive(reason);
|
|
5526
|
+
} else {
|
|
5527
|
+
addWarning(warnings, reason);
|
|
5528
|
+
}
|
|
5529
|
+
}
|
|
5530
|
+
|
|
5531
|
+
function addWarning(warnings, reason, filename) {
|
|
5532
|
+
if (!warnings.some(warning => warning.reason == reason)) {
|
|
5533
|
+
const warning = { reason };
|
|
5534
|
+
if (filename !== UNDEFINED_VALUE) {
|
|
5535
|
+
warning.filename = filename;
|
|
5536
|
+
}
|
|
5537
|
+
warnings.push(warning);
|
|
5381
5538
|
}
|
|
5382
5539
|
}
|
|
5383
5540
|
|
|
@@ -5398,7 +5555,8 @@
|
|
|
5398
5555
|
|
|
5399
5556
|
function getDate(timeRaw) {
|
|
5400
5557
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
5401
|
-
|
|
5558
|
+
const result = new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
5559
|
+
return result < MIN_DATE ? MIN_DATE : result;
|
|
5402
5560
|
}
|
|
5403
5561
|
|
|
5404
5562
|
function getDateNTFS(timeRaw) {
|
|
@@ -5452,7 +5610,24 @@
|
|
|
5452
5610
|
ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
|
|
5453
5611
|
ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
|
|
5454
5612
|
ERR_UNSUPPORTED_UINT64: ERR_UNSUPPORTED_UINT64,
|
|
5455
|
-
|
|
5613
|
+
ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
|
|
5614
|
+
WARNING_APPENDED_DATA: WARNING_APPENDED_DATA,
|
|
5615
|
+
WARNING_COMPRESSED_PATCHED_DATA: WARNING_COMPRESSED_PATCHED_DATA,
|
|
5616
|
+
WARNING_DUPLICATE_FILENAME: WARNING_DUPLICATE_FILENAME,
|
|
5617
|
+
WARNING_MALFORMED_EXTRA_FIELD: WARNING_MALFORMED_EXTRA_FIELD,
|
|
5618
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
|
|
5619
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
|
|
5620
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
|
|
5621
|
+
WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
|
|
5622
|
+
WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
|
|
5623
|
+
WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
|
|
5624
|
+
WARNING_UNKNOWN_VERSION: WARNING_UNKNOWN_VERSION,
|
|
5625
|
+
WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA: WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA,
|
|
5626
|
+
WARNING_UNSORTED_CENTRAL_DIRECTORY: WARNING_UNSORTED_CENTRAL_DIRECTORY,
|
|
5627
|
+
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
5628
|
+
ZipReader: ZipReader,
|
|
5629
|
+
ZipReaderStream: ZipReaderStream,
|
|
5630
|
+
isZipFile: isZipFile
|
|
5456
5631
|
});
|
|
5457
5632
|
|
|
5458
5633
|
/*
|
|
@@ -5549,153 +5724,151 @@
|
|
|
5549
5724
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
5550
5725
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
5551
5726
|
pendingAddFileCalls: new Set(),
|
|
5727
|
+
pendingErrors: [],
|
|
5552
5728
|
bufferedWrites: 0,
|
|
5553
5729
|
lastFileEntry: UNDEFINED_VALUE
|
|
5554
5730
|
});
|
|
5555
5731
|
}
|
|
5556
5732
|
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
5560
|
-
}
|
|
5561
|
-
reader = new GenericReader(reader);
|
|
5562
|
-
await initStream(reader);
|
|
5563
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
5564
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
5565
|
-
await initStream(reader);
|
|
5566
|
-
}
|
|
5567
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5568
|
-
const zipReader$1 = new ZipReader(reader);
|
|
5569
|
-
const entries = await zipReader$1.getEntries();
|
|
5570
|
-
await zipReader$1.close();
|
|
5571
|
-
await initStream(this.writer);
|
|
5572
|
-
const { directoryOffset } = zipReader$1;
|
|
5573
|
-
if (this.addSplitZipSignature) {
|
|
5574
|
-
delete this.addSplitZipSignature;
|
|
5575
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
5576
|
-
await writeData(this.writer, getSplitZipSignatureArray());
|
|
5577
|
-
this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
5578
|
-
}
|
|
5579
|
-
}
|
|
5580
|
-
const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
|
|
5581
|
-
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
5582
|
-
this.fileEntries = new Map(entries.map(entry => {
|
|
5583
|
-
const {
|
|
5584
|
-
version,
|
|
5585
|
-
rawLastModDate,
|
|
5586
|
-
lastAccessDate,
|
|
5587
|
-
creationDate,
|
|
5588
|
-
rawFilename,
|
|
5589
|
-
bitFlag,
|
|
5590
|
-
encrypted,
|
|
5591
|
-
uncompressedSize,
|
|
5592
|
-
compressedSize,
|
|
5593
|
-
extraFieldZip64
|
|
5594
|
-
} = entry;
|
|
5595
|
-
let {
|
|
5596
|
-
compressionMethod,
|
|
5597
|
-
rawExtraFieldZip64,
|
|
5598
|
-
rawExtraFieldAES,
|
|
5599
|
-
rawExtraFieldExtendedTimestamp,
|
|
5600
|
-
rawExtraFieldNTFS,
|
|
5601
|
-
rawExtraFieldUnix,
|
|
5602
|
-
rawExtraField,
|
|
5603
|
-
} = entry;
|
|
5604
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
5605
|
-
rawExtraFieldZip64 = rawExtraFieldZip64 || EMPTY_UINT8_ARRAY;
|
|
5606
|
-
rawExtraFieldAES = rawExtraFieldAES || EMPTY_UINT8_ARRAY;
|
|
5607
|
-
rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
|
|
5608
|
-
rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
|
|
5609
|
-
rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
|
|
5610
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
5611
|
-
if (entry.extraFieldAES) {
|
|
5612
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
5613
|
-
}
|
|
5614
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
5615
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
5616
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
5617
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
5618
|
-
const {
|
|
5619
|
-
headerArray,
|
|
5620
|
-
headerView
|
|
5621
|
-
} = getHeaderArrayData({
|
|
5622
|
-
version,
|
|
5623
|
-
bitFlag: bitFlagValue,
|
|
5624
|
-
compressionMethod,
|
|
5625
|
-
uncompressedSize,
|
|
5626
|
-
compressedSize,
|
|
5627
|
-
rawLastModDate,
|
|
5628
|
-
rawFilename,
|
|
5629
|
-
zip64CompressedSize,
|
|
5630
|
-
zip64UncompressedSize,
|
|
5631
|
-
extraFieldLength
|
|
5632
|
-
});
|
|
5633
|
-
const { crc32 } = entry;
|
|
5634
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
5635
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
5636
|
-
}
|
|
5637
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
5638
|
-
Object.assign(entry, {
|
|
5639
|
-
zip64UncompressedSize,
|
|
5640
|
-
zip64CompressedSize,
|
|
5641
|
-
offset,
|
|
5642
|
-
diskNumberStart,
|
|
5643
|
-
zip64DiskNumberStart: false,
|
|
5644
|
-
rawExtraFieldZip64,
|
|
5645
|
-
rawExtraFieldAES,
|
|
5646
|
-
rawExtraFieldExtendedTimestamp,
|
|
5647
|
-
rawExtraFieldNTFS,
|
|
5648
|
-
rawExtraFieldUnix,
|
|
5649
|
-
rawExtraField,
|
|
5650
|
-
extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
|
|
5651
|
-
extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
|
|
5652
|
-
headerArray,
|
|
5653
|
-
headerView
|
|
5654
|
-
});
|
|
5655
|
-
return [entry.filename, entry];
|
|
5656
|
-
}));
|
|
5733
|
+
prependZip(reader) {
|
|
5734
|
+
return watchPromiseError(this, prependZipEntries(this, reader));
|
|
5657
5735
|
}
|
|
5658
5736
|
|
|
5659
|
-
|
|
5737
|
+
appendZip(reader) {
|
|
5738
|
+
return watchPromiseError(this, this.appendZipEntries(reader));
|
|
5739
|
+
}
|
|
5740
|
+
|
|
5741
|
+
async appendZipEntries(reader) {
|
|
5660
5742
|
const zipWriter = this;
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
workers++;
|
|
5665
|
-
} else {
|
|
5666
|
-
await new Promise(resolve => pendingEntries.push(resolve));
|
|
5743
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
5744
|
+
while (pendingAddFileCalls.size) {
|
|
5745
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
5667
5746
|
}
|
|
5668
|
-
let
|
|
5669
|
-
|
|
5747
|
+
let resolveAppendZip;
|
|
5748
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
5749
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
5750
|
+
const appendedFilenames = [];
|
|
5751
|
+
let releaseLockWriter;
|
|
5670
5752
|
try {
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
}
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5753
|
+
reader = new GenericReader(reader);
|
|
5754
|
+
await initStream(reader);
|
|
5755
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
5756
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
5757
|
+
await initStream(reader);
|
|
5758
|
+
}
|
|
5759
|
+
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5760
|
+
const zipReader$1 = new ZipReader(reader);
|
|
5761
|
+
const entries = await zipReader$1.getEntries();
|
|
5762
|
+
await zipReader$1.close();
|
|
5763
|
+
await initStream(zipWriter.writer);
|
|
5764
|
+
const { directoryOffset } = zipReader$1;
|
|
5765
|
+
entries.forEach(({ filename }) => {
|
|
5766
|
+
if (filenames.has(filename)) {
|
|
5767
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
5768
|
+
}
|
|
5769
|
+
filenames.add(filename);
|
|
5770
|
+
appendedFilenames.push(filename);
|
|
5771
|
+
});
|
|
5772
|
+
zipWriter.writerLocked = true;
|
|
5773
|
+
const { lockWriter } = zipWriter;
|
|
5774
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
5775
|
+
zipWriter.writerLocked = false;
|
|
5776
|
+
resolve();
|
|
5777
|
+
});
|
|
5778
|
+
await lockWriter;
|
|
5779
|
+
if (zipWriter.addSplitZipSignature) {
|
|
5780
|
+
delete zipWriter.addSplitZipSignature;
|
|
5781
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
5782
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
5783
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
5784
|
+
}
|
|
5686
5785
|
}
|
|
5786
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
|
|
5787
|
+
entries.forEach(entry => {
|
|
5788
|
+
const {
|
|
5789
|
+
version,
|
|
5790
|
+
rawLastModDate,
|
|
5791
|
+
rawFilename,
|
|
5792
|
+
bitFlag,
|
|
5793
|
+
encrypted,
|
|
5794
|
+
uncompressedSize,
|
|
5795
|
+
compressedSize,
|
|
5796
|
+
extraFieldZip64
|
|
5797
|
+
} = entry;
|
|
5798
|
+
let {
|
|
5799
|
+
compressionMethod,
|
|
5800
|
+
rawExtraField,
|
|
5801
|
+
} = entry;
|
|
5802
|
+
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
5803
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
5804
|
+
if (entry.extraFieldAES) {
|
|
5805
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
5806
|
+
}
|
|
5807
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
5808
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
5809
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
5810
|
+
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
5811
|
+
const {
|
|
5812
|
+
headerArray,
|
|
5813
|
+
headerView
|
|
5814
|
+
} = getHeaderArrayData({
|
|
5815
|
+
version,
|
|
5816
|
+
bitFlag: bitFlagValue,
|
|
5817
|
+
compressionMethod,
|
|
5818
|
+
uncompressedSize,
|
|
5819
|
+
compressedSize,
|
|
5820
|
+
rawLastModDate,
|
|
5821
|
+
rawFilename,
|
|
5822
|
+
zip64CompressedSize,
|
|
5823
|
+
zip64UncompressedSize,
|
|
5824
|
+
extraFieldLength
|
|
5825
|
+
});
|
|
5826
|
+
const { crc32 } = entry;
|
|
5827
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
5828
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
5829
|
+
}
|
|
5830
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
5831
|
+
Object.assign(entry, {
|
|
5832
|
+
zip64UncompressedSize,
|
|
5833
|
+
zip64CompressedSize,
|
|
5834
|
+
offset,
|
|
5835
|
+
diskNumberStart,
|
|
5836
|
+
zip64DiskNumberStart: false,
|
|
5837
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
5838
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
5839
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
5840
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
5841
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
5842
|
+
rawExtraField,
|
|
5843
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
5844
|
+
extendedTimestamp: false,
|
|
5845
|
+
headerArray,
|
|
5846
|
+
headerView
|
|
5847
|
+
});
|
|
5848
|
+
fileEntries.set(entry.filename, entry);
|
|
5849
|
+
});
|
|
5850
|
+
} catch (error) {
|
|
5851
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
5687
5852
|
throw error;
|
|
5688
5853
|
} finally {
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
if (
|
|
5692
|
-
|
|
5693
|
-
} else {
|
|
5694
|
-
workers--;
|
|
5854
|
+
resolveAppendZip();
|
|
5855
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
5856
|
+
if (releaseLockWriter) {
|
|
5857
|
+
releaseLockWriter();
|
|
5695
5858
|
}
|
|
5696
5859
|
}
|
|
5697
5860
|
}
|
|
5698
5861
|
|
|
5862
|
+
add(name = "", reader, options = {}) {
|
|
5863
|
+
const zipWriter = this;
|
|
5864
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
5865
|
+
const promiseAddFile = addFileEntry(zipWriter, name, reader, options);
|
|
5866
|
+
pendingAddFileCalls.add(promiseAddFile);
|
|
5867
|
+
const deletePendingAddFileCall = () => pendingAddFileCalls.delete(promiseAddFile);
|
|
5868
|
+
Promise.prototype.then.call(promiseAddFile, deletePendingAddFileCall, deletePendingAddFileCall);
|
|
5869
|
+
return watchPromiseError(zipWriter, promiseAddFile);
|
|
5870
|
+
}
|
|
5871
|
+
|
|
5699
5872
|
remove(entry) {
|
|
5700
5873
|
const { filenames, fileEntries } = this;
|
|
5701
5874
|
// deno-lint-ignore valid-typeof
|
|
@@ -5726,6 +5899,19 @@
|
|
|
5726
5899
|
while (pendingAddFileCalls.size) {
|
|
5727
5900
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
5728
5901
|
}
|
|
5902
|
+
await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
|
|
5903
|
+
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
|
|
5904
|
+
if (unobservedWatchers.length) {
|
|
5905
|
+
const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
|
|
5906
|
+
unobservedWatchers.forEach(watcher => watcher.observed = true);
|
|
5907
|
+
const [error] = unobservedErrors;
|
|
5908
|
+
try {
|
|
5909
|
+
error.entryErrors = unobservedErrors;
|
|
5910
|
+
} catch {
|
|
5911
|
+
// ignored
|
|
5912
|
+
}
|
|
5913
|
+
throw error;
|
|
5914
|
+
}
|
|
5729
5915
|
await closeFile(zipWriter, comment, options);
|
|
5730
5916
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
5731
5917
|
if (!preventClose) {
|
|
@@ -5735,6 +5921,62 @@
|
|
|
5735
5921
|
}
|
|
5736
5922
|
}
|
|
5737
5923
|
|
|
5924
|
+
class WatchedPromise extends Promise {
|
|
5925
|
+
|
|
5926
|
+
then(onFulfilled, onRejected) {
|
|
5927
|
+
const { watcher } = this;
|
|
5928
|
+
if (watcher) {
|
|
5929
|
+
watcher.observed = true;
|
|
5930
|
+
}
|
|
5931
|
+
return super.then(onFulfilled, onRejected);
|
|
5932
|
+
}
|
|
5933
|
+
}
|
|
5934
|
+
|
|
5935
|
+
function watchPromiseError(zipWriter, promise) {
|
|
5936
|
+
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
5937
|
+
const watcher = {};
|
|
5938
|
+
watchedPromise.watcher = watcher;
|
|
5939
|
+
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
|
|
5940
|
+
zipWriter.pendingErrors.push(watcher);
|
|
5941
|
+
return watchedPromise;
|
|
5942
|
+
}
|
|
5943
|
+
|
|
5944
|
+
async function prependZipEntries(zipWriter, reader) {
|
|
5945
|
+
if (zipWriter.filenames.size) {
|
|
5946
|
+
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
5947
|
+
}
|
|
5948
|
+
await zipWriter.appendZipEntries(reader);
|
|
5949
|
+
}
|
|
5950
|
+
|
|
5951
|
+
async function addFileEntry(zipWriter, name, reader, options) {
|
|
5952
|
+
options = Object.assign({}, options);
|
|
5953
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
5954
|
+
name += DIRECTORY_SIGNATURE;
|
|
5955
|
+
}
|
|
5956
|
+
if (zipWriter.filenames.has(name)) {
|
|
5957
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
5958
|
+
}
|
|
5959
|
+
zipWriter.filenames.add(name);
|
|
5960
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
5961
|
+
workers++;
|
|
5962
|
+
} else {
|
|
5963
|
+
await new Promise(resolve => pendingEntries.push(resolve));
|
|
5964
|
+
}
|
|
5965
|
+
try {
|
|
5966
|
+
return await addFile(zipWriter, name, reader, options);
|
|
5967
|
+
} catch (error) {
|
|
5968
|
+
zipWriter.filenames.delete(name);
|
|
5969
|
+
throw error;
|
|
5970
|
+
} finally {
|
|
5971
|
+
const pendingEntry = pendingEntries.shift();
|
|
5972
|
+
if (pendingEntry) {
|
|
5973
|
+
pendingEntry();
|
|
5974
|
+
} else {
|
|
5975
|
+
workers--;
|
|
5976
|
+
}
|
|
5977
|
+
}
|
|
5978
|
+
}
|
|
5979
|
+
|
|
5738
5980
|
async function addFile(zipWriter, name, reader, options) {
|
|
5739
5981
|
const attributesInfo = resolveAttributes(zipWriter, name, options);
|
|
5740
5982
|
({ name } = attributesInfo);
|
|
@@ -5779,7 +6021,6 @@
|
|
|
5779
6021
|
}
|
|
5780
6022
|
|
|
5781
6023
|
function resolveAttributes(zipWriter, name, options) {
|
|
5782
|
-
name = name.trim();
|
|
5783
6024
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
5784
6025
|
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
5785
6026
|
const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
|
|
@@ -5923,11 +6164,12 @@
|
|
|
5923
6164
|
if (getLength(rawComment) > MAX_16_BITS) {
|
|
5924
6165
|
throw new Error(ERR_INVALID_ENTRY_COMMENT);
|
|
5925
6166
|
}
|
|
5926
|
-
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION
|
|
5927
|
-
if (version > MAX_16_BITS) {
|
|
6167
|
+
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION);
|
|
6168
|
+
if (version !== UNDEFINED_VALUE && version > MAX_16_BITS) {
|
|
5928
6169
|
throw new Error(ERR_INVALID_VERSION);
|
|
5929
6170
|
}
|
|
5930
6171
|
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
6172
|
+
const rawLastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
|
|
5931
6173
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
5932
6174
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
5933
6175
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
@@ -5971,7 +6213,7 @@
|
|
|
5971
6213
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
5972
6214
|
dataDescriptor = false;
|
|
5973
6215
|
}
|
|
5974
|
-
if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
|
|
6216
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
|
|
5975
6217
|
dataDescriptor = true;
|
|
5976
6218
|
}
|
|
5977
6219
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -5983,6 +6225,7 @@
|
|
|
5983
6225
|
}
|
|
5984
6226
|
const rawExtraField = serializeExtraField(options[PROPERTY_NAME_EXTRA_FIELD]);
|
|
5985
6227
|
const rawLocalExtraField = serializeExtraField(options[OPTION_LOCAL_EXTRA_FIELD]);
|
|
6228
|
+
const rawCentralExtraField = serializeExtraField(options[OPTION_CENTRAL_EXTRA_FIELD]);
|
|
5986
6229
|
return {
|
|
5987
6230
|
comment,
|
|
5988
6231
|
resolvedOptions: {
|
|
@@ -5990,6 +6233,7 @@
|
|
|
5990
6233
|
rawComment,
|
|
5991
6234
|
version,
|
|
5992
6235
|
lastModDate,
|
|
6236
|
+
rawLastModDate,
|
|
5993
6237
|
lastAccessDate,
|
|
5994
6238
|
creationDate,
|
|
5995
6239
|
internalFileAttributes,
|
|
@@ -6017,7 +6261,8 @@
|
|
|
6017
6261
|
dataDescriptor,
|
|
6018
6262
|
zip64,
|
|
6019
6263
|
rawExtraField,
|
|
6020
|
-
rawLocalExtraField
|
|
6264
|
+
rawLocalExtraField,
|
|
6265
|
+
rawCentralExtraField
|
|
6021
6266
|
}
|
|
6022
6267
|
};
|
|
6023
6268
|
}
|
|
@@ -6159,7 +6404,6 @@
|
|
|
6159
6404
|
let { name } = entry;
|
|
6160
6405
|
const { size } = entry;
|
|
6161
6406
|
const options = Object.assign({}, entry.options);
|
|
6162
|
-
name = name.trim();
|
|
6163
6407
|
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6164
6408
|
name += DIRECTORY_SIGNATURE;
|
|
6165
6409
|
}
|
|
@@ -6265,10 +6509,8 @@
|
|
|
6265
6509
|
}
|
|
6266
6510
|
await initStream(fileWriter);
|
|
6267
6511
|
const diskOffset = getDiskOffset(writer);
|
|
6268
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6269
|
-
|
|
6270
|
-
await writeData(writer, getSplitZipSignatureArray());
|
|
6271
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6512
|
+
if (zipWriter.addSplitZipSignature && !bufferedWrite) {
|
|
6513
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
6272
6514
|
}
|
|
6273
6515
|
if (usdz && !bufferedWrite) {
|
|
6274
6516
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -6295,6 +6537,9 @@
|
|
|
6295
6537
|
if (bufferedWrite) {
|
|
6296
6538
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
6297
6539
|
await requestLockWriter();
|
|
6540
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6541
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
6542
|
+
}
|
|
6298
6543
|
writingBufferedEntryData = true;
|
|
6299
6544
|
writerSizeBeforeEntry = writer.size;
|
|
6300
6545
|
await skipDiskIfNeeded();
|
|
@@ -6414,6 +6659,7 @@
|
|
|
6414
6659
|
versionMadeBy,
|
|
6415
6660
|
rawComment,
|
|
6416
6661
|
rawExtraField,
|
|
6662
|
+
rawCentralExtraField,
|
|
6417
6663
|
useWebWorkers,
|
|
6418
6664
|
transferStreams,
|
|
6419
6665
|
onstart,
|
|
@@ -6457,6 +6703,7 @@
|
|
|
6457
6703
|
rawExtraFieldUnix,
|
|
6458
6704
|
rawExtraFieldAES,
|
|
6459
6705
|
rawExtraField,
|
|
6706
|
+
rawCentralExtraField,
|
|
6460
6707
|
extendedTimestamp,
|
|
6461
6708
|
msDosCompatible,
|
|
6462
6709
|
internalFileAttributes,
|
|
@@ -6566,6 +6813,7 @@
|
|
|
6566
6813
|
const {
|
|
6567
6814
|
rawFilename,
|
|
6568
6815
|
lastModDate,
|
|
6816
|
+
rawLastModDate: rawLastModDateOption,
|
|
6569
6817
|
lastAccessDate,
|
|
6570
6818
|
creationDate,
|
|
6571
6819
|
level,
|
|
@@ -6699,6 +6947,9 @@
|
|
|
6699
6947
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
6700
6948
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
6701
6949
|
}
|
|
6950
|
+
if (version === UNDEFINED_VALUE) {
|
|
6951
|
+
version = compressionMethod == COMPRESSION_METHOD_STORE && !directory && !encrypted ? VERSION_STORE : VERSION_DEFLATE;
|
|
6952
|
+
}
|
|
6702
6953
|
const { codecVersionNeeded } = options;
|
|
6703
6954
|
if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
|
|
6704
6955
|
version = version > codecVersionNeeded ? version : codecVersionNeeded;
|
|
@@ -6731,6 +6982,7 @@
|
|
|
6731
6982
|
compressionMethod,
|
|
6732
6983
|
uncompressedSize,
|
|
6733
6984
|
lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
|
|
6985
|
+
rawLastModDate: rawLastModDateOption,
|
|
6734
6986
|
rawFilename,
|
|
6735
6987
|
zip64CompressedSize,
|
|
6736
6988
|
zip64UncompressedSize,
|
|
@@ -6937,9 +7189,9 @@
|
|
|
6937
7189
|
|
|
6938
7190
|
async function closeFile(zipWriter, comment, options) {
|
|
6939
7191
|
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
6940
|
-
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7192
|
+
const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
6941
7193
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
6942
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
7194
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
|
|
6943
7195
|
}
|
|
6944
7196
|
|
|
6945
7197
|
function createDirectoryRecords(files) {
|
|
@@ -6952,6 +7204,7 @@
|
|
|
6952
7204
|
rawExtraFieldNTFS,
|
|
6953
7205
|
rawExtraFieldUnix,
|
|
6954
7206
|
rawExtraField,
|
|
7207
|
+
rawCentralExtraField,
|
|
6955
7208
|
extendedTimestamp,
|
|
6956
7209
|
extraFieldExtendedTimestampFlag,
|
|
6957
7210
|
lastModDate,
|
|
@@ -7006,7 +7259,8 @@
|
|
|
7006
7259
|
rawExtraFieldNTFS,
|
|
7007
7260
|
rawExtraFieldUnix,
|
|
7008
7261
|
rawExtraFieldTimestamp,
|
|
7009
|
-
rawExtraField
|
|
7262
|
+
rawExtraField,
|
|
7263
|
+
rawCentralExtraField);
|
|
7010
7264
|
if (extraFieldLength > MAX_16_BITS) {
|
|
7011
7265
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
7012
7266
|
}
|
|
@@ -7023,6 +7277,7 @@
|
|
|
7023
7277
|
let directoryDiskOffset = 0;
|
|
7024
7278
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
7025
7279
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
7280
|
+
let directoryEndDiskEntriesLength = 0;
|
|
7026
7281
|
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
7027
7282
|
const {
|
|
7028
7283
|
offset: fileEntryOffset,
|
|
@@ -7033,6 +7288,7 @@
|
|
|
7033
7288
|
rawExtraFieldNTFS,
|
|
7034
7289
|
rawExtraFieldUnix,
|
|
7035
7290
|
rawExtraField,
|
|
7291
|
+
rawCentralExtraField,
|
|
7036
7292
|
rawComment,
|
|
7037
7293
|
versionMadeBy,
|
|
7038
7294
|
headerArray,
|
|
@@ -7047,11 +7303,12 @@
|
|
|
7047
7303
|
uncompressedSize,
|
|
7048
7304
|
compressedSize
|
|
7049
7305
|
} = fileEntry;
|
|
7050
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
7306
|
+
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawCentralExtraField);
|
|
7051
7307
|
const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
|
|
7052
7308
|
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
7053
7309
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
7054
7310
|
directoryDiskOffset = offset;
|
|
7311
|
+
directoryEndDiskEntriesLength = 0;
|
|
7055
7312
|
await writer.closeDisk();
|
|
7056
7313
|
}
|
|
7057
7314
|
if (indexFileEntry == 0) {
|
|
@@ -7084,9 +7341,11 @@
|
|
|
7084
7341
|
directoryRecord.writeBytes(rawExtraFieldNTFS);
|
|
7085
7342
|
directoryRecord.writeBytes(rawExtraFieldUnix);
|
|
7086
7343
|
directoryRecord.writeBytes(rawExtraField);
|
|
7344
|
+
directoryRecord.writeBytes(rawCentralExtraField);
|
|
7087
7345
|
directoryRecord.writeBytes(rawComment);
|
|
7088
7346
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
7089
7347
|
offset += directoryRecordLength;
|
|
7348
|
+
directoryEndDiskEntriesLength++;
|
|
7090
7349
|
if (options.onprogress) {
|
|
7091
7350
|
try {
|
|
7092
7351
|
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
@@ -7098,6 +7357,7 @@
|
|
|
7098
7357
|
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
7099
7358
|
return {
|
|
7100
7359
|
directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
|
|
7360
|
+
directoryEnd: { diskNumber: getDiskNumber(writer), entriesLength: directoryEndDiskEntriesLength },
|
|
7101
7361
|
directoryArray
|
|
7102
7362
|
};
|
|
7103
7363
|
}
|
|
@@ -7126,16 +7386,20 @@
|
|
|
7126
7386
|
|
|
7127
7387
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
7128
7388
|
const { writer } = zipWriter;
|
|
7129
|
-
const { directoryStart, signatureLength } = cdInfo;
|
|
7389
|
+
const { directoryStart, directoryEnd, signatureLength } = cdInfo;
|
|
7130
7390
|
let { directoryDataLength } = cdInfo;
|
|
7131
7391
|
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
7132
7392
|
let diskNumber = directoryStart.diskNumber;
|
|
7133
7393
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
7394
|
+
const commentLength = getLength(comment);
|
|
7395
|
+
if (commentLength > MAX_16_BITS) {
|
|
7396
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
7397
|
+
}
|
|
7398
|
+
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7134
7399
|
let lastDiskNumber = getDiskNumber(writer);
|
|
7135
|
-
if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
|
|
7400
|
+
if (exceedsAvailableSize(writer, (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH) + commentLength)) {
|
|
7136
7401
|
lastDiskNumber++;
|
|
7137
7402
|
}
|
|
7138
|
-
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7139
7403
|
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
7140
7404
|
if (zip64 === false) {
|
|
7141
7405
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
@@ -7143,15 +7407,12 @@
|
|
|
7143
7407
|
zip64 = true;
|
|
7144
7408
|
}
|
|
7145
7409
|
}
|
|
7146
|
-
const commentLength = getLength(comment);
|
|
7147
|
-
if (commentLength > MAX_16_BITS) {
|
|
7148
|
-
throw new Error(ERR_INVALID_COMMENT);
|
|
7149
|
-
}
|
|
7150
7410
|
const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
7151
7411
|
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
|
7152
7412
|
await writer.closeDisk();
|
|
7153
7413
|
}
|
|
7154
7414
|
lastDiskNumber = getDiskNumber(writer);
|
|
7415
|
+
let diskFileEntriesLength = lastDiskNumber == directoryEnd.diskNumber ? directoryEnd.entriesLength : 0;
|
|
7155
7416
|
if (zip64) {
|
|
7156
7417
|
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7157
7418
|
endOfdirectoryRecord.writeUint64(44);
|
|
@@ -7159,7 +7420,7 @@
|
|
|
7159
7420
|
endOfdirectoryRecord.writeUint16(45);
|
|
7160
7421
|
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7161
7422
|
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
7162
|
-
endOfdirectoryRecord.writeUint64(
|
|
7423
|
+
endOfdirectoryRecord.writeUint64(diskFileEntriesLength);
|
|
7163
7424
|
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7164
7425
|
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
7165
7426
|
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
@@ -7172,6 +7433,7 @@
|
|
|
7172
7433
|
lastDiskNumber = MAX_16_BITS;
|
|
7173
7434
|
diskNumber = MAX_16_BITS;
|
|
7174
7435
|
}
|
|
7436
|
+
diskFileEntriesLength = MAX_16_BITS;
|
|
7175
7437
|
fileEntriesLength = MAX_16_BITS;
|
|
7176
7438
|
directoryOffset = MAX_32_BITS;
|
|
7177
7439
|
directoryDataLength = MAX_32_BITS;
|
|
@@ -7179,7 +7441,7 @@
|
|
|
7179
7441
|
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7180
7442
|
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
7181
7443
|
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
7182
|
-
endOfdirectoryRecord.writeUint16(
|
|
7444
|
+
endOfdirectoryRecord.writeUint16(diskFileEntriesLength);
|
|
7183
7445
|
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7184
7446
|
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
7185
7447
|
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
@@ -7278,9 +7540,21 @@
|
|
|
7278
7540
|
async function copyData(zipWriter, reader, offset, size) {
|
|
7279
7541
|
if (size > 0) {
|
|
7280
7542
|
const { writer } = zipWriter;
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7543
|
+
let copiedLength = 0;
|
|
7544
|
+
try {
|
|
7545
|
+
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
7546
|
+
} catch (error) {
|
|
7547
|
+
zipWriter.hasCorruptedEntries = true;
|
|
7548
|
+
try {
|
|
7549
|
+
error.corruptedEntry = true;
|
|
7550
|
+
} catch {
|
|
7551
|
+
// ignored
|
|
7552
|
+
}
|
|
7553
|
+
throw error;
|
|
7554
|
+
} finally {
|
|
7555
|
+
writer.size += copiedLength;
|
|
7556
|
+
zipWriter.offset += copiedLength;
|
|
7557
|
+
}
|
|
7284
7558
|
}
|
|
7285
7559
|
}
|
|
7286
7560
|
|
|
@@ -7305,6 +7579,12 @@
|
|
|
7305
7579
|
return signatureArray;
|
|
7306
7580
|
}
|
|
7307
7581
|
|
|
7582
|
+
async function writeSplitZipSignature(zipWriter, writer) {
|
|
7583
|
+
delete zipWriter.addSplitZipSignature;
|
|
7584
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
7585
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
7586
|
+
}
|
|
7587
|
+
|
|
7308
7588
|
async function writeData(writer, array) {
|
|
7309
7589
|
const { writable } = writer;
|
|
7310
7590
|
const streamWriter = writable.getWriter();
|
|
@@ -7536,6 +7816,7 @@
|
|
|
7536
7816
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
7537
7817
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
7538
7818
|
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
7819
|
+
const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
|
|
7539
7820
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
7540
7821
|
const ERR_ABORTED = "The operation was aborted";
|
|
7541
7822
|
const ABORT_ERROR_NAME = "AbortError";
|
|
@@ -8403,6 +8684,7 @@
|
|
|
8403
8684
|
versionMadeBy,
|
|
8404
8685
|
comment,
|
|
8405
8686
|
lastModDate,
|
|
8687
|
+
rawLastModDate,
|
|
8406
8688
|
creationDate,
|
|
8407
8689
|
lastAccessDate,
|
|
8408
8690
|
uncompressedSize,
|
|
@@ -8413,6 +8695,7 @@
|
|
|
8413
8695
|
extraFieldAES,
|
|
8414
8696
|
internalFileAttributes,
|
|
8415
8697
|
extraField,
|
|
8698
|
+
bitFlag,
|
|
8416
8699
|
uid,
|
|
8417
8700
|
gid
|
|
8418
8701
|
} = child.data;
|
|
@@ -8450,6 +8733,16 @@
|
|
|
8450
8733
|
encryptionStrength,
|
|
8451
8734
|
compressionMethod
|
|
8452
8735
|
};
|
|
8736
|
+
if (bitFlag) {
|
|
8737
|
+
passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
|
|
8738
|
+
}
|
|
8739
|
+
const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
|
|
8740
|
+
if (lastModDateOverride === UNDEFINED_VALUE) {
|
|
8741
|
+
passThroughOptions.rawLastModDate = rawLastModDate;
|
|
8742
|
+
} else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
|
|
8743
|
+
getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
|
|
8744
|
+
throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
|
|
8745
|
+
}
|
|
8453
8746
|
}
|
|
8454
8747
|
}
|
|
8455
8748
|
const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
|
|
@@ -8459,6 +8752,16 @@
|
|
|
8459
8752
|
return { name, entryOptions };
|
|
8460
8753
|
}
|
|
8461
8754
|
|
|
8755
|
+
function getDosTimeHighByte(lastModDate) {
|
|
8756
|
+
let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
8757
|
+
if (dosLastModDate < MIN_DATE) {
|
|
8758
|
+
dosLastModDate = MIN_DATE;
|
|
8759
|
+
} else if (dosLastModDate > MAX_DATE) {
|
|
8760
|
+
dosLastModDate = MAX_DATE;
|
|
8761
|
+
}
|
|
8762
|
+
return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
|
|
8763
|
+
}
|
|
8764
|
+
|
|
8462
8765
|
function getDeterminedSize(child, passThrough) {
|
|
8463
8766
|
const { reader } = child;
|
|
8464
8767
|
if (reader && reader.size !== UNDEFINED_VALUE) {
|
|
@@ -8802,6 +9105,7 @@
|
|
|
8802
9105
|
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
8803
9106
|
exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
|
|
8804
9107
|
exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
|
|
9108
|
+
exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
|
|
8805
9109
|
exports.ZipDirectoryEntry = ZipDirectoryEntry;
|
|
8806
9110
|
exports.ZipEntry = ZipEntry;
|
|
8807
9111
|
exports.ZipFS = ZipFS;
|