@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-legacy.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 = "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",
|
|
@@ -4757,12 +4767,9 @@
|
|
|
4757
4767
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4758
4768
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4759
4769
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4760
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4761
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4762
4770
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4763
4771
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4764
4772
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4765
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4766
4773
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4767
4774
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4768
4775
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4826,8 +4833,9 @@
|
|
|
4826
4833
|
constructor(reader, options = {}) {
|
|
4827
4834
|
Object.assign(this, {
|
|
4828
4835
|
reader: new GenericReader(reader),
|
|
4829
|
-
options,
|
|
4830
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4836
|
+
options: options || {},
|
|
4837
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4838
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4831
4839
|
});
|
|
4832
4840
|
}
|
|
4833
4841
|
|
|
@@ -4898,16 +4906,22 @@
|
|
|
4898
4906
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4899
4907
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4900
4908
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4909
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4910
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4911
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4912
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4913
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4914
|
+
}
|
|
4915
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4916
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4917
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4918
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4919
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4920
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4921
|
+
}
|
|
4922
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4923
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4908
4924
|
}
|
|
4909
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4910
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4911
4925
|
}
|
|
4912
4926
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4913
4927
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4952,10 +4966,6 @@
|
|
|
4952
4966
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4953
4967
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4954
4968
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4955
|
-
if (directoryDataOffset >= reader.size) {
|
|
4956
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4957
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4958
|
-
}
|
|
4959
4969
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4960
4970
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4961
4971
|
}
|
|
@@ -4963,52 +4973,64 @@
|
|
|
4963
4973
|
throw new Error(ERR_BAD_FORMAT);
|
|
4964
4974
|
}
|
|
4965
4975
|
let offset = 0;
|
|
4966
|
-
let directoryArray =
|
|
4976
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4977
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4978
|
+
EMPTY_UINT8_ARRAY;
|
|
4967
4979
|
let directoryView = getDataView(directoryArray);
|
|
4968
4980
|
if (directoryDataLength) {
|
|
4969
|
-
if (directoryArray.length < 4) {
|
|
4970
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4971
|
-
}
|
|
4972
4981
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4973
4982
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4974
|
-
const storedPointsAtDirectory =
|
|
4983
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
4984
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4975
4985
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4976
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
4986
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
4987
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
4988
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
4989
|
+
}
|
|
4977
4990
|
let reconcile = !storedPointsAtDirectory;
|
|
4978
4991
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4979
|
-
|
|
4980
|
-
if (
|
|
4981
|
-
reconcile = expectedPointsAtDirectory;
|
|
4982
|
-
} else if (!expectedPointsAtDirectory) {
|
|
4992
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
4993
|
+
if (!expectedPointsAtDirectory) {
|
|
4983
4994
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
4984
4995
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
4985
4996
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
4986
4997
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
4987
4998
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
4999
|
+
expectedPointsAtDirectory = true;
|
|
4988
5000
|
}
|
|
4989
5001
|
}
|
|
5002
|
+
if (storedPointsAtDirectory) {
|
|
5003
|
+
reconcile = expectedPointsAtDirectory;
|
|
5004
|
+
}
|
|
4990
5005
|
}
|
|
4991
|
-
if (reconcile) {
|
|
5006
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
4992
5007
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4993
5008
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4994
5009
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4995
5010
|
directoryView = getDataView(directoryArray);
|
|
4996
|
-
|
|
4997
|
-
|
|
5011
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5012
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5013
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5014
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5015
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5016
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5017
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5018
|
+
prependedDataLength += offsetDelta;
|
|
4998
5019
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
4999
5020
|
} else {
|
|
5000
5021
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5004
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5005
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5006
|
-
prependedDataLength += offsetDelta;
|
|
5007
|
-
}
|
|
5022
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5023
|
+
prependedDataLength += offsetDelta;
|
|
5008
5024
|
}
|
|
5009
5025
|
}
|
|
5010
5026
|
}
|
|
5011
5027
|
}
|
|
5028
|
+
if (directoryArray.length < 4) {
|
|
5029
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5030
|
+
}
|
|
5031
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5032
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5033
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5012
5034
|
}
|
|
5013
5035
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5014
5036
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5050,8 +5072,10 @@
|
|
|
5050
5072
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5051
5073
|
}
|
|
5052
5074
|
}
|
|
5075
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5076
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5053
5077
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5054
|
-
const fileEntry = new ZipEntry(reader,
|
|
5078
|
+
const fileEntry = new ZipEntry(reader, entryOptions);
|
|
5055
5079
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5056
5080
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5057
5081
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5142,13 +5166,17 @@
|
|
|
5142
5166
|
if (malformedExtraField) {
|
|
5143
5167
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5144
5168
|
}
|
|
5145
|
-
fileEntry.offset
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5169
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5170
|
+
startOffset = 0;
|
|
5171
|
+
} else {
|
|
5172
|
+
fileEntry.offset += prependedDataLength;
|
|
5173
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5174
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5175
|
+
if (entryPosition < previousEntryPosition) {
|
|
5176
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5177
|
+
}
|
|
5178
|
+
previousEntryPosition = entryPosition;
|
|
5150
5179
|
}
|
|
5151
|
-
previousEntryPosition = entryPosition;
|
|
5152
5180
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5153
5181
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5154
5182
|
}
|
|
@@ -5185,12 +5213,15 @@
|
|
|
5185
5213
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5186
5214
|
});
|
|
5187
5215
|
const entry = new Entry(fileEntry);
|
|
5188
|
-
|
|
5216
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5217
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5218
|
+
}
|
|
5219
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5189
5220
|
entry.arrayBuffer = async options => {
|
|
5190
5221
|
const writer = new TransformStream();
|
|
5191
5222
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5192
5223
|
arrayBufferPromise.catch(() => { });
|
|
5193
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5224
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5194
5225
|
Object.assign({}, options, { preventClose: false }));
|
|
5195
5226
|
return arrayBufferPromise;
|
|
5196
5227
|
};
|
|
@@ -5398,8 +5429,9 @@
|
|
|
5398
5429
|
});
|
|
5399
5430
|
}
|
|
5400
5431
|
|
|
5401
|
-
async getData(writer, fileEntry,
|
|
5432
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5402
5433
|
const zipEntry = this;
|
|
5434
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5403
5435
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5404
5436
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5405
5437
|
}
|
|
@@ -5473,10 +5505,10 @@
|
|
|
5473
5505
|
}
|
|
5474
5506
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5475
5507
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5476
|
-
if (lastAccessDate) {
|
|
5508
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5477
5509
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5478
5510
|
}
|
|
5479
|
-
if (creationDate) {
|
|
5511
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5480
5512
|
fileEntry.creationDate = creationDate;
|
|
5481
5513
|
}
|
|
5482
5514
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5505,7 +5537,7 @@
|
|
|
5505
5537
|
throw new Error(ERR_ENCRYPTED);
|
|
5506
5538
|
}
|
|
5507
5539
|
}
|
|
5508
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5540
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5509
5541
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5510
5542
|
}
|
|
5511
5543
|
const size = compressedSize;
|
|
@@ -5571,6 +5603,7 @@
|
|
|
5571
5603
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5572
5604
|
readRanges
|
|
5573
5605
|
});
|
|
5606
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5574
5607
|
}
|
|
5575
5608
|
let writable, abortError, aborted;
|
|
5576
5609
|
try {
|
|
@@ -5590,10 +5623,7 @@
|
|
|
5590
5623
|
writer.size += writtenSize;
|
|
5591
5624
|
}
|
|
5592
5625
|
} catch (error) {
|
|
5593
|
-
|
|
5594
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5595
|
-
writer.size += failedOutputSize;
|
|
5596
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5626
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5597
5627
|
writer.size += error.outputSize;
|
|
5598
5628
|
}
|
|
5599
5629
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5621,13 +5651,7 @@
|
|
|
5621
5651
|
}
|
|
5622
5652
|
|
|
5623
5653
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5624
|
-
|
|
5625
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5626
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5627
|
-
return true;
|
|
5628
|
-
}
|
|
5629
|
-
}
|
|
5630
|
-
return false;
|
|
5654
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5631
5655
|
}
|
|
5632
5656
|
|
|
5633
5657
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5664,6 +5688,46 @@
|
|
|
5664
5688
|
}
|
|
5665
5689
|
}
|
|
5666
5690
|
|
|
5691
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5692
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5693
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5694
|
+
const tailView = getDataView(tailArray);
|
|
5695
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5696
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5697
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5698
|
+
return startOffset + indexByte;
|
|
5699
|
+
}
|
|
5700
|
+
}
|
|
5701
|
+
}
|
|
5702
|
+
|
|
5703
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5704
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5705
|
+
return UNDEFINED_VALUE;
|
|
5706
|
+
}
|
|
5707
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5708
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5709
|
+
return localHeaderOffset;
|
|
5710
|
+
}
|
|
5711
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5712
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5713
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5714
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5715
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5716
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5717
|
+
let offsetValue = offsetExtraField + 4;
|
|
5718
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5719
|
+
offsetValue += 8;
|
|
5720
|
+
}
|
|
5721
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5722
|
+
offsetValue += 8;
|
|
5723
|
+
}
|
|
5724
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5725
|
+
}
|
|
5726
|
+
offsetExtraField += 4 + size;
|
|
5727
|
+
}
|
|
5728
|
+
return UNDEFINED_VALUE;
|
|
5729
|
+
}
|
|
5730
|
+
|
|
5667
5731
|
function readDigitalSignature(signatureRecordArray) {
|
|
5668
5732
|
if (signatureRecordArray.length >= 6) {
|
|
5669
5733
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5753,6 +5817,7 @@
|
|
|
5753
5817
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5754
5818
|
});
|
|
5755
5819
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5820
|
+
let extraFieldZip64Missing;
|
|
5756
5821
|
if (extraFieldZip64) {
|
|
5757
5822
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5758
5823
|
malformedExtraField = true;
|
|
@@ -5762,7 +5827,7 @@
|
|
|
5762
5827
|
if (localDirectory) {
|
|
5763
5828
|
malformedExtraField = true;
|
|
5764
5829
|
} else {
|
|
5765
|
-
|
|
5830
|
+
extraFieldZip64Missing = true;
|
|
5766
5831
|
}
|
|
5767
5832
|
}
|
|
5768
5833
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5820,6 +5885,9 @@
|
|
|
5820
5885
|
if (extraFieldUSDZ) {
|
|
5821
5886
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5822
5887
|
}
|
|
5888
|
+
if (extraFieldZip64Missing) {
|
|
5889
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5890
|
+
}
|
|
5823
5891
|
return malformedExtraField;
|
|
5824
5892
|
}
|
|
5825
5893
|
|
|
@@ -6034,13 +6102,7 @@
|
|
|
6034
6102
|
let dataDescriptorLength = 0;
|
|
6035
6103
|
if (dataDescriptor) {
|
|
6036
6104
|
const zip64 = Boolean(extraFieldZip64);
|
|
6037
|
-
const
|
|
6038
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6039
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6040
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6041
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6042
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6043
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6105
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6044
6106
|
if (localDataDescriptor) {
|
|
6045
6107
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6046
6108
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6110,6 +6172,25 @@
|
|
|
6110
6172
|
return mergedRanges;
|
|
6111
6173
|
}
|
|
6112
6174
|
|
|
6175
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6176
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6177
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6178
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6179
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6180
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6181
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6182
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6183
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6184
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6185
|
+
}
|
|
6186
|
+
|
|
6187
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6188
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6189
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6190
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6191
|
+
}
|
|
6192
|
+
}
|
|
6193
|
+
|
|
6113
6194
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6114
6195
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6115
6196
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6369,6 +6450,18 @@
|
|
|
6369
6450
|
}
|
|
6370
6451
|
}
|
|
6371
6452
|
|
|
6453
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6454
|
+
const { dataDescriptor } = localDirectory;
|
|
6455
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6456
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6457
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6458
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6459
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6460
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6461
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6462
|
+
}
|
|
6463
|
+
}
|
|
6464
|
+
|
|
6372
6465
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6373
6466
|
if (reject) {
|
|
6374
6467
|
throwAmbiguousArchive(reason);
|
|
@@ -6471,6 +6564,7 @@
|
|
|
6471
6564
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6472
6565
|
ZipReader: ZipReader,
|
|
6473
6566
|
ZipReaderStream: ZipReaderStream,
|
|
6567
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6474
6568
|
isZipFile: isZipFile
|
|
6475
6569
|
});
|
|
6476
6570
|
|
|
@@ -6594,136 +6688,7 @@
|
|
|
6594
6688
|
}
|
|
6595
6689
|
|
|
6596
6690
|
appendZip(reader, options = {}) {
|
|
6597
|
-
return watchPromiseError(this,
|
|
6598
|
-
}
|
|
6599
|
-
|
|
6600
|
-
async appendZipEntries(reader, options = {}) {
|
|
6601
|
-
const zipWriter = this;
|
|
6602
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6603
|
-
const filter = checkFunctionOption(options.filter);
|
|
6604
|
-
while (pendingAddFileCalls.size) {
|
|
6605
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6606
|
-
}
|
|
6607
|
-
let resolveAppendZip;
|
|
6608
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6609
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6610
|
-
const appendedFilenames = [];
|
|
6611
|
-
let releaseLockWriter;
|
|
6612
|
-
try {
|
|
6613
|
-
reader = new GenericReader(reader);
|
|
6614
|
-
await initStream(reader);
|
|
6615
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6616
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6617
|
-
await initStream(reader);
|
|
6618
|
-
}
|
|
6619
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6620
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6621
|
-
const entries = await zipReader$1.getEntries();
|
|
6622
|
-
const keptEntries = [];
|
|
6623
|
-
for (const entry of entries) {
|
|
6624
|
-
if (!filter || await filter(entry)) {
|
|
6625
|
-
keptEntries.push(entry);
|
|
6626
|
-
}
|
|
6627
|
-
}
|
|
6628
|
-
await zipReader$1.close();
|
|
6629
|
-
await initStream(zipWriter.writer);
|
|
6630
|
-
const { directoryOffset } = zipReader$1;
|
|
6631
|
-
keptEntries.forEach(({ filename }) => {
|
|
6632
|
-
if (filenames.has(filename)) {
|
|
6633
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6634
|
-
}
|
|
6635
|
-
filenames.add(filename);
|
|
6636
|
-
appendedFilenames.push(filename);
|
|
6637
|
-
});
|
|
6638
|
-
zipWriter.writerLocked = true;
|
|
6639
|
-
const { lockWriter } = zipWriter;
|
|
6640
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6641
|
-
zipWriter.writerLocked = false;
|
|
6642
|
-
resolve();
|
|
6643
|
-
});
|
|
6644
|
-
await lockWriter;
|
|
6645
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6646
|
-
delete zipWriter.addSplitZipSignature;
|
|
6647
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6648
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6649
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6650
|
-
}
|
|
6651
|
-
}
|
|
6652
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6653
|
-
keptEntries.forEach(entry => {
|
|
6654
|
-
const {
|
|
6655
|
-
version,
|
|
6656
|
-
rawLastModDate,
|
|
6657
|
-
rawFilename,
|
|
6658
|
-
bitFlag,
|
|
6659
|
-
encrypted,
|
|
6660
|
-
uncompressedSize,
|
|
6661
|
-
compressedSize,
|
|
6662
|
-
extraFieldZip64
|
|
6663
|
-
} = entry;
|
|
6664
|
-
let {
|
|
6665
|
-
compressionMethod,
|
|
6666
|
-
rawExtraField,
|
|
6667
|
-
} = entry;
|
|
6668
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6669
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6670
|
-
if (entry.extraFieldAES) {
|
|
6671
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6672
|
-
}
|
|
6673
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6674
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6675
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6676
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6677
|
-
const {
|
|
6678
|
-
headerArray,
|
|
6679
|
-
headerView
|
|
6680
|
-
} = getHeaderArrayData({
|
|
6681
|
-
version,
|
|
6682
|
-
bitFlag: bitFlagValue,
|
|
6683
|
-
compressionMethod,
|
|
6684
|
-
uncompressedSize,
|
|
6685
|
-
compressedSize,
|
|
6686
|
-
rawLastModDate,
|
|
6687
|
-
rawFilename,
|
|
6688
|
-
zip64CompressedSize,
|
|
6689
|
-
zip64UncompressedSize,
|
|
6690
|
-
extraFieldLength
|
|
6691
|
-
});
|
|
6692
|
-
const { crc32 } = entry;
|
|
6693
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6694
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6695
|
-
}
|
|
6696
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6697
|
-
Object.assign(entry, {
|
|
6698
|
-
zip64Enabled: true,
|
|
6699
|
-
zip64UncompressedSize,
|
|
6700
|
-
zip64CompressedSize,
|
|
6701
|
-
offset,
|
|
6702
|
-
diskNumberStart,
|
|
6703
|
-
zip64DiskNumberStart: false,
|
|
6704
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6705
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6706
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6707
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6708
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6709
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6710
|
-
rawExtraField,
|
|
6711
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6712
|
-
headerArray,
|
|
6713
|
-
headerView
|
|
6714
|
-
});
|
|
6715
|
-
fileEntries.set(entry.filename, entry);
|
|
6716
|
-
});
|
|
6717
|
-
} catch (error) {
|
|
6718
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6719
|
-
throw error;
|
|
6720
|
-
} finally {
|
|
6721
|
-
resolveAppendZip();
|
|
6722
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6723
|
-
if (releaseLockWriter) {
|
|
6724
|
-
releaseLockWriter();
|
|
6725
|
-
}
|
|
6726
|
-
}
|
|
6691
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6727
6692
|
}
|
|
6728
6693
|
|
|
6729
6694
|
add(name = "", reader, options = {}) {
|
|
@@ -6885,11 +6850,149 @@
|
|
|
6885
6850
|
return watchedPromise;
|
|
6886
6851
|
}
|
|
6887
6852
|
|
|
6853
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6854
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6855
|
+
const filter = checkFunctionOption(options.filter);
|
|
6856
|
+
const readerOptions = checkReaderOptionsObject(options.readerOptions);
|
|
6857
|
+
while (pendingAddFileCalls.size) {
|
|
6858
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6859
|
+
}
|
|
6860
|
+
let resolveAppendZip;
|
|
6861
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6862
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6863
|
+
const appendedFilenames = [];
|
|
6864
|
+
let releaseLockWriter;
|
|
6865
|
+
try {
|
|
6866
|
+
reader = new GenericReader(reader);
|
|
6867
|
+
await initStream(reader);
|
|
6868
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6869
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6870
|
+
await initStream(reader);
|
|
6871
|
+
}
|
|
6872
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6873
|
+
const zipReader$1 = new ZipReader(reader, readerOptions);
|
|
6874
|
+
const keptEntries = [];
|
|
6875
|
+
let entries;
|
|
6876
|
+
try {
|
|
6877
|
+
entries = await zipReader$1.getEntries();
|
|
6878
|
+
for (const entry of entries) {
|
|
6879
|
+
if (!filter || await filter(entry, getExistingEntry(fileEntries, entry.filename))) {
|
|
6880
|
+
keptEntries.push(entry);
|
|
6881
|
+
}
|
|
6882
|
+
}
|
|
6883
|
+
} finally {
|
|
6884
|
+
await zipReader$1.close();
|
|
6885
|
+
}
|
|
6886
|
+
await initStream(zipWriter.writer);
|
|
6887
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6888
|
+
keptEntries.forEach(entry => {
|
|
6889
|
+
const { filename } = entry;
|
|
6890
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6891
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6892
|
+
}
|
|
6893
|
+
if (filenames.has(filename)) {
|
|
6894
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6895
|
+
}
|
|
6896
|
+
filenames.add(filename);
|
|
6897
|
+
appendedFilenames.push(filename);
|
|
6898
|
+
});
|
|
6899
|
+
zipWriter.writerLocked = true;
|
|
6900
|
+
const { lockWriter } = zipWriter;
|
|
6901
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6902
|
+
zipWriter.writerLocked = false;
|
|
6903
|
+
resolve();
|
|
6904
|
+
});
|
|
6905
|
+
await lockWriter;
|
|
6906
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6907
|
+
delete zipWriter.addSplitZipSignature;
|
|
6908
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6909
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6910
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6911
|
+
}
|
|
6912
|
+
}
|
|
6913
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6914
|
+
keptEntries.forEach(entry => {
|
|
6915
|
+
const {
|
|
6916
|
+
version,
|
|
6917
|
+
rawLastModDate,
|
|
6918
|
+
rawFilename,
|
|
6919
|
+
rawBitFlag,
|
|
6920
|
+
uncompressedSize,
|
|
6921
|
+
compressedSize,
|
|
6922
|
+
extraFieldZip64
|
|
6923
|
+
} = entry;
|
|
6924
|
+
let {
|
|
6925
|
+
compressionMethod,
|
|
6926
|
+
rawExtraField,
|
|
6927
|
+
} = entry;
|
|
6928
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6929
|
+
if (entry.extraFieldAES) {
|
|
6930
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6931
|
+
}
|
|
6932
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6933
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6934
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6935
|
+
const {
|
|
6936
|
+
headerArray,
|
|
6937
|
+
headerView
|
|
6938
|
+
} = getHeaderArrayData({
|
|
6939
|
+
version,
|
|
6940
|
+
bitFlag: rawBitFlag,
|
|
6941
|
+
compressionMethod,
|
|
6942
|
+
uncompressedSize,
|
|
6943
|
+
compressedSize,
|
|
6944
|
+
rawLastModDate,
|
|
6945
|
+
rawFilename,
|
|
6946
|
+
zip64CompressedSize,
|
|
6947
|
+
zip64UncompressedSize,
|
|
6948
|
+
extraFieldLength
|
|
6949
|
+
});
|
|
6950
|
+
const { crc32 } = entry;
|
|
6951
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6952
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6953
|
+
}
|
|
6954
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6955
|
+
fileEntries.set(entry.filename, Object.assign({}, entry, {
|
|
6956
|
+
zip64Enabled: true,
|
|
6957
|
+
zip64UncompressedSize,
|
|
6958
|
+
zip64CompressedSize,
|
|
6959
|
+
offset,
|
|
6960
|
+
diskNumberStart,
|
|
6961
|
+
zip64DiskNumberStart: false,
|
|
6962
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6963
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6964
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6965
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6966
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6967
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6968
|
+
rawExtraField,
|
|
6969
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6970
|
+
headerArray,
|
|
6971
|
+
headerView
|
|
6972
|
+
}));
|
|
6973
|
+
});
|
|
6974
|
+
} catch (error) {
|
|
6975
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6976
|
+
throw error;
|
|
6977
|
+
} finally {
|
|
6978
|
+
resolveAppendZip();
|
|
6979
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6980
|
+
if (releaseLockWriter) {
|
|
6981
|
+
releaseLockWriter();
|
|
6982
|
+
}
|
|
6983
|
+
}
|
|
6984
|
+
}
|
|
6985
|
+
|
|
6986
|
+
function getExistingEntry(fileEntries, filename) {
|
|
6987
|
+
const fileEntry = fileEntries.get(filename);
|
|
6988
|
+
return fileEntry ? new Entry(fileEntry) : UNDEFINED_VALUE;
|
|
6989
|
+
}
|
|
6990
|
+
|
|
6888
6991
|
async function prependZipEntries(zipWriter, reader) {
|
|
6889
6992
|
if (zipWriter.filenames.size) {
|
|
6890
6993
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6891
6994
|
}
|
|
6892
|
-
await
|
|
6995
|
+
await appendZipEntries(zipWriter, reader);
|
|
6893
6996
|
}
|
|
6894
6997
|
|
|
6895
6998
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8563,7 +8666,7 @@
|
|
|
8563
8666
|
return rawExtraField;
|
|
8564
8667
|
}
|
|
8565
8668
|
|
|
8566
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8669
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8567
8670
|
const { writer } = zipWriter;
|
|
8568
8671
|
const entryPositions = new Map();
|
|
8569
8672
|
if (writer.closeDisk || compact) {
|
|
@@ -8571,6 +8674,27 @@
|
|
|
8571
8674
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8572
8675
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8573
8676
|
const keptEntrySet = new Set(keptEntries);
|
|
8677
|
+
const localHeaderLengths = new Map();
|
|
8678
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8679
|
+
const entry = sortedEntries[indexEntry];
|
|
8680
|
+
if (keptEntrySet.has(entry)) {
|
|
8681
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8682
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8683
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8684
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8685
|
+
}
|
|
8686
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8687
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8688
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8689
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8690
|
+
}
|
|
8691
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8692
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8693
|
+
}
|
|
8694
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8695
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8696
|
+
}
|
|
8697
|
+
}
|
|
8574
8698
|
let copiedOffset = 0;
|
|
8575
8699
|
let lastPosition;
|
|
8576
8700
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8583,7 +8707,7 @@
|
|
|
8583
8707
|
if (!compact) {
|
|
8584
8708
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8585
8709
|
}
|
|
8586
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8710
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8587
8711
|
await writer.closeDisk();
|
|
8588
8712
|
}
|
|
8589
8713
|
lastPosition = {
|
|
@@ -8617,7 +8741,7 @@
|
|
|
8617
8741
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8618
8742
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8619
8743
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8620
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8744
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8621
8745
|
}
|
|
8622
8746
|
regionEnds[indexEntry] = regionEnd;
|
|
8623
8747
|
}
|
|
@@ -8631,11 +8755,13 @@
|
|
|
8631
8755
|
try {
|
|
8632
8756
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8633
8757
|
} catch (error) {
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8758
|
+
if (copiedLength) {
|
|
8759
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8760
|
+
try {
|
|
8761
|
+
error.corruptedEntry = true;
|
|
8762
|
+
} catch {
|
|
8763
|
+
// ignored
|
|
8764
|
+
}
|
|
8639
8765
|
}
|
|
8640
8766
|
throw error;
|
|
8641
8767
|
} finally {
|
|
@@ -8646,11 +8772,16 @@
|
|
|
8646
8772
|
}
|
|
8647
8773
|
|
|
8648
8774
|
async function getLocalHeaderLength(reader, offset) {
|
|
8649
|
-
const headerArray =
|
|
8775
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8776
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8777
|
+
EMPTY_UINT8_ARRAY;
|
|
8650
8778
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8651
|
-
return
|
|
8779
|
+
return UNDEFINED_VALUE;
|
|
8652
8780
|
}
|
|
8653
8781
|
const headerView = getDataView(headerArray);
|
|
8782
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8783
|
+
return UNDEFINED_VALUE;
|
|
8784
|
+
}
|
|
8654
8785
|
return HEADER_SIZE +
|
|
8655
8786
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8656
8787
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9001,7 +9132,7 @@
|
|
|
9001
9132
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9002
9133
|
*/
|
|
9003
9134
|
|
|
9004
|
-
const VERSION = "2.
|
|
9135
|
+
const VERSION = "2.22.0";
|
|
9005
9136
|
|
|
9006
9137
|
/*
|
|
9007
9138
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9530,6 +9661,7 @@
|
|
|
9530
9661
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
9531
9662
|
exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
|
|
9532
9663
|
exports.ERR_INVALID_READER = ERR_INVALID_READER;
|
|
9664
|
+
exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
|
|
9533
9665
|
exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
|
|
9534
9666
|
exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
|
|
9535
9667
|
exports.ERR_INVALID_STRICTNESS = ERR_INVALID_STRICTNESS;
|