@zip.js/zip.js 2.20.0 → 2.22.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 +347 -216
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +347 -215
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +347 -219
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +347 -219
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +347 -219
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +347 -219
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +347 -219
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +347 -215
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +347 -215
- package/dist/zip-native.min.js +1 -1
- package/dist/zip.js +347 -215
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +347 -219
- package/index-native.min.js +1 -1
- package/index.cjs +347 -219
- package/index.d.cts +97 -42
- package/index.d.ts +97 -42
- package/index.min.js +1 -1
- package/lib/core/configuration.js +1 -3
- package/lib/core/constants.js +7 -0
- package/lib/core/options.js +11 -0
- package/lib/core/version.js +1 -1
- package/lib/core/zip-fs.js +2 -6
- package/lib/core/zip-reader.js +157 -70
- package/lib/core/zip-writer.js +182 -142
- package/lib/zip-core-base.js +1 -0
- package/package.json +1 -1
package/dist/zip-fs-native.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";
|
|
@@ -221,6 +225,7 @@
|
|
|
221
225
|
const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
|
|
222
226
|
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
223
227
|
const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
|
|
228
|
+
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
224
229
|
const ERR_ABORTED = "The operation was aborted";
|
|
225
230
|
const ABORT_ERROR_NAME$1 = "AbortError";
|
|
226
231
|
|
|
@@ -231,6 +236,13 @@
|
|
|
231
236
|
return value;
|
|
232
237
|
}
|
|
233
238
|
|
|
239
|
+
function checkReaderOptionsObject(readerOptions) {
|
|
240
|
+
if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
|
|
241
|
+
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
242
|
+
}
|
|
243
|
+
return readerOptions;
|
|
244
|
+
}
|
|
245
|
+
|
|
234
246
|
function checkSignalOption(signal) {
|
|
235
247
|
if (signal && (typeof signal.addEventListener != FUNCTION_TYPE || typeof signal.aborted != BOOLEAN_TYPE)) {
|
|
236
248
|
throw new Error(ERR_INVALID_SIGNAL);
|
|
@@ -326,7 +338,6 @@
|
|
|
326
338
|
workerStartupTimeout: 5000,
|
|
327
339
|
useWebWorkers: true,
|
|
328
340
|
useCompressionStream: true,
|
|
329
|
-
transferStreams: true,
|
|
330
341
|
CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
|
|
331
342
|
DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
332
343
|
};
|
|
@@ -340,8 +351,7 @@
|
|
|
340
351
|
];
|
|
341
352
|
const BOOLEAN_PROPERTY_NAMES = [
|
|
342
353
|
"useCompressionStream",
|
|
343
|
-
"useWebWorkers"
|
|
344
|
-
"transferStreams"
|
|
354
|
+
"useWebWorkers"
|
|
345
355
|
];
|
|
346
356
|
const NUMBER_PROPERTY_NAMES = [
|
|
347
357
|
"chunkSize",
|
|
@@ -4777,12 +4787,9 @@
|
|
|
4777
4787
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4778
4788
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4779
4789
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4780
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4781
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4782
4790
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4783
4791
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4784
4792
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4785
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4786
4793
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4787
4794
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4788
4795
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4846,8 +4853,9 @@
|
|
|
4846
4853
|
constructor(reader, options = {}) {
|
|
4847
4854
|
Object.assign(this, {
|
|
4848
4855
|
reader: new GenericReader(reader),
|
|
4849
|
-
options,
|
|
4850
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4856
|
+
options: options || {},
|
|
4857
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4858
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4851
4859
|
});
|
|
4852
4860
|
}
|
|
4853
4861
|
|
|
@@ -4918,16 +4926,22 @@
|
|
|
4918
4926
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4919
4927
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4920
4928
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4929
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4930
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4931
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4932
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4933
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4934
|
+
}
|
|
4935
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4936
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4937
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4938
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4939
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4940
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4941
|
+
}
|
|
4942
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4943
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4928
4944
|
}
|
|
4929
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4930
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4931
4945
|
}
|
|
4932
4946
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4933
4947
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4972,10 +4986,6 @@
|
|
|
4972
4986
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4973
4987
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4974
4988
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4975
|
-
if (directoryDataOffset >= reader.size) {
|
|
4976
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4977
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4978
|
-
}
|
|
4979
4989
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4980
4990
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4981
4991
|
}
|
|
@@ -4983,52 +4993,64 @@
|
|
|
4983
4993
|
throw new Error(ERR_BAD_FORMAT);
|
|
4984
4994
|
}
|
|
4985
4995
|
let offset = 0;
|
|
4986
|
-
let directoryArray =
|
|
4996
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4997
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4998
|
+
EMPTY_UINT8_ARRAY;
|
|
4987
4999
|
let directoryView = getDataView(directoryArray);
|
|
4988
5000
|
if (directoryDataLength) {
|
|
4989
|
-
if (directoryArray.length < 4) {
|
|
4990
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4991
|
-
}
|
|
4992
5001
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4993
5002
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4994
|
-
const storedPointsAtDirectory =
|
|
5003
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
5004
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4995
5005
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4996
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5006
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5007
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5008
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5009
|
+
}
|
|
4997
5010
|
let reconcile = !storedPointsAtDirectory;
|
|
4998
5011
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4999
|
-
|
|
5000
|
-
if (
|
|
5001
|
-
reconcile = expectedPointsAtDirectory;
|
|
5002
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5012
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5013
|
+
if (!expectedPointsAtDirectory) {
|
|
5003
5014
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5004
5015
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5005
5016
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5006
5017
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5007
5018
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5019
|
+
expectedPointsAtDirectory = true;
|
|
5008
5020
|
}
|
|
5009
5021
|
}
|
|
5022
|
+
if (storedPointsAtDirectory) {
|
|
5023
|
+
reconcile = expectedPointsAtDirectory;
|
|
5024
|
+
}
|
|
5010
5025
|
}
|
|
5011
|
-
if (reconcile) {
|
|
5026
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5012
5027
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5013
5028
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5014
5029
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5015
5030
|
directoryView = getDataView(directoryArray);
|
|
5016
|
-
|
|
5017
|
-
|
|
5031
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5032
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5033
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5034
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5035
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5036
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5037
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5038
|
+
prependedDataLength += offsetDelta;
|
|
5018
5039
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5019
5040
|
} else {
|
|
5020
5041
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5024
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5025
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5026
|
-
prependedDataLength += offsetDelta;
|
|
5027
|
-
}
|
|
5042
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5043
|
+
prependedDataLength += offsetDelta;
|
|
5028
5044
|
}
|
|
5029
5045
|
}
|
|
5030
5046
|
}
|
|
5031
5047
|
}
|
|
5048
|
+
if (directoryArray.length < 4) {
|
|
5049
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5050
|
+
}
|
|
5051
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5052
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5053
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5032
5054
|
}
|
|
5033
5055
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5034
5056
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5070,8 +5092,10 @@
|
|
|
5070
5092
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5071
5093
|
}
|
|
5072
5094
|
}
|
|
5095
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5096
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5073
5097
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5074
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5098
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5075
5099
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5076
5100
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5077
5101
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5162,13 +5186,17 @@
|
|
|
5162
5186
|
if (malformedExtraField) {
|
|
5163
5187
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5164
5188
|
}
|
|
5165
|
-
fileEntry.offset
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5189
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5190
|
+
startOffset = 0;
|
|
5191
|
+
} else {
|
|
5192
|
+
fileEntry.offset += prependedDataLength;
|
|
5193
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5194
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5195
|
+
if (entryPosition < previousEntryPosition) {
|
|
5196
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5197
|
+
}
|
|
5198
|
+
previousEntryPosition = entryPosition;
|
|
5170
5199
|
}
|
|
5171
|
-
previousEntryPosition = entryPosition;
|
|
5172
5200
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5173
5201
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5174
5202
|
}
|
|
@@ -5205,12 +5233,15 @@
|
|
|
5205
5233
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5206
5234
|
});
|
|
5207
5235
|
const entry = new Entry(fileEntry);
|
|
5208
|
-
|
|
5236
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5237
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5238
|
+
}
|
|
5239
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5209
5240
|
entry.arrayBuffer = async options => {
|
|
5210
5241
|
const writer = new TransformStream();
|
|
5211
5242
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5212
5243
|
arrayBufferPromise.catch(() => { });
|
|
5213
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5244
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5214
5245
|
Object.assign({}, options, { preventClose: false }));
|
|
5215
5246
|
return arrayBufferPromise;
|
|
5216
5247
|
};
|
|
@@ -5418,8 +5449,9 @@
|
|
|
5418
5449
|
});
|
|
5419
5450
|
}
|
|
5420
5451
|
|
|
5421
|
-
async getData(writer, fileEntry,
|
|
5452
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5422
5453
|
const zipEntry = this;
|
|
5454
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5423
5455
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5424
5456
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5425
5457
|
}
|
|
@@ -5493,10 +5525,10 @@
|
|
|
5493
5525
|
}
|
|
5494
5526
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5495
5527
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5496
|
-
if (lastAccessDate) {
|
|
5528
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5497
5529
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5498
5530
|
}
|
|
5499
|
-
if (creationDate) {
|
|
5531
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5500
5532
|
fileEntry.creationDate = creationDate;
|
|
5501
5533
|
}
|
|
5502
5534
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5525,7 +5557,7 @@
|
|
|
5525
5557
|
throw new Error(ERR_ENCRYPTED);
|
|
5526
5558
|
}
|
|
5527
5559
|
}
|
|
5528
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5560
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5529
5561
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5530
5562
|
}
|
|
5531
5563
|
const size = compressedSize;
|
|
@@ -5591,6 +5623,7 @@
|
|
|
5591
5623
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5592
5624
|
readRanges
|
|
5593
5625
|
});
|
|
5626
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5594
5627
|
}
|
|
5595
5628
|
let writable, abortError, aborted;
|
|
5596
5629
|
try {
|
|
@@ -5610,10 +5643,7 @@
|
|
|
5610
5643
|
writer.size += writtenSize;
|
|
5611
5644
|
}
|
|
5612
5645
|
} catch (error) {
|
|
5613
|
-
|
|
5614
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5615
|
-
writer.size += failedOutputSize;
|
|
5616
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5646
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5617
5647
|
writer.size += error.outputSize;
|
|
5618
5648
|
}
|
|
5619
5649
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5641,13 +5671,7 @@
|
|
|
5641
5671
|
};
|
|
5642
5672
|
|
|
5643
5673
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5644
|
-
|
|
5645
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5646
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5647
|
-
return true;
|
|
5648
|
-
}
|
|
5649
|
-
}
|
|
5650
|
-
return false;
|
|
5674
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5651
5675
|
}
|
|
5652
5676
|
|
|
5653
5677
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5684,6 +5708,46 @@
|
|
|
5684
5708
|
}
|
|
5685
5709
|
}
|
|
5686
5710
|
|
|
5711
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5712
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5713
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5714
|
+
const tailView = getDataView(tailArray);
|
|
5715
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5716
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5717
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5718
|
+
return startOffset + indexByte;
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
|
|
5723
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5724
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5725
|
+
return UNDEFINED_VALUE;
|
|
5726
|
+
}
|
|
5727
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5728
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5729
|
+
return localHeaderOffset;
|
|
5730
|
+
}
|
|
5731
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5732
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5733
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5734
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5735
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5736
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5737
|
+
let offsetValue = offsetExtraField + 4;
|
|
5738
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5739
|
+
offsetValue += 8;
|
|
5740
|
+
}
|
|
5741
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5742
|
+
offsetValue += 8;
|
|
5743
|
+
}
|
|
5744
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5745
|
+
}
|
|
5746
|
+
offsetExtraField += 4 + size;
|
|
5747
|
+
}
|
|
5748
|
+
return UNDEFINED_VALUE;
|
|
5749
|
+
}
|
|
5750
|
+
|
|
5687
5751
|
function readDigitalSignature(signatureRecordArray) {
|
|
5688
5752
|
if (signatureRecordArray.length >= 6) {
|
|
5689
5753
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5773,6 +5837,7 @@
|
|
|
5773
5837
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5774
5838
|
});
|
|
5775
5839
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5840
|
+
let extraFieldZip64Missing;
|
|
5776
5841
|
if (extraFieldZip64) {
|
|
5777
5842
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5778
5843
|
malformedExtraField = true;
|
|
@@ -5782,7 +5847,7 @@
|
|
|
5782
5847
|
if (localDirectory) {
|
|
5783
5848
|
malformedExtraField = true;
|
|
5784
5849
|
} else {
|
|
5785
|
-
|
|
5850
|
+
extraFieldZip64Missing = true;
|
|
5786
5851
|
}
|
|
5787
5852
|
}
|
|
5788
5853
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5840,6 +5905,9 @@
|
|
|
5840
5905
|
if (extraFieldUSDZ) {
|
|
5841
5906
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5842
5907
|
}
|
|
5908
|
+
if (extraFieldZip64Missing) {
|
|
5909
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5910
|
+
}
|
|
5843
5911
|
return malformedExtraField;
|
|
5844
5912
|
}
|
|
5845
5913
|
|
|
@@ -6054,13 +6122,7 @@
|
|
|
6054
6122
|
let dataDescriptorLength = 0;
|
|
6055
6123
|
if (dataDescriptor) {
|
|
6056
6124
|
const zip64 = Boolean(extraFieldZip64);
|
|
6057
|
-
const
|
|
6058
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6059
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6060
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6061
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6062
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6063
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6125
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6064
6126
|
if (localDataDescriptor) {
|
|
6065
6127
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6066
6128
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6130,6 +6192,25 @@
|
|
|
6130
6192
|
return mergedRanges;
|
|
6131
6193
|
}
|
|
6132
6194
|
|
|
6195
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6196
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6197
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6198
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6199
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6200
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6201
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6202
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6203
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6204
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6205
|
+
}
|
|
6206
|
+
|
|
6207
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6208
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6209
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6210
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6211
|
+
}
|
|
6212
|
+
}
|
|
6213
|
+
|
|
6133
6214
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6134
6215
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6135
6216
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6389,6 +6470,18 @@
|
|
|
6389
6470
|
}
|
|
6390
6471
|
}
|
|
6391
6472
|
|
|
6473
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6474
|
+
const { dataDescriptor } = localDirectory;
|
|
6475
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6476
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6477
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6478
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6479
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6480
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6481
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6482
|
+
}
|
|
6483
|
+
}
|
|
6484
|
+
|
|
6392
6485
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6393
6486
|
if (reject) {
|
|
6394
6487
|
throwAmbiguousArchive(reason);
|
|
@@ -6491,6 +6584,7 @@
|
|
|
6491
6584
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6492
6585
|
ZipReader: ZipReader,
|
|
6493
6586
|
ZipReaderStream: ZipReaderStream,
|
|
6587
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6494
6588
|
isZipFile: isZipFile
|
|
6495
6589
|
});
|
|
6496
6590
|
|
|
@@ -6614,136 +6708,7 @@
|
|
|
6614
6708
|
}
|
|
6615
6709
|
|
|
6616
6710
|
appendZip(reader, options = {}) {
|
|
6617
|
-
return watchPromiseError(this,
|
|
6618
|
-
}
|
|
6619
|
-
|
|
6620
|
-
async appendZipEntries(reader, options = {}) {
|
|
6621
|
-
const zipWriter = this;
|
|
6622
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6623
|
-
const filter = checkFunctionOption(options.filter);
|
|
6624
|
-
while (pendingAddFileCalls.size) {
|
|
6625
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6626
|
-
}
|
|
6627
|
-
let resolveAppendZip;
|
|
6628
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6629
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6630
|
-
const appendedFilenames = [];
|
|
6631
|
-
let releaseLockWriter;
|
|
6632
|
-
try {
|
|
6633
|
-
reader = new GenericReader(reader);
|
|
6634
|
-
await initStream(reader);
|
|
6635
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6636
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6637
|
-
await initStream(reader);
|
|
6638
|
-
}
|
|
6639
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6640
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6641
|
-
const entries = await zipReader$1.getEntries();
|
|
6642
|
-
const keptEntries = [];
|
|
6643
|
-
for (const entry of entries) {
|
|
6644
|
-
if (!filter || await filter(entry)) {
|
|
6645
|
-
keptEntries.push(entry);
|
|
6646
|
-
}
|
|
6647
|
-
}
|
|
6648
|
-
await zipReader$1.close();
|
|
6649
|
-
await initStream(zipWriter.writer);
|
|
6650
|
-
const { directoryOffset } = zipReader$1;
|
|
6651
|
-
keptEntries.forEach(({ filename }) => {
|
|
6652
|
-
if (filenames.has(filename)) {
|
|
6653
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6654
|
-
}
|
|
6655
|
-
filenames.add(filename);
|
|
6656
|
-
appendedFilenames.push(filename);
|
|
6657
|
-
});
|
|
6658
|
-
zipWriter.writerLocked = true;
|
|
6659
|
-
const { lockWriter } = zipWriter;
|
|
6660
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6661
|
-
zipWriter.writerLocked = false;
|
|
6662
|
-
resolve();
|
|
6663
|
-
});
|
|
6664
|
-
await lockWriter;
|
|
6665
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6666
|
-
delete zipWriter.addSplitZipSignature;
|
|
6667
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6668
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6669
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6670
|
-
}
|
|
6671
|
-
}
|
|
6672
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6673
|
-
keptEntries.forEach(entry => {
|
|
6674
|
-
const {
|
|
6675
|
-
version,
|
|
6676
|
-
rawLastModDate,
|
|
6677
|
-
rawFilename,
|
|
6678
|
-
bitFlag,
|
|
6679
|
-
encrypted,
|
|
6680
|
-
uncompressedSize,
|
|
6681
|
-
compressedSize,
|
|
6682
|
-
extraFieldZip64
|
|
6683
|
-
} = entry;
|
|
6684
|
-
let {
|
|
6685
|
-
compressionMethod,
|
|
6686
|
-
rawExtraField,
|
|
6687
|
-
} = entry;
|
|
6688
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6689
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6690
|
-
if (entry.extraFieldAES) {
|
|
6691
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6692
|
-
}
|
|
6693
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6694
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6695
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6696
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6697
|
-
const {
|
|
6698
|
-
headerArray,
|
|
6699
|
-
headerView
|
|
6700
|
-
} = getHeaderArrayData({
|
|
6701
|
-
version,
|
|
6702
|
-
bitFlag: bitFlagValue,
|
|
6703
|
-
compressionMethod,
|
|
6704
|
-
uncompressedSize,
|
|
6705
|
-
compressedSize,
|
|
6706
|
-
rawLastModDate,
|
|
6707
|
-
rawFilename,
|
|
6708
|
-
zip64CompressedSize,
|
|
6709
|
-
zip64UncompressedSize,
|
|
6710
|
-
extraFieldLength
|
|
6711
|
-
});
|
|
6712
|
-
const { crc32 } = entry;
|
|
6713
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6714
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6715
|
-
}
|
|
6716
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6717
|
-
Object.assign(entry, {
|
|
6718
|
-
zip64Enabled: true,
|
|
6719
|
-
zip64UncompressedSize,
|
|
6720
|
-
zip64CompressedSize,
|
|
6721
|
-
offset,
|
|
6722
|
-
diskNumberStart,
|
|
6723
|
-
zip64DiskNumberStart: false,
|
|
6724
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6725
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6726
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6727
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6728
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6729
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6730
|
-
rawExtraField,
|
|
6731
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6732
|
-
headerArray,
|
|
6733
|
-
headerView
|
|
6734
|
-
});
|
|
6735
|
-
fileEntries.set(entry.filename, entry);
|
|
6736
|
-
});
|
|
6737
|
-
} catch (error) {
|
|
6738
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6739
|
-
throw error;
|
|
6740
|
-
} finally {
|
|
6741
|
-
resolveAppendZip();
|
|
6742
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6743
|
-
if (releaseLockWriter) {
|
|
6744
|
-
releaseLockWriter();
|
|
6745
|
-
}
|
|
6746
|
-
}
|
|
6711
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6747
6712
|
}
|
|
6748
6713
|
|
|
6749
6714
|
add(name = "", reader, options = {}) {
|
|
@@ -6905,11 +6870,149 @@
|
|
|
6905
6870
|
return watchedPromise;
|
|
6906
6871
|
}
|
|
6907
6872
|
|
|
6873
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6874
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6875
|
+
const filter = checkFunctionOption(options.filter);
|
|
6876
|
+
const readerOptions = checkReaderOptionsObject(options.readerOptions);
|
|
6877
|
+
while (pendingAddFileCalls.size) {
|
|
6878
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6879
|
+
}
|
|
6880
|
+
let resolveAppendZip;
|
|
6881
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6882
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6883
|
+
const appendedFilenames = [];
|
|
6884
|
+
let releaseLockWriter;
|
|
6885
|
+
try {
|
|
6886
|
+
reader = new GenericReader(reader);
|
|
6887
|
+
await initStream(reader);
|
|
6888
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6889
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6890
|
+
await initStream(reader);
|
|
6891
|
+
}
|
|
6892
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6893
|
+
const zipReader$1 = new ZipReader(reader, readerOptions);
|
|
6894
|
+
const keptEntries = [];
|
|
6895
|
+
let entries;
|
|
6896
|
+
try {
|
|
6897
|
+
entries = await zipReader$1.getEntries();
|
|
6898
|
+
for (const entry of entries) {
|
|
6899
|
+
if (!filter || await filter(entry, getExistingEntry(fileEntries, entry.filename))) {
|
|
6900
|
+
keptEntries.push(entry);
|
|
6901
|
+
}
|
|
6902
|
+
}
|
|
6903
|
+
} finally {
|
|
6904
|
+
await zipReader$1.close();
|
|
6905
|
+
}
|
|
6906
|
+
await initStream(zipWriter.writer);
|
|
6907
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6908
|
+
keptEntries.forEach(entry => {
|
|
6909
|
+
const { filename } = entry;
|
|
6910
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6911
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6912
|
+
}
|
|
6913
|
+
if (filenames.has(filename)) {
|
|
6914
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6915
|
+
}
|
|
6916
|
+
filenames.add(filename);
|
|
6917
|
+
appendedFilenames.push(filename);
|
|
6918
|
+
});
|
|
6919
|
+
zipWriter.writerLocked = true;
|
|
6920
|
+
const { lockWriter } = zipWriter;
|
|
6921
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6922
|
+
zipWriter.writerLocked = false;
|
|
6923
|
+
resolve();
|
|
6924
|
+
});
|
|
6925
|
+
await lockWriter;
|
|
6926
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6927
|
+
delete zipWriter.addSplitZipSignature;
|
|
6928
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6929
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6930
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6931
|
+
}
|
|
6932
|
+
}
|
|
6933
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6934
|
+
keptEntries.forEach(entry => {
|
|
6935
|
+
const {
|
|
6936
|
+
version,
|
|
6937
|
+
rawLastModDate,
|
|
6938
|
+
rawFilename,
|
|
6939
|
+
rawBitFlag,
|
|
6940
|
+
uncompressedSize,
|
|
6941
|
+
compressedSize,
|
|
6942
|
+
extraFieldZip64
|
|
6943
|
+
} = entry;
|
|
6944
|
+
let {
|
|
6945
|
+
compressionMethod,
|
|
6946
|
+
rawExtraField,
|
|
6947
|
+
} = entry;
|
|
6948
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6949
|
+
if (entry.extraFieldAES) {
|
|
6950
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6951
|
+
}
|
|
6952
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6953
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6954
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6955
|
+
const {
|
|
6956
|
+
headerArray,
|
|
6957
|
+
headerView
|
|
6958
|
+
} = getHeaderArrayData({
|
|
6959
|
+
version,
|
|
6960
|
+
bitFlag: rawBitFlag,
|
|
6961
|
+
compressionMethod,
|
|
6962
|
+
uncompressedSize,
|
|
6963
|
+
compressedSize,
|
|
6964
|
+
rawLastModDate,
|
|
6965
|
+
rawFilename,
|
|
6966
|
+
zip64CompressedSize,
|
|
6967
|
+
zip64UncompressedSize,
|
|
6968
|
+
extraFieldLength
|
|
6969
|
+
});
|
|
6970
|
+
const { crc32 } = entry;
|
|
6971
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6972
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6973
|
+
}
|
|
6974
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6975
|
+
fileEntries.set(entry.filename, Object.assign({}, entry, {
|
|
6976
|
+
zip64Enabled: true,
|
|
6977
|
+
zip64UncompressedSize,
|
|
6978
|
+
zip64CompressedSize,
|
|
6979
|
+
offset,
|
|
6980
|
+
diskNumberStart,
|
|
6981
|
+
zip64DiskNumberStart: false,
|
|
6982
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6983
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6984
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6985
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6986
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6987
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6988
|
+
rawExtraField,
|
|
6989
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6990
|
+
headerArray,
|
|
6991
|
+
headerView
|
|
6992
|
+
}));
|
|
6993
|
+
});
|
|
6994
|
+
} catch (error) {
|
|
6995
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6996
|
+
throw error;
|
|
6997
|
+
} finally {
|
|
6998
|
+
resolveAppendZip();
|
|
6999
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
7000
|
+
if (releaseLockWriter) {
|
|
7001
|
+
releaseLockWriter();
|
|
7002
|
+
}
|
|
7003
|
+
}
|
|
7004
|
+
}
|
|
7005
|
+
|
|
7006
|
+
function getExistingEntry(fileEntries, filename) {
|
|
7007
|
+
const fileEntry = fileEntries.get(filename);
|
|
7008
|
+
return fileEntry ? new Entry(fileEntry) : UNDEFINED_VALUE;
|
|
7009
|
+
}
|
|
7010
|
+
|
|
6908
7011
|
async function prependZipEntries(zipWriter, reader) {
|
|
6909
7012
|
if (zipWriter.filenames.size) {
|
|
6910
7013
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6911
7014
|
}
|
|
6912
|
-
await
|
|
7015
|
+
await appendZipEntries(zipWriter, reader);
|
|
6913
7016
|
}
|
|
6914
7017
|
|
|
6915
7018
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8681,7 +8784,7 @@
|
|
|
8681
8784
|
return rawExtraField;
|
|
8682
8785
|
}
|
|
8683
8786
|
|
|
8684
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8787
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8685
8788
|
const { writer } = zipWriter;
|
|
8686
8789
|
const entryPositions = new Map();
|
|
8687
8790
|
if (writer.closeDisk || compact) {
|
|
@@ -8689,6 +8792,27 @@
|
|
|
8689
8792
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8690
8793
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8691
8794
|
const keptEntrySet = new Set(keptEntries);
|
|
8795
|
+
const localHeaderLengths = new Map();
|
|
8796
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8797
|
+
const entry = sortedEntries[indexEntry];
|
|
8798
|
+
if (keptEntrySet.has(entry)) {
|
|
8799
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8800
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8801
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8802
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8803
|
+
}
|
|
8804
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8805
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8806
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8807
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8808
|
+
}
|
|
8809
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8810
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8811
|
+
}
|
|
8812
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8813
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8814
|
+
}
|
|
8815
|
+
}
|
|
8692
8816
|
let copiedOffset = 0;
|
|
8693
8817
|
let lastPosition;
|
|
8694
8818
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8701,7 +8825,7 @@
|
|
|
8701
8825
|
if (!compact) {
|
|
8702
8826
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8703
8827
|
}
|
|
8704
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8828
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8705
8829
|
await writer.closeDisk();
|
|
8706
8830
|
}
|
|
8707
8831
|
lastPosition = {
|
|
@@ -8735,7 +8859,7 @@
|
|
|
8735
8859
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8736
8860
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8737
8861
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8738
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8862
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8739
8863
|
}
|
|
8740
8864
|
regionEnds[indexEntry] = regionEnd;
|
|
8741
8865
|
}
|
|
@@ -8749,11 +8873,13 @@
|
|
|
8749
8873
|
try {
|
|
8750
8874
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8751
8875
|
} catch (error) {
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8876
|
+
if (copiedLength) {
|
|
8877
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8878
|
+
try {
|
|
8879
|
+
error.corruptedEntry = true;
|
|
8880
|
+
} catch {
|
|
8881
|
+
// ignored
|
|
8882
|
+
}
|
|
8757
8883
|
}
|
|
8758
8884
|
throw error;
|
|
8759
8885
|
} finally {
|
|
@@ -8764,11 +8890,16 @@
|
|
|
8764
8890
|
}
|
|
8765
8891
|
|
|
8766
8892
|
async function getLocalHeaderLength(reader, offset) {
|
|
8767
|
-
const headerArray =
|
|
8893
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8894
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8895
|
+
EMPTY_UINT8_ARRAY;
|
|
8768
8896
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8769
|
-
return
|
|
8897
|
+
return UNDEFINED_VALUE;
|
|
8770
8898
|
}
|
|
8771
8899
|
const headerView = getDataView(headerArray);
|
|
8900
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8901
|
+
return UNDEFINED_VALUE;
|
|
8902
|
+
}
|
|
8772
8903
|
return HEADER_SIZE +
|
|
8773
8904
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8774
8905
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9119,7 +9250,7 @@
|
|
|
9119
9250
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9120
9251
|
*/
|
|
9121
9252
|
|
|
9122
|
-
const VERSION = "2.
|
|
9253
|
+
const VERSION = "2.22.0";
|
|
9123
9254
|
|
|
9124
9255
|
/*
|
|
9125
9256
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9648,7 +9779,6 @@
|
|
|
9648
9779
|
const DUPLICATES_KEEP_LAST = "keep-last";
|
|
9649
9780
|
const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
|
|
9650
9781
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
9651
|
-
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
9652
9782
|
const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
|
|
9653
9783
|
const ERR_INVALID_PASSWORDS = "Invalid passwords option (must be an array of strings)";
|
|
9654
9784
|
const ERR_INVALID_REQUEST_PASSWORD = "Invalid requestPassword option (must be a function returning a string or undefined)";
|
|
@@ -10574,9 +10704,7 @@
|
|
|
10574
10704
|
}
|
|
10575
10705
|
|
|
10576
10706
|
function checkReaderOptions(readerOptions) {
|
|
10577
|
-
|
|
10578
|
-
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
10579
|
-
}
|
|
10707
|
+
checkReaderOptionsObject(readerOptions);
|
|
10580
10708
|
if (readerOptions) {
|
|
10581
10709
|
checkPassThroughValue(readerOptions.passThrough);
|
|
10582
10710
|
checkPasswordCandidatesOptions(readerOptions);
|