@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-external.js
CHANGED
|
@@ -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";
|
|
@@ -4810,12 +4814,9 @@ const ERR_BAD_FORMAT = "File format is not recognized";
|
|
|
4810
4814
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4811
4815
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4812
4816
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4813
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4814
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4815
4817
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4816
4818
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4817
4819
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4818
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4819
4820
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4820
4821
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4821
4822
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4880,7 +4881,8 @@ class ZipReader {
|
|
|
4880
4881
|
Object.assign(this, {
|
|
4881
4882
|
reader: new GenericReader(reader),
|
|
4882
4883
|
options,
|
|
4883
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4884
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4885
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4884
4886
|
});
|
|
4885
4887
|
}
|
|
4886
4888
|
|
|
@@ -4951,16 +4953,22 @@ class ZipReader {
|
|
|
4951
4953
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4952
4954
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4953
4955
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4956
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4957
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4958
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4959
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4960
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4961
|
+
}
|
|
4962
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4963
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4964
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4965
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4966
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4967
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4968
|
+
}
|
|
4969
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4970
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4961
4971
|
}
|
|
4962
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4963
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4964
4972
|
}
|
|
4965
4973
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4966
4974
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -5005,10 +5013,6 @@ class ZipReader {
|
|
|
5005
5013
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
5006
5014
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
5007
5015
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
5008
|
-
if (directoryDataOffset >= reader.size) {
|
|
5009
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
5010
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
5011
|
-
}
|
|
5012
5016
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
5013
5017
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
5014
5018
|
}
|
|
@@ -5016,52 +5020,64 @@ class ZipReader {
|
|
|
5016
5020
|
throw new Error(ERR_BAD_FORMAT);
|
|
5017
5021
|
}
|
|
5018
5022
|
let offset = 0;
|
|
5019
|
-
let directoryArray =
|
|
5023
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
5024
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
5025
|
+
EMPTY_UINT8_ARRAY;
|
|
5020
5026
|
let directoryView = getDataView(directoryArray);
|
|
5021
5027
|
if (directoryDataLength) {
|
|
5022
|
-
if (directoryArray.length < 4) {
|
|
5023
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
5024
|
-
}
|
|
5025
5028
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
5026
5029
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
5027
|
-
const storedPointsAtDirectory =
|
|
5030
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
5031
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
5028
5032
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
5029
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5033
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5034
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5035
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5036
|
+
}
|
|
5030
5037
|
let reconcile = !storedPointsAtDirectory;
|
|
5031
5038
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
5032
|
-
|
|
5033
|
-
if (
|
|
5034
|
-
reconcile = expectedPointsAtDirectory;
|
|
5035
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5039
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5040
|
+
if (!expectedPointsAtDirectory) {
|
|
5036
5041
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5037
5042
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5038
5043
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5039
5044
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5040
5045
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5046
|
+
expectedPointsAtDirectory = true;
|
|
5041
5047
|
}
|
|
5042
5048
|
}
|
|
5049
|
+
if (storedPointsAtDirectory) {
|
|
5050
|
+
reconcile = expectedPointsAtDirectory;
|
|
5051
|
+
}
|
|
5043
5052
|
}
|
|
5044
|
-
if (reconcile) {
|
|
5053
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5045
5054
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5046
5055
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5047
5056
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5048
5057
|
directoryView = getDataView(directoryArray);
|
|
5049
|
-
|
|
5050
|
-
|
|
5058
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5059
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5060
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5061
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5062
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5063
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5064
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5065
|
+
prependedDataLength += offsetDelta;
|
|
5051
5066
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5052
5067
|
} else {
|
|
5053
5068
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5057
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5058
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5059
|
-
prependedDataLength += offsetDelta;
|
|
5060
|
-
}
|
|
5069
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5070
|
+
prependedDataLength += offsetDelta;
|
|
5061
5071
|
}
|
|
5062
5072
|
}
|
|
5063
5073
|
}
|
|
5064
5074
|
}
|
|
5075
|
+
if (directoryArray.length < 4) {
|
|
5076
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5077
|
+
}
|
|
5078
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5079
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5080
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5065
5081
|
}
|
|
5066
5082
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5067
5083
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5103,8 +5119,10 @@ class ZipReader {
|
|
|
5103
5119
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5104
5120
|
}
|
|
5105
5121
|
}
|
|
5122
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5123
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5106
5124
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5107
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5125
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5108
5126
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5109
5127
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5110
5128
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5195,13 +5213,17 @@ class ZipReader {
|
|
|
5195
5213
|
if (malformedExtraField) {
|
|
5196
5214
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5197
5215
|
}
|
|
5198
|
-
fileEntry.offset
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5216
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5217
|
+
startOffset = 0;
|
|
5218
|
+
} else {
|
|
5219
|
+
fileEntry.offset += prependedDataLength;
|
|
5220
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5221
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5222
|
+
if (entryPosition < previousEntryPosition) {
|
|
5223
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5224
|
+
}
|
|
5225
|
+
previousEntryPosition = entryPosition;
|
|
5203
5226
|
}
|
|
5204
|
-
previousEntryPosition = entryPosition;
|
|
5205
5227
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5206
5228
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5207
5229
|
}
|
|
@@ -5238,12 +5260,15 @@ class ZipReader {
|
|
|
5238
5260
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5239
5261
|
});
|
|
5240
5262
|
const entry = new Entry(fileEntry);
|
|
5241
|
-
|
|
5263
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5264
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5265
|
+
}
|
|
5266
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5242
5267
|
entry.arrayBuffer = async options => {
|
|
5243
5268
|
const writer = new TransformStream();
|
|
5244
5269
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5245
5270
|
arrayBufferPromise.catch(() => { });
|
|
5246
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5271
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5247
5272
|
Object.assign({}, options, { preventClose: false }));
|
|
5248
5273
|
return arrayBufferPromise;
|
|
5249
5274
|
};
|
|
@@ -5451,8 +5476,9 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5451
5476
|
});
|
|
5452
5477
|
}
|
|
5453
5478
|
|
|
5454
|
-
async getData(writer, fileEntry,
|
|
5479
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5455
5480
|
const zipEntry = this;
|
|
5481
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5456
5482
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5457
5483
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5458
5484
|
}
|
|
@@ -5526,10 +5552,10 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5526
5552
|
}
|
|
5527
5553
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5528
5554
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5529
|
-
if (lastAccessDate) {
|
|
5555
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5530
5556
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5531
5557
|
}
|
|
5532
|
-
if (creationDate) {
|
|
5558
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5533
5559
|
fileEntry.creationDate = creationDate;
|
|
5534
5560
|
}
|
|
5535
5561
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5558,7 +5584,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5558
5584
|
throw new Error(ERR_ENCRYPTED);
|
|
5559
5585
|
}
|
|
5560
5586
|
}
|
|
5561
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5587
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5562
5588
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5563
5589
|
}
|
|
5564
5590
|
const size = compressedSize;
|
|
@@ -5624,6 +5650,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5624
5650
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5625
5651
|
readRanges
|
|
5626
5652
|
});
|
|
5653
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5627
5654
|
}
|
|
5628
5655
|
let writable, abortError, aborted;
|
|
5629
5656
|
try {
|
|
@@ -5643,10 +5670,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5643
5670
|
writer.size += writtenSize;
|
|
5644
5671
|
}
|
|
5645
5672
|
} catch (error) {
|
|
5646
|
-
|
|
5647
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5648
|
-
writer.size += failedOutputSize;
|
|
5649
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5673
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5650
5674
|
writer.size += error.outputSize;
|
|
5651
5675
|
}
|
|
5652
5676
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5674,13 +5698,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5674
5698
|
};
|
|
5675
5699
|
|
|
5676
5700
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5677
|
-
|
|
5678
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5679
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5680
|
-
return true;
|
|
5681
|
-
}
|
|
5682
|
-
}
|
|
5683
|
-
return false;
|
|
5701
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5684
5702
|
}
|
|
5685
5703
|
|
|
5686
5704
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5717,6 +5735,46 @@ async function findDigitalSignatureRecordOffset(reader, endOffset) {
|
|
|
5717
5735
|
}
|
|
5718
5736
|
}
|
|
5719
5737
|
|
|
5738
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5739
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5740
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5741
|
+
const tailView = getDataView(tailArray);
|
|
5742
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5743
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5744
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5745
|
+
return startOffset + indexByte;
|
|
5746
|
+
}
|
|
5747
|
+
}
|
|
5748
|
+
}
|
|
5749
|
+
|
|
5750
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5751
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5752
|
+
return UNDEFINED_VALUE;
|
|
5753
|
+
}
|
|
5754
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5755
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5756
|
+
return localHeaderOffset;
|
|
5757
|
+
}
|
|
5758
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5759
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5760
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5761
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5762
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5763
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5764
|
+
let offsetValue = offsetExtraField + 4;
|
|
5765
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5766
|
+
offsetValue += 8;
|
|
5767
|
+
}
|
|
5768
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5769
|
+
offsetValue += 8;
|
|
5770
|
+
}
|
|
5771
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5772
|
+
}
|
|
5773
|
+
offsetExtraField += 4 + size;
|
|
5774
|
+
}
|
|
5775
|
+
return UNDEFINED_VALUE;
|
|
5776
|
+
}
|
|
5777
|
+
|
|
5720
5778
|
function readDigitalSignature(signatureRecordArray) {
|
|
5721
5779
|
if (signatureRecordArray.length >= 6) {
|
|
5722
5780
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5806,6 +5864,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5806
5864
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5807
5865
|
});
|
|
5808
5866
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5867
|
+
let extraFieldZip64Missing;
|
|
5809
5868
|
if (extraFieldZip64) {
|
|
5810
5869
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5811
5870
|
malformedExtraField = true;
|
|
@@ -5815,7 +5874,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5815
5874
|
if (localDirectory) {
|
|
5816
5875
|
malformedExtraField = true;
|
|
5817
5876
|
} else {
|
|
5818
|
-
|
|
5877
|
+
extraFieldZip64Missing = true;
|
|
5819
5878
|
}
|
|
5820
5879
|
}
|
|
5821
5880
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5873,6 +5932,9 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5873
5932
|
if (extraFieldUSDZ) {
|
|
5874
5933
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5875
5934
|
}
|
|
5935
|
+
if (extraFieldZip64Missing) {
|
|
5936
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5937
|
+
}
|
|
5876
5938
|
return malformedExtraField;
|
|
5877
5939
|
}
|
|
5878
5940
|
|
|
@@ -6087,13 +6149,7 @@ async function detectOverlappingEntry({
|
|
|
6087
6149
|
let dataDescriptorLength = 0;
|
|
6088
6150
|
if (dataDescriptor) {
|
|
6089
6151
|
const zip64 = Boolean(extraFieldZip64);
|
|
6090
|
-
const
|
|
6091
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6092
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6093
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6094
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6095
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6096
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6152
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6097
6153
|
if (localDataDescriptor) {
|
|
6098
6154
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6099
6155
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6163,6 +6219,25 @@ function mergeRanges(sortedRanges, pendingRanges) {
|
|
|
6163
6219
|
return mergedRanges;
|
|
6164
6220
|
}
|
|
6165
6221
|
|
|
6222
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6223
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6224
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6225
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6226
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6227
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6228
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6229
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6230
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6231
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6232
|
+
}
|
|
6233
|
+
|
|
6234
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6235
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6236
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6237
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6238
|
+
}
|
|
6239
|
+
}
|
|
6240
|
+
|
|
6166
6241
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6167
6242
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6168
6243
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6422,6 +6497,18 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
|
|
|
6422
6497
|
}
|
|
6423
6498
|
}
|
|
6424
6499
|
|
|
6500
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6501
|
+
const { dataDescriptor } = localDirectory;
|
|
6502
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6503
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6504
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6505
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6506
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6507
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6508
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6509
|
+
}
|
|
6510
|
+
}
|
|
6511
|
+
|
|
6425
6512
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6426
6513
|
if (reject) {
|
|
6427
6514
|
throwAmbiguousArchive(reason);
|
|
@@ -6524,6 +6611,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6524
6611
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6525
6612
|
ZipReader: ZipReader,
|
|
6526
6613
|
ZipReaderStream: ZipReaderStream,
|
|
6614
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6527
6615
|
isZipFile: isZipFile
|
|
6528
6616
|
});
|
|
6529
6617
|
|
|
@@ -6647,136 +6735,7 @@ class ZipWriter {
|
|
|
6647
6735
|
}
|
|
6648
6736
|
|
|
6649
6737
|
appendZip(reader, options = {}) {
|
|
6650
|
-
return watchPromiseError(this,
|
|
6651
|
-
}
|
|
6652
|
-
|
|
6653
|
-
async appendZipEntries(reader, options = {}) {
|
|
6654
|
-
const zipWriter = this;
|
|
6655
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6656
|
-
const filter = checkFunctionOption(options.filter);
|
|
6657
|
-
while (pendingAddFileCalls.size) {
|
|
6658
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6659
|
-
}
|
|
6660
|
-
let resolveAppendZip;
|
|
6661
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6662
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6663
|
-
const appendedFilenames = [];
|
|
6664
|
-
let releaseLockWriter;
|
|
6665
|
-
try {
|
|
6666
|
-
reader = new GenericReader(reader);
|
|
6667
|
-
await initStream(reader);
|
|
6668
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6669
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6670
|
-
await initStream(reader);
|
|
6671
|
-
}
|
|
6672
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6673
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6674
|
-
const entries = await zipReader$1.getEntries();
|
|
6675
|
-
const keptEntries = [];
|
|
6676
|
-
for (const entry of entries) {
|
|
6677
|
-
if (!filter || await filter(entry)) {
|
|
6678
|
-
keptEntries.push(entry);
|
|
6679
|
-
}
|
|
6680
|
-
}
|
|
6681
|
-
await zipReader$1.close();
|
|
6682
|
-
await initStream(zipWriter.writer);
|
|
6683
|
-
const { directoryOffset } = zipReader$1;
|
|
6684
|
-
keptEntries.forEach(({ filename }) => {
|
|
6685
|
-
if (filenames.has(filename)) {
|
|
6686
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6687
|
-
}
|
|
6688
|
-
filenames.add(filename);
|
|
6689
|
-
appendedFilenames.push(filename);
|
|
6690
|
-
});
|
|
6691
|
-
zipWriter.writerLocked = true;
|
|
6692
|
-
const { lockWriter } = zipWriter;
|
|
6693
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6694
|
-
zipWriter.writerLocked = false;
|
|
6695
|
-
resolve();
|
|
6696
|
-
});
|
|
6697
|
-
await lockWriter;
|
|
6698
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6699
|
-
delete zipWriter.addSplitZipSignature;
|
|
6700
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6701
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6702
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6703
|
-
}
|
|
6704
|
-
}
|
|
6705
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6706
|
-
keptEntries.forEach(entry => {
|
|
6707
|
-
const {
|
|
6708
|
-
version,
|
|
6709
|
-
rawLastModDate,
|
|
6710
|
-
rawFilename,
|
|
6711
|
-
bitFlag,
|
|
6712
|
-
encrypted,
|
|
6713
|
-
uncompressedSize,
|
|
6714
|
-
compressedSize,
|
|
6715
|
-
extraFieldZip64
|
|
6716
|
-
} = entry;
|
|
6717
|
-
let {
|
|
6718
|
-
compressionMethod,
|
|
6719
|
-
rawExtraField,
|
|
6720
|
-
} = entry;
|
|
6721
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6722
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6723
|
-
if (entry.extraFieldAES) {
|
|
6724
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6725
|
-
}
|
|
6726
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6727
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6728
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6729
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6730
|
-
const {
|
|
6731
|
-
headerArray,
|
|
6732
|
-
headerView
|
|
6733
|
-
} = getHeaderArrayData({
|
|
6734
|
-
version,
|
|
6735
|
-
bitFlag: bitFlagValue,
|
|
6736
|
-
compressionMethod,
|
|
6737
|
-
uncompressedSize,
|
|
6738
|
-
compressedSize,
|
|
6739
|
-
rawLastModDate,
|
|
6740
|
-
rawFilename,
|
|
6741
|
-
zip64CompressedSize,
|
|
6742
|
-
zip64UncompressedSize,
|
|
6743
|
-
extraFieldLength
|
|
6744
|
-
});
|
|
6745
|
-
const { crc32 } = entry;
|
|
6746
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6747
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6748
|
-
}
|
|
6749
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6750
|
-
Object.assign(entry, {
|
|
6751
|
-
zip64Enabled: true,
|
|
6752
|
-
zip64UncompressedSize,
|
|
6753
|
-
zip64CompressedSize,
|
|
6754
|
-
offset,
|
|
6755
|
-
diskNumberStart,
|
|
6756
|
-
zip64DiskNumberStart: false,
|
|
6757
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6758
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6759
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6760
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6761
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6762
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6763
|
-
rawExtraField,
|
|
6764
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6765
|
-
headerArray,
|
|
6766
|
-
headerView
|
|
6767
|
-
});
|
|
6768
|
-
fileEntries.set(entry.filename, entry);
|
|
6769
|
-
});
|
|
6770
|
-
} catch (error) {
|
|
6771
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6772
|
-
throw error;
|
|
6773
|
-
} finally {
|
|
6774
|
-
resolveAppendZip();
|
|
6775
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6776
|
-
if (releaseLockWriter) {
|
|
6777
|
-
releaseLockWriter();
|
|
6778
|
-
}
|
|
6779
|
-
}
|
|
6738
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6780
6739
|
}
|
|
6781
6740
|
|
|
6782
6741
|
add(name = "", reader, options = {}) {
|
|
@@ -6938,11 +6897,140 @@ function watchPromiseError(zipWriter, promise) {
|
|
|
6938
6897
|
return watchedPromise;
|
|
6939
6898
|
}
|
|
6940
6899
|
|
|
6900
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6901
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6902
|
+
const filter = checkFunctionOption(options.filter);
|
|
6903
|
+
while (pendingAddFileCalls.size) {
|
|
6904
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6905
|
+
}
|
|
6906
|
+
let resolveAppendZip;
|
|
6907
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6908
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6909
|
+
const appendedFilenames = [];
|
|
6910
|
+
let releaseLockWriter;
|
|
6911
|
+
try {
|
|
6912
|
+
reader = new GenericReader(reader);
|
|
6913
|
+
await initStream(reader);
|
|
6914
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6915
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6916
|
+
await initStream(reader);
|
|
6917
|
+
}
|
|
6918
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6919
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6920
|
+
const entries = await zipReader$1.getEntries();
|
|
6921
|
+
const keptEntries = [];
|
|
6922
|
+
for (const entry of entries) {
|
|
6923
|
+
if (!filter || await filter(entry)) {
|
|
6924
|
+
keptEntries.push(entry);
|
|
6925
|
+
}
|
|
6926
|
+
}
|
|
6927
|
+
await zipReader$1.close();
|
|
6928
|
+
await initStream(zipWriter.writer);
|
|
6929
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6930
|
+
keptEntries.forEach(entry => {
|
|
6931
|
+
const { filename } = entry;
|
|
6932
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6933
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6934
|
+
}
|
|
6935
|
+
if (filenames.has(filename)) {
|
|
6936
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6937
|
+
}
|
|
6938
|
+
filenames.add(filename);
|
|
6939
|
+
appendedFilenames.push(filename);
|
|
6940
|
+
});
|
|
6941
|
+
zipWriter.writerLocked = true;
|
|
6942
|
+
const { lockWriter } = zipWriter;
|
|
6943
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6944
|
+
zipWriter.writerLocked = false;
|
|
6945
|
+
resolve();
|
|
6946
|
+
});
|
|
6947
|
+
await lockWriter;
|
|
6948
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6949
|
+
delete zipWriter.addSplitZipSignature;
|
|
6950
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6951
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6952
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6953
|
+
}
|
|
6954
|
+
}
|
|
6955
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6956
|
+
keptEntries.forEach(entry => {
|
|
6957
|
+
const {
|
|
6958
|
+
version,
|
|
6959
|
+
rawLastModDate,
|
|
6960
|
+
rawFilename,
|
|
6961
|
+
rawBitFlag,
|
|
6962
|
+
uncompressedSize,
|
|
6963
|
+
compressedSize,
|
|
6964
|
+
extraFieldZip64
|
|
6965
|
+
} = entry;
|
|
6966
|
+
let {
|
|
6967
|
+
compressionMethod,
|
|
6968
|
+
rawExtraField,
|
|
6969
|
+
} = entry;
|
|
6970
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6971
|
+
if (entry.extraFieldAES) {
|
|
6972
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6973
|
+
}
|
|
6974
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6975
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6976
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6977
|
+
const {
|
|
6978
|
+
headerArray,
|
|
6979
|
+
headerView
|
|
6980
|
+
} = getHeaderArrayData({
|
|
6981
|
+
version,
|
|
6982
|
+
bitFlag: rawBitFlag,
|
|
6983
|
+
compressionMethod,
|
|
6984
|
+
uncompressedSize,
|
|
6985
|
+
compressedSize,
|
|
6986
|
+
rawLastModDate,
|
|
6987
|
+
rawFilename,
|
|
6988
|
+
zip64CompressedSize,
|
|
6989
|
+
zip64UncompressedSize,
|
|
6990
|
+
extraFieldLength
|
|
6991
|
+
});
|
|
6992
|
+
const { crc32 } = entry;
|
|
6993
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6994
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6995
|
+
}
|
|
6996
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6997
|
+
Object.assign(entry, {
|
|
6998
|
+
zip64Enabled: true,
|
|
6999
|
+
zip64UncompressedSize,
|
|
7000
|
+
zip64CompressedSize,
|
|
7001
|
+
offset,
|
|
7002
|
+
diskNumberStart,
|
|
7003
|
+
zip64DiskNumberStart: false,
|
|
7004
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
7005
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
7006
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
7007
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
7008
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
7009
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
7010
|
+
rawExtraField,
|
|
7011
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
7012
|
+
headerArray,
|
|
7013
|
+
headerView
|
|
7014
|
+
});
|
|
7015
|
+
fileEntries.set(entry.filename, entry);
|
|
7016
|
+
});
|
|
7017
|
+
} catch (error) {
|
|
7018
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
7019
|
+
throw error;
|
|
7020
|
+
} finally {
|
|
7021
|
+
resolveAppendZip();
|
|
7022
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
7023
|
+
if (releaseLockWriter) {
|
|
7024
|
+
releaseLockWriter();
|
|
7025
|
+
}
|
|
7026
|
+
}
|
|
7027
|
+
}
|
|
7028
|
+
|
|
6941
7029
|
async function prependZipEntries(zipWriter, reader) {
|
|
6942
7030
|
if (zipWriter.filenames.size) {
|
|
6943
7031
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6944
7032
|
}
|
|
6945
|
-
await
|
|
7033
|
+
await appendZipEntries(zipWriter, reader);
|
|
6946
7034
|
}
|
|
6947
7035
|
|
|
6948
7036
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8714,7 +8802,7 @@ function removeExtraFieldZip64(rawExtraField) {
|
|
|
8714
8802
|
return rawExtraField;
|
|
8715
8803
|
}
|
|
8716
8804
|
|
|
8717
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8805
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8718
8806
|
const { writer } = zipWriter;
|
|
8719
8807
|
const entryPositions = new Map();
|
|
8720
8808
|
if (writer.closeDisk || compact) {
|
|
@@ -8722,6 +8810,27 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8722
8810
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8723
8811
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8724
8812
|
const keptEntrySet = new Set(keptEntries);
|
|
8813
|
+
const localHeaderLengths = new Map();
|
|
8814
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8815
|
+
const entry = sortedEntries[indexEntry];
|
|
8816
|
+
if (keptEntrySet.has(entry)) {
|
|
8817
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8818
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8819
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8820
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8821
|
+
}
|
|
8822
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8823
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8824
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8825
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8826
|
+
}
|
|
8827
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8828
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8829
|
+
}
|
|
8830
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8831
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8832
|
+
}
|
|
8833
|
+
}
|
|
8725
8834
|
let copiedOffset = 0;
|
|
8726
8835
|
let lastPosition;
|
|
8727
8836
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8734,7 +8843,7 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8734
8843
|
if (!compact) {
|
|
8735
8844
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8736
8845
|
}
|
|
8737
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8846
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8738
8847
|
await writer.closeDisk();
|
|
8739
8848
|
}
|
|
8740
8849
|
lastPosition = {
|
|
@@ -8768,7 +8877,7 @@ function getRegionEnds(reader, sortedEntries, directoryOffset) {
|
|
|
8768
8877
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8769
8878
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8770
8879
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8771
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8880
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8772
8881
|
}
|
|
8773
8882
|
regionEnds[indexEntry] = regionEnd;
|
|
8774
8883
|
}
|
|
@@ -8782,11 +8891,13 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8782
8891
|
try {
|
|
8783
8892
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8784
8893
|
} catch (error) {
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
|
|
8789
|
-
|
|
8894
|
+
if (copiedLength) {
|
|
8895
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8896
|
+
try {
|
|
8897
|
+
error.corruptedEntry = true;
|
|
8898
|
+
} catch {
|
|
8899
|
+
// ignored
|
|
8900
|
+
}
|
|
8790
8901
|
}
|
|
8791
8902
|
throw error;
|
|
8792
8903
|
} finally {
|
|
@@ -8797,11 +8908,16 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8797
8908
|
}
|
|
8798
8909
|
|
|
8799
8910
|
async function getLocalHeaderLength(reader, offset) {
|
|
8800
|
-
const headerArray =
|
|
8911
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8912
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8913
|
+
EMPTY_UINT8_ARRAY;
|
|
8801
8914
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8802
|
-
return
|
|
8915
|
+
return UNDEFINED_VALUE;
|
|
8803
8916
|
}
|
|
8804
8917
|
const headerView = getDataView(headerArray);
|
|
8918
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8919
|
+
return UNDEFINED_VALUE;
|
|
8920
|
+
}
|
|
8805
8921
|
return HEADER_SIZE +
|
|
8806
8922
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8807
8923
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9152,7 +9268,7 @@ function formatSupported(StreamClass, format) {
|
|
|
9152
9268
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9153
9269
|
*/
|
|
9154
9270
|
|
|
9155
|
-
const VERSION = "2.
|
|
9271
|
+
const VERSION = "2.21.0";
|
|
9156
9272
|
|
|
9157
9273
|
/*
|
|
9158
9274
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|