@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.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";
|
|
@@ -4765,12 +4769,9 @@
|
|
|
4765
4769
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4766
4770
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4767
4771
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4768
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4769
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4770
4772
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4771
4773
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4772
4774
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4773
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4774
4775
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4775
4776
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4776
4777
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4835,7 +4836,8 @@
|
|
|
4835
4836
|
Object.assign(this, {
|
|
4836
4837
|
reader: new GenericReader(reader),
|
|
4837
4838
|
options,
|
|
4838
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4839
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4840
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4839
4841
|
});
|
|
4840
4842
|
}
|
|
4841
4843
|
|
|
@@ -4906,16 +4908,22 @@
|
|
|
4906
4908
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4907
4909
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4908
4910
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4911
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4912
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4913
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4914
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4915
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4916
|
+
}
|
|
4917
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4918
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4919
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4920
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4921
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4922
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4923
|
+
}
|
|
4924
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4925
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4916
4926
|
}
|
|
4917
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4918
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4919
4927
|
}
|
|
4920
4928
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4921
4929
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4960,10 +4968,6 @@
|
|
|
4960
4968
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4961
4969
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4962
4970
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4963
|
-
if (directoryDataOffset >= reader.size) {
|
|
4964
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4965
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4966
|
-
}
|
|
4967
4971
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4968
4972
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4969
4973
|
}
|
|
@@ -4971,52 +4975,64 @@
|
|
|
4971
4975
|
throw new Error(ERR_BAD_FORMAT);
|
|
4972
4976
|
}
|
|
4973
4977
|
let offset = 0;
|
|
4974
|
-
let directoryArray =
|
|
4978
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4979
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4980
|
+
EMPTY_UINT8_ARRAY;
|
|
4975
4981
|
let directoryView = getDataView(directoryArray);
|
|
4976
4982
|
if (directoryDataLength) {
|
|
4977
|
-
if (directoryArray.length < 4) {
|
|
4978
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4979
|
-
}
|
|
4980
4983
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4981
4984
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4982
|
-
const storedPointsAtDirectory =
|
|
4985
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
4986
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4983
4987
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4984
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
4988
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
4989
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
4990
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
4991
|
+
}
|
|
4985
4992
|
let reconcile = !storedPointsAtDirectory;
|
|
4986
4993
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4987
|
-
|
|
4988
|
-
if (
|
|
4989
|
-
reconcile = expectedPointsAtDirectory;
|
|
4990
|
-
} else if (!expectedPointsAtDirectory) {
|
|
4994
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
4995
|
+
if (!expectedPointsAtDirectory) {
|
|
4991
4996
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
4992
4997
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
4993
4998
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
4994
4999
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
4995
5000
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5001
|
+
expectedPointsAtDirectory = true;
|
|
4996
5002
|
}
|
|
4997
5003
|
}
|
|
5004
|
+
if (storedPointsAtDirectory) {
|
|
5005
|
+
reconcile = expectedPointsAtDirectory;
|
|
5006
|
+
}
|
|
4998
5007
|
}
|
|
4999
|
-
if (reconcile) {
|
|
5008
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5000
5009
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5001
5010
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5002
5011
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5003
5012
|
directoryView = getDataView(directoryArray);
|
|
5004
|
-
|
|
5005
|
-
|
|
5013
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5014
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5015
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5016
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5017
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5018
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5019
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5020
|
+
prependedDataLength += offsetDelta;
|
|
5006
5021
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5007
5022
|
} else {
|
|
5008
5023
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5012
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5013
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5014
|
-
prependedDataLength += offsetDelta;
|
|
5015
|
-
}
|
|
5024
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5025
|
+
prependedDataLength += offsetDelta;
|
|
5016
5026
|
}
|
|
5017
5027
|
}
|
|
5018
5028
|
}
|
|
5019
5029
|
}
|
|
5030
|
+
if (directoryArray.length < 4) {
|
|
5031
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5032
|
+
}
|
|
5033
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5034
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5035
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5020
5036
|
}
|
|
5021
5037
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5022
5038
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5058,8 +5074,10 @@
|
|
|
5058
5074
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5059
5075
|
}
|
|
5060
5076
|
}
|
|
5077
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5078
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5061
5079
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5062
|
-
const fileEntry = new ZipEntry(reader,
|
|
5080
|
+
const fileEntry = new ZipEntry(reader, entryOptions);
|
|
5063
5081
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5064
5082
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5065
5083
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5150,13 +5168,17 @@
|
|
|
5150
5168
|
if (malformedExtraField) {
|
|
5151
5169
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5152
5170
|
}
|
|
5153
|
-
fileEntry.offset
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5171
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5172
|
+
startOffset = 0;
|
|
5173
|
+
} else {
|
|
5174
|
+
fileEntry.offset += prependedDataLength;
|
|
5175
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5176
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5177
|
+
if (entryPosition < previousEntryPosition) {
|
|
5178
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5179
|
+
}
|
|
5180
|
+
previousEntryPosition = entryPosition;
|
|
5158
5181
|
}
|
|
5159
|
-
previousEntryPosition = entryPosition;
|
|
5160
5182
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5161
5183
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5162
5184
|
}
|
|
@@ -5193,12 +5215,15 @@
|
|
|
5193
5215
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5194
5216
|
});
|
|
5195
5217
|
const entry = new Entry(fileEntry);
|
|
5196
|
-
|
|
5218
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5219
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5220
|
+
}
|
|
5221
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5197
5222
|
entry.arrayBuffer = async options => {
|
|
5198
5223
|
const writer = new TransformStream();
|
|
5199
5224
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5200
5225
|
arrayBufferPromise.catch(() => { });
|
|
5201
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5226
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5202
5227
|
Object.assign({}, options, { preventClose: false }));
|
|
5203
5228
|
return arrayBufferPromise;
|
|
5204
5229
|
};
|
|
@@ -5406,8 +5431,9 @@
|
|
|
5406
5431
|
});
|
|
5407
5432
|
}
|
|
5408
5433
|
|
|
5409
|
-
async getData(writer, fileEntry,
|
|
5434
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5410
5435
|
const zipEntry = this;
|
|
5436
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5411
5437
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5412
5438
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5413
5439
|
}
|
|
@@ -5481,10 +5507,10 @@
|
|
|
5481
5507
|
}
|
|
5482
5508
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5483
5509
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5484
|
-
if (lastAccessDate) {
|
|
5510
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5485
5511
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5486
5512
|
}
|
|
5487
|
-
if (creationDate) {
|
|
5513
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5488
5514
|
fileEntry.creationDate = creationDate;
|
|
5489
5515
|
}
|
|
5490
5516
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5513,7 +5539,7 @@
|
|
|
5513
5539
|
throw new Error(ERR_ENCRYPTED);
|
|
5514
5540
|
}
|
|
5515
5541
|
}
|
|
5516
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5542
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5517
5543
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5518
5544
|
}
|
|
5519
5545
|
const size = compressedSize;
|
|
@@ -5579,6 +5605,7 @@
|
|
|
5579
5605
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5580
5606
|
readRanges
|
|
5581
5607
|
});
|
|
5608
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5582
5609
|
}
|
|
5583
5610
|
let writable, abortError, aborted;
|
|
5584
5611
|
try {
|
|
@@ -5598,10 +5625,7 @@
|
|
|
5598
5625
|
writer.size += writtenSize;
|
|
5599
5626
|
}
|
|
5600
5627
|
} catch (error) {
|
|
5601
|
-
|
|
5602
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5603
|
-
writer.size += failedOutputSize;
|
|
5604
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5628
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5605
5629
|
writer.size += error.outputSize;
|
|
5606
5630
|
}
|
|
5607
5631
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5629,13 +5653,7 @@
|
|
|
5629
5653
|
}
|
|
5630
5654
|
|
|
5631
5655
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5632
|
-
|
|
5633
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5634
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5635
|
-
return true;
|
|
5636
|
-
}
|
|
5637
|
-
}
|
|
5638
|
-
return false;
|
|
5656
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5639
5657
|
}
|
|
5640
5658
|
|
|
5641
5659
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5672,6 +5690,46 @@
|
|
|
5672
5690
|
}
|
|
5673
5691
|
}
|
|
5674
5692
|
|
|
5693
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5694
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5695
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5696
|
+
const tailView = getDataView(tailArray);
|
|
5697
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5698
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5699
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5700
|
+
return startOffset + indexByte;
|
|
5701
|
+
}
|
|
5702
|
+
}
|
|
5703
|
+
}
|
|
5704
|
+
|
|
5705
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5706
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5707
|
+
return UNDEFINED_VALUE;
|
|
5708
|
+
}
|
|
5709
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5710
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5711
|
+
return localHeaderOffset;
|
|
5712
|
+
}
|
|
5713
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5714
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5715
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5716
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5717
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5718
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5719
|
+
let offsetValue = offsetExtraField + 4;
|
|
5720
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5721
|
+
offsetValue += 8;
|
|
5722
|
+
}
|
|
5723
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5724
|
+
offsetValue += 8;
|
|
5725
|
+
}
|
|
5726
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5727
|
+
}
|
|
5728
|
+
offsetExtraField += 4 + size;
|
|
5729
|
+
}
|
|
5730
|
+
return UNDEFINED_VALUE;
|
|
5731
|
+
}
|
|
5732
|
+
|
|
5675
5733
|
function readDigitalSignature(signatureRecordArray) {
|
|
5676
5734
|
if (signatureRecordArray.length >= 6) {
|
|
5677
5735
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5761,6 +5819,7 @@
|
|
|
5761
5819
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5762
5820
|
});
|
|
5763
5821
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5822
|
+
let extraFieldZip64Missing;
|
|
5764
5823
|
if (extraFieldZip64) {
|
|
5765
5824
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5766
5825
|
malformedExtraField = true;
|
|
@@ -5770,7 +5829,7 @@
|
|
|
5770
5829
|
if (localDirectory) {
|
|
5771
5830
|
malformedExtraField = true;
|
|
5772
5831
|
} else {
|
|
5773
|
-
|
|
5832
|
+
extraFieldZip64Missing = true;
|
|
5774
5833
|
}
|
|
5775
5834
|
}
|
|
5776
5835
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5828,6 +5887,9 @@
|
|
|
5828
5887
|
if (extraFieldUSDZ) {
|
|
5829
5888
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5830
5889
|
}
|
|
5890
|
+
if (extraFieldZip64Missing) {
|
|
5891
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5892
|
+
}
|
|
5831
5893
|
return malformedExtraField;
|
|
5832
5894
|
}
|
|
5833
5895
|
|
|
@@ -6042,13 +6104,7 @@
|
|
|
6042
6104
|
let dataDescriptorLength = 0;
|
|
6043
6105
|
if (dataDescriptor) {
|
|
6044
6106
|
const zip64 = Boolean(extraFieldZip64);
|
|
6045
|
-
const
|
|
6046
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6047
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6048
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6049
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6050
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6051
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6107
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6052
6108
|
if (localDataDescriptor) {
|
|
6053
6109
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6054
6110
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6118,6 +6174,25 @@
|
|
|
6118
6174
|
return mergedRanges;
|
|
6119
6175
|
}
|
|
6120
6176
|
|
|
6177
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6178
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6179
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6180
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6181
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6182
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6183
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6184
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6185
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6186
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6187
|
+
}
|
|
6188
|
+
|
|
6189
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6190
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6191
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6192
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6193
|
+
}
|
|
6194
|
+
}
|
|
6195
|
+
|
|
6121
6196
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6122
6197
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6123
6198
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6377,6 +6452,18 @@
|
|
|
6377
6452
|
}
|
|
6378
6453
|
}
|
|
6379
6454
|
|
|
6455
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6456
|
+
const { dataDescriptor } = localDirectory;
|
|
6457
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6458
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6459
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6460
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6461
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6462
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6463
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6464
|
+
}
|
|
6465
|
+
}
|
|
6466
|
+
|
|
6380
6467
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6381
6468
|
if (reject) {
|
|
6382
6469
|
throwAmbiguousArchive(reason);
|
|
@@ -6479,6 +6566,7 @@
|
|
|
6479
6566
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6480
6567
|
ZipReader: ZipReader,
|
|
6481
6568
|
ZipReaderStream: ZipReaderStream,
|
|
6569
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6482
6570
|
isZipFile: isZipFile
|
|
6483
6571
|
});
|
|
6484
6572
|
|
|
@@ -6602,136 +6690,7 @@
|
|
|
6602
6690
|
}
|
|
6603
6691
|
|
|
6604
6692
|
appendZip(reader, options = {}) {
|
|
6605
|
-
return watchPromiseError(this,
|
|
6606
|
-
}
|
|
6607
|
-
|
|
6608
|
-
async appendZipEntries(reader, options = {}) {
|
|
6609
|
-
const zipWriter = this;
|
|
6610
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6611
|
-
const filter = checkFunctionOption(options.filter);
|
|
6612
|
-
while (pendingAddFileCalls.size) {
|
|
6613
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6614
|
-
}
|
|
6615
|
-
let resolveAppendZip;
|
|
6616
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6617
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6618
|
-
const appendedFilenames = [];
|
|
6619
|
-
let releaseLockWriter;
|
|
6620
|
-
try {
|
|
6621
|
-
reader = new GenericReader(reader);
|
|
6622
|
-
await initStream(reader);
|
|
6623
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6624
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6625
|
-
await initStream(reader);
|
|
6626
|
-
}
|
|
6627
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6628
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6629
|
-
const entries = await zipReader$1.getEntries();
|
|
6630
|
-
const keptEntries = [];
|
|
6631
|
-
for (const entry of entries) {
|
|
6632
|
-
if (!filter || await filter(entry)) {
|
|
6633
|
-
keptEntries.push(entry);
|
|
6634
|
-
}
|
|
6635
|
-
}
|
|
6636
|
-
await zipReader$1.close();
|
|
6637
|
-
await initStream(zipWriter.writer);
|
|
6638
|
-
const { directoryOffset } = zipReader$1;
|
|
6639
|
-
keptEntries.forEach(({ filename }) => {
|
|
6640
|
-
if (filenames.has(filename)) {
|
|
6641
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6642
|
-
}
|
|
6643
|
-
filenames.add(filename);
|
|
6644
|
-
appendedFilenames.push(filename);
|
|
6645
|
-
});
|
|
6646
|
-
zipWriter.writerLocked = true;
|
|
6647
|
-
const { lockWriter } = zipWriter;
|
|
6648
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6649
|
-
zipWriter.writerLocked = false;
|
|
6650
|
-
resolve();
|
|
6651
|
-
});
|
|
6652
|
-
await lockWriter;
|
|
6653
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6654
|
-
delete zipWriter.addSplitZipSignature;
|
|
6655
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6656
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6657
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6658
|
-
}
|
|
6659
|
-
}
|
|
6660
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6661
|
-
keptEntries.forEach(entry => {
|
|
6662
|
-
const {
|
|
6663
|
-
version,
|
|
6664
|
-
rawLastModDate,
|
|
6665
|
-
rawFilename,
|
|
6666
|
-
bitFlag,
|
|
6667
|
-
encrypted,
|
|
6668
|
-
uncompressedSize,
|
|
6669
|
-
compressedSize,
|
|
6670
|
-
extraFieldZip64
|
|
6671
|
-
} = entry;
|
|
6672
|
-
let {
|
|
6673
|
-
compressionMethod,
|
|
6674
|
-
rawExtraField,
|
|
6675
|
-
} = entry;
|
|
6676
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6677
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6678
|
-
if (entry.extraFieldAES) {
|
|
6679
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6680
|
-
}
|
|
6681
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6682
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6683
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6684
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6685
|
-
const {
|
|
6686
|
-
headerArray,
|
|
6687
|
-
headerView
|
|
6688
|
-
} = getHeaderArrayData({
|
|
6689
|
-
version,
|
|
6690
|
-
bitFlag: bitFlagValue,
|
|
6691
|
-
compressionMethod,
|
|
6692
|
-
uncompressedSize,
|
|
6693
|
-
compressedSize,
|
|
6694
|
-
rawLastModDate,
|
|
6695
|
-
rawFilename,
|
|
6696
|
-
zip64CompressedSize,
|
|
6697
|
-
zip64UncompressedSize,
|
|
6698
|
-
extraFieldLength
|
|
6699
|
-
});
|
|
6700
|
-
const { crc32 } = entry;
|
|
6701
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6702
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6703
|
-
}
|
|
6704
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6705
|
-
Object.assign(entry, {
|
|
6706
|
-
zip64Enabled: true,
|
|
6707
|
-
zip64UncompressedSize,
|
|
6708
|
-
zip64CompressedSize,
|
|
6709
|
-
offset,
|
|
6710
|
-
diskNumberStart,
|
|
6711
|
-
zip64DiskNumberStart: false,
|
|
6712
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6713
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6714
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6715
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6716
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6717
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6718
|
-
rawExtraField,
|
|
6719
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6720
|
-
headerArray,
|
|
6721
|
-
headerView
|
|
6722
|
-
});
|
|
6723
|
-
fileEntries.set(entry.filename, entry);
|
|
6724
|
-
});
|
|
6725
|
-
} catch (error) {
|
|
6726
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6727
|
-
throw error;
|
|
6728
|
-
} finally {
|
|
6729
|
-
resolveAppendZip();
|
|
6730
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6731
|
-
if (releaseLockWriter) {
|
|
6732
|
-
releaseLockWriter();
|
|
6733
|
-
}
|
|
6734
|
-
}
|
|
6693
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6735
6694
|
}
|
|
6736
6695
|
|
|
6737
6696
|
add(name = "", reader, options = {}) {
|
|
@@ -6893,11 +6852,140 @@
|
|
|
6893
6852
|
return watchedPromise;
|
|
6894
6853
|
}
|
|
6895
6854
|
|
|
6855
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6856
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6857
|
+
const filter = checkFunctionOption(options.filter);
|
|
6858
|
+
while (pendingAddFileCalls.size) {
|
|
6859
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6860
|
+
}
|
|
6861
|
+
let resolveAppendZip;
|
|
6862
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6863
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6864
|
+
const appendedFilenames = [];
|
|
6865
|
+
let releaseLockWriter;
|
|
6866
|
+
try {
|
|
6867
|
+
reader = new GenericReader(reader);
|
|
6868
|
+
await initStream(reader);
|
|
6869
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6870
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6871
|
+
await initStream(reader);
|
|
6872
|
+
}
|
|
6873
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6874
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6875
|
+
const entries = await zipReader$1.getEntries();
|
|
6876
|
+
const keptEntries = [];
|
|
6877
|
+
for (const entry of entries) {
|
|
6878
|
+
if (!filter || await filter(entry)) {
|
|
6879
|
+
keptEntries.push(entry);
|
|
6880
|
+
}
|
|
6881
|
+
}
|
|
6882
|
+
await zipReader$1.close();
|
|
6883
|
+
await initStream(zipWriter.writer);
|
|
6884
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6885
|
+
keptEntries.forEach(entry => {
|
|
6886
|
+
const { filename } = entry;
|
|
6887
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6888
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6889
|
+
}
|
|
6890
|
+
if (filenames.has(filename)) {
|
|
6891
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6892
|
+
}
|
|
6893
|
+
filenames.add(filename);
|
|
6894
|
+
appendedFilenames.push(filename);
|
|
6895
|
+
});
|
|
6896
|
+
zipWriter.writerLocked = true;
|
|
6897
|
+
const { lockWriter } = zipWriter;
|
|
6898
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6899
|
+
zipWriter.writerLocked = false;
|
|
6900
|
+
resolve();
|
|
6901
|
+
});
|
|
6902
|
+
await lockWriter;
|
|
6903
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6904
|
+
delete zipWriter.addSplitZipSignature;
|
|
6905
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6906
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6907
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6908
|
+
}
|
|
6909
|
+
}
|
|
6910
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6911
|
+
keptEntries.forEach(entry => {
|
|
6912
|
+
const {
|
|
6913
|
+
version,
|
|
6914
|
+
rawLastModDate,
|
|
6915
|
+
rawFilename,
|
|
6916
|
+
rawBitFlag,
|
|
6917
|
+
uncompressedSize,
|
|
6918
|
+
compressedSize,
|
|
6919
|
+
extraFieldZip64
|
|
6920
|
+
} = entry;
|
|
6921
|
+
let {
|
|
6922
|
+
compressionMethod,
|
|
6923
|
+
rawExtraField,
|
|
6924
|
+
} = entry;
|
|
6925
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6926
|
+
if (entry.extraFieldAES) {
|
|
6927
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6928
|
+
}
|
|
6929
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6930
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6931
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6932
|
+
const {
|
|
6933
|
+
headerArray,
|
|
6934
|
+
headerView
|
|
6935
|
+
} = getHeaderArrayData({
|
|
6936
|
+
version,
|
|
6937
|
+
bitFlag: rawBitFlag,
|
|
6938
|
+
compressionMethod,
|
|
6939
|
+
uncompressedSize,
|
|
6940
|
+
compressedSize,
|
|
6941
|
+
rawLastModDate,
|
|
6942
|
+
rawFilename,
|
|
6943
|
+
zip64CompressedSize,
|
|
6944
|
+
zip64UncompressedSize,
|
|
6945
|
+
extraFieldLength
|
|
6946
|
+
});
|
|
6947
|
+
const { crc32 } = entry;
|
|
6948
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6949
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6950
|
+
}
|
|
6951
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6952
|
+
Object.assign(entry, {
|
|
6953
|
+
zip64Enabled: true,
|
|
6954
|
+
zip64UncompressedSize,
|
|
6955
|
+
zip64CompressedSize,
|
|
6956
|
+
offset,
|
|
6957
|
+
diskNumberStart,
|
|
6958
|
+
zip64DiskNumberStart: false,
|
|
6959
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6960
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6961
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6962
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6963
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6964
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6965
|
+
rawExtraField,
|
|
6966
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6967
|
+
headerArray,
|
|
6968
|
+
headerView
|
|
6969
|
+
});
|
|
6970
|
+
fileEntries.set(entry.filename, entry);
|
|
6971
|
+
});
|
|
6972
|
+
} catch (error) {
|
|
6973
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6974
|
+
throw error;
|
|
6975
|
+
} finally {
|
|
6976
|
+
resolveAppendZip();
|
|
6977
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6978
|
+
if (releaseLockWriter) {
|
|
6979
|
+
releaseLockWriter();
|
|
6980
|
+
}
|
|
6981
|
+
}
|
|
6982
|
+
}
|
|
6983
|
+
|
|
6896
6984
|
async function prependZipEntries(zipWriter, reader) {
|
|
6897
6985
|
if (zipWriter.filenames.size) {
|
|
6898
6986
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6899
6987
|
}
|
|
6900
|
-
await
|
|
6988
|
+
await appendZipEntries(zipWriter, reader);
|
|
6901
6989
|
}
|
|
6902
6990
|
|
|
6903
6991
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8571,7 +8659,7 @@
|
|
|
8571
8659
|
return rawExtraField;
|
|
8572
8660
|
}
|
|
8573
8661
|
|
|
8574
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8662
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8575
8663
|
const { writer } = zipWriter;
|
|
8576
8664
|
const entryPositions = new Map();
|
|
8577
8665
|
if (writer.closeDisk || compact) {
|
|
@@ -8579,6 +8667,27 @@
|
|
|
8579
8667
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8580
8668
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8581
8669
|
const keptEntrySet = new Set(keptEntries);
|
|
8670
|
+
const localHeaderLengths = new Map();
|
|
8671
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8672
|
+
const entry = sortedEntries[indexEntry];
|
|
8673
|
+
if (keptEntrySet.has(entry)) {
|
|
8674
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8675
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8676
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8677
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8678
|
+
}
|
|
8679
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8680
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8681
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8682
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8683
|
+
}
|
|
8684
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8685
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8686
|
+
}
|
|
8687
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8688
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8689
|
+
}
|
|
8690
|
+
}
|
|
8582
8691
|
let copiedOffset = 0;
|
|
8583
8692
|
let lastPosition;
|
|
8584
8693
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8591,7 +8700,7 @@
|
|
|
8591
8700
|
if (!compact) {
|
|
8592
8701
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8593
8702
|
}
|
|
8594
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8703
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8595
8704
|
await writer.closeDisk();
|
|
8596
8705
|
}
|
|
8597
8706
|
lastPosition = {
|
|
@@ -8625,7 +8734,7 @@
|
|
|
8625
8734
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8626
8735
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8627
8736
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8628
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8737
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8629
8738
|
}
|
|
8630
8739
|
regionEnds[indexEntry] = regionEnd;
|
|
8631
8740
|
}
|
|
@@ -8639,11 +8748,13 @@
|
|
|
8639
8748
|
try {
|
|
8640
8749
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8641
8750
|
} catch (error) {
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8751
|
+
if (copiedLength) {
|
|
8752
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8753
|
+
try {
|
|
8754
|
+
error.corruptedEntry = true;
|
|
8755
|
+
} catch {
|
|
8756
|
+
// ignored
|
|
8757
|
+
}
|
|
8647
8758
|
}
|
|
8648
8759
|
throw error;
|
|
8649
8760
|
} finally {
|
|
@@ -8654,11 +8765,16 @@
|
|
|
8654
8765
|
}
|
|
8655
8766
|
|
|
8656
8767
|
async function getLocalHeaderLength(reader, offset) {
|
|
8657
|
-
const headerArray =
|
|
8768
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8769
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8770
|
+
EMPTY_UINT8_ARRAY;
|
|
8658
8771
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8659
|
-
return
|
|
8772
|
+
return UNDEFINED_VALUE;
|
|
8660
8773
|
}
|
|
8661
8774
|
const headerView = getDataView(headerArray);
|
|
8775
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8776
|
+
return UNDEFINED_VALUE;
|
|
8777
|
+
}
|
|
8662
8778
|
return HEADER_SIZE +
|
|
8663
8779
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8664
8780
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9009,7 +9125,7 @@
|
|
|
9009
9125
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9010
9126
|
*/
|
|
9011
9127
|
|
|
9012
|
-
const VERSION = "2.
|
|
9128
|
+
const VERSION = "2.21.0";
|
|
9013
9129
|
|
|
9014
9130
|
/*
|
|
9015
9131
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|