@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-core.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",
|
|
@@ -4775,12 +4785,9 @@
|
|
|
4775
4785
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4776
4786
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4777
4787
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4778
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4779
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4780
4788
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4781
4789
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4782
4790
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4783
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4784
4791
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4785
4792
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4786
4793
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4844,8 +4851,9 @@
|
|
|
4844
4851
|
constructor(reader, options = {}) {
|
|
4845
4852
|
Object.assign(this, {
|
|
4846
4853
|
reader: new GenericReader(reader),
|
|
4847
|
-
options,
|
|
4848
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4854
|
+
options: options || {},
|
|
4855
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4856
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4849
4857
|
});
|
|
4850
4858
|
}
|
|
4851
4859
|
|
|
@@ -4916,16 +4924,22 @@
|
|
|
4916
4924
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4917
4925
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4918
4926
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4927
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4928
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4929
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4930
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4931
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4932
|
+
}
|
|
4933
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4934
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4935
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4936
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4937
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4938
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4939
|
+
}
|
|
4940
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4941
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4926
4942
|
}
|
|
4927
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4928
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4929
4943
|
}
|
|
4930
4944
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4931
4945
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4970,10 +4984,6 @@
|
|
|
4970
4984
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4971
4985
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4972
4986
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4973
|
-
if (directoryDataOffset >= reader.size) {
|
|
4974
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4975
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4976
|
-
}
|
|
4977
4987
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4978
4988
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4979
4989
|
}
|
|
@@ -4981,52 +4991,64 @@
|
|
|
4981
4991
|
throw new Error(ERR_BAD_FORMAT);
|
|
4982
4992
|
}
|
|
4983
4993
|
let offset = 0;
|
|
4984
|
-
let directoryArray =
|
|
4994
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4995
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4996
|
+
EMPTY_UINT8_ARRAY;
|
|
4985
4997
|
let directoryView = getDataView(directoryArray);
|
|
4986
4998
|
if (directoryDataLength) {
|
|
4987
|
-
if (directoryArray.length < 4) {
|
|
4988
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4989
|
-
}
|
|
4990
4999
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4991
5000
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4992
|
-
const storedPointsAtDirectory =
|
|
5001
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
5002
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4993
5003
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4994
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5004
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5005
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5006
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5007
|
+
}
|
|
4995
5008
|
let reconcile = !storedPointsAtDirectory;
|
|
4996
5009
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4997
|
-
|
|
4998
|
-
if (
|
|
4999
|
-
reconcile = expectedPointsAtDirectory;
|
|
5000
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5010
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5011
|
+
if (!expectedPointsAtDirectory) {
|
|
5001
5012
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5002
5013
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5003
5014
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5004
5015
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5005
5016
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5017
|
+
expectedPointsAtDirectory = true;
|
|
5006
5018
|
}
|
|
5007
5019
|
}
|
|
5020
|
+
if (storedPointsAtDirectory) {
|
|
5021
|
+
reconcile = expectedPointsAtDirectory;
|
|
5022
|
+
}
|
|
5008
5023
|
}
|
|
5009
|
-
if (reconcile) {
|
|
5024
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5010
5025
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5011
5026
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5012
5027
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5013
5028
|
directoryView = getDataView(directoryArray);
|
|
5014
|
-
|
|
5015
|
-
|
|
5029
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5030
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5031
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5032
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5033
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5034
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5035
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5036
|
+
prependedDataLength += offsetDelta;
|
|
5016
5037
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5017
5038
|
} else {
|
|
5018
5039
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5022
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5023
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5024
|
-
prependedDataLength += offsetDelta;
|
|
5025
|
-
}
|
|
5040
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5041
|
+
prependedDataLength += offsetDelta;
|
|
5026
5042
|
}
|
|
5027
5043
|
}
|
|
5028
5044
|
}
|
|
5029
5045
|
}
|
|
5046
|
+
if (directoryArray.length < 4) {
|
|
5047
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5048
|
+
}
|
|
5049
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5050
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5051
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5030
5052
|
}
|
|
5031
5053
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5032
5054
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5068,8 +5090,10 @@
|
|
|
5068
5090
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5069
5091
|
}
|
|
5070
5092
|
}
|
|
5093
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5094
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5071
5095
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5072
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5096
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5073
5097
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5074
5098
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5075
5099
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5160,13 +5184,17 @@
|
|
|
5160
5184
|
if (malformedExtraField) {
|
|
5161
5185
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5162
5186
|
}
|
|
5163
|
-
fileEntry.offset
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5187
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5188
|
+
startOffset = 0;
|
|
5189
|
+
} else {
|
|
5190
|
+
fileEntry.offset += prependedDataLength;
|
|
5191
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5192
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5193
|
+
if (entryPosition < previousEntryPosition) {
|
|
5194
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5195
|
+
}
|
|
5196
|
+
previousEntryPosition = entryPosition;
|
|
5168
5197
|
}
|
|
5169
|
-
previousEntryPosition = entryPosition;
|
|
5170
5198
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5171
5199
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5172
5200
|
}
|
|
@@ -5203,12 +5231,15 @@
|
|
|
5203
5231
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5204
5232
|
});
|
|
5205
5233
|
const entry = new Entry(fileEntry);
|
|
5206
|
-
|
|
5234
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5235
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5236
|
+
}
|
|
5237
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5207
5238
|
entry.arrayBuffer = async options => {
|
|
5208
5239
|
const writer = new TransformStream();
|
|
5209
5240
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5210
5241
|
arrayBufferPromise.catch(() => { });
|
|
5211
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5242
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5212
5243
|
Object.assign({}, options, { preventClose: false }));
|
|
5213
5244
|
return arrayBufferPromise;
|
|
5214
5245
|
};
|
|
@@ -5416,8 +5447,9 @@
|
|
|
5416
5447
|
});
|
|
5417
5448
|
}
|
|
5418
5449
|
|
|
5419
|
-
async getData(writer, fileEntry,
|
|
5450
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5420
5451
|
const zipEntry = this;
|
|
5452
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5421
5453
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5422
5454
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5423
5455
|
}
|
|
@@ -5491,10 +5523,10 @@
|
|
|
5491
5523
|
}
|
|
5492
5524
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5493
5525
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5494
|
-
if (lastAccessDate) {
|
|
5526
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5495
5527
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5496
5528
|
}
|
|
5497
|
-
if (creationDate) {
|
|
5529
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5498
5530
|
fileEntry.creationDate = creationDate;
|
|
5499
5531
|
}
|
|
5500
5532
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5523,7 +5555,7 @@
|
|
|
5523
5555
|
throw new Error(ERR_ENCRYPTED);
|
|
5524
5556
|
}
|
|
5525
5557
|
}
|
|
5526
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5558
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5527
5559
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5528
5560
|
}
|
|
5529
5561
|
const size = compressedSize;
|
|
@@ -5589,6 +5621,7 @@
|
|
|
5589
5621
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5590
5622
|
readRanges
|
|
5591
5623
|
});
|
|
5624
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5592
5625
|
}
|
|
5593
5626
|
let writable, abortError, aborted;
|
|
5594
5627
|
try {
|
|
@@ -5608,10 +5641,7 @@
|
|
|
5608
5641
|
writer.size += writtenSize;
|
|
5609
5642
|
}
|
|
5610
5643
|
} catch (error) {
|
|
5611
|
-
|
|
5612
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5613
|
-
writer.size += failedOutputSize;
|
|
5614
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5644
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5615
5645
|
writer.size += error.outputSize;
|
|
5616
5646
|
}
|
|
5617
5647
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5639,13 +5669,7 @@
|
|
|
5639
5669
|
};
|
|
5640
5670
|
|
|
5641
5671
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5642
|
-
|
|
5643
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5644
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5645
|
-
return true;
|
|
5646
|
-
}
|
|
5647
|
-
}
|
|
5648
|
-
return false;
|
|
5672
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5649
5673
|
}
|
|
5650
5674
|
|
|
5651
5675
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5682,6 +5706,46 @@
|
|
|
5682
5706
|
}
|
|
5683
5707
|
}
|
|
5684
5708
|
|
|
5709
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5710
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5711
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5712
|
+
const tailView = getDataView(tailArray);
|
|
5713
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5714
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5715
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5716
|
+
return startOffset + indexByte;
|
|
5717
|
+
}
|
|
5718
|
+
}
|
|
5719
|
+
}
|
|
5720
|
+
|
|
5721
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5722
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5723
|
+
return UNDEFINED_VALUE;
|
|
5724
|
+
}
|
|
5725
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5726
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5727
|
+
return localHeaderOffset;
|
|
5728
|
+
}
|
|
5729
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5730
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5731
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5732
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5733
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5734
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5735
|
+
let offsetValue = offsetExtraField + 4;
|
|
5736
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5737
|
+
offsetValue += 8;
|
|
5738
|
+
}
|
|
5739
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5740
|
+
offsetValue += 8;
|
|
5741
|
+
}
|
|
5742
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5743
|
+
}
|
|
5744
|
+
offsetExtraField += 4 + size;
|
|
5745
|
+
}
|
|
5746
|
+
return UNDEFINED_VALUE;
|
|
5747
|
+
}
|
|
5748
|
+
|
|
5685
5749
|
function readDigitalSignature(signatureRecordArray) {
|
|
5686
5750
|
if (signatureRecordArray.length >= 6) {
|
|
5687
5751
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5771,6 +5835,7 @@
|
|
|
5771
5835
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5772
5836
|
});
|
|
5773
5837
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5838
|
+
let extraFieldZip64Missing;
|
|
5774
5839
|
if (extraFieldZip64) {
|
|
5775
5840
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5776
5841
|
malformedExtraField = true;
|
|
@@ -5780,7 +5845,7 @@
|
|
|
5780
5845
|
if (localDirectory) {
|
|
5781
5846
|
malformedExtraField = true;
|
|
5782
5847
|
} else {
|
|
5783
|
-
|
|
5848
|
+
extraFieldZip64Missing = true;
|
|
5784
5849
|
}
|
|
5785
5850
|
}
|
|
5786
5851
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5838,6 +5903,9 @@
|
|
|
5838
5903
|
if (extraFieldUSDZ) {
|
|
5839
5904
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5840
5905
|
}
|
|
5906
|
+
if (extraFieldZip64Missing) {
|
|
5907
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5908
|
+
}
|
|
5841
5909
|
return malformedExtraField;
|
|
5842
5910
|
}
|
|
5843
5911
|
|
|
@@ -6052,13 +6120,7 @@
|
|
|
6052
6120
|
let dataDescriptorLength = 0;
|
|
6053
6121
|
if (dataDescriptor) {
|
|
6054
6122
|
const zip64 = Boolean(extraFieldZip64);
|
|
6055
|
-
const
|
|
6056
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6057
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6058
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6059
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6060
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6061
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6123
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6062
6124
|
if (localDataDescriptor) {
|
|
6063
6125
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6064
6126
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6128,6 +6190,25 @@
|
|
|
6128
6190
|
return mergedRanges;
|
|
6129
6191
|
}
|
|
6130
6192
|
|
|
6193
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6194
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6195
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6196
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6197
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6198
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6199
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6200
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6201
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6202
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6203
|
+
}
|
|
6204
|
+
|
|
6205
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6206
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6207
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6208
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6209
|
+
}
|
|
6210
|
+
}
|
|
6211
|
+
|
|
6131
6212
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6132
6213
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6133
6214
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6387,6 +6468,18 @@
|
|
|
6387
6468
|
}
|
|
6388
6469
|
}
|
|
6389
6470
|
|
|
6471
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6472
|
+
const { dataDescriptor } = localDirectory;
|
|
6473
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6474
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6475
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6476
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6477
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6478
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6479
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6480
|
+
}
|
|
6481
|
+
}
|
|
6482
|
+
|
|
6390
6483
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6391
6484
|
if (reject) {
|
|
6392
6485
|
throwAmbiguousArchive(reason);
|
|
@@ -6489,6 +6582,7 @@
|
|
|
6489
6582
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6490
6583
|
ZipReader: ZipReader,
|
|
6491
6584
|
ZipReaderStream: ZipReaderStream,
|
|
6585
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6492
6586
|
isZipFile: isZipFile
|
|
6493
6587
|
});
|
|
6494
6588
|
|
|
@@ -6612,136 +6706,7 @@
|
|
|
6612
6706
|
}
|
|
6613
6707
|
|
|
6614
6708
|
appendZip(reader, options = {}) {
|
|
6615
|
-
return watchPromiseError(this,
|
|
6616
|
-
}
|
|
6617
|
-
|
|
6618
|
-
async appendZipEntries(reader, options = {}) {
|
|
6619
|
-
const zipWriter = this;
|
|
6620
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6621
|
-
const filter = checkFunctionOption(options.filter);
|
|
6622
|
-
while (pendingAddFileCalls.size) {
|
|
6623
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6624
|
-
}
|
|
6625
|
-
let resolveAppendZip;
|
|
6626
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6627
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6628
|
-
const appendedFilenames = [];
|
|
6629
|
-
let releaseLockWriter;
|
|
6630
|
-
try {
|
|
6631
|
-
reader = new GenericReader(reader);
|
|
6632
|
-
await initStream(reader);
|
|
6633
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6634
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6635
|
-
await initStream(reader);
|
|
6636
|
-
}
|
|
6637
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6638
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6639
|
-
const entries = await zipReader$1.getEntries();
|
|
6640
|
-
const keptEntries = [];
|
|
6641
|
-
for (const entry of entries) {
|
|
6642
|
-
if (!filter || await filter(entry)) {
|
|
6643
|
-
keptEntries.push(entry);
|
|
6644
|
-
}
|
|
6645
|
-
}
|
|
6646
|
-
await zipReader$1.close();
|
|
6647
|
-
await initStream(zipWriter.writer);
|
|
6648
|
-
const { directoryOffset } = zipReader$1;
|
|
6649
|
-
keptEntries.forEach(({ filename }) => {
|
|
6650
|
-
if (filenames.has(filename)) {
|
|
6651
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6652
|
-
}
|
|
6653
|
-
filenames.add(filename);
|
|
6654
|
-
appendedFilenames.push(filename);
|
|
6655
|
-
});
|
|
6656
|
-
zipWriter.writerLocked = true;
|
|
6657
|
-
const { lockWriter } = zipWriter;
|
|
6658
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6659
|
-
zipWriter.writerLocked = false;
|
|
6660
|
-
resolve();
|
|
6661
|
-
});
|
|
6662
|
-
await lockWriter;
|
|
6663
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6664
|
-
delete zipWriter.addSplitZipSignature;
|
|
6665
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6666
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6667
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6668
|
-
}
|
|
6669
|
-
}
|
|
6670
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6671
|
-
keptEntries.forEach(entry => {
|
|
6672
|
-
const {
|
|
6673
|
-
version,
|
|
6674
|
-
rawLastModDate,
|
|
6675
|
-
rawFilename,
|
|
6676
|
-
bitFlag,
|
|
6677
|
-
encrypted,
|
|
6678
|
-
uncompressedSize,
|
|
6679
|
-
compressedSize,
|
|
6680
|
-
extraFieldZip64
|
|
6681
|
-
} = entry;
|
|
6682
|
-
let {
|
|
6683
|
-
compressionMethod,
|
|
6684
|
-
rawExtraField,
|
|
6685
|
-
} = entry;
|
|
6686
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6687
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6688
|
-
if (entry.extraFieldAES) {
|
|
6689
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6690
|
-
}
|
|
6691
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6692
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6693
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6694
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6695
|
-
const {
|
|
6696
|
-
headerArray,
|
|
6697
|
-
headerView
|
|
6698
|
-
} = getHeaderArrayData({
|
|
6699
|
-
version,
|
|
6700
|
-
bitFlag: bitFlagValue,
|
|
6701
|
-
compressionMethod,
|
|
6702
|
-
uncompressedSize,
|
|
6703
|
-
compressedSize,
|
|
6704
|
-
rawLastModDate,
|
|
6705
|
-
rawFilename,
|
|
6706
|
-
zip64CompressedSize,
|
|
6707
|
-
zip64UncompressedSize,
|
|
6708
|
-
extraFieldLength
|
|
6709
|
-
});
|
|
6710
|
-
const { crc32 } = entry;
|
|
6711
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6712
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6713
|
-
}
|
|
6714
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6715
|
-
Object.assign(entry, {
|
|
6716
|
-
zip64Enabled: true,
|
|
6717
|
-
zip64UncompressedSize,
|
|
6718
|
-
zip64CompressedSize,
|
|
6719
|
-
offset,
|
|
6720
|
-
diskNumberStart,
|
|
6721
|
-
zip64DiskNumberStart: false,
|
|
6722
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6723
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6724
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6725
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6726
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6727
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6728
|
-
rawExtraField,
|
|
6729
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6730
|
-
headerArray,
|
|
6731
|
-
headerView
|
|
6732
|
-
});
|
|
6733
|
-
fileEntries.set(entry.filename, entry);
|
|
6734
|
-
});
|
|
6735
|
-
} catch (error) {
|
|
6736
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6737
|
-
throw error;
|
|
6738
|
-
} finally {
|
|
6739
|
-
resolveAppendZip();
|
|
6740
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6741
|
-
if (releaseLockWriter) {
|
|
6742
|
-
releaseLockWriter();
|
|
6743
|
-
}
|
|
6744
|
-
}
|
|
6709
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6745
6710
|
}
|
|
6746
6711
|
|
|
6747
6712
|
add(name = "", reader, options = {}) {
|
|
@@ -6903,11 +6868,149 @@
|
|
|
6903
6868
|
return watchedPromise;
|
|
6904
6869
|
}
|
|
6905
6870
|
|
|
6871
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6872
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6873
|
+
const filter = checkFunctionOption(options.filter);
|
|
6874
|
+
const readerOptions = checkReaderOptionsObject(options.readerOptions);
|
|
6875
|
+
while (pendingAddFileCalls.size) {
|
|
6876
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6877
|
+
}
|
|
6878
|
+
let resolveAppendZip;
|
|
6879
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6880
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6881
|
+
const appendedFilenames = [];
|
|
6882
|
+
let releaseLockWriter;
|
|
6883
|
+
try {
|
|
6884
|
+
reader = new GenericReader(reader);
|
|
6885
|
+
await initStream(reader);
|
|
6886
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6887
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6888
|
+
await initStream(reader);
|
|
6889
|
+
}
|
|
6890
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6891
|
+
const zipReader$1 = new ZipReader(reader, readerOptions);
|
|
6892
|
+
const keptEntries = [];
|
|
6893
|
+
let entries;
|
|
6894
|
+
try {
|
|
6895
|
+
entries = await zipReader$1.getEntries();
|
|
6896
|
+
for (const entry of entries) {
|
|
6897
|
+
if (!filter || await filter(entry, getExistingEntry(fileEntries, entry.filename))) {
|
|
6898
|
+
keptEntries.push(entry);
|
|
6899
|
+
}
|
|
6900
|
+
}
|
|
6901
|
+
} finally {
|
|
6902
|
+
await zipReader$1.close();
|
|
6903
|
+
}
|
|
6904
|
+
await initStream(zipWriter.writer);
|
|
6905
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6906
|
+
keptEntries.forEach(entry => {
|
|
6907
|
+
const { filename } = entry;
|
|
6908
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6909
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6910
|
+
}
|
|
6911
|
+
if (filenames.has(filename)) {
|
|
6912
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6913
|
+
}
|
|
6914
|
+
filenames.add(filename);
|
|
6915
|
+
appendedFilenames.push(filename);
|
|
6916
|
+
});
|
|
6917
|
+
zipWriter.writerLocked = true;
|
|
6918
|
+
const { lockWriter } = zipWriter;
|
|
6919
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6920
|
+
zipWriter.writerLocked = false;
|
|
6921
|
+
resolve();
|
|
6922
|
+
});
|
|
6923
|
+
await lockWriter;
|
|
6924
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6925
|
+
delete zipWriter.addSplitZipSignature;
|
|
6926
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6927
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6928
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6929
|
+
}
|
|
6930
|
+
}
|
|
6931
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6932
|
+
keptEntries.forEach(entry => {
|
|
6933
|
+
const {
|
|
6934
|
+
version,
|
|
6935
|
+
rawLastModDate,
|
|
6936
|
+
rawFilename,
|
|
6937
|
+
rawBitFlag,
|
|
6938
|
+
uncompressedSize,
|
|
6939
|
+
compressedSize,
|
|
6940
|
+
extraFieldZip64
|
|
6941
|
+
} = entry;
|
|
6942
|
+
let {
|
|
6943
|
+
compressionMethod,
|
|
6944
|
+
rawExtraField,
|
|
6945
|
+
} = entry;
|
|
6946
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6947
|
+
if (entry.extraFieldAES) {
|
|
6948
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6949
|
+
}
|
|
6950
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6951
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6952
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6953
|
+
const {
|
|
6954
|
+
headerArray,
|
|
6955
|
+
headerView
|
|
6956
|
+
} = getHeaderArrayData({
|
|
6957
|
+
version,
|
|
6958
|
+
bitFlag: rawBitFlag,
|
|
6959
|
+
compressionMethod,
|
|
6960
|
+
uncompressedSize,
|
|
6961
|
+
compressedSize,
|
|
6962
|
+
rawLastModDate,
|
|
6963
|
+
rawFilename,
|
|
6964
|
+
zip64CompressedSize,
|
|
6965
|
+
zip64UncompressedSize,
|
|
6966
|
+
extraFieldLength
|
|
6967
|
+
});
|
|
6968
|
+
const { crc32 } = entry;
|
|
6969
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6970
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6971
|
+
}
|
|
6972
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6973
|
+
fileEntries.set(entry.filename, Object.assign({}, entry, {
|
|
6974
|
+
zip64Enabled: true,
|
|
6975
|
+
zip64UncompressedSize,
|
|
6976
|
+
zip64CompressedSize,
|
|
6977
|
+
offset,
|
|
6978
|
+
diskNumberStart,
|
|
6979
|
+
zip64DiskNumberStart: false,
|
|
6980
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6981
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6982
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6983
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6984
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6985
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6986
|
+
rawExtraField,
|
|
6987
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6988
|
+
headerArray,
|
|
6989
|
+
headerView
|
|
6990
|
+
}));
|
|
6991
|
+
});
|
|
6992
|
+
} catch (error) {
|
|
6993
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6994
|
+
throw error;
|
|
6995
|
+
} finally {
|
|
6996
|
+
resolveAppendZip();
|
|
6997
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6998
|
+
if (releaseLockWriter) {
|
|
6999
|
+
releaseLockWriter();
|
|
7000
|
+
}
|
|
7001
|
+
}
|
|
7002
|
+
}
|
|
7003
|
+
|
|
7004
|
+
function getExistingEntry(fileEntries, filename) {
|
|
7005
|
+
const fileEntry = fileEntries.get(filename);
|
|
7006
|
+
return fileEntry ? new Entry(fileEntry) : UNDEFINED_VALUE;
|
|
7007
|
+
}
|
|
7008
|
+
|
|
6906
7009
|
async function prependZipEntries(zipWriter, reader) {
|
|
6907
7010
|
if (zipWriter.filenames.size) {
|
|
6908
7011
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6909
7012
|
}
|
|
6910
|
-
await
|
|
7013
|
+
await appendZipEntries(zipWriter, reader);
|
|
6911
7014
|
}
|
|
6912
7015
|
|
|
6913
7016
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8679,7 +8782,7 @@
|
|
|
8679
8782
|
return rawExtraField;
|
|
8680
8783
|
}
|
|
8681
8784
|
|
|
8682
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8785
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8683
8786
|
const { writer } = zipWriter;
|
|
8684
8787
|
const entryPositions = new Map();
|
|
8685
8788
|
if (writer.closeDisk || compact) {
|
|
@@ -8687,6 +8790,27 @@
|
|
|
8687
8790
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8688
8791
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8689
8792
|
const keptEntrySet = new Set(keptEntries);
|
|
8793
|
+
const localHeaderLengths = new Map();
|
|
8794
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8795
|
+
const entry = sortedEntries[indexEntry];
|
|
8796
|
+
if (keptEntrySet.has(entry)) {
|
|
8797
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8798
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8799
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8800
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8801
|
+
}
|
|
8802
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8803
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8804
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8805
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8806
|
+
}
|
|
8807
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8808
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8809
|
+
}
|
|
8810
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8811
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8812
|
+
}
|
|
8813
|
+
}
|
|
8690
8814
|
let copiedOffset = 0;
|
|
8691
8815
|
let lastPosition;
|
|
8692
8816
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8699,7 +8823,7 @@
|
|
|
8699
8823
|
if (!compact) {
|
|
8700
8824
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8701
8825
|
}
|
|
8702
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8826
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8703
8827
|
await writer.closeDisk();
|
|
8704
8828
|
}
|
|
8705
8829
|
lastPosition = {
|
|
@@ -8733,7 +8857,7 @@
|
|
|
8733
8857
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8734
8858
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8735
8859
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8736
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8860
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8737
8861
|
}
|
|
8738
8862
|
regionEnds[indexEntry] = regionEnd;
|
|
8739
8863
|
}
|
|
@@ -8747,11 +8871,13 @@
|
|
|
8747
8871
|
try {
|
|
8748
8872
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8749
8873
|
} catch (error) {
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8874
|
+
if (copiedLength) {
|
|
8875
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8876
|
+
try {
|
|
8877
|
+
error.corruptedEntry = true;
|
|
8878
|
+
} catch {
|
|
8879
|
+
// ignored
|
|
8880
|
+
}
|
|
8755
8881
|
}
|
|
8756
8882
|
throw error;
|
|
8757
8883
|
} finally {
|
|
@@ -8762,11 +8888,16 @@
|
|
|
8762
8888
|
}
|
|
8763
8889
|
|
|
8764
8890
|
async function getLocalHeaderLength(reader, offset) {
|
|
8765
|
-
const headerArray =
|
|
8891
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8892
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8893
|
+
EMPTY_UINT8_ARRAY;
|
|
8766
8894
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8767
|
-
return
|
|
8895
|
+
return UNDEFINED_VALUE;
|
|
8768
8896
|
}
|
|
8769
8897
|
const headerView = getDataView(headerArray);
|
|
8898
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8899
|
+
return UNDEFINED_VALUE;
|
|
8900
|
+
}
|
|
8770
8901
|
return HEADER_SIZE +
|
|
8771
8902
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8772
8903
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9117,7 +9248,7 @@
|
|
|
9117
9248
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9118
9249
|
*/
|
|
9119
9250
|
|
|
9120
|
-
const VERSION = "2.
|
|
9251
|
+
const VERSION = "2.22.0";
|
|
9121
9252
|
|
|
9122
9253
|
/*
|
|
9123
9254
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9608,7 +9739,6 @@
|
|
|
9608
9739
|
const DUPLICATES_KEEP_LAST = "keep-last";
|
|
9609
9740
|
const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
|
|
9610
9741
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
9611
|
-
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
9612
9742
|
const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
|
|
9613
9743
|
const ERR_INVALID_PASSWORDS = "Invalid passwords option (must be an array of strings)";
|
|
9614
9744
|
const ERR_INVALID_REQUEST_PASSWORD = "Invalid requestPassword option (must be a function returning a string or undefined)";
|
|
@@ -10534,9 +10664,7 @@
|
|
|
10534
10664
|
}
|
|
10535
10665
|
|
|
10536
10666
|
function checkReaderOptions(readerOptions) {
|
|
10537
|
-
|
|
10538
|
-
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
10539
|
-
}
|
|
10667
|
+
checkReaderOptionsObject(readerOptions);
|
|
10540
10668
|
if (readerOptions) {
|
|
10541
10669
|
checkPassThroughValue(readerOptions.passThrough);
|
|
10542
10670
|
checkPasswordCandidatesOptions(readerOptions);
|