@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.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",
|
|
@@ -4785,12 +4795,9 @@
|
|
|
4785
4795
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4786
4796
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4787
4797
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4788
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4789
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4790
4798
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4791
4799
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4792
4800
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4793
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4794
4801
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4795
4802
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4796
4803
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4854,8 +4861,9 @@
|
|
|
4854
4861
|
constructor(reader, options = {}) {
|
|
4855
4862
|
Object.assign(this, {
|
|
4856
4863
|
reader: new GenericReader(reader),
|
|
4857
|
-
options,
|
|
4858
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4864
|
+
options: options || {},
|
|
4865
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4866
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4859
4867
|
});
|
|
4860
4868
|
}
|
|
4861
4869
|
|
|
@@ -4926,16 +4934,22 @@
|
|
|
4926
4934
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4927
4935
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4928
4936
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4937
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4938
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4939
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4940
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4941
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4942
|
+
}
|
|
4943
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4944
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4945
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4946
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4947
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4948
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4949
|
+
}
|
|
4950
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4951
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4936
4952
|
}
|
|
4937
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4938
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4939
4953
|
}
|
|
4940
4954
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4941
4955
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4980,10 +4994,6 @@
|
|
|
4980
4994
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4981
4995
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4982
4996
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4983
|
-
if (directoryDataOffset >= reader.size) {
|
|
4984
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4985
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4986
|
-
}
|
|
4987
4997
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4988
4998
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4989
4999
|
}
|
|
@@ -4991,52 +5001,64 @@
|
|
|
4991
5001
|
throw new Error(ERR_BAD_FORMAT);
|
|
4992
5002
|
}
|
|
4993
5003
|
let offset = 0;
|
|
4994
|
-
let directoryArray =
|
|
5004
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
5005
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
5006
|
+
EMPTY_UINT8_ARRAY;
|
|
4995
5007
|
let directoryView = getDataView(directoryArray);
|
|
4996
5008
|
if (directoryDataLength) {
|
|
4997
|
-
if (directoryArray.length < 4) {
|
|
4998
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4999
|
-
}
|
|
5000
5009
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
5001
5010
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
5002
|
-
const storedPointsAtDirectory =
|
|
5011
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
5012
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
5003
5013
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
5004
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5014
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5015
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5016
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5017
|
+
}
|
|
5005
5018
|
let reconcile = !storedPointsAtDirectory;
|
|
5006
5019
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
5007
|
-
|
|
5008
|
-
if (
|
|
5009
|
-
reconcile = expectedPointsAtDirectory;
|
|
5010
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5020
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5021
|
+
if (!expectedPointsAtDirectory) {
|
|
5011
5022
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5012
5023
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5013
5024
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5014
5025
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5015
5026
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5027
|
+
expectedPointsAtDirectory = true;
|
|
5016
5028
|
}
|
|
5017
5029
|
}
|
|
5030
|
+
if (storedPointsAtDirectory) {
|
|
5031
|
+
reconcile = expectedPointsAtDirectory;
|
|
5032
|
+
}
|
|
5018
5033
|
}
|
|
5019
|
-
if (reconcile) {
|
|
5034
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5020
5035
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5021
5036
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5022
5037
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5023
5038
|
directoryView = getDataView(directoryArray);
|
|
5024
|
-
|
|
5025
|
-
|
|
5039
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5040
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5041
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5042
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5043
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5044
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5045
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5046
|
+
prependedDataLength += offsetDelta;
|
|
5026
5047
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5027
5048
|
} else {
|
|
5028
5049
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5032
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5033
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5034
|
-
prependedDataLength += offsetDelta;
|
|
5035
|
-
}
|
|
5050
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5051
|
+
prependedDataLength += offsetDelta;
|
|
5036
5052
|
}
|
|
5037
5053
|
}
|
|
5038
5054
|
}
|
|
5039
5055
|
}
|
|
5056
|
+
if (directoryArray.length < 4) {
|
|
5057
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5058
|
+
}
|
|
5059
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5060
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5061
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5040
5062
|
}
|
|
5041
5063
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5042
5064
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5078,8 +5100,10 @@
|
|
|
5078
5100
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5079
5101
|
}
|
|
5080
5102
|
}
|
|
5103
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5104
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5081
5105
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5082
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5106
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5083
5107
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5084
5108
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5085
5109
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5170,13 +5194,17 @@
|
|
|
5170
5194
|
if (malformedExtraField) {
|
|
5171
5195
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5172
5196
|
}
|
|
5173
|
-
fileEntry.offset
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5197
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5198
|
+
startOffset = 0;
|
|
5199
|
+
} else {
|
|
5200
|
+
fileEntry.offset += prependedDataLength;
|
|
5201
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5202
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5203
|
+
if (entryPosition < previousEntryPosition) {
|
|
5204
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5205
|
+
}
|
|
5206
|
+
previousEntryPosition = entryPosition;
|
|
5178
5207
|
}
|
|
5179
|
-
previousEntryPosition = entryPosition;
|
|
5180
5208
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5181
5209
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5182
5210
|
}
|
|
@@ -5213,12 +5241,15 @@
|
|
|
5213
5241
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5214
5242
|
});
|
|
5215
5243
|
const entry = new Entry(fileEntry);
|
|
5216
|
-
|
|
5244
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5245
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5246
|
+
}
|
|
5247
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5217
5248
|
entry.arrayBuffer = async options => {
|
|
5218
5249
|
const writer = new TransformStream();
|
|
5219
5250
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5220
5251
|
arrayBufferPromise.catch(() => { });
|
|
5221
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5252
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5222
5253
|
Object.assign({}, options, { preventClose: false }));
|
|
5223
5254
|
return arrayBufferPromise;
|
|
5224
5255
|
};
|
|
@@ -5426,8 +5457,9 @@
|
|
|
5426
5457
|
});
|
|
5427
5458
|
}
|
|
5428
5459
|
|
|
5429
|
-
async getData(writer, fileEntry,
|
|
5460
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5430
5461
|
const zipEntry = this;
|
|
5462
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5431
5463
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5432
5464
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5433
5465
|
}
|
|
@@ -5501,10 +5533,10 @@
|
|
|
5501
5533
|
}
|
|
5502
5534
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5503
5535
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5504
|
-
if (lastAccessDate) {
|
|
5536
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5505
5537
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5506
5538
|
}
|
|
5507
|
-
if (creationDate) {
|
|
5539
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5508
5540
|
fileEntry.creationDate = creationDate;
|
|
5509
5541
|
}
|
|
5510
5542
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5533,7 +5565,7 @@
|
|
|
5533
5565
|
throw new Error(ERR_ENCRYPTED);
|
|
5534
5566
|
}
|
|
5535
5567
|
}
|
|
5536
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5568
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5537
5569
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5538
5570
|
}
|
|
5539
5571
|
const size = compressedSize;
|
|
@@ -5599,6 +5631,7 @@
|
|
|
5599
5631
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5600
5632
|
readRanges
|
|
5601
5633
|
});
|
|
5634
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5602
5635
|
}
|
|
5603
5636
|
let writable, abortError, aborted;
|
|
5604
5637
|
try {
|
|
@@ -5618,10 +5651,7 @@
|
|
|
5618
5651
|
writer.size += writtenSize;
|
|
5619
5652
|
}
|
|
5620
5653
|
} catch (error) {
|
|
5621
|
-
|
|
5622
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5623
|
-
writer.size += failedOutputSize;
|
|
5624
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5654
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5625
5655
|
writer.size += error.outputSize;
|
|
5626
5656
|
}
|
|
5627
5657
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5649,13 +5679,7 @@
|
|
|
5649
5679
|
};
|
|
5650
5680
|
|
|
5651
5681
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5652
|
-
|
|
5653
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5654
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5655
|
-
return true;
|
|
5656
|
-
}
|
|
5657
|
-
}
|
|
5658
|
-
return false;
|
|
5682
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5659
5683
|
}
|
|
5660
5684
|
|
|
5661
5685
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5692,6 +5716,46 @@
|
|
|
5692
5716
|
}
|
|
5693
5717
|
}
|
|
5694
5718
|
|
|
5719
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5720
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5721
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5722
|
+
const tailView = getDataView(tailArray);
|
|
5723
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5724
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5725
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5726
|
+
return startOffset + indexByte;
|
|
5727
|
+
}
|
|
5728
|
+
}
|
|
5729
|
+
}
|
|
5730
|
+
|
|
5731
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5732
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5733
|
+
return UNDEFINED_VALUE;
|
|
5734
|
+
}
|
|
5735
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5736
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5737
|
+
return localHeaderOffset;
|
|
5738
|
+
}
|
|
5739
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5740
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5741
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5742
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5743
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5744
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5745
|
+
let offsetValue = offsetExtraField + 4;
|
|
5746
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5747
|
+
offsetValue += 8;
|
|
5748
|
+
}
|
|
5749
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5750
|
+
offsetValue += 8;
|
|
5751
|
+
}
|
|
5752
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5753
|
+
}
|
|
5754
|
+
offsetExtraField += 4 + size;
|
|
5755
|
+
}
|
|
5756
|
+
return UNDEFINED_VALUE;
|
|
5757
|
+
}
|
|
5758
|
+
|
|
5695
5759
|
function readDigitalSignature(signatureRecordArray) {
|
|
5696
5760
|
if (signatureRecordArray.length >= 6) {
|
|
5697
5761
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5781,6 +5845,7 @@
|
|
|
5781
5845
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5782
5846
|
});
|
|
5783
5847
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5848
|
+
let extraFieldZip64Missing;
|
|
5784
5849
|
if (extraFieldZip64) {
|
|
5785
5850
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5786
5851
|
malformedExtraField = true;
|
|
@@ -5790,7 +5855,7 @@
|
|
|
5790
5855
|
if (localDirectory) {
|
|
5791
5856
|
malformedExtraField = true;
|
|
5792
5857
|
} else {
|
|
5793
|
-
|
|
5858
|
+
extraFieldZip64Missing = true;
|
|
5794
5859
|
}
|
|
5795
5860
|
}
|
|
5796
5861
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5848,6 +5913,9 @@
|
|
|
5848
5913
|
if (extraFieldUSDZ) {
|
|
5849
5914
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5850
5915
|
}
|
|
5916
|
+
if (extraFieldZip64Missing) {
|
|
5917
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5918
|
+
}
|
|
5851
5919
|
return malformedExtraField;
|
|
5852
5920
|
}
|
|
5853
5921
|
|
|
@@ -6062,13 +6130,7 @@
|
|
|
6062
6130
|
let dataDescriptorLength = 0;
|
|
6063
6131
|
if (dataDescriptor) {
|
|
6064
6132
|
const zip64 = Boolean(extraFieldZip64);
|
|
6065
|
-
const
|
|
6066
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6067
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6068
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6069
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6070
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6071
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6133
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6072
6134
|
if (localDataDescriptor) {
|
|
6073
6135
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6074
6136
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6138,6 +6200,25 @@
|
|
|
6138
6200
|
return mergedRanges;
|
|
6139
6201
|
}
|
|
6140
6202
|
|
|
6203
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6204
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6205
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6206
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6207
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6208
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6209
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6210
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6211
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6212
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6213
|
+
}
|
|
6214
|
+
|
|
6215
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6216
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6217
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6218
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6219
|
+
}
|
|
6220
|
+
}
|
|
6221
|
+
|
|
6141
6222
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6142
6223
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6143
6224
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6397,6 +6478,18 @@
|
|
|
6397
6478
|
}
|
|
6398
6479
|
}
|
|
6399
6480
|
|
|
6481
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6482
|
+
const { dataDescriptor } = localDirectory;
|
|
6483
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6484
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6485
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6486
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6487
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6488
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6489
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6490
|
+
}
|
|
6491
|
+
}
|
|
6492
|
+
|
|
6400
6493
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6401
6494
|
if (reject) {
|
|
6402
6495
|
throwAmbiguousArchive(reason);
|
|
@@ -6499,6 +6592,7 @@
|
|
|
6499
6592
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6500
6593
|
ZipReader: ZipReader,
|
|
6501
6594
|
ZipReaderStream: ZipReaderStream,
|
|
6595
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6502
6596
|
isZipFile: isZipFile
|
|
6503
6597
|
});
|
|
6504
6598
|
|
|
@@ -6622,136 +6716,7 @@
|
|
|
6622
6716
|
}
|
|
6623
6717
|
|
|
6624
6718
|
appendZip(reader, options = {}) {
|
|
6625
|
-
return watchPromiseError(this,
|
|
6626
|
-
}
|
|
6627
|
-
|
|
6628
|
-
async appendZipEntries(reader, options = {}) {
|
|
6629
|
-
const zipWriter = this;
|
|
6630
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6631
|
-
const filter = checkFunctionOption(options.filter);
|
|
6632
|
-
while (pendingAddFileCalls.size) {
|
|
6633
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6634
|
-
}
|
|
6635
|
-
let resolveAppendZip;
|
|
6636
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6637
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6638
|
-
const appendedFilenames = [];
|
|
6639
|
-
let releaseLockWriter;
|
|
6640
|
-
try {
|
|
6641
|
-
reader = new GenericReader(reader);
|
|
6642
|
-
await initStream(reader);
|
|
6643
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6644
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6645
|
-
await initStream(reader);
|
|
6646
|
-
}
|
|
6647
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6648
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6649
|
-
const entries = await zipReader$1.getEntries();
|
|
6650
|
-
const keptEntries = [];
|
|
6651
|
-
for (const entry of entries) {
|
|
6652
|
-
if (!filter || await filter(entry)) {
|
|
6653
|
-
keptEntries.push(entry);
|
|
6654
|
-
}
|
|
6655
|
-
}
|
|
6656
|
-
await zipReader$1.close();
|
|
6657
|
-
await initStream(zipWriter.writer);
|
|
6658
|
-
const { directoryOffset } = zipReader$1;
|
|
6659
|
-
keptEntries.forEach(({ filename }) => {
|
|
6660
|
-
if (filenames.has(filename)) {
|
|
6661
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6662
|
-
}
|
|
6663
|
-
filenames.add(filename);
|
|
6664
|
-
appendedFilenames.push(filename);
|
|
6665
|
-
});
|
|
6666
|
-
zipWriter.writerLocked = true;
|
|
6667
|
-
const { lockWriter } = zipWriter;
|
|
6668
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6669
|
-
zipWriter.writerLocked = false;
|
|
6670
|
-
resolve();
|
|
6671
|
-
});
|
|
6672
|
-
await lockWriter;
|
|
6673
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6674
|
-
delete zipWriter.addSplitZipSignature;
|
|
6675
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6676
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6677
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6678
|
-
}
|
|
6679
|
-
}
|
|
6680
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6681
|
-
keptEntries.forEach(entry => {
|
|
6682
|
-
const {
|
|
6683
|
-
version,
|
|
6684
|
-
rawLastModDate,
|
|
6685
|
-
rawFilename,
|
|
6686
|
-
bitFlag,
|
|
6687
|
-
encrypted,
|
|
6688
|
-
uncompressedSize,
|
|
6689
|
-
compressedSize,
|
|
6690
|
-
extraFieldZip64
|
|
6691
|
-
} = entry;
|
|
6692
|
-
let {
|
|
6693
|
-
compressionMethod,
|
|
6694
|
-
rawExtraField,
|
|
6695
|
-
} = entry;
|
|
6696
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6697
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6698
|
-
if (entry.extraFieldAES) {
|
|
6699
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6700
|
-
}
|
|
6701
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6702
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6703
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6704
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6705
|
-
const {
|
|
6706
|
-
headerArray,
|
|
6707
|
-
headerView
|
|
6708
|
-
} = getHeaderArrayData({
|
|
6709
|
-
version,
|
|
6710
|
-
bitFlag: bitFlagValue,
|
|
6711
|
-
compressionMethod,
|
|
6712
|
-
uncompressedSize,
|
|
6713
|
-
compressedSize,
|
|
6714
|
-
rawLastModDate,
|
|
6715
|
-
rawFilename,
|
|
6716
|
-
zip64CompressedSize,
|
|
6717
|
-
zip64UncompressedSize,
|
|
6718
|
-
extraFieldLength
|
|
6719
|
-
});
|
|
6720
|
-
const { crc32 } = entry;
|
|
6721
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6722
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6723
|
-
}
|
|
6724
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6725
|
-
Object.assign(entry, {
|
|
6726
|
-
zip64Enabled: true,
|
|
6727
|
-
zip64UncompressedSize,
|
|
6728
|
-
zip64CompressedSize,
|
|
6729
|
-
offset,
|
|
6730
|
-
diskNumberStart,
|
|
6731
|
-
zip64DiskNumberStart: false,
|
|
6732
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6733
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6734
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6735
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6736
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6737
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6738
|
-
rawExtraField,
|
|
6739
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6740
|
-
headerArray,
|
|
6741
|
-
headerView
|
|
6742
|
-
});
|
|
6743
|
-
fileEntries.set(entry.filename, entry);
|
|
6744
|
-
});
|
|
6745
|
-
} catch (error) {
|
|
6746
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6747
|
-
throw error;
|
|
6748
|
-
} finally {
|
|
6749
|
-
resolveAppendZip();
|
|
6750
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6751
|
-
if (releaseLockWriter) {
|
|
6752
|
-
releaseLockWriter();
|
|
6753
|
-
}
|
|
6754
|
-
}
|
|
6719
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6755
6720
|
}
|
|
6756
6721
|
|
|
6757
6722
|
add(name = "", reader, options = {}) {
|
|
@@ -6913,11 +6878,149 @@
|
|
|
6913
6878
|
return watchedPromise;
|
|
6914
6879
|
}
|
|
6915
6880
|
|
|
6881
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6882
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6883
|
+
const filter = checkFunctionOption(options.filter);
|
|
6884
|
+
const readerOptions = checkReaderOptionsObject(options.readerOptions);
|
|
6885
|
+
while (pendingAddFileCalls.size) {
|
|
6886
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6887
|
+
}
|
|
6888
|
+
let resolveAppendZip;
|
|
6889
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6890
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6891
|
+
const appendedFilenames = [];
|
|
6892
|
+
let releaseLockWriter;
|
|
6893
|
+
try {
|
|
6894
|
+
reader = new GenericReader(reader);
|
|
6895
|
+
await initStream(reader);
|
|
6896
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6897
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6898
|
+
await initStream(reader);
|
|
6899
|
+
}
|
|
6900
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6901
|
+
const zipReader$1 = new ZipReader(reader, readerOptions);
|
|
6902
|
+
const keptEntries = [];
|
|
6903
|
+
let entries;
|
|
6904
|
+
try {
|
|
6905
|
+
entries = await zipReader$1.getEntries();
|
|
6906
|
+
for (const entry of entries) {
|
|
6907
|
+
if (!filter || await filter(entry, getExistingEntry(fileEntries, entry.filename))) {
|
|
6908
|
+
keptEntries.push(entry);
|
|
6909
|
+
}
|
|
6910
|
+
}
|
|
6911
|
+
} finally {
|
|
6912
|
+
await zipReader$1.close();
|
|
6913
|
+
}
|
|
6914
|
+
await initStream(zipWriter.writer);
|
|
6915
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6916
|
+
keptEntries.forEach(entry => {
|
|
6917
|
+
const { filename } = entry;
|
|
6918
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6919
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6920
|
+
}
|
|
6921
|
+
if (filenames.has(filename)) {
|
|
6922
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6923
|
+
}
|
|
6924
|
+
filenames.add(filename);
|
|
6925
|
+
appendedFilenames.push(filename);
|
|
6926
|
+
});
|
|
6927
|
+
zipWriter.writerLocked = true;
|
|
6928
|
+
const { lockWriter } = zipWriter;
|
|
6929
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6930
|
+
zipWriter.writerLocked = false;
|
|
6931
|
+
resolve();
|
|
6932
|
+
});
|
|
6933
|
+
await lockWriter;
|
|
6934
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6935
|
+
delete zipWriter.addSplitZipSignature;
|
|
6936
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6937
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6938
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6939
|
+
}
|
|
6940
|
+
}
|
|
6941
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6942
|
+
keptEntries.forEach(entry => {
|
|
6943
|
+
const {
|
|
6944
|
+
version,
|
|
6945
|
+
rawLastModDate,
|
|
6946
|
+
rawFilename,
|
|
6947
|
+
rawBitFlag,
|
|
6948
|
+
uncompressedSize,
|
|
6949
|
+
compressedSize,
|
|
6950
|
+
extraFieldZip64
|
|
6951
|
+
} = entry;
|
|
6952
|
+
let {
|
|
6953
|
+
compressionMethod,
|
|
6954
|
+
rawExtraField,
|
|
6955
|
+
} = entry;
|
|
6956
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6957
|
+
if (entry.extraFieldAES) {
|
|
6958
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6959
|
+
}
|
|
6960
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6961
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6962
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6963
|
+
const {
|
|
6964
|
+
headerArray,
|
|
6965
|
+
headerView
|
|
6966
|
+
} = getHeaderArrayData({
|
|
6967
|
+
version,
|
|
6968
|
+
bitFlag: rawBitFlag,
|
|
6969
|
+
compressionMethod,
|
|
6970
|
+
uncompressedSize,
|
|
6971
|
+
compressedSize,
|
|
6972
|
+
rawLastModDate,
|
|
6973
|
+
rawFilename,
|
|
6974
|
+
zip64CompressedSize,
|
|
6975
|
+
zip64UncompressedSize,
|
|
6976
|
+
extraFieldLength
|
|
6977
|
+
});
|
|
6978
|
+
const { crc32 } = entry;
|
|
6979
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6980
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6981
|
+
}
|
|
6982
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6983
|
+
fileEntries.set(entry.filename, Object.assign({}, entry, {
|
|
6984
|
+
zip64Enabled: true,
|
|
6985
|
+
zip64UncompressedSize,
|
|
6986
|
+
zip64CompressedSize,
|
|
6987
|
+
offset,
|
|
6988
|
+
diskNumberStart,
|
|
6989
|
+
zip64DiskNumberStart: false,
|
|
6990
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6991
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6992
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6993
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6994
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6995
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6996
|
+
rawExtraField,
|
|
6997
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6998
|
+
headerArray,
|
|
6999
|
+
headerView
|
|
7000
|
+
}));
|
|
7001
|
+
});
|
|
7002
|
+
} catch (error) {
|
|
7003
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
7004
|
+
throw error;
|
|
7005
|
+
} finally {
|
|
7006
|
+
resolveAppendZip();
|
|
7007
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
7008
|
+
if (releaseLockWriter) {
|
|
7009
|
+
releaseLockWriter();
|
|
7010
|
+
}
|
|
7011
|
+
}
|
|
7012
|
+
}
|
|
7013
|
+
|
|
7014
|
+
function getExistingEntry(fileEntries, filename) {
|
|
7015
|
+
const fileEntry = fileEntries.get(filename);
|
|
7016
|
+
return fileEntry ? new Entry(fileEntry) : UNDEFINED_VALUE;
|
|
7017
|
+
}
|
|
7018
|
+
|
|
6916
7019
|
async function prependZipEntries(zipWriter, reader) {
|
|
6917
7020
|
if (zipWriter.filenames.size) {
|
|
6918
7021
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6919
7022
|
}
|
|
6920
|
-
await
|
|
7023
|
+
await appendZipEntries(zipWriter, reader);
|
|
6921
7024
|
}
|
|
6922
7025
|
|
|
6923
7026
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8689,7 +8792,7 @@
|
|
|
8689
8792
|
return rawExtraField;
|
|
8690
8793
|
}
|
|
8691
8794
|
|
|
8692
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8795
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8693
8796
|
const { writer } = zipWriter;
|
|
8694
8797
|
const entryPositions = new Map();
|
|
8695
8798
|
if (writer.closeDisk || compact) {
|
|
@@ -8697,6 +8800,27 @@
|
|
|
8697
8800
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8698
8801
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8699
8802
|
const keptEntrySet = new Set(keptEntries);
|
|
8803
|
+
const localHeaderLengths = new Map();
|
|
8804
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8805
|
+
const entry = sortedEntries[indexEntry];
|
|
8806
|
+
if (keptEntrySet.has(entry)) {
|
|
8807
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8808
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8809
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8810
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8811
|
+
}
|
|
8812
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8813
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8814
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8815
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8816
|
+
}
|
|
8817
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8818
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8819
|
+
}
|
|
8820
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8821
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8822
|
+
}
|
|
8823
|
+
}
|
|
8700
8824
|
let copiedOffset = 0;
|
|
8701
8825
|
let lastPosition;
|
|
8702
8826
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8709,7 +8833,7 @@
|
|
|
8709
8833
|
if (!compact) {
|
|
8710
8834
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8711
8835
|
}
|
|
8712
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8836
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8713
8837
|
await writer.closeDisk();
|
|
8714
8838
|
}
|
|
8715
8839
|
lastPosition = {
|
|
@@ -8743,7 +8867,7 @@
|
|
|
8743
8867
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8744
8868
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8745
8869
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8746
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8870
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8747
8871
|
}
|
|
8748
8872
|
regionEnds[indexEntry] = regionEnd;
|
|
8749
8873
|
}
|
|
@@ -8757,11 +8881,13 @@
|
|
|
8757
8881
|
try {
|
|
8758
8882
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8759
8883
|
} catch (error) {
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8884
|
+
if (copiedLength) {
|
|
8885
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8886
|
+
try {
|
|
8887
|
+
error.corruptedEntry = true;
|
|
8888
|
+
} catch {
|
|
8889
|
+
// ignored
|
|
8890
|
+
}
|
|
8765
8891
|
}
|
|
8766
8892
|
throw error;
|
|
8767
8893
|
} finally {
|
|
@@ -8772,11 +8898,16 @@
|
|
|
8772
8898
|
}
|
|
8773
8899
|
|
|
8774
8900
|
async function getLocalHeaderLength(reader, offset) {
|
|
8775
|
-
const headerArray =
|
|
8901
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8902
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8903
|
+
EMPTY_UINT8_ARRAY;
|
|
8776
8904
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8777
|
-
return
|
|
8905
|
+
return UNDEFINED_VALUE;
|
|
8778
8906
|
}
|
|
8779
8907
|
const headerView = getDataView(headerArray);
|
|
8908
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8909
|
+
return UNDEFINED_VALUE;
|
|
8910
|
+
}
|
|
8780
8911
|
return HEADER_SIZE +
|
|
8781
8912
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8782
8913
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9127,7 +9258,7 @@
|
|
|
9127
9258
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9128
9259
|
*/
|
|
9129
9260
|
|
|
9130
|
-
const VERSION = "2.
|
|
9261
|
+
const VERSION = "2.22.0";
|
|
9131
9262
|
|
|
9132
9263
|
/*
|
|
9133
9264
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -10202,7 +10333,6 @@
|
|
|
10202
10333
|
const DUPLICATES_KEEP_LAST = "keep-last";
|
|
10203
10334
|
const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
|
|
10204
10335
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
10205
|
-
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
10206
10336
|
const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
|
|
10207
10337
|
const ERR_INVALID_PASSWORDS = "Invalid passwords option (must be an array of strings)";
|
|
10208
10338
|
const ERR_INVALID_REQUEST_PASSWORD = "Invalid requestPassword option (must be a function returning a string or undefined)";
|
|
@@ -11128,9 +11258,7 @@
|
|
|
11128
11258
|
}
|
|
11129
11259
|
|
|
11130
11260
|
function checkReaderOptions(readerOptions) {
|
|
11131
|
-
|
|
11132
|
-
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
11133
|
-
}
|
|
11261
|
+
checkReaderOptionsObject(readerOptions);
|
|
11134
11262
|
if (readerOptions) {
|
|
11135
11263
|
checkPassThroughValue(readerOptions.passThrough);
|
|
11136
11264
|
checkPasswordCandidatesOptions(readerOptions);
|