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