@zip.js/zip.js 2.20.0 → 2.21.0
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 +327 -211
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +327 -211
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +327 -211
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +327 -211
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +327 -211
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +327 -211
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +327 -211
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +327 -211
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +327 -211
- package/dist/zip-native.min.js +1 -1
- package/dist/zip.js +327 -211
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +327 -211
- package/index-native.min.js +1 -1
- package/index.cjs +327 -211
- package/index.d.cts +62 -29
- package/index.d.ts +62 -29
- package/index.min.js +1 -1
- package/lib/core/constants.js +7 -0
- package/lib/core/version.js +1 -1
- package/lib/core/zip-reader.js +156 -69
- package/lib/core/zip-writer.js +172 -142
- package/package.json +1 -1
package/dist/zip-fs-native.js
CHANGED
|
@@ -126,6 +126,10 @@
|
|
|
126
126
|
|
|
127
127
|
const UNDEFINED_VALUE = undefined;
|
|
128
128
|
const INFINITY_VALUE = Infinity;
|
|
129
|
+
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
130
|
+
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
131
|
+
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
132
|
+
|
|
129
133
|
const UNDEFINED_TYPE = "undefined";
|
|
130
134
|
const FUNCTION_TYPE = "function";
|
|
131
135
|
const OBJECT_TYPE = "object";
|
|
@@ -4777,12 +4781,9 @@
|
|
|
4777
4781
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4778
4782
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4779
4783
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4780
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4781
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4782
4784
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4783
4785
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4784
4786
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4785
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4786
4787
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4787
4788
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4788
4789
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4847,7 +4848,8 @@
|
|
|
4847
4848
|
Object.assign(this, {
|
|
4848
4849
|
reader: new GenericReader(reader),
|
|
4849
4850
|
options,
|
|
4850
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4851
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4852
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4851
4853
|
});
|
|
4852
4854
|
}
|
|
4853
4855
|
|
|
@@ -4918,16 +4920,22 @@
|
|
|
4918
4920
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4919
4921
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4920
4922
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4923
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4924
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4925
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4926
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4927
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4928
|
+
}
|
|
4929
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4930
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4931
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4932
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4933
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4934
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4935
|
+
}
|
|
4936
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4937
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4928
4938
|
}
|
|
4929
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4930
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4931
4939
|
}
|
|
4932
4940
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4933
4941
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4972,10 +4980,6 @@
|
|
|
4972
4980
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4973
4981
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4974
4982
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4975
|
-
if (directoryDataOffset >= reader.size) {
|
|
4976
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4977
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4978
|
-
}
|
|
4979
4983
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4980
4984
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4981
4985
|
}
|
|
@@ -4983,52 +4987,64 @@
|
|
|
4983
4987
|
throw new Error(ERR_BAD_FORMAT);
|
|
4984
4988
|
}
|
|
4985
4989
|
let offset = 0;
|
|
4986
|
-
let directoryArray =
|
|
4990
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4991
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4992
|
+
EMPTY_UINT8_ARRAY;
|
|
4987
4993
|
let directoryView = getDataView(directoryArray);
|
|
4988
4994
|
if (directoryDataLength) {
|
|
4989
|
-
if (directoryArray.length < 4) {
|
|
4990
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4991
|
-
}
|
|
4992
4995
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4993
4996
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4994
|
-
const storedPointsAtDirectory =
|
|
4997
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
4998
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4995
4999
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4996
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5000
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5001
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5002
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5003
|
+
}
|
|
4997
5004
|
let reconcile = !storedPointsAtDirectory;
|
|
4998
5005
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4999
|
-
|
|
5000
|
-
if (
|
|
5001
|
-
reconcile = expectedPointsAtDirectory;
|
|
5002
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5006
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5007
|
+
if (!expectedPointsAtDirectory) {
|
|
5003
5008
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5004
5009
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5005
5010
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5006
5011
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5007
5012
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5013
|
+
expectedPointsAtDirectory = true;
|
|
5008
5014
|
}
|
|
5009
5015
|
}
|
|
5016
|
+
if (storedPointsAtDirectory) {
|
|
5017
|
+
reconcile = expectedPointsAtDirectory;
|
|
5018
|
+
}
|
|
5010
5019
|
}
|
|
5011
|
-
if (reconcile) {
|
|
5020
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5012
5021
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5013
5022
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5014
5023
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5015
5024
|
directoryView = getDataView(directoryArray);
|
|
5016
|
-
|
|
5017
|
-
|
|
5025
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5026
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5027
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5028
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5029
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5030
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5031
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5032
|
+
prependedDataLength += offsetDelta;
|
|
5018
5033
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5019
5034
|
} else {
|
|
5020
5035
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5024
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5025
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5026
|
-
prependedDataLength += offsetDelta;
|
|
5027
|
-
}
|
|
5036
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5037
|
+
prependedDataLength += offsetDelta;
|
|
5028
5038
|
}
|
|
5029
5039
|
}
|
|
5030
5040
|
}
|
|
5031
5041
|
}
|
|
5042
|
+
if (directoryArray.length < 4) {
|
|
5043
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5044
|
+
}
|
|
5045
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5046
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5047
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5032
5048
|
}
|
|
5033
5049
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5034
5050
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5070,8 +5086,10 @@
|
|
|
5070
5086
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5071
5087
|
}
|
|
5072
5088
|
}
|
|
5089
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5090
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5073
5091
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5074
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5092
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5075
5093
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5076
5094
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5077
5095
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5162,13 +5180,17 @@
|
|
|
5162
5180
|
if (malformedExtraField) {
|
|
5163
5181
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5164
5182
|
}
|
|
5165
|
-
fileEntry.offset
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5183
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5184
|
+
startOffset = 0;
|
|
5185
|
+
} else {
|
|
5186
|
+
fileEntry.offset += prependedDataLength;
|
|
5187
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5188
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5189
|
+
if (entryPosition < previousEntryPosition) {
|
|
5190
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5191
|
+
}
|
|
5192
|
+
previousEntryPosition = entryPosition;
|
|
5170
5193
|
}
|
|
5171
|
-
previousEntryPosition = entryPosition;
|
|
5172
5194
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5173
5195
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5174
5196
|
}
|
|
@@ -5205,12 +5227,15 @@
|
|
|
5205
5227
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5206
5228
|
});
|
|
5207
5229
|
const entry = new Entry(fileEntry);
|
|
5208
|
-
|
|
5230
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5231
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5232
|
+
}
|
|
5233
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5209
5234
|
entry.arrayBuffer = async options => {
|
|
5210
5235
|
const writer = new TransformStream();
|
|
5211
5236
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5212
5237
|
arrayBufferPromise.catch(() => { });
|
|
5213
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5238
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5214
5239
|
Object.assign({}, options, { preventClose: false }));
|
|
5215
5240
|
return arrayBufferPromise;
|
|
5216
5241
|
};
|
|
@@ -5418,8 +5443,9 @@
|
|
|
5418
5443
|
});
|
|
5419
5444
|
}
|
|
5420
5445
|
|
|
5421
|
-
async getData(writer, fileEntry,
|
|
5446
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5422
5447
|
const zipEntry = this;
|
|
5448
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5423
5449
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5424
5450
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5425
5451
|
}
|
|
@@ -5493,10 +5519,10 @@
|
|
|
5493
5519
|
}
|
|
5494
5520
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5495
5521
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5496
|
-
if (lastAccessDate) {
|
|
5522
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5497
5523
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5498
5524
|
}
|
|
5499
|
-
if (creationDate) {
|
|
5525
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5500
5526
|
fileEntry.creationDate = creationDate;
|
|
5501
5527
|
}
|
|
5502
5528
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5525,7 +5551,7 @@
|
|
|
5525
5551
|
throw new Error(ERR_ENCRYPTED);
|
|
5526
5552
|
}
|
|
5527
5553
|
}
|
|
5528
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5554
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5529
5555
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5530
5556
|
}
|
|
5531
5557
|
const size = compressedSize;
|
|
@@ -5591,6 +5617,7 @@
|
|
|
5591
5617
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5592
5618
|
readRanges
|
|
5593
5619
|
});
|
|
5620
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5594
5621
|
}
|
|
5595
5622
|
let writable, abortError, aborted;
|
|
5596
5623
|
try {
|
|
@@ -5610,10 +5637,7 @@
|
|
|
5610
5637
|
writer.size += writtenSize;
|
|
5611
5638
|
}
|
|
5612
5639
|
} catch (error) {
|
|
5613
|
-
|
|
5614
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5615
|
-
writer.size += failedOutputSize;
|
|
5616
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5640
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5617
5641
|
writer.size += error.outputSize;
|
|
5618
5642
|
}
|
|
5619
5643
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5641,13 +5665,7 @@
|
|
|
5641
5665
|
};
|
|
5642
5666
|
|
|
5643
5667
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5644
|
-
|
|
5645
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5646
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5647
|
-
return true;
|
|
5648
|
-
}
|
|
5649
|
-
}
|
|
5650
|
-
return false;
|
|
5668
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5651
5669
|
}
|
|
5652
5670
|
|
|
5653
5671
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5684,6 +5702,46 @@
|
|
|
5684
5702
|
}
|
|
5685
5703
|
}
|
|
5686
5704
|
|
|
5705
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5706
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5707
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5708
|
+
const tailView = getDataView(tailArray);
|
|
5709
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5710
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5711
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5712
|
+
return startOffset + indexByte;
|
|
5713
|
+
}
|
|
5714
|
+
}
|
|
5715
|
+
}
|
|
5716
|
+
|
|
5717
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5718
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5719
|
+
return UNDEFINED_VALUE;
|
|
5720
|
+
}
|
|
5721
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5722
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5723
|
+
return localHeaderOffset;
|
|
5724
|
+
}
|
|
5725
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5726
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5727
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5728
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5729
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5730
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5731
|
+
let offsetValue = offsetExtraField + 4;
|
|
5732
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5733
|
+
offsetValue += 8;
|
|
5734
|
+
}
|
|
5735
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5736
|
+
offsetValue += 8;
|
|
5737
|
+
}
|
|
5738
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5739
|
+
}
|
|
5740
|
+
offsetExtraField += 4 + size;
|
|
5741
|
+
}
|
|
5742
|
+
return UNDEFINED_VALUE;
|
|
5743
|
+
}
|
|
5744
|
+
|
|
5687
5745
|
function readDigitalSignature(signatureRecordArray) {
|
|
5688
5746
|
if (signatureRecordArray.length >= 6) {
|
|
5689
5747
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5773,6 +5831,7 @@
|
|
|
5773
5831
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5774
5832
|
});
|
|
5775
5833
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5834
|
+
let extraFieldZip64Missing;
|
|
5776
5835
|
if (extraFieldZip64) {
|
|
5777
5836
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5778
5837
|
malformedExtraField = true;
|
|
@@ -5782,7 +5841,7 @@
|
|
|
5782
5841
|
if (localDirectory) {
|
|
5783
5842
|
malformedExtraField = true;
|
|
5784
5843
|
} else {
|
|
5785
|
-
|
|
5844
|
+
extraFieldZip64Missing = true;
|
|
5786
5845
|
}
|
|
5787
5846
|
}
|
|
5788
5847
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5840,6 +5899,9 @@
|
|
|
5840
5899
|
if (extraFieldUSDZ) {
|
|
5841
5900
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5842
5901
|
}
|
|
5902
|
+
if (extraFieldZip64Missing) {
|
|
5903
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5904
|
+
}
|
|
5843
5905
|
return malformedExtraField;
|
|
5844
5906
|
}
|
|
5845
5907
|
|
|
@@ -6054,13 +6116,7 @@
|
|
|
6054
6116
|
let dataDescriptorLength = 0;
|
|
6055
6117
|
if (dataDescriptor) {
|
|
6056
6118
|
const zip64 = Boolean(extraFieldZip64);
|
|
6057
|
-
const
|
|
6058
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6059
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6060
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6061
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6062
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6063
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6119
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6064
6120
|
if (localDataDescriptor) {
|
|
6065
6121
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6066
6122
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6130,6 +6186,25 @@
|
|
|
6130
6186
|
return mergedRanges;
|
|
6131
6187
|
}
|
|
6132
6188
|
|
|
6189
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6190
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6191
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6192
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6193
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6194
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6195
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6196
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6197
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6198
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6199
|
+
}
|
|
6200
|
+
|
|
6201
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6202
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6203
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6204
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6205
|
+
}
|
|
6206
|
+
}
|
|
6207
|
+
|
|
6133
6208
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6134
6209
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6135
6210
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6389,6 +6464,18 @@
|
|
|
6389
6464
|
}
|
|
6390
6465
|
}
|
|
6391
6466
|
|
|
6467
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6468
|
+
const { dataDescriptor } = localDirectory;
|
|
6469
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6470
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6471
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6472
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6473
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6474
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6475
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6476
|
+
}
|
|
6477
|
+
}
|
|
6478
|
+
|
|
6392
6479
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6393
6480
|
if (reject) {
|
|
6394
6481
|
throwAmbiguousArchive(reason);
|
|
@@ -6491,6 +6578,7 @@
|
|
|
6491
6578
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6492
6579
|
ZipReader: ZipReader,
|
|
6493
6580
|
ZipReaderStream: ZipReaderStream,
|
|
6581
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6494
6582
|
isZipFile: isZipFile
|
|
6495
6583
|
});
|
|
6496
6584
|
|
|
@@ -6614,136 +6702,7 @@
|
|
|
6614
6702
|
}
|
|
6615
6703
|
|
|
6616
6704
|
appendZip(reader, options = {}) {
|
|
6617
|
-
return watchPromiseError(this,
|
|
6618
|
-
}
|
|
6619
|
-
|
|
6620
|
-
async appendZipEntries(reader, options = {}) {
|
|
6621
|
-
const zipWriter = this;
|
|
6622
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6623
|
-
const filter = checkFunctionOption(options.filter);
|
|
6624
|
-
while (pendingAddFileCalls.size) {
|
|
6625
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6626
|
-
}
|
|
6627
|
-
let resolveAppendZip;
|
|
6628
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6629
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6630
|
-
const appendedFilenames = [];
|
|
6631
|
-
let releaseLockWriter;
|
|
6632
|
-
try {
|
|
6633
|
-
reader = new GenericReader(reader);
|
|
6634
|
-
await initStream(reader);
|
|
6635
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6636
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6637
|
-
await initStream(reader);
|
|
6638
|
-
}
|
|
6639
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6640
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6641
|
-
const entries = await zipReader$1.getEntries();
|
|
6642
|
-
const keptEntries = [];
|
|
6643
|
-
for (const entry of entries) {
|
|
6644
|
-
if (!filter || await filter(entry)) {
|
|
6645
|
-
keptEntries.push(entry);
|
|
6646
|
-
}
|
|
6647
|
-
}
|
|
6648
|
-
await zipReader$1.close();
|
|
6649
|
-
await initStream(zipWriter.writer);
|
|
6650
|
-
const { directoryOffset } = zipReader$1;
|
|
6651
|
-
keptEntries.forEach(({ filename }) => {
|
|
6652
|
-
if (filenames.has(filename)) {
|
|
6653
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6654
|
-
}
|
|
6655
|
-
filenames.add(filename);
|
|
6656
|
-
appendedFilenames.push(filename);
|
|
6657
|
-
});
|
|
6658
|
-
zipWriter.writerLocked = true;
|
|
6659
|
-
const { lockWriter } = zipWriter;
|
|
6660
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6661
|
-
zipWriter.writerLocked = false;
|
|
6662
|
-
resolve();
|
|
6663
|
-
});
|
|
6664
|
-
await lockWriter;
|
|
6665
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6666
|
-
delete zipWriter.addSplitZipSignature;
|
|
6667
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6668
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6669
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6670
|
-
}
|
|
6671
|
-
}
|
|
6672
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6673
|
-
keptEntries.forEach(entry => {
|
|
6674
|
-
const {
|
|
6675
|
-
version,
|
|
6676
|
-
rawLastModDate,
|
|
6677
|
-
rawFilename,
|
|
6678
|
-
bitFlag,
|
|
6679
|
-
encrypted,
|
|
6680
|
-
uncompressedSize,
|
|
6681
|
-
compressedSize,
|
|
6682
|
-
extraFieldZip64
|
|
6683
|
-
} = entry;
|
|
6684
|
-
let {
|
|
6685
|
-
compressionMethod,
|
|
6686
|
-
rawExtraField,
|
|
6687
|
-
} = entry;
|
|
6688
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6689
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6690
|
-
if (entry.extraFieldAES) {
|
|
6691
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6692
|
-
}
|
|
6693
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6694
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6695
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6696
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6697
|
-
const {
|
|
6698
|
-
headerArray,
|
|
6699
|
-
headerView
|
|
6700
|
-
} = getHeaderArrayData({
|
|
6701
|
-
version,
|
|
6702
|
-
bitFlag: bitFlagValue,
|
|
6703
|
-
compressionMethod,
|
|
6704
|
-
uncompressedSize,
|
|
6705
|
-
compressedSize,
|
|
6706
|
-
rawLastModDate,
|
|
6707
|
-
rawFilename,
|
|
6708
|
-
zip64CompressedSize,
|
|
6709
|
-
zip64UncompressedSize,
|
|
6710
|
-
extraFieldLength
|
|
6711
|
-
});
|
|
6712
|
-
const { crc32 } = entry;
|
|
6713
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6714
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6715
|
-
}
|
|
6716
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6717
|
-
Object.assign(entry, {
|
|
6718
|
-
zip64Enabled: true,
|
|
6719
|
-
zip64UncompressedSize,
|
|
6720
|
-
zip64CompressedSize,
|
|
6721
|
-
offset,
|
|
6722
|
-
diskNumberStart,
|
|
6723
|
-
zip64DiskNumberStart: false,
|
|
6724
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6725
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6726
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6727
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6728
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6729
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6730
|
-
rawExtraField,
|
|
6731
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6732
|
-
headerArray,
|
|
6733
|
-
headerView
|
|
6734
|
-
});
|
|
6735
|
-
fileEntries.set(entry.filename, entry);
|
|
6736
|
-
});
|
|
6737
|
-
} catch (error) {
|
|
6738
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6739
|
-
throw error;
|
|
6740
|
-
} finally {
|
|
6741
|
-
resolveAppendZip();
|
|
6742
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6743
|
-
if (releaseLockWriter) {
|
|
6744
|
-
releaseLockWriter();
|
|
6745
|
-
}
|
|
6746
|
-
}
|
|
6705
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6747
6706
|
}
|
|
6748
6707
|
|
|
6749
6708
|
add(name = "", reader, options = {}) {
|
|
@@ -6905,11 +6864,140 @@
|
|
|
6905
6864
|
return watchedPromise;
|
|
6906
6865
|
}
|
|
6907
6866
|
|
|
6867
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6868
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6869
|
+
const filter = checkFunctionOption(options.filter);
|
|
6870
|
+
while (pendingAddFileCalls.size) {
|
|
6871
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6872
|
+
}
|
|
6873
|
+
let resolveAppendZip;
|
|
6874
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6875
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6876
|
+
const appendedFilenames = [];
|
|
6877
|
+
let releaseLockWriter;
|
|
6878
|
+
try {
|
|
6879
|
+
reader = new GenericReader(reader);
|
|
6880
|
+
await initStream(reader);
|
|
6881
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6882
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6883
|
+
await initStream(reader);
|
|
6884
|
+
}
|
|
6885
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6886
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6887
|
+
const entries = await zipReader$1.getEntries();
|
|
6888
|
+
const keptEntries = [];
|
|
6889
|
+
for (const entry of entries) {
|
|
6890
|
+
if (!filter || await filter(entry)) {
|
|
6891
|
+
keptEntries.push(entry);
|
|
6892
|
+
}
|
|
6893
|
+
}
|
|
6894
|
+
await zipReader$1.close();
|
|
6895
|
+
await initStream(zipWriter.writer);
|
|
6896
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6897
|
+
keptEntries.forEach(entry => {
|
|
6898
|
+
const { filename } = entry;
|
|
6899
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6900
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6901
|
+
}
|
|
6902
|
+
if (filenames.has(filename)) {
|
|
6903
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6904
|
+
}
|
|
6905
|
+
filenames.add(filename);
|
|
6906
|
+
appendedFilenames.push(filename);
|
|
6907
|
+
});
|
|
6908
|
+
zipWriter.writerLocked = true;
|
|
6909
|
+
const { lockWriter } = zipWriter;
|
|
6910
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6911
|
+
zipWriter.writerLocked = false;
|
|
6912
|
+
resolve();
|
|
6913
|
+
});
|
|
6914
|
+
await lockWriter;
|
|
6915
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6916
|
+
delete zipWriter.addSplitZipSignature;
|
|
6917
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6918
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6919
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6920
|
+
}
|
|
6921
|
+
}
|
|
6922
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6923
|
+
keptEntries.forEach(entry => {
|
|
6924
|
+
const {
|
|
6925
|
+
version,
|
|
6926
|
+
rawLastModDate,
|
|
6927
|
+
rawFilename,
|
|
6928
|
+
rawBitFlag,
|
|
6929
|
+
uncompressedSize,
|
|
6930
|
+
compressedSize,
|
|
6931
|
+
extraFieldZip64
|
|
6932
|
+
} = entry;
|
|
6933
|
+
let {
|
|
6934
|
+
compressionMethod,
|
|
6935
|
+
rawExtraField,
|
|
6936
|
+
} = entry;
|
|
6937
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6938
|
+
if (entry.extraFieldAES) {
|
|
6939
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6940
|
+
}
|
|
6941
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6942
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6943
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6944
|
+
const {
|
|
6945
|
+
headerArray,
|
|
6946
|
+
headerView
|
|
6947
|
+
} = getHeaderArrayData({
|
|
6948
|
+
version,
|
|
6949
|
+
bitFlag: rawBitFlag,
|
|
6950
|
+
compressionMethod,
|
|
6951
|
+
uncompressedSize,
|
|
6952
|
+
compressedSize,
|
|
6953
|
+
rawLastModDate,
|
|
6954
|
+
rawFilename,
|
|
6955
|
+
zip64CompressedSize,
|
|
6956
|
+
zip64UncompressedSize,
|
|
6957
|
+
extraFieldLength
|
|
6958
|
+
});
|
|
6959
|
+
const { crc32 } = entry;
|
|
6960
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6961
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6962
|
+
}
|
|
6963
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6964
|
+
Object.assign(entry, {
|
|
6965
|
+
zip64Enabled: true,
|
|
6966
|
+
zip64UncompressedSize,
|
|
6967
|
+
zip64CompressedSize,
|
|
6968
|
+
offset,
|
|
6969
|
+
diskNumberStart,
|
|
6970
|
+
zip64DiskNumberStart: false,
|
|
6971
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6972
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6973
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6974
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6975
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6976
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6977
|
+
rawExtraField,
|
|
6978
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6979
|
+
headerArray,
|
|
6980
|
+
headerView
|
|
6981
|
+
});
|
|
6982
|
+
fileEntries.set(entry.filename, entry);
|
|
6983
|
+
});
|
|
6984
|
+
} catch (error) {
|
|
6985
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6986
|
+
throw error;
|
|
6987
|
+
} finally {
|
|
6988
|
+
resolveAppendZip();
|
|
6989
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6990
|
+
if (releaseLockWriter) {
|
|
6991
|
+
releaseLockWriter();
|
|
6992
|
+
}
|
|
6993
|
+
}
|
|
6994
|
+
}
|
|
6995
|
+
|
|
6908
6996
|
async function prependZipEntries(zipWriter, reader) {
|
|
6909
6997
|
if (zipWriter.filenames.size) {
|
|
6910
6998
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6911
6999
|
}
|
|
6912
|
-
await
|
|
7000
|
+
await appendZipEntries(zipWriter, reader);
|
|
6913
7001
|
}
|
|
6914
7002
|
|
|
6915
7003
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8681,7 +8769,7 @@
|
|
|
8681
8769
|
return rawExtraField;
|
|
8682
8770
|
}
|
|
8683
8771
|
|
|
8684
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8772
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8685
8773
|
const { writer } = zipWriter;
|
|
8686
8774
|
const entryPositions = new Map();
|
|
8687
8775
|
if (writer.closeDisk || compact) {
|
|
@@ -8689,6 +8777,27 @@
|
|
|
8689
8777
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8690
8778
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8691
8779
|
const keptEntrySet = new Set(keptEntries);
|
|
8780
|
+
const localHeaderLengths = new Map();
|
|
8781
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8782
|
+
const entry = sortedEntries[indexEntry];
|
|
8783
|
+
if (keptEntrySet.has(entry)) {
|
|
8784
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8785
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8786
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8787
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8788
|
+
}
|
|
8789
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8790
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8791
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8792
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8793
|
+
}
|
|
8794
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8795
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8796
|
+
}
|
|
8797
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8798
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8799
|
+
}
|
|
8800
|
+
}
|
|
8692
8801
|
let copiedOffset = 0;
|
|
8693
8802
|
let lastPosition;
|
|
8694
8803
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8701,7 +8810,7 @@
|
|
|
8701
8810
|
if (!compact) {
|
|
8702
8811
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8703
8812
|
}
|
|
8704
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8813
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8705
8814
|
await writer.closeDisk();
|
|
8706
8815
|
}
|
|
8707
8816
|
lastPosition = {
|
|
@@ -8735,7 +8844,7 @@
|
|
|
8735
8844
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8736
8845
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8737
8846
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8738
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8847
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8739
8848
|
}
|
|
8740
8849
|
regionEnds[indexEntry] = regionEnd;
|
|
8741
8850
|
}
|
|
@@ -8749,11 +8858,13 @@
|
|
|
8749
8858
|
try {
|
|
8750
8859
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8751
8860
|
} catch (error) {
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8861
|
+
if (copiedLength) {
|
|
8862
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8863
|
+
try {
|
|
8864
|
+
error.corruptedEntry = true;
|
|
8865
|
+
} catch {
|
|
8866
|
+
// ignored
|
|
8867
|
+
}
|
|
8757
8868
|
}
|
|
8758
8869
|
throw error;
|
|
8759
8870
|
} finally {
|
|
@@ -8764,11 +8875,16 @@
|
|
|
8764
8875
|
}
|
|
8765
8876
|
|
|
8766
8877
|
async function getLocalHeaderLength(reader, offset) {
|
|
8767
|
-
const headerArray =
|
|
8878
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8879
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8880
|
+
EMPTY_UINT8_ARRAY;
|
|
8768
8881
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8769
|
-
return
|
|
8882
|
+
return UNDEFINED_VALUE;
|
|
8770
8883
|
}
|
|
8771
8884
|
const headerView = getDataView(headerArray);
|
|
8885
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8886
|
+
return UNDEFINED_VALUE;
|
|
8887
|
+
}
|
|
8772
8888
|
return HEADER_SIZE +
|
|
8773
8889
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8774
8890
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9119,7 +9235,7 @@
|
|
|
9119
9235
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9120
9236
|
*/
|
|
9121
9237
|
|
|
9122
|
-
const VERSION = "2.
|
|
9238
|
+
const VERSION = "2.21.0";
|
|
9123
9239
|
|
|
9124
9240
|
/*
|
|
9125
9241
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|