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