@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.js
CHANGED
|
@@ -126,6 +126,10 @@
|
|
|
126
126
|
|
|
127
127
|
const UNDEFINED_VALUE = undefined;
|
|
128
128
|
const INFINITY_VALUE = Infinity;
|
|
129
|
+
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
130
|
+
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
131
|
+
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
132
|
+
|
|
129
133
|
const UNDEFINED_TYPE = "undefined";
|
|
130
134
|
const FUNCTION_TYPE = "function";
|
|
131
135
|
const OBJECT_TYPE = "object";
|
|
@@ -4785,12 +4789,9 @@
|
|
|
4785
4789
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4786
4790
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4787
4791
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4788
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4789
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4790
4792
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4791
4793
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4792
4794
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4793
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4794
4795
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4795
4796
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4796
4797
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4855,7 +4856,8 @@
|
|
|
4855
4856
|
Object.assign(this, {
|
|
4856
4857
|
reader: new GenericReader(reader),
|
|
4857
4858
|
options,
|
|
4858
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4859
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4860
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4859
4861
|
});
|
|
4860
4862
|
}
|
|
4861
4863
|
|
|
@@ -4926,16 +4928,22 @@
|
|
|
4926
4928
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4927
4929
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4928
4930
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4931
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4932
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4933
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4934
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4935
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4936
|
+
}
|
|
4937
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4938
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4939
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4940
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4941
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4942
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4943
|
+
}
|
|
4944
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4945
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4936
4946
|
}
|
|
4937
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4938
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4939
4947
|
}
|
|
4940
4948
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4941
4949
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4980,10 +4988,6 @@
|
|
|
4980
4988
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4981
4989
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4982
4990
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4983
|
-
if (directoryDataOffset >= reader.size) {
|
|
4984
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4985
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4986
|
-
}
|
|
4987
4991
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4988
4992
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4989
4993
|
}
|
|
@@ -4991,52 +4995,64 @@
|
|
|
4991
4995
|
throw new Error(ERR_BAD_FORMAT);
|
|
4992
4996
|
}
|
|
4993
4997
|
let offset = 0;
|
|
4994
|
-
let directoryArray =
|
|
4998
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4999
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
5000
|
+
EMPTY_UINT8_ARRAY;
|
|
4995
5001
|
let directoryView = getDataView(directoryArray);
|
|
4996
5002
|
if (directoryDataLength) {
|
|
4997
|
-
if (directoryArray.length < 4) {
|
|
4998
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4999
|
-
}
|
|
5000
5003
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
5001
5004
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
5002
|
-
const storedPointsAtDirectory =
|
|
5005
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
5006
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
5003
5007
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
5004
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5008
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5009
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5010
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5011
|
+
}
|
|
5005
5012
|
let reconcile = !storedPointsAtDirectory;
|
|
5006
5013
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
5007
|
-
|
|
5008
|
-
if (
|
|
5009
|
-
reconcile = expectedPointsAtDirectory;
|
|
5010
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5014
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5015
|
+
if (!expectedPointsAtDirectory) {
|
|
5011
5016
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5012
5017
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5013
5018
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5014
5019
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5015
5020
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5021
|
+
expectedPointsAtDirectory = true;
|
|
5016
5022
|
}
|
|
5017
5023
|
}
|
|
5024
|
+
if (storedPointsAtDirectory) {
|
|
5025
|
+
reconcile = expectedPointsAtDirectory;
|
|
5026
|
+
}
|
|
5018
5027
|
}
|
|
5019
|
-
if (reconcile) {
|
|
5028
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5020
5029
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5021
5030
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5022
5031
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5023
5032
|
directoryView = getDataView(directoryArray);
|
|
5024
|
-
|
|
5025
|
-
|
|
5033
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5034
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5035
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5036
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5037
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5038
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5039
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5040
|
+
prependedDataLength += offsetDelta;
|
|
5026
5041
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5027
5042
|
} else {
|
|
5028
5043
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5032
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5033
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5034
|
-
prependedDataLength += offsetDelta;
|
|
5035
|
-
}
|
|
5044
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5045
|
+
prependedDataLength += offsetDelta;
|
|
5036
5046
|
}
|
|
5037
5047
|
}
|
|
5038
5048
|
}
|
|
5039
5049
|
}
|
|
5050
|
+
if (directoryArray.length < 4) {
|
|
5051
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5052
|
+
}
|
|
5053
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5054
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5055
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5040
5056
|
}
|
|
5041
5057
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5042
5058
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5078,8 +5094,10 @@
|
|
|
5078
5094
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5079
5095
|
}
|
|
5080
5096
|
}
|
|
5097
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5098
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5081
5099
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5082
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5100
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5083
5101
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5084
5102
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5085
5103
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5170,13 +5188,17 @@
|
|
|
5170
5188
|
if (malformedExtraField) {
|
|
5171
5189
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5172
5190
|
}
|
|
5173
|
-
fileEntry.offset
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5191
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5192
|
+
startOffset = 0;
|
|
5193
|
+
} else {
|
|
5194
|
+
fileEntry.offset += prependedDataLength;
|
|
5195
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5196
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5197
|
+
if (entryPosition < previousEntryPosition) {
|
|
5198
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5199
|
+
}
|
|
5200
|
+
previousEntryPosition = entryPosition;
|
|
5178
5201
|
}
|
|
5179
|
-
previousEntryPosition = entryPosition;
|
|
5180
5202
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5181
5203
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5182
5204
|
}
|
|
@@ -5213,12 +5235,15 @@
|
|
|
5213
5235
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5214
5236
|
});
|
|
5215
5237
|
const entry = new Entry(fileEntry);
|
|
5216
|
-
|
|
5238
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5239
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5240
|
+
}
|
|
5241
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5217
5242
|
entry.arrayBuffer = async options => {
|
|
5218
5243
|
const writer = new TransformStream();
|
|
5219
5244
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5220
5245
|
arrayBufferPromise.catch(() => { });
|
|
5221
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5246
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5222
5247
|
Object.assign({}, options, { preventClose: false }));
|
|
5223
5248
|
return arrayBufferPromise;
|
|
5224
5249
|
};
|
|
@@ -5426,8 +5451,9 @@
|
|
|
5426
5451
|
});
|
|
5427
5452
|
}
|
|
5428
5453
|
|
|
5429
|
-
async getData(writer, fileEntry,
|
|
5454
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5430
5455
|
const zipEntry = this;
|
|
5456
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5431
5457
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5432
5458
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5433
5459
|
}
|
|
@@ -5501,10 +5527,10 @@
|
|
|
5501
5527
|
}
|
|
5502
5528
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5503
5529
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5504
|
-
if (lastAccessDate) {
|
|
5530
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5505
5531
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5506
5532
|
}
|
|
5507
|
-
if (creationDate) {
|
|
5533
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5508
5534
|
fileEntry.creationDate = creationDate;
|
|
5509
5535
|
}
|
|
5510
5536
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5533,7 +5559,7 @@
|
|
|
5533
5559
|
throw new Error(ERR_ENCRYPTED);
|
|
5534
5560
|
}
|
|
5535
5561
|
}
|
|
5536
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5562
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5537
5563
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5538
5564
|
}
|
|
5539
5565
|
const size = compressedSize;
|
|
@@ -5599,6 +5625,7 @@
|
|
|
5599
5625
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5600
5626
|
readRanges
|
|
5601
5627
|
});
|
|
5628
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5602
5629
|
}
|
|
5603
5630
|
let writable, abortError, aborted;
|
|
5604
5631
|
try {
|
|
@@ -5618,10 +5645,7 @@
|
|
|
5618
5645
|
writer.size += writtenSize;
|
|
5619
5646
|
}
|
|
5620
5647
|
} catch (error) {
|
|
5621
|
-
|
|
5622
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5623
|
-
writer.size += failedOutputSize;
|
|
5624
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5648
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5625
5649
|
writer.size += error.outputSize;
|
|
5626
5650
|
}
|
|
5627
5651
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5649,13 +5673,7 @@
|
|
|
5649
5673
|
};
|
|
5650
5674
|
|
|
5651
5675
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5652
|
-
|
|
5653
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5654
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5655
|
-
return true;
|
|
5656
|
-
}
|
|
5657
|
-
}
|
|
5658
|
-
return false;
|
|
5676
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5659
5677
|
}
|
|
5660
5678
|
|
|
5661
5679
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5692,6 +5710,46 @@
|
|
|
5692
5710
|
}
|
|
5693
5711
|
}
|
|
5694
5712
|
|
|
5713
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5714
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5715
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5716
|
+
const tailView = getDataView(tailArray);
|
|
5717
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5718
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5719
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5720
|
+
return startOffset + indexByte;
|
|
5721
|
+
}
|
|
5722
|
+
}
|
|
5723
|
+
}
|
|
5724
|
+
|
|
5725
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5726
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5727
|
+
return UNDEFINED_VALUE;
|
|
5728
|
+
}
|
|
5729
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5730
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5731
|
+
return localHeaderOffset;
|
|
5732
|
+
}
|
|
5733
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5734
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5735
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5736
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5737
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5738
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5739
|
+
let offsetValue = offsetExtraField + 4;
|
|
5740
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5741
|
+
offsetValue += 8;
|
|
5742
|
+
}
|
|
5743
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5744
|
+
offsetValue += 8;
|
|
5745
|
+
}
|
|
5746
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5747
|
+
}
|
|
5748
|
+
offsetExtraField += 4 + size;
|
|
5749
|
+
}
|
|
5750
|
+
return UNDEFINED_VALUE;
|
|
5751
|
+
}
|
|
5752
|
+
|
|
5695
5753
|
function readDigitalSignature(signatureRecordArray) {
|
|
5696
5754
|
if (signatureRecordArray.length >= 6) {
|
|
5697
5755
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5781,6 +5839,7 @@
|
|
|
5781
5839
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5782
5840
|
});
|
|
5783
5841
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5842
|
+
let extraFieldZip64Missing;
|
|
5784
5843
|
if (extraFieldZip64) {
|
|
5785
5844
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5786
5845
|
malformedExtraField = true;
|
|
@@ -5790,7 +5849,7 @@
|
|
|
5790
5849
|
if (localDirectory) {
|
|
5791
5850
|
malformedExtraField = true;
|
|
5792
5851
|
} else {
|
|
5793
|
-
|
|
5852
|
+
extraFieldZip64Missing = true;
|
|
5794
5853
|
}
|
|
5795
5854
|
}
|
|
5796
5855
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5848,6 +5907,9 @@
|
|
|
5848
5907
|
if (extraFieldUSDZ) {
|
|
5849
5908
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5850
5909
|
}
|
|
5910
|
+
if (extraFieldZip64Missing) {
|
|
5911
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5912
|
+
}
|
|
5851
5913
|
return malformedExtraField;
|
|
5852
5914
|
}
|
|
5853
5915
|
|
|
@@ -6062,13 +6124,7 @@
|
|
|
6062
6124
|
let dataDescriptorLength = 0;
|
|
6063
6125
|
if (dataDescriptor) {
|
|
6064
6126
|
const zip64 = Boolean(extraFieldZip64);
|
|
6065
|
-
const
|
|
6066
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6067
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6068
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6069
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6070
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6071
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6127
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6072
6128
|
if (localDataDescriptor) {
|
|
6073
6129
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6074
6130
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6138,6 +6194,25 @@
|
|
|
6138
6194
|
return mergedRanges;
|
|
6139
6195
|
}
|
|
6140
6196
|
|
|
6197
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6198
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6199
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6200
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6201
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6202
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6203
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6204
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6205
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6206
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6207
|
+
}
|
|
6208
|
+
|
|
6209
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6210
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6211
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6212
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6213
|
+
}
|
|
6214
|
+
}
|
|
6215
|
+
|
|
6141
6216
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6142
6217
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6143
6218
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6397,6 +6472,18 @@
|
|
|
6397
6472
|
}
|
|
6398
6473
|
}
|
|
6399
6474
|
|
|
6475
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6476
|
+
const { dataDescriptor } = localDirectory;
|
|
6477
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6478
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6479
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6480
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6481
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6482
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6483
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6484
|
+
}
|
|
6485
|
+
}
|
|
6486
|
+
|
|
6400
6487
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6401
6488
|
if (reject) {
|
|
6402
6489
|
throwAmbiguousArchive(reason);
|
|
@@ -6499,6 +6586,7 @@
|
|
|
6499
6586
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6500
6587
|
ZipReader: ZipReader,
|
|
6501
6588
|
ZipReaderStream: ZipReaderStream,
|
|
6589
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6502
6590
|
isZipFile: isZipFile
|
|
6503
6591
|
});
|
|
6504
6592
|
|
|
@@ -6622,136 +6710,7 @@
|
|
|
6622
6710
|
}
|
|
6623
6711
|
|
|
6624
6712
|
appendZip(reader, options = {}) {
|
|
6625
|
-
return watchPromiseError(this,
|
|
6626
|
-
}
|
|
6627
|
-
|
|
6628
|
-
async appendZipEntries(reader, options = {}) {
|
|
6629
|
-
const zipWriter = this;
|
|
6630
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6631
|
-
const filter = checkFunctionOption(options.filter);
|
|
6632
|
-
while (pendingAddFileCalls.size) {
|
|
6633
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6634
|
-
}
|
|
6635
|
-
let resolveAppendZip;
|
|
6636
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6637
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6638
|
-
const appendedFilenames = [];
|
|
6639
|
-
let releaseLockWriter;
|
|
6640
|
-
try {
|
|
6641
|
-
reader = new GenericReader(reader);
|
|
6642
|
-
await initStream(reader);
|
|
6643
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6644
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6645
|
-
await initStream(reader);
|
|
6646
|
-
}
|
|
6647
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6648
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6649
|
-
const entries = await zipReader$1.getEntries();
|
|
6650
|
-
const keptEntries = [];
|
|
6651
|
-
for (const entry of entries) {
|
|
6652
|
-
if (!filter || await filter(entry)) {
|
|
6653
|
-
keptEntries.push(entry);
|
|
6654
|
-
}
|
|
6655
|
-
}
|
|
6656
|
-
await zipReader$1.close();
|
|
6657
|
-
await initStream(zipWriter.writer);
|
|
6658
|
-
const { directoryOffset } = zipReader$1;
|
|
6659
|
-
keptEntries.forEach(({ filename }) => {
|
|
6660
|
-
if (filenames.has(filename)) {
|
|
6661
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6662
|
-
}
|
|
6663
|
-
filenames.add(filename);
|
|
6664
|
-
appendedFilenames.push(filename);
|
|
6665
|
-
});
|
|
6666
|
-
zipWriter.writerLocked = true;
|
|
6667
|
-
const { lockWriter } = zipWriter;
|
|
6668
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6669
|
-
zipWriter.writerLocked = false;
|
|
6670
|
-
resolve();
|
|
6671
|
-
});
|
|
6672
|
-
await lockWriter;
|
|
6673
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6674
|
-
delete zipWriter.addSplitZipSignature;
|
|
6675
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6676
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6677
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6678
|
-
}
|
|
6679
|
-
}
|
|
6680
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6681
|
-
keptEntries.forEach(entry => {
|
|
6682
|
-
const {
|
|
6683
|
-
version,
|
|
6684
|
-
rawLastModDate,
|
|
6685
|
-
rawFilename,
|
|
6686
|
-
bitFlag,
|
|
6687
|
-
encrypted,
|
|
6688
|
-
uncompressedSize,
|
|
6689
|
-
compressedSize,
|
|
6690
|
-
extraFieldZip64
|
|
6691
|
-
} = entry;
|
|
6692
|
-
let {
|
|
6693
|
-
compressionMethod,
|
|
6694
|
-
rawExtraField,
|
|
6695
|
-
} = entry;
|
|
6696
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6697
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6698
|
-
if (entry.extraFieldAES) {
|
|
6699
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6700
|
-
}
|
|
6701
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6702
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6703
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6704
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6705
|
-
const {
|
|
6706
|
-
headerArray,
|
|
6707
|
-
headerView
|
|
6708
|
-
} = getHeaderArrayData({
|
|
6709
|
-
version,
|
|
6710
|
-
bitFlag: bitFlagValue,
|
|
6711
|
-
compressionMethod,
|
|
6712
|
-
uncompressedSize,
|
|
6713
|
-
compressedSize,
|
|
6714
|
-
rawLastModDate,
|
|
6715
|
-
rawFilename,
|
|
6716
|
-
zip64CompressedSize,
|
|
6717
|
-
zip64UncompressedSize,
|
|
6718
|
-
extraFieldLength
|
|
6719
|
-
});
|
|
6720
|
-
const { crc32 } = entry;
|
|
6721
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6722
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6723
|
-
}
|
|
6724
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6725
|
-
Object.assign(entry, {
|
|
6726
|
-
zip64Enabled: true,
|
|
6727
|
-
zip64UncompressedSize,
|
|
6728
|
-
zip64CompressedSize,
|
|
6729
|
-
offset,
|
|
6730
|
-
diskNumberStart,
|
|
6731
|
-
zip64DiskNumberStart: false,
|
|
6732
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6733
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6734
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6735
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6736
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6737
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6738
|
-
rawExtraField,
|
|
6739
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6740
|
-
headerArray,
|
|
6741
|
-
headerView
|
|
6742
|
-
});
|
|
6743
|
-
fileEntries.set(entry.filename, entry);
|
|
6744
|
-
});
|
|
6745
|
-
} catch (error) {
|
|
6746
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6747
|
-
throw error;
|
|
6748
|
-
} finally {
|
|
6749
|
-
resolveAppendZip();
|
|
6750
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6751
|
-
if (releaseLockWriter) {
|
|
6752
|
-
releaseLockWriter();
|
|
6753
|
-
}
|
|
6754
|
-
}
|
|
6713
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6755
6714
|
}
|
|
6756
6715
|
|
|
6757
6716
|
add(name = "", reader, options = {}) {
|
|
@@ -6913,11 +6872,140 @@
|
|
|
6913
6872
|
return watchedPromise;
|
|
6914
6873
|
}
|
|
6915
6874
|
|
|
6875
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6876
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6877
|
+
const filter = checkFunctionOption(options.filter);
|
|
6878
|
+
while (pendingAddFileCalls.size) {
|
|
6879
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6880
|
+
}
|
|
6881
|
+
let resolveAppendZip;
|
|
6882
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6883
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6884
|
+
const appendedFilenames = [];
|
|
6885
|
+
let releaseLockWriter;
|
|
6886
|
+
try {
|
|
6887
|
+
reader = new GenericReader(reader);
|
|
6888
|
+
await initStream(reader);
|
|
6889
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6890
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6891
|
+
await initStream(reader);
|
|
6892
|
+
}
|
|
6893
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6894
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6895
|
+
const entries = await zipReader$1.getEntries();
|
|
6896
|
+
const keptEntries = [];
|
|
6897
|
+
for (const entry of entries) {
|
|
6898
|
+
if (!filter || await filter(entry)) {
|
|
6899
|
+
keptEntries.push(entry);
|
|
6900
|
+
}
|
|
6901
|
+
}
|
|
6902
|
+
await zipReader$1.close();
|
|
6903
|
+
await initStream(zipWriter.writer);
|
|
6904
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6905
|
+
keptEntries.forEach(entry => {
|
|
6906
|
+
const { filename } = entry;
|
|
6907
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6908
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6909
|
+
}
|
|
6910
|
+
if (filenames.has(filename)) {
|
|
6911
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6912
|
+
}
|
|
6913
|
+
filenames.add(filename);
|
|
6914
|
+
appendedFilenames.push(filename);
|
|
6915
|
+
});
|
|
6916
|
+
zipWriter.writerLocked = true;
|
|
6917
|
+
const { lockWriter } = zipWriter;
|
|
6918
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6919
|
+
zipWriter.writerLocked = false;
|
|
6920
|
+
resolve();
|
|
6921
|
+
});
|
|
6922
|
+
await lockWriter;
|
|
6923
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6924
|
+
delete zipWriter.addSplitZipSignature;
|
|
6925
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6926
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6927
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6928
|
+
}
|
|
6929
|
+
}
|
|
6930
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6931
|
+
keptEntries.forEach(entry => {
|
|
6932
|
+
const {
|
|
6933
|
+
version,
|
|
6934
|
+
rawLastModDate,
|
|
6935
|
+
rawFilename,
|
|
6936
|
+
rawBitFlag,
|
|
6937
|
+
uncompressedSize,
|
|
6938
|
+
compressedSize,
|
|
6939
|
+
extraFieldZip64
|
|
6940
|
+
} = entry;
|
|
6941
|
+
let {
|
|
6942
|
+
compressionMethod,
|
|
6943
|
+
rawExtraField,
|
|
6944
|
+
} = entry;
|
|
6945
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6946
|
+
if (entry.extraFieldAES) {
|
|
6947
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6948
|
+
}
|
|
6949
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6950
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6951
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6952
|
+
const {
|
|
6953
|
+
headerArray,
|
|
6954
|
+
headerView
|
|
6955
|
+
} = getHeaderArrayData({
|
|
6956
|
+
version,
|
|
6957
|
+
bitFlag: rawBitFlag,
|
|
6958
|
+
compressionMethod,
|
|
6959
|
+
uncompressedSize,
|
|
6960
|
+
compressedSize,
|
|
6961
|
+
rawLastModDate,
|
|
6962
|
+
rawFilename,
|
|
6963
|
+
zip64CompressedSize,
|
|
6964
|
+
zip64UncompressedSize,
|
|
6965
|
+
extraFieldLength
|
|
6966
|
+
});
|
|
6967
|
+
const { crc32 } = entry;
|
|
6968
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6969
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6970
|
+
}
|
|
6971
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6972
|
+
Object.assign(entry, {
|
|
6973
|
+
zip64Enabled: true,
|
|
6974
|
+
zip64UncompressedSize,
|
|
6975
|
+
zip64CompressedSize,
|
|
6976
|
+
offset,
|
|
6977
|
+
diskNumberStart,
|
|
6978
|
+
zip64DiskNumberStart: false,
|
|
6979
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6980
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6981
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6982
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6983
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6984
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6985
|
+
rawExtraField,
|
|
6986
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6987
|
+
headerArray,
|
|
6988
|
+
headerView
|
|
6989
|
+
});
|
|
6990
|
+
fileEntries.set(entry.filename, entry);
|
|
6991
|
+
});
|
|
6992
|
+
} catch (error) {
|
|
6993
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6994
|
+
throw error;
|
|
6995
|
+
} finally {
|
|
6996
|
+
resolveAppendZip();
|
|
6997
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6998
|
+
if (releaseLockWriter) {
|
|
6999
|
+
releaseLockWriter();
|
|
7000
|
+
}
|
|
7001
|
+
}
|
|
7002
|
+
}
|
|
7003
|
+
|
|
6916
7004
|
async function prependZipEntries(zipWriter, reader) {
|
|
6917
7005
|
if (zipWriter.filenames.size) {
|
|
6918
7006
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6919
7007
|
}
|
|
6920
|
-
await
|
|
7008
|
+
await appendZipEntries(zipWriter, reader);
|
|
6921
7009
|
}
|
|
6922
7010
|
|
|
6923
7011
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8689,7 +8777,7 @@
|
|
|
8689
8777
|
return rawExtraField;
|
|
8690
8778
|
}
|
|
8691
8779
|
|
|
8692
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8780
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8693
8781
|
const { writer } = zipWriter;
|
|
8694
8782
|
const entryPositions = new Map();
|
|
8695
8783
|
if (writer.closeDisk || compact) {
|
|
@@ -8697,6 +8785,27 @@
|
|
|
8697
8785
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8698
8786
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8699
8787
|
const keptEntrySet = new Set(keptEntries);
|
|
8788
|
+
const localHeaderLengths = new Map();
|
|
8789
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8790
|
+
const entry = sortedEntries[indexEntry];
|
|
8791
|
+
if (keptEntrySet.has(entry)) {
|
|
8792
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8793
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8794
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8795
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8796
|
+
}
|
|
8797
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8798
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8799
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8800
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8801
|
+
}
|
|
8802
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8803
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8804
|
+
}
|
|
8805
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8806
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8807
|
+
}
|
|
8808
|
+
}
|
|
8700
8809
|
let copiedOffset = 0;
|
|
8701
8810
|
let lastPosition;
|
|
8702
8811
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8709,7 +8818,7 @@
|
|
|
8709
8818
|
if (!compact) {
|
|
8710
8819
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8711
8820
|
}
|
|
8712
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8821
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8713
8822
|
await writer.closeDisk();
|
|
8714
8823
|
}
|
|
8715
8824
|
lastPosition = {
|
|
@@ -8743,7 +8852,7 @@
|
|
|
8743
8852
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8744
8853
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8745
8854
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8746
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8855
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8747
8856
|
}
|
|
8748
8857
|
regionEnds[indexEntry] = regionEnd;
|
|
8749
8858
|
}
|
|
@@ -8757,11 +8866,13 @@
|
|
|
8757
8866
|
try {
|
|
8758
8867
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8759
8868
|
} catch (error) {
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8869
|
+
if (copiedLength) {
|
|
8870
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8871
|
+
try {
|
|
8872
|
+
error.corruptedEntry = true;
|
|
8873
|
+
} catch {
|
|
8874
|
+
// ignored
|
|
8875
|
+
}
|
|
8765
8876
|
}
|
|
8766
8877
|
throw error;
|
|
8767
8878
|
} finally {
|
|
@@ -8772,11 +8883,16 @@
|
|
|
8772
8883
|
}
|
|
8773
8884
|
|
|
8774
8885
|
async function getLocalHeaderLength(reader, offset) {
|
|
8775
|
-
const headerArray =
|
|
8886
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8887
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8888
|
+
EMPTY_UINT8_ARRAY;
|
|
8776
8889
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8777
|
-
return
|
|
8890
|
+
return UNDEFINED_VALUE;
|
|
8778
8891
|
}
|
|
8779
8892
|
const headerView = getDataView(headerArray);
|
|
8893
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8894
|
+
return UNDEFINED_VALUE;
|
|
8895
|
+
}
|
|
8780
8896
|
return HEADER_SIZE +
|
|
8781
8897
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8782
8898
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9127,7 +9243,7 @@
|
|
|
9127
9243
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9128
9244
|
*/
|
|
9129
9245
|
|
|
9130
|
-
const VERSION = "2.
|
|
9246
|
+
const VERSION = "2.21.0";
|
|
9131
9247
|
|
|
9132
9248
|
/*
|
|
9133
9249
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|