@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
|
@@ -117,6 +117,10 @@ const MIN_DATE = new Date(1980, 0, 1);
|
|
|
117
117
|
|
|
118
118
|
const UNDEFINED_VALUE = undefined;
|
|
119
119
|
const INFINITY_VALUE = Infinity;
|
|
120
|
+
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
121
|
+
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
122
|
+
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
123
|
+
|
|
120
124
|
const UNDEFINED_TYPE = "undefined";
|
|
121
125
|
const FUNCTION_TYPE = "function";
|
|
122
126
|
const OBJECT_TYPE = "object";
|
|
@@ -4790,12 +4794,9 @@ const ERR_BAD_FORMAT = "File format is not recognized";
|
|
|
4790
4794
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4791
4795
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4792
4796
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4793
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4794
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4795
4797
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4796
4798
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4797
4799
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4798
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4799
4800
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4800
4801
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4801
4802
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4860,7 +4861,8 @@ class ZipReader {
|
|
|
4860
4861
|
Object.assign(this, {
|
|
4861
4862
|
reader: new GenericReader(reader),
|
|
4862
4863
|
options,
|
|
4863
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4864
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4865
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4864
4866
|
});
|
|
4865
4867
|
}
|
|
4866
4868
|
|
|
@@ -4931,16 +4933,22 @@ class ZipReader {
|
|
|
4931
4933
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4932
4934
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4933
4935
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4936
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4937
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4938
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4939
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4940
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4941
|
+
}
|
|
4942
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4943
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4944
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4945
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4946
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4947
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4948
|
+
}
|
|
4949
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4950
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4941
4951
|
}
|
|
4942
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4943
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4944
4952
|
}
|
|
4945
4953
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4946
4954
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4985,10 +4993,6 @@ class ZipReader {
|
|
|
4985
4993
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4986
4994
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4987
4995
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4988
|
-
if (directoryDataOffset >= reader.size) {
|
|
4989
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4990
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4991
|
-
}
|
|
4992
4996
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4993
4997
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4994
4998
|
}
|
|
@@ -4996,52 +5000,64 @@ class ZipReader {
|
|
|
4996
5000
|
throw new Error(ERR_BAD_FORMAT);
|
|
4997
5001
|
}
|
|
4998
5002
|
let offset = 0;
|
|
4999
|
-
let directoryArray =
|
|
5003
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
5004
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
5005
|
+
EMPTY_UINT8_ARRAY;
|
|
5000
5006
|
let directoryView = getDataView(directoryArray);
|
|
5001
5007
|
if (directoryDataLength) {
|
|
5002
|
-
if (directoryArray.length < 4) {
|
|
5003
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
5004
|
-
}
|
|
5005
5008
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
5006
5009
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
5007
|
-
const storedPointsAtDirectory =
|
|
5010
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
5011
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
5008
5012
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
5009
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5013
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5014
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5015
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5016
|
+
}
|
|
5010
5017
|
let reconcile = !storedPointsAtDirectory;
|
|
5011
5018
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
5012
|
-
|
|
5013
|
-
if (
|
|
5014
|
-
reconcile = expectedPointsAtDirectory;
|
|
5015
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5019
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5020
|
+
if (!expectedPointsAtDirectory) {
|
|
5016
5021
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5017
5022
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5018
5023
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5019
5024
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5020
5025
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5026
|
+
expectedPointsAtDirectory = true;
|
|
5021
5027
|
}
|
|
5022
5028
|
}
|
|
5029
|
+
if (storedPointsAtDirectory) {
|
|
5030
|
+
reconcile = expectedPointsAtDirectory;
|
|
5031
|
+
}
|
|
5023
5032
|
}
|
|
5024
|
-
if (reconcile) {
|
|
5033
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5025
5034
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5026
5035
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5027
5036
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5028
5037
|
directoryView = getDataView(directoryArray);
|
|
5029
|
-
|
|
5030
|
-
|
|
5038
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5039
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5040
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5041
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5042
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5043
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5044
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5045
|
+
prependedDataLength += offsetDelta;
|
|
5031
5046
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5032
5047
|
} else {
|
|
5033
5048
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5037
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5038
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5039
|
-
prependedDataLength += offsetDelta;
|
|
5040
|
-
}
|
|
5049
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5050
|
+
prependedDataLength += offsetDelta;
|
|
5041
5051
|
}
|
|
5042
5052
|
}
|
|
5043
5053
|
}
|
|
5044
5054
|
}
|
|
5055
|
+
if (directoryArray.length < 4) {
|
|
5056
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5057
|
+
}
|
|
5058
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5059
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5060
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5045
5061
|
}
|
|
5046
5062
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5047
5063
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5083,8 +5099,10 @@ class ZipReader {
|
|
|
5083
5099
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5084
5100
|
}
|
|
5085
5101
|
}
|
|
5102
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5103
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5086
5104
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5087
|
-
const fileEntry = new ZipEntry(reader,
|
|
5105
|
+
const fileEntry = new ZipEntry(reader, entryOptions);
|
|
5088
5106
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5089
5107
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5090
5108
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5175,13 +5193,17 @@ class ZipReader {
|
|
|
5175
5193
|
if (malformedExtraField) {
|
|
5176
5194
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5177
5195
|
}
|
|
5178
|
-
fileEntry.offset
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5196
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5197
|
+
startOffset = 0;
|
|
5198
|
+
} else {
|
|
5199
|
+
fileEntry.offset += prependedDataLength;
|
|
5200
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5201
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5202
|
+
if (entryPosition < previousEntryPosition) {
|
|
5203
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5204
|
+
}
|
|
5205
|
+
previousEntryPosition = entryPosition;
|
|
5183
5206
|
}
|
|
5184
|
-
previousEntryPosition = entryPosition;
|
|
5185
5207
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5186
5208
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5187
5209
|
}
|
|
@@ -5218,12 +5240,15 @@ class ZipReader {
|
|
|
5218
5240
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5219
5241
|
});
|
|
5220
5242
|
const entry = new Entry(fileEntry);
|
|
5221
|
-
|
|
5243
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5244
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5245
|
+
}
|
|
5246
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5222
5247
|
entry.arrayBuffer = async options => {
|
|
5223
5248
|
const writer = new TransformStream();
|
|
5224
5249
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5225
5250
|
arrayBufferPromise.catch(() => { });
|
|
5226
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5251
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5227
5252
|
Object.assign({}, options, { preventClose: false }));
|
|
5228
5253
|
return arrayBufferPromise;
|
|
5229
5254
|
};
|
|
@@ -5431,8 +5456,9 @@ class ZipEntry {
|
|
|
5431
5456
|
});
|
|
5432
5457
|
}
|
|
5433
5458
|
|
|
5434
|
-
async getData(writer, fileEntry,
|
|
5459
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5435
5460
|
const zipEntry = this;
|
|
5461
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5436
5462
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5437
5463
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5438
5464
|
}
|
|
@@ -5506,10 +5532,10 @@ class ZipEntry {
|
|
|
5506
5532
|
}
|
|
5507
5533
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5508
5534
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5509
|
-
if (lastAccessDate) {
|
|
5535
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5510
5536
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5511
5537
|
}
|
|
5512
|
-
if (creationDate) {
|
|
5538
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5513
5539
|
fileEntry.creationDate = creationDate;
|
|
5514
5540
|
}
|
|
5515
5541
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5538,7 +5564,7 @@ class ZipEntry {
|
|
|
5538
5564
|
throw new Error(ERR_ENCRYPTED);
|
|
5539
5565
|
}
|
|
5540
5566
|
}
|
|
5541
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5567
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5542
5568
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5543
5569
|
}
|
|
5544
5570
|
const size = compressedSize;
|
|
@@ -5604,6 +5630,7 @@ class ZipEntry {
|
|
|
5604
5630
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5605
5631
|
readRanges
|
|
5606
5632
|
});
|
|
5633
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5607
5634
|
}
|
|
5608
5635
|
let writable, abortError, aborted;
|
|
5609
5636
|
try {
|
|
@@ -5623,10 +5650,7 @@ class ZipEntry {
|
|
|
5623
5650
|
writer.size += writtenSize;
|
|
5624
5651
|
}
|
|
5625
5652
|
} catch (error) {
|
|
5626
|
-
|
|
5627
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5628
|
-
writer.size += failedOutputSize;
|
|
5629
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5653
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5630
5654
|
writer.size += error.outputSize;
|
|
5631
5655
|
}
|
|
5632
5656
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5654,13 +5678,7 @@ class ZipEntry {
|
|
|
5654
5678
|
}
|
|
5655
5679
|
|
|
5656
5680
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5657
|
-
|
|
5658
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5659
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5660
|
-
return true;
|
|
5661
|
-
}
|
|
5662
|
-
}
|
|
5663
|
-
return false;
|
|
5681
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5664
5682
|
}
|
|
5665
5683
|
|
|
5666
5684
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5697,6 +5715,46 @@ async function findDigitalSignatureRecordOffset(reader, endOffset) {
|
|
|
5697
5715
|
}
|
|
5698
5716
|
}
|
|
5699
5717
|
|
|
5718
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5719
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5720
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5721
|
+
const tailView = getDataView(tailArray);
|
|
5722
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5723
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5724
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5725
|
+
return startOffset + indexByte;
|
|
5726
|
+
}
|
|
5727
|
+
}
|
|
5728
|
+
}
|
|
5729
|
+
|
|
5730
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5731
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5732
|
+
return UNDEFINED_VALUE;
|
|
5733
|
+
}
|
|
5734
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5735
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5736
|
+
return localHeaderOffset;
|
|
5737
|
+
}
|
|
5738
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5739
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5740
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5741
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5742
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5743
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5744
|
+
let offsetValue = offsetExtraField + 4;
|
|
5745
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5746
|
+
offsetValue += 8;
|
|
5747
|
+
}
|
|
5748
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5749
|
+
offsetValue += 8;
|
|
5750
|
+
}
|
|
5751
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5752
|
+
}
|
|
5753
|
+
offsetExtraField += 4 + size;
|
|
5754
|
+
}
|
|
5755
|
+
return UNDEFINED_VALUE;
|
|
5756
|
+
}
|
|
5757
|
+
|
|
5700
5758
|
function readDigitalSignature(signatureRecordArray) {
|
|
5701
5759
|
if (signatureRecordArray.length >= 6) {
|
|
5702
5760
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5786,6 +5844,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5786
5844
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5787
5845
|
});
|
|
5788
5846
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5847
|
+
let extraFieldZip64Missing;
|
|
5789
5848
|
if (extraFieldZip64) {
|
|
5790
5849
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5791
5850
|
malformedExtraField = true;
|
|
@@ -5795,7 +5854,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5795
5854
|
if (localDirectory) {
|
|
5796
5855
|
malformedExtraField = true;
|
|
5797
5856
|
} else {
|
|
5798
|
-
|
|
5857
|
+
extraFieldZip64Missing = true;
|
|
5799
5858
|
}
|
|
5800
5859
|
}
|
|
5801
5860
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5853,6 +5912,9 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5853
5912
|
if (extraFieldUSDZ) {
|
|
5854
5913
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5855
5914
|
}
|
|
5915
|
+
if (extraFieldZip64Missing) {
|
|
5916
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5917
|
+
}
|
|
5856
5918
|
return malformedExtraField;
|
|
5857
5919
|
}
|
|
5858
5920
|
|
|
@@ -6067,13 +6129,7 @@ async function detectOverlappingEntry({
|
|
|
6067
6129
|
let dataDescriptorLength = 0;
|
|
6068
6130
|
if (dataDescriptor) {
|
|
6069
6131
|
const zip64 = Boolean(extraFieldZip64);
|
|
6070
|
-
const
|
|
6071
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6072
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6073
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6074
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6075
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6076
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6132
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6077
6133
|
if (localDataDescriptor) {
|
|
6078
6134
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6079
6135
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6143,6 +6199,25 @@ function mergeRanges(sortedRanges, pendingRanges) {
|
|
|
6143
6199
|
return mergedRanges;
|
|
6144
6200
|
}
|
|
6145
6201
|
|
|
6202
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6203
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6204
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6205
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6206
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6207
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6208
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6209
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6210
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6211
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6212
|
+
}
|
|
6213
|
+
|
|
6214
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6215
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6216
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6217
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6218
|
+
}
|
|
6219
|
+
}
|
|
6220
|
+
|
|
6146
6221
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6147
6222
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6148
6223
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6402,6 +6477,18 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
|
|
|
6402
6477
|
}
|
|
6403
6478
|
}
|
|
6404
6479
|
|
|
6480
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6481
|
+
const { dataDescriptor } = localDirectory;
|
|
6482
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6483
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6484
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6485
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6486
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6487
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6488
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6489
|
+
}
|
|
6490
|
+
}
|
|
6491
|
+
|
|
6405
6492
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6406
6493
|
if (reject) {
|
|
6407
6494
|
throwAmbiguousArchive(reason);
|
|
@@ -6504,6 +6591,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6504
6591
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6505
6592
|
ZipReader: ZipReader,
|
|
6506
6593
|
ZipReaderStream: ZipReaderStream,
|
|
6594
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6507
6595
|
isZipFile: isZipFile
|
|
6508
6596
|
});
|
|
6509
6597
|
|
|
@@ -6627,136 +6715,7 @@ class ZipWriter {
|
|
|
6627
6715
|
}
|
|
6628
6716
|
|
|
6629
6717
|
appendZip(reader, options = {}) {
|
|
6630
|
-
return watchPromiseError(this,
|
|
6631
|
-
}
|
|
6632
|
-
|
|
6633
|
-
async appendZipEntries(reader, options = {}) {
|
|
6634
|
-
const zipWriter = this;
|
|
6635
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6636
|
-
const filter = checkFunctionOption(options.filter);
|
|
6637
|
-
while (pendingAddFileCalls.size) {
|
|
6638
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6639
|
-
}
|
|
6640
|
-
let resolveAppendZip;
|
|
6641
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6642
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6643
|
-
const appendedFilenames = [];
|
|
6644
|
-
let releaseLockWriter;
|
|
6645
|
-
try {
|
|
6646
|
-
reader = new GenericReader(reader);
|
|
6647
|
-
await initStream(reader);
|
|
6648
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6649
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6650
|
-
await initStream(reader);
|
|
6651
|
-
}
|
|
6652
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6653
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6654
|
-
const entries = await zipReader$1.getEntries();
|
|
6655
|
-
const keptEntries = [];
|
|
6656
|
-
for (const entry of entries) {
|
|
6657
|
-
if (!filter || await filter(entry)) {
|
|
6658
|
-
keptEntries.push(entry);
|
|
6659
|
-
}
|
|
6660
|
-
}
|
|
6661
|
-
await zipReader$1.close();
|
|
6662
|
-
await initStream(zipWriter.writer);
|
|
6663
|
-
const { directoryOffset } = zipReader$1;
|
|
6664
|
-
keptEntries.forEach(({ filename }) => {
|
|
6665
|
-
if (filenames.has(filename)) {
|
|
6666
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6667
|
-
}
|
|
6668
|
-
filenames.add(filename);
|
|
6669
|
-
appendedFilenames.push(filename);
|
|
6670
|
-
});
|
|
6671
|
-
zipWriter.writerLocked = true;
|
|
6672
|
-
const { lockWriter } = zipWriter;
|
|
6673
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6674
|
-
zipWriter.writerLocked = false;
|
|
6675
|
-
resolve();
|
|
6676
|
-
});
|
|
6677
|
-
await lockWriter;
|
|
6678
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6679
|
-
delete zipWriter.addSplitZipSignature;
|
|
6680
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6681
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6682
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6683
|
-
}
|
|
6684
|
-
}
|
|
6685
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6686
|
-
keptEntries.forEach(entry => {
|
|
6687
|
-
const {
|
|
6688
|
-
version,
|
|
6689
|
-
rawLastModDate,
|
|
6690
|
-
rawFilename,
|
|
6691
|
-
bitFlag,
|
|
6692
|
-
encrypted,
|
|
6693
|
-
uncompressedSize,
|
|
6694
|
-
compressedSize,
|
|
6695
|
-
extraFieldZip64
|
|
6696
|
-
} = entry;
|
|
6697
|
-
let {
|
|
6698
|
-
compressionMethod,
|
|
6699
|
-
rawExtraField,
|
|
6700
|
-
} = entry;
|
|
6701
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6702
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6703
|
-
if (entry.extraFieldAES) {
|
|
6704
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6705
|
-
}
|
|
6706
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6707
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6708
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6709
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6710
|
-
const {
|
|
6711
|
-
headerArray,
|
|
6712
|
-
headerView
|
|
6713
|
-
} = getHeaderArrayData({
|
|
6714
|
-
version,
|
|
6715
|
-
bitFlag: bitFlagValue,
|
|
6716
|
-
compressionMethod,
|
|
6717
|
-
uncompressedSize,
|
|
6718
|
-
compressedSize,
|
|
6719
|
-
rawLastModDate,
|
|
6720
|
-
rawFilename,
|
|
6721
|
-
zip64CompressedSize,
|
|
6722
|
-
zip64UncompressedSize,
|
|
6723
|
-
extraFieldLength
|
|
6724
|
-
});
|
|
6725
|
-
const { crc32 } = entry;
|
|
6726
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6727
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6728
|
-
}
|
|
6729
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6730
|
-
Object.assign(entry, {
|
|
6731
|
-
zip64Enabled: true,
|
|
6732
|
-
zip64UncompressedSize,
|
|
6733
|
-
zip64CompressedSize,
|
|
6734
|
-
offset,
|
|
6735
|
-
diskNumberStart,
|
|
6736
|
-
zip64DiskNumberStart: false,
|
|
6737
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6738
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6739
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6740
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6741
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6742
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6743
|
-
rawExtraField,
|
|
6744
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6745
|
-
headerArray,
|
|
6746
|
-
headerView
|
|
6747
|
-
});
|
|
6748
|
-
fileEntries.set(entry.filename, entry);
|
|
6749
|
-
});
|
|
6750
|
-
} catch (error) {
|
|
6751
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6752
|
-
throw error;
|
|
6753
|
-
} finally {
|
|
6754
|
-
resolveAppendZip();
|
|
6755
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6756
|
-
if (releaseLockWriter) {
|
|
6757
|
-
releaseLockWriter();
|
|
6758
|
-
}
|
|
6759
|
-
}
|
|
6718
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6760
6719
|
}
|
|
6761
6720
|
|
|
6762
6721
|
add(name = "", reader, options = {}) {
|
|
@@ -6918,11 +6877,140 @@ function watchPromiseError(zipWriter, promise) {
|
|
|
6918
6877
|
return watchedPromise;
|
|
6919
6878
|
}
|
|
6920
6879
|
|
|
6880
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6881
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6882
|
+
const filter = checkFunctionOption(options.filter);
|
|
6883
|
+
while (pendingAddFileCalls.size) {
|
|
6884
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6885
|
+
}
|
|
6886
|
+
let resolveAppendZip;
|
|
6887
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6888
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6889
|
+
const appendedFilenames = [];
|
|
6890
|
+
let releaseLockWriter;
|
|
6891
|
+
try {
|
|
6892
|
+
reader = new GenericReader(reader);
|
|
6893
|
+
await initStream(reader);
|
|
6894
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6895
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6896
|
+
await initStream(reader);
|
|
6897
|
+
}
|
|
6898
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6899
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6900
|
+
const entries = await zipReader$1.getEntries();
|
|
6901
|
+
const keptEntries = [];
|
|
6902
|
+
for (const entry of entries) {
|
|
6903
|
+
if (!filter || await filter(entry)) {
|
|
6904
|
+
keptEntries.push(entry);
|
|
6905
|
+
}
|
|
6906
|
+
}
|
|
6907
|
+
await zipReader$1.close();
|
|
6908
|
+
await initStream(zipWriter.writer);
|
|
6909
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6910
|
+
keptEntries.forEach(entry => {
|
|
6911
|
+
const { filename } = entry;
|
|
6912
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6913
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6914
|
+
}
|
|
6915
|
+
if (filenames.has(filename)) {
|
|
6916
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6917
|
+
}
|
|
6918
|
+
filenames.add(filename);
|
|
6919
|
+
appendedFilenames.push(filename);
|
|
6920
|
+
});
|
|
6921
|
+
zipWriter.writerLocked = true;
|
|
6922
|
+
const { lockWriter } = zipWriter;
|
|
6923
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6924
|
+
zipWriter.writerLocked = false;
|
|
6925
|
+
resolve();
|
|
6926
|
+
});
|
|
6927
|
+
await lockWriter;
|
|
6928
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6929
|
+
delete zipWriter.addSplitZipSignature;
|
|
6930
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6931
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6932
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6933
|
+
}
|
|
6934
|
+
}
|
|
6935
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6936
|
+
keptEntries.forEach(entry => {
|
|
6937
|
+
const {
|
|
6938
|
+
version,
|
|
6939
|
+
rawLastModDate,
|
|
6940
|
+
rawFilename,
|
|
6941
|
+
rawBitFlag,
|
|
6942
|
+
uncompressedSize,
|
|
6943
|
+
compressedSize,
|
|
6944
|
+
extraFieldZip64
|
|
6945
|
+
} = entry;
|
|
6946
|
+
let {
|
|
6947
|
+
compressionMethod,
|
|
6948
|
+
rawExtraField,
|
|
6949
|
+
} = entry;
|
|
6950
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6951
|
+
if (entry.extraFieldAES) {
|
|
6952
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6953
|
+
}
|
|
6954
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6955
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6956
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6957
|
+
const {
|
|
6958
|
+
headerArray,
|
|
6959
|
+
headerView
|
|
6960
|
+
} = getHeaderArrayData({
|
|
6961
|
+
version,
|
|
6962
|
+
bitFlag: rawBitFlag,
|
|
6963
|
+
compressionMethod,
|
|
6964
|
+
uncompressedSize,
|
|
6965
|
+
compressedSize,
|
|
6966
|
+
rawLastModDate,
|
|
6967
|
+
rawFilename,
|
|
6968
|
+
zip64CompressedSize,
|
|
6969
|
+
zip64UncompressedSize,
|
|
6970
|
+
extraFieldLength
|
|
6971
|
+
});
|
|
6972
|
+
const { crc32 } = entry;
|
|
6973
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6974
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6975
|
+
}
|
|
6976
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6977
|
+
Object.assign(entry, {
|
|
6978
|
+
zip64Enabled: true,
|
|
6979
|
+
zip64UncompressedSize,
|
|
6980
|
+
zip64CompressedSize,
|
|
6981
|
+
offset,
|
|
6982
|
+
diskNumberStart,
|
|
6983
|
+
zip64DiskNumberStart: false,
|
|
6984
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6985
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6986
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6987
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6988
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6989
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6990
|
+
rawExtraField,
|
|
6991
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6992
|
+
headerArray,
|
|
6993
|
+
headerView
|
|
6994
|
+
});
|
|
6995
|
+
fileEntries.set(entry.filename, entry);
|
|
6996
|
+
});
|
|
6997
|
+
} catch (error) {
|
|
6998
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6999
|
+
throw error;
|
|
7000
|
+
} finally {
|
|
7001
|
+
resolveAppendZip();
|
|
7002
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
7003
|
+
if (releaseLockWriter) {
|
|
7004
|
+
releaseLockWriter();
|
|
7005
|
+
}
|
|
7006
|
+
}
|
|
7007
|
+
}
|
|
7008
|
+
|
|
6921
7009
|
async function prependZipEntries(zipWriter, reader) {
|
|
6922
7010
|
if (zipWriter.filenames.size) {
|
|
6923
7011
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6924
7012
|
}
|
|
6925
|
-
await
|
|
7013
|
+
await appendZipEntries(zipWriter, reader);
|
|
6926
7014
|
}
|
|
6927
7015
|
|
|
6928
7016
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8596,7 +8684,7 @@ function removeExtraFieldZip64(rawExtraField) {
|
|
|
8596
8684
|
return rawExtraField;
|
|
8597
8685
|
}
|
|
8598
8686
|
|
|
8599
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8687
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8600
8688
|
const { writer } = zipWriter;
|
|
8601
8689
|
const entryPositions = new Map();
|
|
8602
8690
|
if (writer.closeDisk || compact) {
|
|
@@ -8604,6 +8692,27 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8604
8692
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8605
8693
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8606
8694
|
const keptEntrySet = new Set(keptEntries);
|
|
8695
|
+
const localHeaderLengths = new Map();
|
|
8696
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8697
|
+
const entry = sortedEntries[indexEntry];
|
|
8698
|
+
if (keptEntrySet.has(entry)) {
|
|
8699
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8700
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8701
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8702
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8703
|
+
}
|
|
8704
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8705
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8706
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8707
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8708
|
+
}
|
|
8709
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8710
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8711
|
+
}
|
|
8712
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8713
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8714
|
+
}
|
|
8715
|
+
}
|
|
8607
8716
|
let copiedOffset = 0;
|
|
8608
8717
|
let lastPosition;
|
|
8609
8718
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8616,7 +8725,7 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8616
8725
|
if (!compact) {
|
|
8617
8726
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8618
8727
|
}
|
|
8619
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8728
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8620
8729
|
await writer.closeDisk();
|
|
8621
8730
|
}
|
|
8622
8731
|
lastPosition = {
|
|
@@ -8650,7 +8759,7 @@ function getRegionEnds(reader, sortedEntries, directoryOffset) {
|
|
|
8650
8759
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8651
8760
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8652
8761
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8653
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8762
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8654
8763
|
}
|
|
8655
8764
|
regionEnds[indexEntry] = regionEnd;
|
|
8656
8765
|
}
|
|
@@ -8664,11 +8773,13 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8664
8773
|
try {
|
|
8665
8774
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8666
8775
|
} catch (error) {
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8776
|
+
if (copiedLength) {
|
|
8777
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8778
|
+
try {
|
|
8779
|
+
error.corruptedEntry = true;
|
|
8780
|
+
} catch {
|
|
8781
|
+
// ignored
|
|
8782
|
+
}
|
|
8672
8783
|
}
|
|
8673
8784
|
throw error;
|
|
8674
8785
|
} finally {
|
|
@@ -8679,11 +8790,16 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8679
8790
|
}
|
|
8680
8791
|
|
|
8681
8792
|
async function getLocalHeaderLength(reader, offset) {
|
|
8682
|
-
const headerArray =
|
|
8793
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8794
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8795
|
+
EMPTY_UINT8_ARRAY;
|
|
8683
8796
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8684
|
-
return
|
|
8797
|
+
return UNDEFINED_VALUE;
|
|
8685
8798
|
}
|
|
8686
8799
|
const headerView = getDataView(headerArray);
|
|
8800
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8801
|
+
return UNDEFINED_VALUE;
|
|
8802
|
+
}
|
|
8687
8803
|
return HEADER_SIZE +
|
|
8688
8804
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8689
8805
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9034,7 +9150,7 @@ function formatSupported(StreamClass, format) {
|
|
|
9034
9150
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9035
9151
|
*/
|
|
9036
9152
|
|
|
9037
|
-
const VERSION = "2.
|
|
9153
|
+
const VERSION = "2.21.0";
|
|
9038
9154
|
|
|
9039
9155
|
/*
|
|
9040
9156
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|