@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.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",
|
|
@@ -4765,12 +4775,9 @@
|
|
|
4765
4775
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4766
4776
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4767
4777
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4768
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4769
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4770
4778
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4771
4779
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4772
4780
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4773
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4774
4781
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4775
4782
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4776
4783
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4834,8 +4841,9 @@
|
|
|
4834
4841
|
constructor(reader, options = {}) {
|
|
4835
4842
|
Object.assign(this, {
|
|
4836
4843
|
reader: new GenericReader(reader),
|
|
4837
|
-
options,
|
|
4838
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4844
|
+
options: options || {},
|
|
4845
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4846
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4839
4847
|
});
|
|
4840
4848
|
}
|
|
4841
4849
|
|
|
@@ -4906,16 +4914,22 @@
|
|
|
4906
4914
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4907
4915
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4908
4916
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4917
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4918
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4919
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4920
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4921
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4922
|
+
}
|
|
4923
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4924
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4925
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4926
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4927
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4928
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4929
|
+
}
|
|
4930
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4931
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4916
4932
|
}
|
|
4917
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4918
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4919
4933
|
}
|
|
4920
4934
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4921
4935
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4960,10 +4974,6 @@
|
|
|
4960
4974
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4961
4975
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4962
4976
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4963
|
-
if (directoryDataOffset >= reader.size) {
|
|
4964
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4965
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4966
|
-
}
|
|
4967
4977
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4968
4978
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4969
4979
|
}
|
|
@@ -4971,52 +4981,64 @@
|
|
|
4971
4981
|
throw new Error(ERR_BAD_FORMAT);
|
|
4972
4982
|
}
|
|
4973
4983
|
let offset = 0;
|
|
4974
|
-
let directoryArray =
|
|
4984
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4985
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4986
|
+
EMPTY_UINT8_ARRAY;
|
|
4975
4987
|
let directoryView = getDataView(directoryArray);
|
|
4976
4988
|
if (directoryDataLength) {
|
|
4977
|
-
if (directoryArray.length < 4) {
|
|
4978
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4979
|
-
}
|
|
4980
4989
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4981
4990
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4982
|
-
const storedPointsAtDirectory =
|
|
4991
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
4992
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4983
4993
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4984
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
4994
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
4995
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
4996
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
4997
|
+
}
|
|
4985
4998
|
let reconcile = !storedPointsAtDirectory;
|
|
4986
4999
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4987
|
-
|
|
4988
|
-
if (
|
|
4989
|
-
reconcile = expectedPointsAtDirectory;
|
|
4990
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5000
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5001
|
+
if (!expectedPointsAtDirectory) {
|
|
4991
5002
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
4992
5003
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
4993
5004
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
4994
5005
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
4995
5006
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5007
|
+
expectedPointsAtDirectory = true;
|
|
4996
5008
|
}
|
|
4997
5009
|
}
|
|
5010
|
+
if (storedPointsAtDirectory) {
|
|
5011
|
+
reconcile = expectedPointsAtDirectory;
|
|
5012
|
+
}
|
|
4998
5013
|
}
|
|
4999
|
-
if (reconcile) {
|
|
5014
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5000
5015
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5001
5016
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5002
5017
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5003
5018
|
directoryView = getDataView(directoryArray);
|
|
5004
|
-
|
|
5005
|
-
|
|
5019
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5020
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5021
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5022
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5023
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5024
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5025
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5026
|
+
prependedDataLength += offsetDelta;
|
|
5006
5027
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5007
5028
|
} else {
|
|
5008
5029
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5012
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5013
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5014
|
-
prependedDataLength += offsetDelta;
|
|
5015
|
-
}
|
|
5030
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5031
|
+
prependedDataLength += offsetDelta;
|
|
5016
5032
|
}
|
|
5017
5033
|
}
|
|
5018
5034
|
}
|
|
5019
5035
|
}
|
|
5036
|
+
if (directoryArray.length < 4) {
|
|
5037
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5038
|
+
}
|
|
5039
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5040
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5041
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5020
5042
|
}
|
|
5021
5043
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5022
5044
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5058,8 +5080,10 @@
|
|
|
5058
5080
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5059
5081
|
}
|
|
5060
5082
|
}
|
|
5083
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5084
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5061
5085
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5062
|
-
const fileEntry = new ZipEntry(reader,
|
|
5086
|
+
const fileEntry = new ZipEntry(reader, entryOptions);
|
|
5063
5087
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5064
5088
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5065
5089
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5150,13 +5174,17 @@
|
|
|
5150
5174
|
if (malformedExtraField) {
|
|
5151
5175
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5152
5176
|
}
|
|
5153
|
-
fileEntry.offset
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5177
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5178
|
+
startOffset = 0;
|
|
5179
|
+
} else {
|
|
5180
|
+
fileEntry.offset += prependedDataLength;
|
|
5181
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5182
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5183
|
+
if (entryPosition < previousEntryPosition) {
|
|
5184
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5185
|
+
}
|
|
5186
|
+
previousEntryPosition = entryPosition;
|
|
5158
5187
|
}
|
|
5159
|
-
previousEntryPosition = entryPosition;
|
|
5160
5188
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5161
5189
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5162
5190
|
}
|
|
@@ -5193,12 +5221,15 @@
|
|
|
5193
5221
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5194
5222
|
});
|
|
5195
5223
|
const entry = new Entry(fileEntry);
|
|
5196
|
-
|
|
5224
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5225
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5226
|
+
}
|
|
5227
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5197
5228
|
entry.arrayBuffer = async options => {
|
|
5198
5229
|
const writer = new TransformStream();
|
|
5199
5230
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5200
5231
|
arrayBufferPromise.catch(() => { });
|
|
5201
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5232
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5202
5233
|
Object.assign({}, options, { preventClose: false }));
|
|
5203
5234
|
return arrayBufferPromise;
|
|
5204
5235
|
};
|
|
@@ -5406,8 +5437,9 @@
|
|
|
5406
5437
|
});
|
|
5407
5438
|
}
|
|
5408
5439
|
|
|
5409
|
-
async getData(writer, fileEntry,
|
|
5440
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5410
5441
|
const zipEntry = this;
|
|
5442
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5411
5443
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5412
5444
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5413
5445
|
}
|
|
@@ -5481,10 +5513,10 @@
|
|
|
5481
5513
|
}
|
|
5482
5514
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5483
5515
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5484
|
-
if (lastAccessDate) {
|
|
5516
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5485
5517
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5486
5518
|
}
|
|
5487
|
-
if (creationDate) {
|
|
5519
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5488
5520
|
fileEntry.creationDate = creationDate;
|
|
5489
5521
|
}
|
|
5490
5522
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5513,7 +5545,7 @@
|
|
|
5513
5545
|
throw new Error(ERR_ENCRYPTED);
|
|
5514
5546
|
}
|
|
5515
5547
|
}
|
|
5516
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5548
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5517
5549
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5518
5550
|
}
|
|
5519
5551
|
const size = compressedSize;
|
|
@@ -5579,6 +5611,7 @@
|
|
|
5579
5611
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5580
5612
|
readRanges
|
|
5581
5613
|
});
|
|
5614
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5582
5615
|
}
|
|
5583
5616
|
let writable, abortError, aborted;
|
|
5584
5617
|
try {
|
|
@@ -5598,10 +5631,7 @@
|
|
|
5598
5631
|
writer.size += writtenSize;
|
|
5599
5632
|
}
|
|
5600
5633
|
} catch (error) {
|
|
5601
|
-
|
|
5602
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5603
|
-
writer.size += failedOutputSize;
|
|
5604
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5634
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5605
5635
|
writer.size += error.outputSize;
|
|
5606
5636
|
}
|
|
5607
5637
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5629,13 +5659,7 @@
|
|
|
5629
5659
|
}
|
|
5630
5660
|
|
|
5631
5661
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5632
|
-
|
|
5633
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5634
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5635
|
-
return true;
|
|
5636
|
-
}
|
|
5637
|
-
}
|
|
5638
|
-
return false;
|
|
5662
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5639
5663
|
}
|
|
5640
5664
|
|
|
5641
5665
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5672,6 +5696,46 @@
|
|
|
5672
5696
|
}
|
|
5673
5697
|
}
|
|
5674
5698
|
|
|
5699
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5700
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5701
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5702
|
+
const tailView = getDataView(tailArray);
|
|
5703
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5704
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5705
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5706
|
+
return startOffset + indexByte;
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
|
|
5711
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5712
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5713
|
+
return UNDEFINED_VALUE;
|
|
5714
|
+
}
|
|
5715
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5716
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5717
|
+
return localHeaderOffset;
|
|
5718
|
+
}
|
|
5719
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5720
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5721
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5722
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5723
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5724
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5725
|
+
let offsetValue = offsetExtraField + 4;
|
|
5726
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5727
|
+
offsetValue += 8;
|
|
5728
|
+
}
|
|
5729
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5730
|
+
offsetValue += 8;
|
|
5731
|
+
}
|
|
5732
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5733
|
+
}
|
|
5734
|
+
offsetExtraField += 4 + size;
|
|
5735
|
+
}
|
|
5736
|
+
return UNDEFINED_VALUE;
|
|
5737
|
+
}
|
|
5738
|
+
|
|
5675
5739
|
function readDigitalSignature(signatureRecordArray) {
|
|
5676
5740
|
if (signatureRecordArray.length >= 6) {
|
|
5677
5741
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5761,6 +5825,7 @@
|
|
|
5761
5825
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5762
5826
|
});
|
|
5763
5827
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5828
|
+
let extraFieldZip64Missing;
|
|
5764
5829
|
if (extraFieldZip64) {
|
|
5765
5830
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5766
5831
|
malformedExtraField = true;
|
|
@@ -5770,7 +5835,7 @@
|
|
|
5770
5835
|
if (localDirectory) {
|
|
5771
5836
|
malformedExtraField = true;
|
|
5772
5837
|
} else {
|
|
5773
|
-
|
|
5838
|
+
extraFieldZip64Missing = true;
|
|
5774
5839
|
}
|
|
5775
5840
|
}
|
|
5776
5841
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5828,6 +5893,9 @@
|
|
|
5828
5893
|
if (extraFieldUSDZ) {
|
|
5829
5894
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5830
5895
|
}
|
|
5896
|
+
if (extraFieldZip64Missing) {
|
|
5897
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5898
|
+
}
|
|
5831
5899
|
return malformedExtraField;
|
|
5832
5900
|
}
|
|
5833
5901
|
|
|
@@ -6042,13 +6110,7 @@
|
|
|
6042
6110
|
let dataDescriptorLength = 0;
|
|
6043
6111
|
if (dataDescriptor) {
|
|
6044
6112
|
const zip64 = Boolean(extraFieldZip64);
|
|
6045
|
-
const
|
|
6046
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6047
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6048
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6049
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6050
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6051
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6113
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6052
6114
|
if (localDataDescriptor) {
|
|
6053
6115
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6054
6116
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6118,6 +6180,25 @@
|
|
|
6118
6180
|
return mergedRanges;
|
|
6119
6181
|
}
|
|
6120
6182
|
|
|
6183
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6184
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6185
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6186
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6187
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6188
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6189
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6190
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6191
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6192
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6193
|
+
}
|
|
6194
|
+
|
|
6195
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6196
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6197
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6198
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6199
|
+
}
|
|
6200
|
+
}
|
|
6201
|
+
|
|
6121
6202
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6122
6203
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6123
6204
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6377,6 +6458,18 @@
|
|
|
6377
6458
|
}
|
|
6378
6459
|
}
|
|
6379
6460
|
|
|
6461
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6462
|
+
const { dataDescriptor } = localDirectory;
|
|
6463
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6464
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6465
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6466
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6467
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6468
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6469
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6470
|
+
}
|
|
6471
|
+
}
|
|
6472
|
+
|
|
6380
6473
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6381
6474
|
if (reject) {
|
|
6382
6475
|
throwAmbiguousArchive(reason);
|
|
@@ -6479,6 +6572,7 @@
|
|
|
6479
6572
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6480
6573
|
ZipReader: ZipReader,
|
|
6481
6574
|
ZipReaderStream: ZipReaderStream,
|
|
6575
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6482
6576
|
isZipFile: isZipFile
|
|
6483
6577
|
});
|
|
6484
6578
|
|
|
@@ -6602,136 +6696,7 @@
|
|
|
6602
6696
|
}
|
|
6603
6697
|
|
|
6604
6698
|
appendZip(reader, options = {}) {
|
|
6605
|
-
return watchPromiseError(this,
|
|
6606
|
-
}
|
|
6607
|
-
|
|
6608
|
-
async appendZipEntries(reader, options = {}) {
|
|
6609
|
-
const zipWriter = this;
|
|
6610
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6611
|
-
const filter = checkFunctionOption(options.filter);
|
|
6612
|
-
while (pendingAddFileCalls.size) {
|
|
6613
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6614
|
-
}
|
|
6615
|
-
let resolveAppendZip;
|
|
6616
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6617
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6618
|
-
const appendedFilenames = [];
|
|
6619
|
-
let releaseLockWriter;
|
|
6620
|
-
try {
|
|
6621
|
-
reader = new GenericReader(reader);
|
|
6622
|
-
await initStream(reader);
|
|
6623
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6624
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6625
|
-
await initStream(reader);
|
|
6626
|
-
}
|
|
6627
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6628
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6629
|
-
const entries = await zipReader$1.getEntries();
|
|
6630
|
-
const keptEntries = [];
|
|
6631
|
-
for (const entry of entries) {
|
|
6632
|
-
if (!filter || await filter(entry)) {
|
|
6633
|
-
keptEntries.push(entry);
|
|
6634
|
-
}
|
|
6635
|
-
}
|
|
6636
|
-
await zipReader$1.close();
|
|
6637
|
-
await initStream(zipWriter.writer);
|
|
6638
|
-
const { directoryOffset } = zipReader$1;
|
|
6639
|
-
keptEntries.forEach(({ filename }) => {
|
|
6640
|
-
if (filenames.has(filename)) {
|
|
6641
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6642
|
-
}
|
|
6643
|
-
filenames.add(filename);
|
|
6644
|
-
appendedFilenames.push(filename);
|
|
6645
|
-
});
|
|
6646
|
-
zipWriter.writerLocked = true;
|
|
6647
|
-
const { lockWriter } = zipWriter;
|
|
6648
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6649
|
-
zipWriter.writerLocked = false;
|
|
6650
|
-
resolve();
|
|
6651
|
-
});
|
|
6652
|
-
await lockWriter;
|
|
6653
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6654
|
-
delete zipWriter.addSplitZipSignature;
|
|
6655
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6656
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6657
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6658
|
-
}
|
|
6659
|
-
}
|
|
6660
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6661
|
-
keptEntries.forEach(entry => {
|
|
6662
|
-
const {
|
|
6663
|
-
version,
|
|
6664
|
-
rawLastModDate,
|
|
6665
|
-
rawFilename,
|
|
6666
|
-
bitFlag,
|
|
6667
|
-
encrypted,
|
|
6668
|
-
uncompressedSize,
|
|
6669
|
-
compressedSize,
|
|
6670
|
-
extraFieldZip64
|
|
6671
|
-
} = entry;
|
|
6672
|
-
let {
|
|
6673
|
-
compressionMethod,
|
|
6674
|
-
rawExtraField,
|
|
6675
|
-
} = entry;
|
|
6676
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6677
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6678
|
-
if (entry.extraFieldAES) {
|
|
6679
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6680
|
-
}
|
|
6681
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6682
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6683
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6684
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6685
|
-
const {
|
|
6686
|
-
headerArray,
|
|
6687
|
-
headerView
|
|
6688
|
-
} = getHeaderArrayData({
|
|
6689
|
-
version,
|
|
6690
|
-
bitFlag: bitFlagValue,
|
|
6691
|
-
compressionMethod,
|
|
6692
|
-
uncompressedSize,
|
|
6693
|
-
compressedSize,
|
|
6694
|
-
rawLastModDate,
|
|
6695
|
-
rawFilename,
|
|
6696
|
-
zip64CompressedSize,
|
|
6697
|
-
zip64UncompressedSize,
|
|
6698
|
-
extraFieldLength
|
|
6699
|
-
});
|
|
6700
|
-
const { crc32 } = entry;
|
|
6701
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6702
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6703
|
-
}
|
|
6704
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6705
|
-
Object.assign(entry, {
|
|
6706
|
-
zip64Enabled: true,
|
|
6707
|
-
zip64UncompressedSize,
|
|
6708
|
-
zip64CompressedSize,
|
|
6709
|
-
offset,
|
|
6710
|
-
diskNumberStart,
|
|
6711
|
-
zip64DiskNumberStart: false,
|
|
6712
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6713
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6714
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6715
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6716
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6717
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6718
|
-
rawExtraField,
|
|
6719
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6720
|
-
headerArray,
|
|
6721
|
-
headerView
|
|
6722
|
-
});
|
|
6723
|
-
fileEntries.set(entry.filename, entry);
|
|
6724
|
-
});
|
|
6725
|
-
} catch (error) {
|
|
6726
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6727
|
-
throw error;
|
|
6728
|
-
} finally {
|
|
6729
|
-
resolveAppendZip();
|
|
6730
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6731
|
-
if (releaseLockWriter) {
|
|
6732
|
-
releaseLockWriter();
|
|
6733
|
-
}
|
|
6734
|
-
}
|
|
6699
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6735
6700
|
}
|
|
6736
6701
|
|
|
6737
6702
|
add(name = "", reader, options = {}) {
|
|
@@ -6893,11 +6858,149 @@
|
|
|
6893
6858
|
return watchedPromise;
|
|
6894
6859
|
}
|
|
6895
6860
|
|
|
6861
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6862
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6863
|
+
const filter = checkFunctionOption(options.filter);
|
|
6864
|
+
const readerOptions = checkReaderOptionsObject(options.readerOptions);
|
|
6865
|
+
while (pendingAddFileCalls.size) {
|
|
6866
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6867
|
+
}
|
|
6868
|
+
let resolveAppendZip;
|
|
6869
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6870
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6871
|
+
const appendedFilenames = [];
|
|
6872
|
+
let releaseLockWriter;
|
|
6873
|
+
try {
|
|
6874
|
+
reader = new GenericReader(reader);
|
|
6875
|
+
await initStream(reader);
|
|
6876
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6877
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6878
|
+
await initStream(reader);
|
|
6879
|
+
}
|
|
6880
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6881
|
+
const zipReader$1 = new ZipReader(reader, readerOptions);
|
|
6882
|
+
const keptEntries = [];
|
|
6883
|
+
let entries;
|
|
6884
|
+
try {
|
|
6885
|
+
entries = await zipReader$1.getEntries();
|
|
6886
|
+
for (const entry of entries) {
|
|
6887
|
+
if (!filter || await filter(entry, getExistingEntry(fileEntries, entry.filename))) {
|
|
6888
|
+
keptEntries.push(entry);
|
|
6889
|
+
}
|
|
6890
|
+
}
|
|
6891
|
+
} finally {
|
|
6892
|
+
await zipReader$1.close();
|
|
6893
|
+
}
|
|
6894
|
+
await initStream(zipWriter.writer);
|
|
6895
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6896
|
+
keptEntries.forEach(entry => {
|
|
6897
|
+
const { filename } = entry;
|
|
6898
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6899
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6900
|
+
}
|
|
6901
|
+
if (filenames.has(filename)) {
|
|
6902
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6903
|
+
}
|
|
6904
|
+
filenames.add(filename);
|
|
6905
|
+
appendedFilenames.push(filename);
|
|
6906
|
+
});
|
|
6907
|
+
zipWriter.writerLocked = true;
|
|
6908
|
+
const { lockWriter } = zipWriter;
|
|
6909
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6910
|
+
zipWriter.writerLocked = false;
|
|
6911
|
+
resolve();
|
|
6912
|
+
});
|
|
6913
|
+
await lockWriter;
|
|
6914
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6915
|
+
delete zipWriter.addSplitZipSignature;
|
|
6916
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6917
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6918
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6919
|
+
}
|
|
6920
|
+
}
|
|
6921
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6922
|
+
keptEntries.forEach(entry => {
|
|
6923
|
+
const {
|
|
6924
|
+
version,
|
|
6925
|
+
rawLastModDate,
|
|
6926
|
+
rawFilename,
|
|
6927
|
+
rawBitFlag,
|
|
6928
|
+
uncompressedSize,
|
|
6929
|
+
compressedSize,
|
|
6930
|
+
extraFieldZip64
|
|
6931
|
+
} = entry;
|
|
6932
|
+
let {
|
|
6933
|
+
compressionMethod,
|
|
6934
|
+
rawExtraField,
|
|
6935
|
+
} = entry;
|
|
6936
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6937
|
+
if (entry.extraFieldAES) {
|
|
6938
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6939
|
+
}
|
|
6940
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6941
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6942
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6943
|
+
const {
|
|
6944
|
+
headerArray,
|
|
6945
|
+
headerView
|
|
6946
|
+
} = getHeaderArrayData({
|
|
6947
|
+
version,
|
|
6948
|
+
bitFlag: rawBitFlag,
|
|
6949
|
+
compressionMethod,
|
|
6950
|
+
uncompressedSize,
|
|
6951
|
+
compressedSize,
|
|
6952
|
+
rawLastModDate,
|
|
6953
|
+
rawFilename,
|
|
6954
|
+
zip64CompressedSize,
|
|
6955
|
+
zip64UncompressedSize,
|
|
6956
|
+
extraFieldLength
|
|
6957
|
+
});
|
|
6958
|
+
const { crc32 } = entry;
|
|
6959
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6960
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6961
|
+
}
|
|
6962
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6963
|
+
fileEntries.set(entry.filename, Object.assign({}, entry, {
|
|
6964
|
+
zip64Enabled: true,
|
|
6965
|
+
zip64UncompressedSize,
|
|
6966
|
+
zip64CompressedSize,
|
|
6967
|
+
offset,
|
|
6968
|
+
diskNumberStart,
|
|
6969
|
+
zip64DiskNumberStart: false,
|
|
6970
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6971
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6972
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6973
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6974
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6975
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6976
|
+
rawExtraField,
|
|
6977
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6978
|
+
headerArray,
|
|
6979
|
+
headerView
|
|
6980
|
+
}));
|
|
6981
|
+
});
|
|
6982
|
+
} catch (error) {
|
|
6983
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6984
|
+
throw error;
|
|
6985
|
+
} finally {
|
|
6986
|
+
resolveAppendZip();
|
|
6987
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6988
|
+
if (releaseLockWriter) {
|
|
6989
|
+
releaseLockWriter();
|
|
6990
|
+
}
|
|
6991
|
+
}
|
|
6992
|
+
}
|
|
6993
|
+
|
|
6994
|
+
function getExistingEntry(fileEntries, filename) {
|
|
6995
|
+
const fileEntry = fileEntries.get(filename);
|
|
6996
|
+
return fileEntry ? new Entry(fileEntry) : UNDEFINED_VALUE;
|
|
6997
|
+
}
|
|
6998
|
+
|
|
6896
6999
|
async function prependZipEntries(zipWriter, reader) {
|
|
6897
7000
|
if (zipWriter.filenames.size) {
|
|
6898
7001
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6899
7002
|
}
|
|
6900
|
-
await
|
|
7003
|
+
await appendZipEntries(zipWriter, reader);
|
|
6901
7004
|
}
|
|
6902
7005
|
|
|
6903
7006
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8571,7 +8674,7 @@
|
|
|
8571
8674
|
return rawExtraField;
|
|
8572
8675
|
}
|
|
8573
8676
|
|
|
8574
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8677
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8575
8678
|
const { writer } = zipWriter;
|
|
8576
8679
|
const entryPositions = new Map();
|
|
8577
8680
|
if (writer.closeDisk || compact) {
|
|
@@ -8579,6 +8682,27 @@
|
|
|
8579
8682
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8580
8683
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8581
8684
|
const keptEntrySet = new Set(keptEntries);
|
|
8685
|
+
const localHeaderLengths = new Map();
|
|
8686
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8687
|
+
const entry = sortedEntries[indexEntry];
|
|
8688
|
+
if (keptEntrySet.has(entry)) {
|
|
8689
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8690
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8691
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8692
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8693
|
+
}
|
|
8694
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8695
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8696
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8697
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8698
|
+
}
|
|
8699
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8700
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8701
|
+
}
|
|
8702
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8703
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8704
|
+
}
|
|
8705
|
+
}
|
|
8582
8706
|
let copiedOffset = 0;
|
|
8583
8707
|
let lastPosition;
|
|
8584
8708
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8591,7 +8715,7 @@
|
|
|
8591
8715
|
if (!compact) {
|
|
8592
8716
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8593
8717
|
}
|
|
8594
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8718
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8595
8719
|
await writer.closeDisk();
|
|
8596
8720
|
}
|
|
8597
8721
|
lastPosition = {
|
|
@@ -8625,7 +8749,7 @@
|
|
|
8625
8749
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8626
8750
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8627
8751
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8628
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8752
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8629
8753
|
}
|
|
8630
8754
|
regionEnds[indexEntry] = regionEnd;
|
|
8631
8755
|
}
|
|
@@ -8639,11 +8763,13 @@
|
|
|
8639
8763
|
try {
|
|
8640
8764
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8641
8765
|
} catch (error) {
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8766
|
+
if (copiedLength) {
|
|
8767
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8768
|
+
try {
|
|
8769
|
+
error.corruptedEntry = true;
|
|
8770
|
+
} catch {
|
|
8771
|
+
// ignored
|
|
8772
|
+
}
|
|
8647
8773
|
}
|
|
8648
8774
|
throw error;
|
|
8649
8775
|
} finally {
|
|
@@ -8654,11 +8780,16 @@
|
|
|
8654
8780
|
}
|
|
8655
8781
|
|
|
8656
8782
|
async function getLocalHeaderLength(reader, offset) {
|
|
8657
|
-
const headerArray =
|
|
8783
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8784
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8785
|
+
EMPTY_UINT8_ARRAY;
|
|
8658
8786
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8659
|
-
return
|
|
8787
|
+
return UNDEFINED_VALUE;
|
|
8660
8788
|
}
|
|
8661
8789
|
const headerView = getDataView(headerArray);
|
|
8790
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8791
|
+
return UNDEFINED_VALUE;
|
|
8792
|
+
}
|
|
8662
8793
|
return HEADER_SIZE +
|
|
8663
8794
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8664
8795
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9009,7 +9140,7 @@
|
|
|
9009
9140
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9010
9141
|
*/
|
|
9011
9142
|
|
|
9012
|
-
const VERSION = "2.
|
|
9143
|
+
const VERSION = "2.22.0";
|
|
9013
9144
|
|
|
9014
9145
|
/*
|
|
9015
9146
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -10122,6 +10253,7 @@
|
|
|
10122
10253
|
exports.ERR_INVALID_PASSWORD_TYPE = ERR_INVALID_PASSWORD_TYPE;
|
|
10123
10254
|
exports.ERR_INVALID_PASS_THROUGH_VALUE = ERR_INVALID_PASS_THROUGH_VALUE;
|
|
10124
10255
|
exports.ERR_INVALID_READER = ERR_INVALID_READER;
|
|
10256
|
+
exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
|
|
10125
10257
|
exports.ERR_INVALID_SIGNAL = ERR_INVALID_SIGNAL;
|
|
10126
10258
|
exports.ERR_INVALID_SIGNATURE_DATA = ERR_INVALID_SIGNATURE_DATA;
|
|
10127
10259
|
exports.ERR_INVALID_STRICTNESS = ERR_INVALID_STRICTNESS;
|