@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-native.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";
|
|
@@ -4771,12 +4775,9 @@ const ERR_BAD_FORMAT = "File format is not recognized";
|
|
|
4771
4775
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4772
4776
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4773
4777
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4774
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4775
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4776
4778
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4777
4779
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4778
4780
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4779
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4780
4781
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4781
4782
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4782
4783
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4841,7 +4842,8 @@ class ZipReader {
|
|
|
4841
4842
|
Object.assign(this, {
|
|
4842
4843
|
reader: new GenericReader(reader),
|
|
4843
4844
|
options,
|
|
4844
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4845
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4846
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4845
4847
|
});
|
|
4846
4848
|
}
|
|
4847
4849
|
|
|
@@ -4912,16 +4914,22 @@ class ZipReader {
|
|
|
4912
4914
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4913
4915
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4914
4916
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4917
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4918
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4919
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4920
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4921
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4922
|
+
}
|
|
4923
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4924
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4925
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4926
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4927
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4928
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4929
|
+
}
|
|
4930
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4931
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4922
4932
|
}
|
|
4923
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4924
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4925
4933
|
}
|
|
4926
4934
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4927
4935
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4966,10 +4974,6 @@ class ZipReader {
|
|
|
4966
4974
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4967
4975
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4968
4976
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4969
|
-
if (directoryDataOffset >= reader.size) {
|
|
4970
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4971
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4972
|
-
}
|
|
4973
4977
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4974
4978
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4975
4979
|
}
|
|
@@ -4977,52 +4981,64 @@ class ZipReader {
|
|
|
4977
4981
|
throw new Error(ERR_BAD_FORMAT);
|
|
4978
4982
|
}
|
|
4979
4983
|
let offset = 0;
|
|
4980
|
-
let directoryArray =
|
|
4984
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4985
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4986
|
+
EMPTY_UINT8_ARRAY;
|
|
4981
4987
|
let directoryView = getDataView(directoryArray);
|
|
4982
4988
|
if (directoryDataLength) {
|
|
4983
|
-
if (directoryArray.length < 4) {
|
|
4984
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4985
|
-
}
|
|
4986
4989
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4987
4990
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4988
|
-
const storedPointsAtDirectory =
|
|
4991
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
4992
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4989
4993
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4990
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
4994
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
4995
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
4996
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
4997
|
+
}
|
|
4991
4998
|
let reconcile = !storedPointsAtDirectory;
|
|
4992
4999
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4993
|
-
|
|
4994
|
-
if (
|
|
4995
|
-
reconcile = expectedPointsAtDirectory;
|
|
4996
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5000
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5001
|
+
if (!expectedPointsAtDirectory) {
|
|
4997
5002
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
4998
5003
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
4999
5004
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5000
5005
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5001
5006
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5007
|
+
expectedPointsAtDirectory = true;
|
|
5002
5008
|
}
|
|
5003
5009
|
}
|
|
5010
|
+
if (storedPointsAtDirectory) {
|
|
5011
|
+
reconcile = expectedPointsAtDirectory;
|
|
5012
|
+
}
|
|
5004
5013
|
}
|
|
5005
|
-
if (reconcile) {
|
|
5014
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5006
5015
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5007
5016
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5008
5017
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5009
5018
|
directoryView = getDataView(directoryArray);
|
|
5010
|
-
|
|
5011
|
-
|
|
5019
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5020
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5021
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5022
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5023
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5024
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5025
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5026
|
+
prependedDataLength += offsetDelta;
|
|
5012
5027
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5013
5028
|
} else {
|
|
5014
5029
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5018
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5019
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5020
|
-
prependedDataLength += offsetDelta;
|
|
5021
|
-
}
|
|
5030
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5031
|
+
prependedDataLength += offsetDelta;
|
|
5022
5032
|
}
|
|
5023
5033
|
}
|
|
5024
5034
|
}
|
|
5025
5035
|
}
|
|
5036
|
+
if (directoryArray.length < 4) {
|
|
5037
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5038
|
+
}
|
|
5039
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5040
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5041
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5026
5042
|
}
|
|
5027
5043
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5028
5044
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5064,8 +5080,10 @@ class ZipReader {
|
|
|
5064
5080
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5065
5081
|
}
|
|
5066
5082
|
}
|
|
5083
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5084
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5067
5085
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5068
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5086
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5069
5087
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5070
5088
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5071
5089
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5156,13 +5174,17 @@ class ZipReader {
|
|
|
5156
5174
|
if (malformedExtraField) {
|
|
5157
5175
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5158
5176
|
}
|
|
5159
|
-
fileEntry.offset
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5177
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5178
|
+
startOffset = 0;
|
|
5179
|
+
} else {
|
|
5180
|
+
fileEntry.offset += prependedDataLength;
|
|
5181
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5182
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5183
|
+
if (entryPosition < previousEntryPosition) {
|
|
5184
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5185
|
+
}
|
|
5186
|
+
previousEntryPosition = entryPosition;
|
|
5164
5187
|
}
|
|
5165
|
-
previousEntryPosition = entryPosition;
|
|
5166
5188
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5167
5189
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5168
5190
|
}
|
|
@@ -5199,12 +5221,15 @@ class ZipReader {
|
|
|
5199
5221
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5200
5222
|
});
|
|
5201
5223
|
const entry = new Entry(fileEntry);
|
|
5202
|
-
|
|
5224
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5225
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5226
|
+
}
|
|
5227
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5203
5228
|
entry.arrayBuffer = async options => {
|
|
5204
5229
|
const writer = new TransformStream();
|
|
5205
5230
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5206
5231
|
arrayBufferPromise.catch(() => { });
|
|
5207
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5232
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5208
5233
|
Object.assign({}, options, { preventClose: false }));
|
|
5209
5234
|
return arrayBufferPromise;
|
|
5210
5235
|
};
|
|
@@ -5412,8 +5437,9 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5412
5437
|
});
|
|
5413
5438
|
}
|
|
5414
5439
|
|
|
5415
|
-
async getData(writer, fileEntry,
|
|
5440
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5416
5441
|
const zipEntry = this;
|
|
5442
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5417
5443
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5418
5444
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5419
5445
|
}
|
|
@@ -5487,10 +5513,10 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5487
5513
|
}
|
|
5488
5514
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5489
5515
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5490
|
-
if (lastAccessDate) {
|
|
5516
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5491
5517
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5492
5518
|
}
|
|
5493
|
-
if (creationDate) {
|
|
5519
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5494
5520
|
fileEntry.creationDate = creationDate;
|
|
5495
5521
|
}
|
|
5496
5522
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5519,7 +5545,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5519
5545
|
throw new Error(ERR_ENCRYPTED);
|
|
5520
5546
|
}
|
|
5521
5547
|
}
|
|
5522
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5548
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5523
5549
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5524
5550
|
}
|
|
5525
5551
|
const size = compressedSize;
|
|
@@ -5585,6 +5611,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5585
5611
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5586
5612
|
readRanges
|
|
5587
5613
|
});
|
|
5614
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5588
5615
|
}
|
|
5589
5616
|
let writable, abortError, aborted;
|
|
5590
5617
|
try {
|
|
@@ -5604,10 +5631,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5604
5631
|
writer.size += writtenSize;
|
|
5605
5632
|
}
|
|
5606
5633
|
} catch (error) {
|
|
5607
|
-
|
|
5608
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5609
|
-
writer.size += failedOutputSize;
|
|
5610
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5634
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5611
5635
|
writer.size += error.outputSize;
|
|
5612
5636
|
}
|
|
5613
5637
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5635,13 +5659,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5635
5659
|
};
|
|
5636
5660
|
|
|
5637
5661
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5638
|
-
|
|
5639
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5640
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5641
|
-
return true;
|
|
5642
|
-
}
|
|
5643
|
-
}
|
|
5644
|
-
return false;
|
|
5662
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5645
5663
|
}
|
|
5646
5664
|
|
|
5647
5665
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5678,6 +5696,46 @@ async function findDigitalSignatureRecordOffset(reader, endOffset) {
|
|
|
5678
5696
|
}
|
|
5679
5697
|
}
|
|
5680
5698
|
|
|
5699
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5700
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5701
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5702
|
+
const tailView = getDataView(tailArray);
|
|
5703
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5704
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5705
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5706
|
+
return startOffset + indexByte;
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
|
|
5711
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5712
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5713
|
+
return UNDEFINED_VALUE;
|
|
5714
|
+
}
|
|
5715
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5716
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5717
|
+
return localHeaderOffset;
|
|
5718
|
+
}
|
|
5719
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5720
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5721
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5722
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5723
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5724
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5725
|
+
let offsetValue = offsetExtraField + 4;
|
|
5726
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5727
|
+
offsetValue += 8;
|
|
5728
|
+
}
|
|
5729
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5730
|
+
offsetValue += 8;
|
|
5731
|
+
}
|
|
5732
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5733
|
+
}
|
|
5734
|
+
offsetExtraField += 4 + size;
|
|
5735
|
+
}
|
|
5736
|
+
return UNDEFINED_VALUE;
|
|
5737
|
+
}
|
|
5738
|
+
|
|
5681
5739
|
function readDigitalSignature(signatureRecordArray) {
|
|
5682
5740
|
if (signatureRecordArray.length >= 6) {
|
|
5683
5741
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5767,6 +5825,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5767
5825
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5768
5826
|
});
|
|
5769
5827
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5828
|
+
let extraFieldZip64Missing;
|
|
5770
5829
|
if (extraFieldZip64) {
|
|
5771
5830
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5772
5831
|
malformedExtraField = true;
|
|
@@ -5776,7 +5835,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5776
5835
|
if (localDirectory) {
|
|
5777
5836
|
malformedExtraField = true;
|
|
5778
5837
|
} else {
|
|
5779
|
-
|
|
5838
|
+
extraFieldZip64Missing = true;
|
|
5780
5839
|
}
|
|
5781
5840
|
}
|
|
5782
5841
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5834,6 +5893,9 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5834
5893
|
if (extraFieldUSDZ) {
|
|
5835
5894
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5836
5895
|
}
|
|
5896
|
+
if (extraFieldZip64Missing) {
|
|
5897
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5898
|
+
}
|
|
5837
5899
|
return malformedExtraField;
|
|
5838
5900
|
}
|
|
5839
5901
|
|
|
@@ -6048,13 +6110,7 @@ async function detectOverlappingEntry({
|
|
|
6048
6110
|
let dataDescriptorLength = 0;
|
|
6049
6111
|
if (dataDescriptor) {
|
|
6050
6112
|
const zip64 = Boolean(extraFieldZip64);
|
|
6051
|
-
const
|
|
6052
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6053
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6054
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6055
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6056
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6057
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6113
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6058
6114
|
if (localDataDescriptor) {
|
|
6059
6115
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6060
6116
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6124,6 +6180,25 @@ function mergeRanges(sortedRanges, pendingRanges) {
|
|
|
6124
6180
|
return mergedRanges;
|
|
6125
6181
|
}
|
|
6126
6182
|
|
|
6183
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6184
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6185
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6186
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6187
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6188
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6189
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6190
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6191
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6192
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6193
|
+
}
|
|
6194
|
+
|
|
6195
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6196
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6197
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6198
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6199
|
+
}
|
|
6200
|
+
}
|
|
6201
|
+
|
|
6127
6202
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6128
6203
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6129
6204
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6383,6 +6458,18 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
|
|
|
6383
6458
|
}
|
|
6384
6459
|
}
|
|
6385
6460
|
|
|
6461
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6462
|
+
const { dataDescriptor } = localDirectory;
|
|
6463
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6464
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6465
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6466
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6467
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6468
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6469
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6470
|
+
}
|
|
6471
|
+
}
|
|
6472
|
+
|
|
6386
6473
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6387
6474
|
if (reject) {
|
|
6388
6475
|
throwAmbiguousArchive(reason);
|
|
@@ -6485,6 +6572,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6485
6572
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6486
6573
|
ZipReader: ZipReader,
|
|
6487
6574
|
ZipReaderStream: ZipReaderStream,
|
|
6575
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6488
6576
|
isZipFile: isZipFile
|
|
6489
6577
|
});
|
|
6490
6578
|
|
|
@@ -6608,136 +6696,7 @@ class ZipWriter {
|
|
|
6608
6696
|
}
|
|
6609
6697
|
|
|
6610
6698
|
appendZip(reader, options = {}) {
|
|
6611
|
-
return watchPromiseError(this,
|
|
6612
|
-
}
|
|
6613
|
-
|
|
6614
|
-
async appendZipEntries(reader, options = {}) {
|
|
6615
|
-
const zipWriter = this;
|
|
6616
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6617
|
-
const filter = checkFunctionOption(options.filter);
|
|
6618
|
-
while (pendingAddFileCalls.size) {
|
|
6619
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6620
|
-
}
|
|
6621
|
-
let resolveAppendZip;
|
|
6622
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6623
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6624
|
-
const appendedFilenames = [];
|
|
6625
|
-
let releaseLockWriter;
|
|
6626
|
-
try {
|
|
6627
|
-
reader = new GenericReader(reader);
|
|
6628
|
-
await initStream(reader);
|
|
6629
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6630
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6631
|
-
await initStream(reader);
|
|
6632
|
-
}
|
|
6633
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6634
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6635
|
-
const entries = await zipReader$1.getEntries();
|
|
6636
|
-
const keptEntries = [];
|
|
6637
|
-
for (const entry of entries) {
|
|
6638
|
-
if (!filter || await filter(entry)) {
|
|
6639
|
-
keptEntries.push(entry);
|
|
6640
|
-
}
|
|
6641
|
-
}
|
|
6642
|
-
await zipReader$1.close();
|
|
6643
|
-
await initStream(zipWriter.writer);
|
|
6644
|
-
const { directoryOffset } = zipReader$1;
|
|
6645
|
-
keptEntries.forEach(({ filename }) => {
|
|
6646
|
-
if (filenames.has(filename)) {
|
|
6647
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6648
|
-
}
|
|
6649
|
-
filenames.add(filename);
|
|
6650
|
-
appendedFilenames.push(filename);
|
|
6651
|
-
});
|
|
6652
|
-
zipWriter.writerLocked = true;
|
|
6653
|
-
const { lockWriter } = zipWriter;
|
|
6654
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6655
|
-
zipWriter.writerLocked = false;
|
|
6656
|
-
resolve();
|
|
6657
|
-
});
|
|
6658
|
-
await lockWriter;
|
|
6659
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6660
|
-
delete zipWriter.addSplitZipSignature;
|
|
6661
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6662
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6663
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6664
|
-
}
|
|
6665
|
-
}
|
|
6666
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6667
|
-
keptEntries.forEach(entry => {
|
|
6668
|
-
const {
|
|
6669
|
-
version,
|
|
6670
|
-
rawLastModDate,
|
|
6671
|
-
rawFilename,
|
|
6672
|
-
bitFlag,
|
|
6673
|
-
encrypted,
|
|
6674
|
-
uncompressedSize,
|
|
6675
|
-
compressedSize,
|
|
6676
|
-
extraFieldZip64
|
|
6677
|
-
} = entry;
|
|
6678
|
-
let {
|
|
6679
|
-
compressionMethod,
|
|
6680
|
-
rawExtraField,
|
|
6681
|
-
} = entry;
|
|
6682
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6683
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6684
|
-
if (entry.extraFieldAES) {
|
|
6685
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6686
|
-
}
|
|
6687
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6688
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6689
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6690
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6691
|
-
const {
|
|
6692
|
-
headerArray,
|
|
6693
|
-
headerView
|
|
6694
|
-
} = getHeaderArrayData({
|
|
6695
|
-
version,
|
|
6696
|
-
bitFlag: bitFlagValue,
|
|
6697
|
-
compressionMethod,
|
|
6698
|
-
uncompressedSize,
|
|
6699
|
-
compressedSize,
|
|
6700
|
-
rawLastModDate,
|
|
6701
|
-
rawFilename,
|
|
6702
|
-
zip64CompressedSize,
|
|
6703
|
-
zip64UncompressedSize,
|
|
6704
|
-
extraFieldLength
|
|
6705
|
-
});
|
|
6706
|
-
const { crc32 } = entry;
|
|
6707
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6708
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6709
|
-
}
|
|
6710
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6711
|
-
Object.assign(entry, {
|
|
6712
|
-
zip64Enabled: true,
|
|
6713
|
-
zip64UncompressedSize,
|
|
6714
|
-
zip64CompressedSize,
|
|
6715
|
-
offset,
|
|
6716
|
-
diskNumberStart,
|
|
6717
|
-
zip64DiskNumberStart: false,
|
|
6718
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6719
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6720
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6721
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6722
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6723
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6724
|
-
rawExtraField,
|
|
6725
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6726
|
-
headerArray,
|
|
6727
|
-
headerView
|
|
6728
|
-
});
|
|
6729
|
-
fileEntries.set(entry.filename, entry);
|
|
6730
|
-
});
|
|
6731
|
-
} catch (error) {
|
|
6732
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6733
|
-
throw error;
|
|
6734
|
-
} finally {
|
|
6735
|
-
resolveAppendZip();
|
|
6736
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6737
|
-
if (releaseLockWriter) {
|
|
6738
|
-
releaseLockWriter();
|
|
6739
|
-
}
|
|
6740
|
-
}
|
|
6699
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6741
6700
|
}
|
|
6742
6701
|
|
|
6743
6702
|
add(name = "", reader, options = {}) {
|
|
@@ -6899,11 +6858,140 @@ function watchPromiseError(zipWriter, promise) {
|
|
|
6899
6858
|
return watchedPromise;
|
|
6900
6859
|
}
|
|
6901
6860
|
|
|
6861
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6862
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6863
|
+
const filter = checkFunctionOption(options.filter);
|
|
6864
|
+
while (pendingAddFileCalls.size) {
|
|
6865
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6866
|
+
}
|
|
6867
|
+
let resolveAppendZip;
|
|
6868
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6869
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6870
|
+
const appendedFilenames = [];
|
|
6871
|
+
let releaseLockWriter;
|
|
6872
|
+
try {
|
|
6873
|
+
reader = new GenericReader(reader);
|
|
6874
|
+
await initStream(reader);
|
|
6875
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6876
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6877
|
+
await initStream(reader);
|
|
6878
|
+
}
|
|
6879
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6880
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6881
|
+
const entries = await zipReader$1.getEntries();
|
|
6882
|
+
const keptEntries = [];
|
|
6883
|
+
for (const entry of entries) {
|
|
6884
|
+
if (!filter || await filter(entry)) {
|
|
6885
|
+
keptEntries.push(entry);
|
|
6886
|
+
}
|
|
6887
|
+
}
|
|
6888
|
+
await zipReader$1.close();
|
|
6889
|
+
await initStream(zipWriter.writer);
|
|
6890
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6891
|
+
keptEntries.forEach(entry => {
|
|
6892
|
+
const { filename } = entry;
|
|
6893
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6894
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6895
|
+
}
|
|
6896
|
+
if (filenames.has(filename)) {
|
|
6897
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6898
|
+
}
|
|
6899
|
+
filenames.add(filename);
|
|
6900
|
+
appendedFilenames.push(filename);
|
|
6901
|
+
});
|
|
6902
|
+
zipWriter.writerLocked = true;
|
|
6903
|
+
const { lockWriter } = zipWriter;
|
|
6904
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6905
|
+
zipWriter.writerLocked = false;
|
|
6906
|
+
resolve();
|
|
6907
|
+
});
|
|
6908
|
+
await lockWriter;
|
|
6909
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6910
|
+
delete zipWriter.addSplitZipSignature;
|
|
6911
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6912
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6913
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6914
|
+
}
|
|
6915
|
+
}
|
|
6916
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6917
|
+
keptEntries.forEach(entry => {
|
|
6918
|
+
const {
|
|
6919
|
+
version,
|
|
6920
|
+
rawLastModDate,
|
|
6921
|
+
rawFilename,
|
|
6922
|
+
rawBitFlag,
|
|
6923
|
+
uncompressedSize,
|
|
6924
|
+
compressedSize,
|
|
6925
|
+
extraFieldZip64
|
|
6926
|
+
} = entry;
|
|
6927
|
+
let {
|
|
6928
|
+
compressionMethod,
|
|
6929
|
+
rawExtraField,
|
|
6930
|
+
} = entry;
|
|
6931
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6932
|
+
if (entry.extraFieldAES) {
|
|
6933
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6934
|
+
}
|
|
6935
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6936
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6937
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6938
|
+
const {
|
|
6939
|
+
headerArray,
|
|
6940
|
+
headerView
|
|
6941
|
+
} = getHeaderArrayData({
|
|
6942
|
+
version,
|
|
6943
|
+
bitFlag: rawBitFlag,
|
|
6944
|
+
compressionMethod,
|
|
6945
|
+
uncompressedSize,
|
|
6946
|
+
compressedSize,
|
|
6947
|
+
rawLastModDate,
|
|
6948
|
+
rawFilename,
|
|
6949
|
+
zip64CompressedSize,
|
|
6950
|
+
zip64UncompressedSize,
|
|
6951
|
+
extraFieldLength
|
|
6952
|
+
});
|
|
6953
|
+
const { crc32 } = entry;
|
|
6954
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6955
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6956
|
+
}
|
|
6957
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6958
|
+
Object.assign(entry, {
|
|
6959
|
+
zip64Enabled: true,
|
|
6960
|
+
zip64UncompressedSize,
|
|
6961
|
+
zip64CompressedSize,
|
|
6962
|
+
offset,
|
|
6963
|
+
diskNumberStart,
|
|
6964
|
+
zip64DiskNumberStart: false,
|
|
6965
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6966
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6967
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6968
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6969
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6970
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6971
|
+
rawExtraField,
|
|
6972
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6973
|
+
headerArray,
|
|
6974
|
+
headerView
|
|
6975
|
+
});
|
|
6976
|
+
fileEntries.set(entry.filename, entry);
|
|
6977
|
+
});
|
|
6978
|
+
} catch (error) {
|
|
6979
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6980
|
+
throw error;
|
|
6981
|
+
} finally {
|
|
6982
|
+
resolveAppendZip();
|
|
6983
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6984
|
+
if (releaseLockWriter) {
|
|
6985
|
+
releaseLockWriter();
|
|
6986
|
+
}
|
|
6987
|
+
}
|
|
6988
|
+
}
|
|
6989
|
+
|
|
6902
6990
|
async function prependZipEntries(zipWriter, reader) {
|
|
6903
6991
|
if (zipWriter.filenames.size) {
|
|
6904
6992
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6905
6993
|
}
|
|
6906
|
-
await
|
|
6994
|
+
await appendZipEntries(zipWriter, reader);
|
|
6907
6995
|
}
|
|
6908
6996
|
|
|
6909
6997
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8675,7 +8763,7 @@ function removeExtraFieldZip64(rawExtraField) {
|
|
|
8675
8763
|
return rawExtraField;
|
|
8676
8764
|
}
|
|
8677
8765
|
|
|
8678
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8766
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8679
8767
|
const { writer } = zipWriter;
|
|
8680
8768
|
const entryPositions = new Map();
|
|
8681
8769
|
if (writer.closeDisk || compact) {
|
|
@@ -8683,6 +8771,27 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8683
8771
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8684
8772
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8685
8773
|
const keptEntrySet = new Set(keptEntries);
|
|
8774
|
+
const localHeaderLengths = new Map();
|
|
8775
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8776
|
+
const entry = sortedEntries[indexEntry];
|
|
8777
|
+
if (keptEntrySet.has(entry)) {
|
|
8778
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8779
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8780
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8781
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8782
|
+
}
|
|
8783
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8784
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8785
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8786
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8787
|
+
}
|
|
8788
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8789
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8790
|
+
}
|
|
8791
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8792
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8793
|
+
}
|
|
8794
|
+
}
|
|
8686
8795
|
let copiedOffset = 0;
|
|
8687
8796
|
let lastPosition;
|
|
8688
8797
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8695,7 +8804,7 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8695
8804
|
if (!compact) {
|
|
8696
8805
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8697
8806
|
}
|
|
8698
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8807
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8699
8808
|
await writer.closeDisk();
|
|
8700
8809
|
}
|
|
8701
8810
|
lastPosition = {
|
|
@@ -8729,7 +8838,7 @@ function getRegionEnds(reader, sortedEntries, directoryOffset) {
|
|
|
8729
8838
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8730
8839
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8731
8840
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8732
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8841
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8733
8842
|
}
|
|
8734
8843
|
regionEnds[indexEntry] = regionEnd;
|
|
8735
8844
|
}
|
|
@@ -8743,11 +8852,13 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8743
8852
|
try {
|
|
8744
8853
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8745
8854
|
} catch (error) {
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8855
|
+
if (copiedLength) {
|
|
8856
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8857
|
+
try {
|
|
8858
|
+
error.corruptedEntry = true;
|
|
8859
|
+
} catch {
|
|
8860
|
+
// ignored
|
|
8861
|
+
}
|
|
8751
8862
|
}
|
|
8752
8863
|
throw error;
|
|
8753
8864
|
} finally {
|
|
@@ -8758,11 +8869,16 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8758
8869
|
}
|
|
8759
8870
|
|
|
8760
8871
|
async function getLocalHeaderLength(reader, offset) {
|
|
8761
|
-
const headerArray =
|
|
8872
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8873
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8874
|
+
EMPTY_UINT8_ARRAY;
|
|
8762
8875
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8763
|
-
return
|
|
8876
|
+
return UNDEFINED_VALUE;
|
|
8764
8877
|
}
|
|
8765
8878
|
const headerView = getDataView(headerArray);
|
|
8879
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8880
|
+
return UNDEFINED_VALUE;
|
|
8881
|
+
}
|
|
8766
8882
|
return HEADER_SIZE +
|
|
8767
8883
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8768
8884
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9113,7 +9229,7 @@ function formatSupported(StreamClass, format) {
|
|
|
9113
9229
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9114
9230
|
*/
|
|
9115
9231
|
|
|
9116
|
-
const VERSION = "2.
|
|
9232
|
+
const VERSION = "2.21.0";
|
|
9117
9233
|
|
|
9118
9234
|
/*
|
|
9119
9235
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|