@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-core.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";
|
|
@@ -4755,12 +4759,9 @@
|
|
|
4755
4759
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4756
4760
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4757
4761
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4758
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4759
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4760
4762
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4761
4763
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4762
4764
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4763
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4764
4765
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4765
4766
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4766
4767
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4825,7 +4826,8 @@
|
|
|
4825
4826
|
Object.assign(this, {
|
|
4826
4827
|
reader: new GenericReader(reader),
|
|
4827
4828
|
options,
|
|
4828
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4829
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4830
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4829
4831
|
});
|
|
4830
4832
|
}
|
|
4831
4833
|
|
|
@@ -4896,16 +4898,22 @@
|
|
|
4896
4898
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4897
4899
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4898
4900
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4901
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4902
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4903
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4904
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4905
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4906
|
+
}
|
|
4907
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4908
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4909
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4910
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4911
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4912
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4913
|
+
}
|
|
4914
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4915
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4906
4916
|
}
|
|
4907
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4908
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4909
4917
|
}
|
|
4910
4918
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4911
4919
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4950,10 +4958,6 @@
|
|
|
4950
4958
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4951
4959
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4952
4960
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4953
|
-
if (directoryDataOffset >= reader.size) {
|
|
4954
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4955
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4956
|
-
}
|
|
4957
4961
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4958
4962
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4959
4963
|
}
|
|
@@ -4961,52 +4965,64 @@
|
|
|
4961
4965
|
throw new Error(ERR_BAD_FORMAT);
|
|
4962
4966
|
}
|
|
4963
4967
|
let offset = 0;
|
|
4964
|
-
let directoryArray =
|
|
4968
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4969
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4970
|
+
EMPTY_UINT8_ARRAY;
|
|
4965
4971
|
let directoryView = getDataView(directoryArray);
|
|
4966
4972
|
if (directoryDataLength) {
|
|
4967
|
-
if (directoryArray.length < 4) {
|
|
4968
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4969
|
-
}
|
|
4970
4973
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4971
4974
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4972
|
-
const storedPointsAtDirectory =
|
|
4975
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
4976
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4973
4977
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4974
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
4978
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
4979
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
4980
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
4981
|
+
}
|
|
4975
4982
|
let reconcile = !storedPointsAtDirectory;
|
|
4976
4983
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4977
|
-
|
|
4978
|
-
if (
|
|
4979
|
-
reconcile = expectedPointsAtDirectory;
|
|
4980
|
-
} else if (!expectedPointsAtDirectory) {
|
|
4984
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
4985
|
+
if (!expectedPointsAtDirectory) {
|
|
4981
4986
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
4982
4987
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
4983
4988
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
4984
4989
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
4985
4990
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
4991
|
+
expectedPointsAtDirectory = true;
|
|
4986
4992
|
}
|
|
4987
4993
|
}
|
|
4994
|
+
if (storedPointsAtDirectory) {
|
|
4995
|
+
reconcile = expectedPointsAtDirectory;
|
|
4996
|
+
}
|
|
4988
4997
|
}
|
|
4989
|
-
if (reconcile) {
|
|
4998
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
4990
4999
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4991
5000
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4992
5001
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4993
5002
|
directoryView = getDataView(directoryArray);
|
|
4994
|
-
|
|
4995
|
-
|
|
5003
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5004
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5005
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5006
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5007
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5008
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5009
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5010
|
+
prependedDataLength += offsetDelta;
|
|
4996
5011
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
4997
5012
|
} else {
|
|
4998
5013
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5002
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5003
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5004
|
-
prependedDataLength += offsetDelta;
|
|
5005
|
-
}
|
|
5014
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5015
|
+
prependedDataLength += offsetDelta;
|
|
5006
5016
|
}
|
|
5007
5017
|
}
|
|
5008
5018
|
}
|
|
5009
5019
|
}
|
|
5020
|
+
if (directoryArray.length < 4) {
|
|
5021
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5022
|
+
}
|
|
5023
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5024
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5025
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5010
5026
|
}
|
|
5011
5027
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5012
5028
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5048,8 +5064,10 @@
|
|
|
5048
5064
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5049
5065
|
}
|
|
5050
5066
|
}
|
|
5067
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5068
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5051
5069
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5052
|
-
const fileEntry = new ZipEntry(reader,
|
|
5070
|
+
const fileEntry = new ZipEntry(reader, entryOptions);
|
|
5053
5071
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5054
5072
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5055
5073
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5140,13 +5158,17 @@
|
|
|
5140
5158
|
if (malformedExtraField) {
|
|
5141
5159
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5142
5160
|
}
|
|
5143
|
-
fileEntry.offset
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5161
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5162
|
+
startOffset = 0;
|
|
5163
|
+
} else {
|
|
5164
|
+
fileEntry.offset += prependedDataLength;
|
|
5165
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5166
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5167
|
+
if (entryPosition < previousEntryPosition) {
|
|
5168
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5169
|
+
}
|
|
5170
|
+
previousEntryPosition = entryPosition;
|
|
5148
5171
|
}
|
|
5149
|
-
previousEntryPosition = entryPosition;
|
|
5150
5172
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5151
5173
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5152
5174
|
}
|
|
@@ -5183,12 +5205,15 @@
|
|
|
5183
5205
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5184
5206
|
});
|
|
5185
5207
|
const entry = new Entry(fileEntry);
|
|
5186
|
-
|
|
5208
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5209
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5210
|
+
}
|
|
5211
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5187
5212
|
entry.arrayBuffer = async options => {
|
|
5188
5213
|
const writer = new TransformStream();
|
|
5189
5214
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5190
5215
|
arrayBufferPromise.catch(() => { });
|
|
5191
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5216
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5192
5217
|
Object.assign({}, options, { preventClose: false }));
|
|
5193
5218
|
return arrayBufferPromise;
|
|
5194
5219
|
};
|
|
@@ -5396,8 +5421,9 @@
|
|
|
5396
5421
|
});
|
|
5397
5422
|
}
|
|
5398
5423
|
|
|
5399
|
-
async getData(writer, fileEntry,
|
|
5424
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5400
5425
|
const zipEntry = this;
|
|
5426
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5401
5427
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5402
5428
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5403
5429
|
}
|
|
@@ -5471,10 +5497,10 @@
|
|
|
5471
5497
|
}
|
|
5472
5498
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5473
5499
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5474
|
-
if (lastAccessDate) {
|
|
5500
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5475
5501
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5476
5502
|
}
|
|
5477
|
-
if (creationDate) {
|
|
5503
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5478
5504
|
fileEntry.creationDate = creationDate;
|
|
5479
5505
|
}
|
|
5480
5506
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5503,7 +5529,7 @@
|
|
|
5503
5529
|
throw new Error(ERR_ENCRYPTED);
|
|
5504
5530
|
}
|
|
5505
5531
|
}
|
|
5506
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5532
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5507
5533
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5508
5534
|
}
|
|
5509
5535
|
const size = compressedSize;
|
|
@@ -5569,6 +5595,7 @@
|
|
|
5569
5595
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5570
5596
|
readRanges
|
|
5571
5597
|
});
|
|
5598
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5572
5599
|
}
|
|
5573
5600
|
let writable, abortError, aborted;
|
|
5574
5601
|
try {
|
|
@@ -5588,10 +5615,7 @@
|
|
|
5588
5615
|
writer.size += writtenSize;
|
|
5589
5616
|
}
|
|
5590
5617
|
} catch (error) {
|
|
5591
|
-
|
|
5592
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5593
|
-
writer.size += failedOutputSize;
|
|
5594
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5618
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5595
5619
|
writer.size += error.outputSize;
|
|
5596
5620
|
}
|
|
5597
5621
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5619,13 +5643,7 @@
|
|
|
5619
5643
|
}
|
|
5620
5644
|
|
|
5621
5645
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5622
|
-
|
|
5623
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5624
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5625
|
-
return true;
|
|
5626
|
-
}
|
|
5627
|
-
}
|
|
5628
|
-
return false;
|
|
5646
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5629
5647
|
}
|
|
5630
5648
|
|
|
5631
5649
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5662,6 +5680,46 @@
|
|
|
5662
5680
|
}
|
|
5663
5681
|
}
|
|
5664
5682
|
|
|
5683
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5684
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5685
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5686
|
+
const tailView = getDataView(tailArray);
|
|
5687
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5688
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5689
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5690
|
+
return startOffset + indexByte;
|
|
5691
|
+
}
|
|
5692
|
+
}
|
|
5693
|
+
}
|
|
5694
|
+
|
|
5695
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5696
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5697
|
+
return UNDEFINED_VALUE;
|
|
5698
|
+
}
|
|
5699
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5700
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5701
|
+
return localHeaderOffset;
|
|
5702
|
+
}
|
|
5703
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5704
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5705
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5706
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5707
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5708
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5709
|
+
let offsetValue = offsetExtraField + 4;
|
|
5710
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5711
|
+
offsetValue += 8;
|
|
5712
|
+
}
|
|
5713
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5714
|
+
offsetValue += 8;
|
|
5715
|
+
}
|
|
5716
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5717
|
+
}
|
|
5718
|
+
offsetExtraField += 4 + size;
|
|
5719
|
+
}
|
|
5720
|
+
return UNDEFINED_VALUE;
|
|
5721
|
+
}
|
|
5722
|
+
|
|
5665
5723
|
function readDigitalSignature(signatureRecordArray) {
|
|
5666
5724
|
if (signatureRecordArray.length >= 6) {
|
|
5667
5725
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5751,6 +5809,7 @@
|
|
|
5751
5809
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5752
5810
|
});
|
|
5753
5811
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5812
|
+
let extraFieldZip64Missing;
|
|
5754
5813
|
if (extraFieldZip64) {
|
|
5755
5814
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5756
5815
|
malformedExtraField = true;
|
|
@@ -5760,7 +5819,7 @@
|
|
|
5760
5819
|
if (localDirectory) {
|
|
5761
5820
|
malformedExtraField = true;
|
|
5762
5821
|
} else {
|
|
5763
|
-
|
|
5822
|
+
extraFieldZip64Missing = true;
|
|
5764
5823
|
}
|
|
5765
5824
|
}
|
|
5766
5825
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5818,6 +5877,9 @@
|
|
|
5818
5877
|
if (extraFieldUSDZ) {
|
|
5819
5878
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5820
5879
|
}
|
|
5880
|
+
if (extraFieldZip64Missing) {
|
|
5881
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5882
|
+
}
|
|
5821
5883
|
return malformedExtraField;
|
|
5822
5884
|
}
|
|
5823
5885
|
|
|
@@ -6032,13 +6094,7 @@
|
|
|
6032
6094
|
let dataDescriptorLength = 0;
|
|
6033
6095
|
if (dataDescriptor) {
|
|
6034
6096
|
const zip64 = Boolean(extraFieldZip64);
|
|
6035
|
-
const
|
|
6036
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6037
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6038
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6039
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6040
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6041
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6097
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6042
6098
|
if (localDataDescriptor) {
|
|
6043
6099
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6044
6100
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6108,6 +6164,25 @@
|
|
|
6108
6164
|
return mergedRanges;
|
|
6109
6165
|
}
|
|
6110
6166
|
|
|
6167
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6168
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6169
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6170
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6171
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6172
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6173
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6174
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6175
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6176
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6177
|
+
}
|
|
6178
|
+
|
|
6179
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6180
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6181
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6182
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6183
|
+
}
|
|
6184
|
+
}
|
|
6185
|
+
|
|
6111
6186
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6112
6187
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6113
6188
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6367,6 +6442,18 @@
|
|
|
6367
6442
|
}
|
|
6368
6443
|
}
|
|
6369
6444
|
|
|
6445
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6446
|
+
const { dataDescriptor } = localDirectory;
|
|
6447
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6448
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6449
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6450
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6451
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6452
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6453
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6454
|
+
}
|
|
6455
|
+
}
|
|
6456
|
+
|
|
6370
6457
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6371
6458
|
if (reject) {
|
|
6372
6459
|
throwAmbiguousArchive(reason);
|
|
@@ -6469,6 +6556,7 @@
|
|
|
6469
6556
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6470
6557
|
ZipReader: ZipReader,
|
|
6471
6558
|
ZipReaderStream: ZipReaderStream,
|
|
6559
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6472
6560
|
isZipFile: isZipFile
|
|
6473
6561
|
});
|
|
6474
6562
|
|
|
@@ -6592,136 +6680,7 @@
|
|
|
6592
6680
|
}
|
|
6593
6681
|
|
|
6594
6682
|
appendZip(reader, options = {}) {
|
|
6595
|
-
return watchPromiseError(this,
|
|
6596
|
-
}
|
|
6597
|
-
|
|
6598
|
-
async appendZipEntries(reader, options = {}) {
|
|
6599
|
-
const zipWriter = this;
|
|
6600
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6601
|
-
const filter = checkFunctionOption(options.filter);
|
|
6602
|
-
while (pendingAddFileCalls.size) {
|
|
6603
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6604
|
-
}
|
|
6605
|
-
let resolveAppendZip;
|
|
6606
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6607
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6608
|
-
const appendedFilenames = [];
|
|
6609
|
-
let releaseLockWriter;
|
|
6610
|
-
try {
|
|
6611
|
-
reader = new GenericReader(reader);
|
|
6612
|
-
await initStream(reader);
|
|
6613
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6614
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6615
|
-
await initStream(reader);
|
|
6616
|
-
}
|
|
6617
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6618
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6619
|
-
const entries = await zipReader$1.getEntries();
|
|
6620
|
-
const keptEntries = [];
|
|
6621
|
-
for (const entry of entries) {
|
|
6622
|
-
if (!filter || await filter(entry)) {
|
|
6623
|
-
keptEntries.push(entry);
|
|
6624
|
-
}
|
|
6625
|
-
}
|
|
6626
|
-
await zipReader$1.close();
|
|
6627
|
-
await initStream(zipWriter.writer);
|
|
6628
|
-
const { directoryOffset } = zipReader$1;
|
|
6629
|
-
keptEntries.forEach(({ filename }) => {
|
|
6630
|
-
if (filenames.has(filename)) {
|
|
6631
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6632
|
-
}
|
|
6633
|
-
filenames.add(filename);
|
|
6634
|
-
appendedFilenames.push(filename);
|
|
6635
|
-
});
|
|
6636
|
-
zipWriter.writerLocked = true;
|
|
6637
|
-
const { lockWriter } = zipWriter;
|
|
6638
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6639
|
-
zipWriter.writerLocked = false;
|
|
6640
|
-
resolve();
|
|
6641
|
-
});
|
|
6642
|
-
await lockWriter;
|
|
6643
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6644
|
-
delete zipWriter.addSplitZipSignature;
|
|
6645
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6646
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6647
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6648
|
-
}
|
|
6649
|
-
}
|
|
6650
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6651
|
-
keptEntries.forEach(entry => {
|
|
6652
|
-
const {
|
|
6653
|
-
version,
|
|
6654
|
-
rawLastModDate,
|
|
6655
|
-
rawFilename,
|
|
6656
|
-
bitFlag,
|
|
6657
|
-
encrypted,
|
|
6658
|
-
uncompressedSize,
|
|
6659
|
-
compressedSize,
|
|
6660
|
-
extraFieldZip64
|
|
6661
|
-
} = entry;
|
|
6662
|
-
let {
|
|
6663
|
-
compressionMethod,
|
|
6664
|
-
rawExtraField,
|
|
6665
|
-
} = entry;
|
|
6666
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6667
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6668
|
-
if (entry.extraFieldAES) {
|
|
6669
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6670
|
-
}
|
|
6671
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6672
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6673
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6674
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6675
|
-
const {
|
|
6676
|
-
headerArray,
|
|
6677
|
-
headerView
|
|
6678
|
-
} = getHeaderArrayData({
|
|
6679
|
-
version,
|
|
6680
|
-
bitFlag: bitFlagValue,
|
|
6681
|
-
compressionMethod,
|
|
6682
|
-
uncompressedSize,
|
|
6683
|
-
compressedSize,
|
|
6684
|
-
rawLastModDate,
|
|
6685
|
-
rawFilename,
|
|
6686
|
-
zip64CompressedSize,
|
|
6687
|
-
zip64UncompressedSize,
|
|
6688
|
-
extraFieldLength
|
|
6689
|
-
});
|
|
6690
|
-
const { crc32 } = entry;
|
|
6691
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6692
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6693
|
-
}
|
|
6694
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6695
|
-
Object.assign(entry, {
|
|
6696
|
-
zip64Enabled: true,
|
|
6697
|
-
zip64UncompressedSize,
|
|
6698
|
-
zip64CompressedSize,
|
|
6699
|
-
offset,
|
|
6700
|
-
diskNumberStart,
|
|
6701
|
-
zip64DiskNumberStart: false,
|
|
6702
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6703
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6704
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6705
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6706
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6707
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6708
|
-
rawExtraField,
|
|
6709
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6710
|
-
headerArray,
|
|
6711
|
-
headerView
|
|
6712
|
-
});
|
|
6713
|
-
fileEntries.set(entry.filename, entry);
|
|
6714
|
-
});
|
|
6715
|
-
} catch (error) {
|
|
6716
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6717
|
-
throw error;
|
|
6718
|
-
} finally {
|
|
6719
|
-
resolveAppendZip();
|
|
6720
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6721
|
-
if (releaseLockWriter) {
|
|
6722
|
-
releaseLockWriter();
|
|
6723
|
-
}
|
|
6724
|
-
}
|
|
6683
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6725
6684
|
}
|
|
6726
6685
|
|
|
6727
6686
|
add(name = "", reader, options = {}) {
|
|
@@ -6883,11 +6842,140 @@
|
|
|
6883
6842
|
return watchedPromise;
|
|
6884
6843
|
}
|
|
6885
6844
|
|
|
6845
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6846
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6847
|
+
const filter = checkFunctionOption(options.filter);
|
|
6848
|
+
while (pendingAddFileCalls.size) {
|
|
6849
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6850
|
+
}
|
|
6851
|
+
let resolveAppendZip;
|
|
6852
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6853
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6854
|
+
const appendedFilenames = [];
|
|
6855
|
+
let releaseLockWriter;
|
|
6856
|
+
try {
|
|
6857
|
+
reader = new GenericReader(reader);
|
|
6858
|
+
await initStream(reader);
|
|
6859
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6860
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6861
|
+
await initStream(reader);
|
|
6862
|
+
}
|
|
6863
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6864
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6865
|
+
const entries = await zipReader$1.getEntries();
|
|
6866
|
+
const keptEntries = [];
|
|
6867
|
+
for (const entry of entries) {
|
|
6868
|
+
if (!filter || await filter(entry)) {
|
|
6869
|
+
keptEntries.push(entry);
|
|
6870
|
+
}
|
|
6871
|
+
}
|
|
6872
|
+
await zipReader$1.close();
|
|
6873
|
+
await initStream(zipWriter.writer);
|
|
6874
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6875
|
+
keptEntries.forEach(entry => {
|
|
6876
|
+
const { filename } = entry;
|
|
6877
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6878
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6879
|
+
}
|
|
6880
|
+
if (filenames.has(filename)) {
|
|
6881
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6882
|
+
}
|
|
6883
|
+
filenames.add(filename);
|
|
6884
|
+
appendedFilenames.push(filename);
|
|
6885
|
+
});
|
|
6886
|
+
zipWriter.writerLocked = true;
|
|
6887
|
+
const { lockWriter } = zipWriter;
|
|
6888
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6889
|
+
zipWriter.writerLocked = false;
|
|
6890
|
+
resolve();
|
|
6891
|
+
});
|
|
6892
|
+
await lockWriter;
|
|
6893
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6894
|
+
delete zipWriter.addSplitZipSignature;
|
|
6895
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6896
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6897
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6898
|
+
}
|
|
6899
|
+
}
|
|
6900
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6901
|
+
keptEntries.forEach(entry => {
|
|
6902
|
+
const {
|
|
6903
|
+
version,
|
|
6904
|
+
rawLastModDate,
|
|
6905
|
+
rawFilename,
|
|
6906
|
+
rawBitFlag,
|
|
6907
|
+
uncompressedSize,
|
|
6908
|
+
compressedSize,
|
|
6909
|
+
extraFieldZip64
|
|
6910
|
+
} = entry;
|
|
6911
|
+
let {
|
|
6912
|
+
compressionMethod,
|
|
6913
|
+
rawExtraField,
|
|
6914
|
+
} = entry;
|
|
6915
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6916
|
+
if (entry.extraFieldAES) {
|
|
6917
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6918
|
+
}
|
|
6919
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6920
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6921
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6922
|
+
const {
|
|
6923
|
+
headerArray,
|
|
6924
|
+
headerView
|
|
6925
|
+
} = getHeaderArrayData({
|
|
6926
|
+
version,
|
|
6927
|
+
bitFlag: rawBitFlag,
|
|
6928
|
+
compressionMethod,
|
|
6929
|
+
uncompressedSize,
|
|
6930
|
+
compressedSize,
|
|
6931
|
+
rawLastModDate,
|
|
6932
|
+
rawFilename,
|
|
6933
|
+
zip64CompressedSize,
|
|
6934
|
+
zip64UncompressedSize,
|
|
6935
|
+
extraFieldLength
|
|
6936
|
+
});
|
|
6937
|
+
const { crc32 } = entry;
|
|
6938
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6939
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6940
|
+
}
|
|
6941
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6942
|
+
Object.assign(entry, {
|
|
6943
|
+
zip64Enabled: true,
|
|
6944
|
+
zip64UncompressedSize,
|
|
6945
|
+
zip64CompressedSize,
|
|
6946
|
+
offset,
|
|
6947
|
+
diskNumberStart,
|
|
6948
|
+
zip64DiskNumberStart: false,
|
|
6949
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6950
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6951
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6952
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6953
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6954
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6955
|
+
rawExtraField,
|
|
6956
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6957
|
+
headerArray,
|
|
6958
|
+
headerView
|
|
6959
|
+
});
|
|
6960
|
+
fileEntries.set(entry.filename, entry);
|
|
6961
|
+
});
|
|
6962
|
+
} catch (error) {
|
|
6963
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6964
|
+
throw error;
|
|
6965
|
+
} finally {
|
|
6966
|
+
resolveAppendZip();
|
|
6967
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6968
|
+
if (releaseLockWriter) {
|
|
6969
|
+
releaseLockWriter();
|
|
6970
|
+
}
|
|
6971
|
+
}
|
|
6972
|
+
}
|
|
6973
|
+
|
|
6886
6974
|
async function prependZipEntries(zipWriter, reader) {
|
|
6887
6975
|
if (zipWriter.filenames.size) {
|
|
6888
6976
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6889
6977
|
}
|
|
6890
|
-
await
|
|
6978
|
+
await appendZipEntries(zipWriter, reader);
|
|
6891
6979
|
}
|
|
6892
6980
|
|
|
6893
6981
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8561,7 +8649,7 @@
|
|
|
8561
8649
|
return rawExtraField;
|
|
8562
8650
|
}
|
|
8563
8651
|
|
|
8564
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8652
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8565
8653
|
const { writer } = zipWriter;
|
|
8566
8654
|
const entryPositions = new Map();
|
|
8567
8655
|
if (writer.closeDisk || compact) {
|
|
@@ -8569,6 +8657,27 @@
|
|
|
8569
8657
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8570
8658
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8571
8659
|
const keptEntrySet = new Set(keptEntries);
|
|
8660
|
+
const localHeaderLengths = new Map();
|
|
8661
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8662
|
+
const entry = sortedEntries[indexEntry];
|
|
8663
|
+
if (keptEntrySet.has(entry)) {
|
|
8664
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8665
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8666
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8667
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8668
|
+
}
|
|
8669
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8670
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8671
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8672
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8673
|
+
}
|
|
8674
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8675
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8676
|
+
}
|
|
8677
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8678
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8679
|
+
}
|
|
8680
|
+
}
|
|
8572
8681
|
let copiedOffset = 0;
|
|
8573
8682
|
let lastPosition;
|
|
8574
8683
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8581,7 +8690,7 @@
|
|
|
8581
8690
|
if (!compact) {
|
|
8582
8691
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8583
8692
|
}
|
|
8584
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8693
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8585
8694
|
await writer.closeDisk();
|
|
8586
8695
|
}
|
|
8587
8696
|
lastPosition = {
|
|
@@ -8615,7 +8724,7 @@
|
|
|
8615
8724
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8616
8725
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8617
8726
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8618
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8727
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8619
8728
|
}
|
|
8620
8729
|
regionEnds[indexEntry] = regionEnd;
|
|
8621
8730
|
}
|
|
@@ -8629,11 +8738,13 @@
|
|
|
8629
8738
|
try {
|
|
8630
8739
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8631
8740
|
} catch (error) {
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8741
|
+
if (copiedLength) {
|
|
8742
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8743
|
+
try {
|
|
8744
|
+
error.corruptedEntry = true;
|
|
8745
|
+
} catch {
|
|
8746
|
+
// ignored
|
|
8747
|
+
}
|
|
8637
8748
|
}
|
|
8638
8749
|
throw error;
|
|
8639
8750
|
} finally {
|
|
@@ -8644,11 +8755,16 @@
|
|
|
8644
8755
|
}
|
|
8645
8756
|
|
|
8646
8757
|
async function getLocalHeaderLength(reader, offset) {
|
|
8647
|
-
const headerArray =
|
|
8758
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8759
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8760
|
+
EMPTY_UINT8_ARRAY;
|
|
8648
8761
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8649
|
-
return
|
|
8762
|
+
return UNDEFINED_VALUE;
|
|
8650
8763
|
}
|
|
8651
8764
|
const headerView = getDataView(headerArray);
|
|
8765
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8766
|
+
return UNDEFINED_VALUE;
|
|
8767
|
+
}
|
|
8652
8768
|
return HEADER_SIZE +
|
|
8653
8769
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8654
8770
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -8999,7 +9115,7 @@
|
|
|
8999
9115
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9000
9116
|
*/
|
|
9001
9117
|
|
|
9002
|
-
const VERSION = "2.
|
|
9118
|
+
const VERSION = "2.21.0";
|
|
9003
9119
|
|
|
9004
9120
|
/*
|
|
9005
9121
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|