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