@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/index.cjs
CHANGED
|
@@ -120,6 +120,10 @@ const MIN_DATE = new Date(1980, 0, 1);
|
|
|
120
120
|
|
|
121
121
|
const UNDEFINED_VALUE = undefined;
|
|
122
122
|
const INFINITY_VALUE = Infinity;
|
|
123
|
+
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
124
|
+
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
125
|
+
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
126
|
+
|
|
123
127
|
const UNDEFINED_TYPE = "undefined";
|
|
124
128
|
const FUNCTION_TYPE = "function";
|
|
125
129
|
const OBJECT_TYPE = "object";
|
|
@@ -4779,12 +4783,9 @@ const ERR_BAD_FORMAT = "File format is not recognized";
|
|
|
4779
4783
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4780
4784
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4781
4785
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4782
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4783
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4784
4786
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4785
4787
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4786
4788
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4787
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4788
4789
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4789
4790
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4790
4791
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4849,7 +4850,8 @@ class ZipReader {
|
|
|
4849
4850
|
Object.assign(this, {
|
|
4850
4851
|
reader: new GenericReader(reader),
|
|
4851
4852
|
options,
|
|
4852
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4853
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4854
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4853
4855
|
});
|
|
4854
4856
|
}
|
|
4855
4857
|
|
|
@@ -4920,16 +4922,22 @@ class ZipReader {
|
|
|
4920
4922
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4921
4923
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4922
4924
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4925
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4926
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4927
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4928
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4929
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4930
|
+
}
|
|
4931
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4932
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4933
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4934
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4935
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4936
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4937
|
+
}
|
|
4938
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4939
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4930
4940
|
}
|
|
4931
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4932
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4933
4941
|
}
|
|
4934
4942
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4935
4943
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4974,10 +4982,6 @@ class ZipReader {
|
|
|
4974
4982
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4975
4983
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4976
4984
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4977
|
-
if (directoryDataOffset >= reader.size) {
|
|
4978
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4979
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4980
|
-
}
|
|
4981
4985
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4982
4986
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4983
4987
|
}
|
|
@@ -4985,52 +4989,64 @@ class ZipReader {
|
|
|
4985
4989
|
throw new Error(ERR_BAD_FORMAT);
|
|
4986
4990
|
}
|
|
4987
4991
|
let offset = 0;
|
|
4988
|
-
let directoryArray =
|
|
4992
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4993
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4994
|
+
EMPTY_UINT8_ARRAY;
|
|
4989
4995
|
let directoryView = getDataView(directoryArray);
|
|
4990
4996
|
if (directoryDataLength) {
|
|
4991
|
-
if (directoryArray.length < 4) {
|
|
4992
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4993
|
-
}
|
|
4994
4997
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4995
4998
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4996
|
-
const storedPointsAtDirectory =
|
|
4999
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
5000
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4997
5001
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4998
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5002
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5003
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5004
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5005
|
+
}
|
|
4999
5006
|
let reconcile = !storedPointsAtDirectory;
|
|
5000
5007
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
5001
|
-
|
|
5002
|
-
if (
|
|
5003
|
-
reconcile = expectedPointsAtDirectory;
|
|
5004
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5008
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5009
|
+
if (!expectedPointsAtDirectory) {
|
|
5005
5010
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5006
5011
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5007
5012
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5008
5013
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5009
5014
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5015
|
+
expectedPointsAtDirectory = true;
|
|
5010
5016
|
}
|
|
5011
5017
|
}
|
|
5018
|
+
if (storedPointsAtDirectory) {
|
|
5019
|
+
reconcile = expectedPointsAtDirectory;
|
|
5020
|
+
}
|
|
5012
5021
|
}
|
|
5013
|
-
if (reconcile) {
|
|
5022
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5014
5023
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5015
5024
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5016
5025
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5017
5026
|
directoryView = getDataView(directoryArray);
|
|
5018
|
-
|
|
5019
|
-
|
|
5027
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5028
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5029
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5030
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5031
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5032
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5033
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5034
|
+
prependedDataLength += offsetDelta;
|
|
5020
5035
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5021
5036
|
} else {
|
|
5022
5037
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5026
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5027
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5028
|
-
prependedDataLength += offsetDelta;
|
|
5029
|
-
}
|
|
5038
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5039
|
+
prependedDataLength += offsetDelta;
|
|
5030
5040
|
}
|
|
5031
5041
|
}
|
|
5032
5042
|
}
|
|
5033
5043
|
}
|
|
5044
|
+
if (directoryArray.length < 4) {
|
|
5045
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5046
|
+
}
|
|
5047
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5048
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5049
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5034
5050
|
}
|
|
5035
5051
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5036
5052
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5072,8 +5088,10 @@ class ZipReader {
|
|
|
5072
5088
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5073
5089
|
}
|
|
5074
5090
|
}
|
|
5091
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5092
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5075
5093
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5076
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5094
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5077
5095
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5078
5096
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5079
5097
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5164,13 +5182,17 @@ class ZipReader {
|
|
|
5164
5182
|
if (malformedExtraField) {
|
|
5165
5183
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5166
5184
|
}
|
|
5167
|
-
fileEntry.offset
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5185
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5186
|
+
startOffset = 0;
|
|
5187
|
+
} else {
|
|
5188
|
+
fileEntry.offset += prependedDataLength;
|
|
5189
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5190
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5191
|
+
if (entryPosition < previousEntryPosition) {
|
|
5192
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5193
|
+
}
|
|
5194
|
+
previousEntryPosition = entryPosition;
|
|
5172
5195
|
}
|
|
5173
|
-
previousEntryPosition = entryPosition;
|
|
5174
5196
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5175
5197
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5176
5198
|
}
|
|
@@ -5207,12 +5229,15 @@ class ZipReader {
|
|
|
5207
5229
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5208
5230
|
});
|
|
5209
5231
|
const entry = new Entry(fileEntry);
|
|
5210
|
-
|
|
5232
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5233
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5234
|
+
}
|
|
5235
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5211
5236
|
entry.arrayBuffer = async options => {
|
|
5212
5237
|
const writer = new TransformStream();
|
|
5213
5238
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5214
5239
|
arrayBufferPromise.catch(() => { });
|
|
5215
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5240
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5216
5241
|
Object.assign({}, options, { preventClose: false }));
|
|
5217
5242
|
return arrayBufferPromise;
|
|
5218
5243
|
};
|
|
@@ -5420,8 +5445,9 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5420
5445
|
});
|
|
5421
5446
|
}
|
|
5422
5447
|
|
|
5423
|
-
async getData(writer, fileEntry,
|
|
5448
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5424
5449
|
const zipEntry = this;
|
|
5450
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5425
5451
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5426
5452
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5427
5453
|
}
|
|
@@ -5495,10 +5521,10 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5495
5521
|
}
|
|
5496
5522
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5497
5523
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5498
|
-
if (lastAccessDate) {
|
|
5524
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5499
5525
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5500
5526
|
}
|
|
5501
|
-
if (creationDate) {
|
|
5527
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5502
5528
|
fileEntry.creationDate = creationDate;
|
|
5503
5529
|
}
|
|
5504
5530
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5527,7 +5553,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5527
5553
|
throw new Error(ERR_ENCRYPTED);
|
|
5528
5554
|
}
|
|
5529
5555
|
}
|
|
5530
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5556
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5531
5557
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5532
5558
|
}
|
|
5533
5559
|
const size = compressedSize;
|
|
@@ -5593,6 +5619,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5593
5619
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5594
5620
|
readRanges
|
|
5595
5621
|
});
|
|
5622
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5596
5623
|
}
|
|
5597
5624
|
let writable, abortError, aborted;
|
|
5598
5625
|
try {
|
|
@@ -5612,10 +5639,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5612
5639
|
writer.size += writtenSize;
|
|
5613
5640
|
}
|
|
5614
5641
|
} catch (error) {
|
|
5615
|
-
|
|
5616
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5617
|
-
writer.size += failedOutputSize;
|
|
5618
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5642
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5619
5643
|
writer.size += error.outputSize;
|
|
5620
5644
|
}
|
|
5621
5645
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5643,13 +5667,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5643
5667
|
};
|
|
5644
5668
|
|
|
5645
5669
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5646
|
-
|
|
5647
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5648
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5649
|
-
return true;
|
|
5650
|
-
}
|
|
5651
|
-
}
|
|
5652
|
-
return false;
|
|
5670
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5653
5671
|
}
|
|
5654
5672
|
|
|
5655
5673
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5686,6 +5704,46 @@ async function findDigitalSignatureRecordOffset(reader, endOffset) {
|
|
|
5686
5704
|
}
|
|
5687
5705
|
}
|
|
5688
5706
|
|
|
5707
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5708
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5709
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5710
|
+
const tailView = getDataView(tailArray);
|
|
5711
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5712
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5713
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5714
|
+
return startOffset + indexByte;
|
|
5715
|
+
}
|
|
5716
|
+
}
|
|
5717
|
+
}
|
|
5718
|
+
|
|
5719
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5720
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5721
|
+
return UNDEFINED_VALUE;
|
|
5722
|
+
}
|
|
5723
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5724
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5725
|
+
return localHeaderOffset;
|
|
5726
|
+
}
|
|
5727
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5728
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5729
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5730
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5731
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5732
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5733
|
+
let offsetValue = offsetExtraField + 4;
|
|
5734
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5735
|
+
offsetValue += 8;
|
|
5736
|
+
}
|
|
5737
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5738
|
+
offsetValue += 8;
|
|
5739
|
+
}
|
|
5740
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5741
|
+
}
|
|
5742
|
+
offsetExtraField += 4 + size;
|
|
5743
|
+
}
|
|
5744
|
+
return UNDEFINED_VALUE;
|
|
5745
|
+
}
|
|
5746
|
+
|
|
5689
5747
|
function readDigitalSignature(signatureRecordArray) {
|
|
5690
5748
|
if (signatureRecordArray.length >= 6) {
|
|
5691
5749
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5775,6 +5833,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5775
5833
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5776
5834
|
});
|
|
5777
5835
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5836
|
+
let extraFieldZip64Missing;
|
|
5778
5837
|
if (extraFieldZip64) {
|
|
5779
5838
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5780
5839
|
malformedExtraField = true;
|
|
@@ -5784,7 +5843,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5784
5843
|
if (localDirectory) {
|
|
5785
5844
|
malformedExtraField = true;
|
|
5786
5845
|
} else {
|
|
5787
|
-
|
|
5846
|
+
extraFieldZip64Missing = true;
|
|
5788
5847
|
}
|
|
5789
5848
|
}
|
|
5790
5849
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5842,6 +5901,9 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5842
5901
|
if (extraFieldUSDZ) {
|
|
5843
5902
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5844
5903
|
}
|
|
5904
|
+
if (extraFieldZip64Missing) {
|
|
5905
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5906
|
+
}
|
|
5845
5907
|
return malformedExtraField;
|
|
5846
5908
|
}
|
|
5847
5909
|
|
|
@@ -6056,13 +6118,7 @@ async function detectOverlappingEntry({
|
|
|
6056
6118
|
let dataDescriptorLength = 0;
|
|
6057
6119
|
if (dataDescriptor) {
|
|
6058
6120
|
const zip64 = Boolean(extraFieldZip64);
|
|
6059
|
-
const
|
|
6060
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6061
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6062
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6063
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6064
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6065
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6121
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6066
6122
|
if (localDataDescriptor) {
|
|
6067
6123
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6068
6124
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6132,6 +6188,25 @@ function mergeRanges(sortedRanges, pendingRanges) {
|
|
|
6132
6188
|
return mergedRanges;
|
|
6133
6189
|
}
|
|
6134
6190
|
|
|
6191
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6192
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6193
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6194
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6195
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6196
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6197
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6198
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6199
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6200
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6201
|
+
}
|
|
6202
|
+
|
|
6203
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6204
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6205
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6206
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6207
|
+
}
|
|
6208
|
+
}
|
|
6209
|
+
|
|
6135
6210
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6136
6211
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6137
6212
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6391,6 +6466,18 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
|
|
|
6391
6466
|
}
|
|
6392
6467
|
}
|
|
6393
6468
|
|
|
6469
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6470
|
+
const { dataDescriptor } = localDirectory;
|
|
6471
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6472
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6473
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6474
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6475
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6476
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6477
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6478
|
+
}
|
|
6479
|
+
}
|
|
6480
|
+
|
|
6394
6481
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6395
6482
|
if (reject) {
|
|
6396
6483
|
throwAmbiguousArchive(reason);
|
|
@@ -6493,6 +6580,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6493
6580
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6494
6581
|
ZipReader: ZipReader,
|
|
6495
6582
|
ZipReaderStream: ZipReaderStream,
|
|
6583
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6496
6584
|
isZipFile: isZipFile
|
|
6497
6585
|
});
|
|
6498
6586
|
|
|
@@ -6616,136 +6704,7 @@ class ZipWriter {
|
|
|
6616
6704
|
}
|
|
6617
6705
|
|
|
6618
6706
|
appendZip(reader, options = {}) {
|
|
6619
|
-
return watchPromiseError(this,
|
|
6620
|
-
}
|
|
6621
|
-
|
|
6622
|
-
async appendZipEntries(reader, options = {}) {
|
|
6623
|
-
const zipWriter = this;
|
|
6624
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6625
|
-
const filter = checkFunctionOption(options.filter);
|
|
6626
|
-
while (pendingAddFileCalls.size) {
|
|
6627
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6628
|
-
}
|
|
6629
|
-
let resolveAppendZip;
|
|
6630
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6631
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6632
|
-
const appendedFilenames = [];
|
|
6633
|
-
let releaseLockWriter;
|
|
6634
|
-
try {
|
|
6635
|
-
reader = new GenericReader(reader);
|
|
6636
|
-
await initStream(reader);
|
|
6637
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6638
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6639
|
-
await initStream(reader);
|
|
6640
|
-
}
|
|
6641
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6642
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6643
|
-
const entries = await zipReader$1.getEntries();
|
|
6644
|
-
const keptEntries = [];
|
|
6645
|
-
for (const entry of entries) {
|
|
6646
|
-
if (!filter || await filter(entry)) {
|
|
6647
|
-
keptEntries.push(entry);
|
|
6648
|
-
}
|
|
6649
|
-
}
|
|
6650
|
-
await zipReader$1.close();
|
|
6651
|
-
await initStream(zipWriter.writer);
|
|
6652
|
-
const { directoryOffset } = zipReader$1;
|
|
6653
|
-
keptEntries.forEach(({ filename }) => {
|
|
6654
|
-
if (filenames.has(filename)) {
|
|
6655
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6656
|
-
}
|
|
6657
|
-
filenames.add(filename);
|
|
6658
|
-
appendedFilenames.push(filename);
|
|
6659
|
-
});
|
|
6660
|
-
zipWriter.writerLocked = true;
|
|
6661
|
-
const { lockWriter } = zipWriter;
|
|
6662
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6663
|
-
zipWriter.writerLocked = false;
|
|
6664
|
-
resolve();
|
|
6665
|
-
});
|
|
6666
|
-
await lockWriter;
|
|
6667
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6668
|
-
delete zipWriter.addSplitZipSignature;
|
|
6669
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6670
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6671
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6672
|
-
}
|
|
6673
|
-
}
|
|
6674
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6675
|
-
keptEntries.forEach(entry => {
|
|
6676
|
-
const {
|
|
6677
|
-
version,
|
|
6678
|
-
rawLastModDate,
|
|
6679
|
-
rawFilename,
|
|
6680
|
-
bitFlag,
|
|
6681
|
-
encrypted,
|
|
6682
|
-
uncompressedSize,
|
|
6683
|
-
compressedSize,
|
|
6684
|
-
extraFieldZip64
|
|
6685
|
-
} = entry;
|
|
6686
|
-
let {
|
|
6687
|
-
compressionMethod,
|
|
6688
|
-
rawExtraField,
|
|
6689
|
-
} = entry;
|
|
6690
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6691
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6692
|
-
if (entry.extraFieldAES) {
|
|
6693
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6694
|
-
}
|
|
6695
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6696
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6697
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6698
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6699
|
-
const {
|
|
6700
|
-
headerArray,
|
|
6701
|
-
headerView
|
|
6702
|
-
} = getHeaderArrayData({
|
|
6703
|
-
version,
|
|
6704
|
-
bitFlag: bitFlagValue,
|
|
6705
|
-
compressionMethod,
|
|
6706
|
-
uncompressedSize,
|
|
6707
|
-
compressedSize,
|
|
6708
|
-
rawLastModDate,
|
|
6709
|
-
rawFilename,
|
|
6710
|
-
zip64CompressedSize,
|
|
6711
|
-
zip64UncompressedSize,
|
|
6712
|
-
extraFieldLength
|
|
6713
|
-
});
|
|
6714
|
-
const { crc32 } = entry;
|
|
6715
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6716
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6717
|
-
}
|
|
6718
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6719
|
-
Object.assign(entry, {
|
|
6720
|
-
zip64Enabled: true,
|
|
6721
|
-
zip64UncompressedSize,
|
|
6722
|
-
zip64CompressedSize,
|
|
6723
|
-
offset,
|
|
6724
|
-
diskNumberStart,
|
|
6725
|
-
zip64DiskNumberStart: false,
|
|
6726
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6727
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6728
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6729
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6730
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6731
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6732
|
-
rawExtraField,
|
|
6733
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6734
|
-
headerArray,
|
|
6735
|
-
headerView
|
|
6736
|
-
});
|
|
6737
|
-
fileEntries.set(entry.filename, entry);
|
|
6738
|
-
});
|
|
6739
|
-
} catch (error) {
|
|
6740
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6741
|
-
throw error;
|
|
6742
|
-
} finally {
|
|
6743
|
-
resolveAppendZip();
|
|
6744
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6745
|
-
if (releaseLockWriter) {
|
|
6746
|
-
releaseLockWriter();
|
|
6747
|
-
}
|
|
6748
|
-
}
|
|
6707
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6749
6708
|
}
|
|
6750
6709
|
|
|
6751
6710
|
add(name = "", reader, options = {}) {
|
|
@@ -6907,11 +6866,140 @@ function watchPromiseError(zipWriter, promise) {
|
|
|
6907
6866
|
return watchedPromise;
|
|
6908
6867
|
}
|
|
6909
6868
|
|
|
6869
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6870
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6871
|
+
const filter = checkFunctionOption(options.filter);
|
|
6872
|
+
while (pendingAddFileCalls.size) {
|
|
6873
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6874
|
+
}
|
|
6875
|
+
let resolveAppendZip;
|
|
6876
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6877
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6878
|
+
const appendedFilenames = [];
|
|
6879
|
+
let releaseLockWriter;
|
|
6880
|
+
try {
|
|
6881
|
+
reader = new GenericReader(reader);
|
|
6882
|
+
await initStream(reader);
|
|
6883
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6884
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6885
|
+
await initStream(reader);
|
|
6886
|
+
}
|
|
6887
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6888
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6889
|
+
const entries = await zipReader$1.getEntries();
|
|
6890
|
+
const keptEntries = [];
|
|
6891
|
+
for (const entry of entries) {
|
|
6892
|
+
if (!filter || await filter(entry)) {
|
|
6893
|
+
keptEntries.push(entry);
|
|
6894
|
+
}
|
|
6895
|
+
}
|
|
6896
|
+
await zipReader$1.close();
|
|
6897
|
+
await initStream(zipWriter.writer);
|
|
6898
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6899
|
+
keptEntries.forEach(entry => {
|
|
6900
|
+
const { filename } = entry;
|
|
6901
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6902
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6903
|
+
}
|
|
6904
|
+
if (filenames.has(filename)) {
|
|
6905
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6906
|
+
}
|
|
6907
|
+
filenames.add(filename);
|
|
6908
|
+
appendedFilenames.push(filename);
|
|
6909
|
+
});
|
|
6910
|
+
zipWriter.writerLocked = true;
|
|
6911
|
+
const { lockWriter } = zipWriter;
|
|
6912
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6913
|
+
zipWriter.writerLocked = false;
|
|
6914
|
+
resolve();
|
|
6915
|
+
});
|
|
6916
|
+
await lockWriter;
|
|
6917
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6918
|
+
delete zipWriter.addSplitZipSignature;
|
|
6919
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6920
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6921
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6922
|
+
}
|
|
6923
|
+
}
|
|
6924
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6925
|
+
keptEntries.forEach(entry => {
|
|
6926
|
+
const {
|
|
6927
|
+
version,
|
|
6928
|
+
rawLastModDate,
|
|
6929
|
+
rawFilename,
|
|
6930
|
+
rawBitFlag,
|
|
6931
|
+
uncompressedSize,
|
|
6932
|
+
compressedSize,
|
|
6933
|
+
extraFieldZip64
|
|
6934
|
+
} = entry;
|
|
6935
|
+
let {
|
|
6936
|
+
compressionMethod,
|
|
6937
|
+
rawExtraField,
|
|
6938
|
+
} = entry;
|
|
6939
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6940
|
+
if (entry.extraFieldAES) {
|
|
6941
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6942
|
+
}
|
|
6943
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6944
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6945
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6946
|
+
const {
|
|
6947
|
+
headerArray,
|
|
6948
|
+
headerView
|
|
6949
|
+
} = getHeaderArrayData({
|
|
6950
|
+
version,
|
|
6951
|
+
bitFlag: rawBitFlag,
|
|
6952
|
+
compressionMethod,
|
|
6953
|
+
uncompressedSize,
|
|
6954
|
+
compressedSize,
|
|
6955
|
+
rawLastModDate,
|
|
6956
|
+
rawFilename,
|
|
6957
|
+
zip64CompressedSize,
|
|
6958
|
+
zip64UncompressedSize,
|
|
6959
|
+
extraFieldLength
|
|
6960
|
+
});
|
|
6961
|
+
const { crc32 } = entry;
|
|
6962
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6963
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6964
|
+
}
|
|
6965
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6966
|
+
Object.assign(entry, {
|
|
6967
|
+
zip64Enabled: true,
|
|
6968
|
+
zip64UncompressedSize,
|
|
6969
|
+
zip64CompressedSize,
|
|
6970
|
+
offset,
|
|
6971
|
+
diskNumberStart,
|
|
6972
|
+
zip64DiskNumberStart: false,
|
|
6973
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6974
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6975
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6976
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6977
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6978
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6979
|
+
rawExtraField,
|
|
6980
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6981
|
+
headerArray,
|
|
6982
|
+
headerView
|
|
6983
|
+
});
|
|
6984
|
+
fileEntries.set(entry.filename, entry);
|
|
6985
|
+
});
|
|
6986
|
+
} catch (error) {
|
|
6987
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6988
|
+
throw error;
|
|
6989
|
+
} finally {
|
|
6990
|
+
resolveAppendZip();
|
|
6991
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6992
|
+
if (releaseLockWriter) {
|
|
6993
|
+
releaseLockWriter();
|
|
6994
|
+
}
|
|
6995
|
+
}
|
|
6996
|
+
}
|
|
6997
|
+
|
|
6910
6998
|
async function prependZipEntries(zipWriter, reader) {
|
|
6911
6999
|
if (zipWriter.filenames.size) {
|
|
6912
7000
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6913
7001
|
}
|
|
6914
|
-
await
|
|
7002
|
+
await appendZipEntries(zipWriter, reader);
|
|
6915
7003
|
}
|
|
6916
7004
|
|
|
6917
7005
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8683,7 +8771,7 @@ function removeExtraFieldZip64(rawExtraField) {
|
|
|
8683
8771
|
return rawExtraField;
|
|
8684
8772
|
}
|
|
8685
8773
|
|
|
8686
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8774
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8687
8775
|
const { writer } = zipWriter;
|
|
8688
8776
|
const entryPositions = new Map();
|
|
8689
8777
|
if (writer.closeDisk || compact) {
|
|
@@ -8691,6 +8779,27 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8691
8779
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8692
8780
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8693
8781
|
const keptEntrySet = new Set(keptEntries);
|
|
8782
|
+
const localHeaderLengths = new Map();
|
|
8783
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8784
|
+
const entry = sortedEntries[indexEntry];
|
|
8785
|
+
if (keptEntrySet.has(entry)) {
|
|
8786
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8787
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8788
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8789
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8790
|
+
}
|
|
8791
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8792
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8793
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8794
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8795
|
+
}
|
|
8796
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8797
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8798
|
+
}
|
|
8799
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8800
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8801
|
+
}
|
|
8802
|
+
}
|
|
8694
8803
|
let copiedOffset = 0;
|
|
8695
8804
|
let lastPosition;
|
|
8696
8805
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8703,7 +8812,7 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8703
8812
|
if (!compact) {
|
|
8704
8813
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8705
8814
|
}
|
|
8706
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8815
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8707
8816
|
await writer.closeDisk();
|
|
8708
8817
|
}
|
|
8709
8818
|
lastPosition = {
|
|
@@ -8737,7 +8846,7 @@ function getRegionEnds(reader, sortedEntries, directoryOffset) {
|
|
|
8737
8846
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8738
8847
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8739
8848
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8740
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8849
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8741
8850
|
}
|
|
8742
8851
|
regionEnds[indexEntry] = regionEnd;
|
|
8743
8852
|
}
|
|
@@ -8751,11 +8860,13 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8751
8860
|
try {
|
|
8752
8861
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8753
8862
|
} catch (error) {
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8863
|
+
if (copiedLength) {
|
|
8864
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8865
|
+
try {
|
|
8866
|
+
error.corruptedEntry = true;
|
|
8867
|
+
} catch {
|
|
8868
|
+
// ignored
|
|
8869
|
+
}
|
|
8759
8870
|
}
|
|
8760
8871
|
throw error;
|
|
8761
8872
|
} finally {
|
|
@@ -8766,11 +8877,16 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8766
8877
|
}
|
|
8767
8878
|
|
|
8768
8879
|
async function getLocalHeaderLength(reader, offset) {
|
|
8769
|
-
const headerArray =
|
|
8880
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8881
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8882
|
+
EMPTY_UINT8_ARRAY;
|
|
8770
8883
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8771
|
-
return
|
|
8884
|
+
return UNDEFINED_VALUE;
|
|
8772
8885
|
}
|
|
8773
8886
|
const headerView = getDataView(headerArray);
|
|
8887
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8888
|
+
return UNDEFINED_VALUE;
|
|
8889
|
+
}
|
|
8774
8890
|
return HEADER_SIZE +
|
|
8775
8891
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8776
8892
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9121,7 +9237,7 @@ function formatSupported(StreamClass, format) {
|
|
|
9121
9237
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9122
9238
|
*/
|
|
9123
9239
|
|
|
9124
|
-
const VERSION = "2.
|
|
9240
|
+
const VERSION = "2.21.0";
|
|
9125
9241
|
|
|
9126
9242
|
/*
|
|
9127
9243
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|