@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/index-native.cjs
CHANGED
|
@@ -120,6 +120,10 @@ const MIN_DATE = new Date(1980, 0, 1);
|
|
|
120
120
|
|
|
121
121
|
const UNDEFINED_VALUE = undefined;
|
|
122
122
|
const INFINITY_VALUE = Infinity;
|
|
123
|
+
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
124
|
+
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
125
|
+
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
126
|
+
|
|
123
127
|
const UNDEFINED_TYPE = "undefined";
|
|
124
128
|
const FUNCTION_TYPE = "function";
|
|
125
129
|
const OBJECT_TYPE = "object";
|
|
@@ -215,6 +219,7 @@ const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
|
|
|
215
219
|
const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
|
|
216
220
|
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
217
221
|
const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
|
|
222
|
+
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
218
223
|
const ERR_ABORTED = "The operation was aborted";
|
|
219
224
|
const ABORT_ERROR_NAME$1 = "AbortError";
|
|
220
225
|
|
|
@@ -225,6 +230,13 @@ function checkFunctionOption(value) {
|
|
|
225
230
|
return value;
|
|
226
231
|
}
|
|
227
232
|
|
|
233
|
+
function checkReaderOptionsObject(readerOptions) {
|
|
234
|
+
if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
|
|
235
|
+
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
236
|
+
}
|
|
237
|
+
return readerOptions;
|
|
238
|
+
}
|
|
239
|
+
|
|
228
240
|
function checkSignalOption(signal) {
|
|
229
241
|
if (signal && (typeof signal.addEventListener != FUNCTION_TYPE || typeof signal.aborted != BOOLEAN_TYPE)) {
|
|
230
242
|
throw new Error(ERR_INVALID_SIGNAL);
|
|
@@ -320,7 +332,6 @@ const DEFAULT_CONFIGURATION = {
|
|
|
320
332
|
workerStartupTimeout: 5000,
|
|
321
333
|
useWebWorkers: true,
|
|
322
334
|
useCompressionStream: true,
|
|
323
|
-
transferStreams: true,
|
|
324
335
|
CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
|
|
325
336
|
DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
326
337
|
};
|
|
@@ -334,8 +345,7 @@ const URI_PROPERTY_NAMES = [
|
|
|
334
345
|
];
|
|
335
346
|
const BOOLEAN_PROPERTY_NAMES = [
|
|
336
347
|
"useCompressionStream",
|
|
337
|
-
"useWebWorkers"
|
|
338
|
-
"transferStreams"
|
|
348
|
+
"useWebWorkers"
|
|
339
349
|
];
|
|
340
350
|
const NUMBER_PROPERTY_NAMES = [
|
|
341
351
|
"chunkSize",
|
|
@@ -4771,12 +4781,9 @@ const ERR_BAD_FORMAT = "File format is not recognized";
|
|
|
4771
4781
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4772
4782
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4773
4783
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4774
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4775
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4776
4784
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4777
4785
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4778
4786
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4779
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4780
4787
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4781
4788
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4782
4789
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4840,8 +4847,9 @@ class ZipReader {
|
|
|
4840
4847
|
constructor(reader, options = {}) {
|
|
4841
4848
|
Object.assign(this, {
|
|
4842
4849
|
reader: new GenericReader(reader),
|
|
4843
|
-
options,
|
|
4844
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4850
|
+
options: options || {},
|
|
4851
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4852
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4845
4853
|
});
|
|
4846
4854
|
}
|
|
4847
4855
|
|
|
@@ -4912,16 +4920,22 @@ class ZipReader {
|
|
|
4912
4920
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4913
4921
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4914
4922
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4923
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4924
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4925
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4926
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4927
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4928
|
+
}
|
|
4929
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4930
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4931
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4932
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4933
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4934
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4935
|
+
}
|
|
4936
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4937
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4922
4938
|
}
|
|
4923
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4924
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4925
4939
|
}
|
|
4926
4940
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4927
4941
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4966,10 +4980,6 @@ class ZipReader {
|
|
|
4966
4980
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4967
4981
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4968
4982
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4969
|
-
if (directoryDataOffset >= reader.size) {
|
|
4970
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4971
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4972
|
-
}
|
|
4973
4983
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4974
4984
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4975
4985
|
}
|
|
@@ -4977,52 +4987,64 @@ class ZipReader {
|
|
|
4977
4987
|
throw new Error(ERR_BAD_FORMAT);
|
|
4978
4988
|
}
|
|
4979
4989
|
let offset = 0;
|
|
4980
|
-
let directoryArray =
|
|
4990
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4991
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4992
|
+
EMPTY_UINT8_ARRAY;
|
|
4981
4993
|
let directoryView = getDataView(directoryArray);
|
|
4982
4994
|
if (directoryDataLength) {
|
|
4983
|
-
if (directoryArray.length < 4) {
|
|
4984
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4985
|
-
}
|
|
4986
4995
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4987
4996
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4988
|
-
const storedPointsAtDirectory =
|
|
4997
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
4998
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4989
4999
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4990
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5000
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5001
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5002
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5003
|
+
}
|
|
4991
5004
|
let reconcile = !storedPointsAtDirectory;
|
|
4992
5005
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4993
|
-
|
|
4994
|
-
if (
|
|
4995
|
-
reconcile = expectedPointsAtDirectory;
|
|
4996
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5006
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5007
|
+
if (!expectedPointsAtDirectory) {
|
|
4997
5008
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
4998
5009
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
4999
5010
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5000
5011
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5001
5012
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5013
|
+
expectedPointsAtDirectory = true;
|
|
5002
5014
|
}
|
|
5003
5015
|
}
|
|
5016
|
+
if (storedPointsAtDirectory) {
|
|
5017
|
+
reconcile = expectedPointsAtDirectory;
|
|
5018
|
+
}
|
|
5004
5019
|
}
|
|
5005
|
-
if (reconcile) {
|
|
5020
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5006
5021
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5007
5022
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5008
5023
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5009
5024
|
directoryView = getDataView(directoryArray);
|
|
5010
|
-
|
|
5011
|
-
|
|
5025
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5026
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5027
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5028
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5029
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5030
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5031
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5032
|
+
prependedDataLength += offsetDelta;
|
|
5012
5033
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5013
5034
|
} else {
|
|
5014
5035
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5018
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5019
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5020
|
-
prependedDataLength += offsetDelta;
|
|
5021
|
-
}
|
|
5036
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5037
|
+
prependedDataLength += offsetDelta;
|
|
5022
5038
|
}
|
|
5023
5039
|
}
|
|
5024
5040
|
}
|
|
5025
5041
|
}
|
|
5042
|
+
if (directoryArray.length < 4) {
|
|
5043
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5044
|
+
}
|
|
5045
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5046
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5047
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5026
5048
|
}
|
|
5027
5049
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5028
5050
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5064,8 +5086,10 @@ class ZipReader {
|
|
|
5064
5086
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5065
5087
|
}
|
|
5066
5088
|
}
|
|
5089
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5090
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5067
5091
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5068
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5092
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5069
5093
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5070
5094
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5071
5095
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5156,13 +5180,17 @@ class ZipReader {
|
|
|
5156
5180
|
if (malformedExtraField) {
|
|
5157
5181
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5158
5182
|
}
|
|
5159
|
-
fileEntry.offset
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5183
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5184
|
+
startOffset = 0;
|
|
5185
|
+
} else {
|
|
5186
|
+
fileEntry.offset += prependedDataLength;
|
|
5187
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5188
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5189
|
+
if (entryPosition < previousEntryPosition) {
|
|
5190
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5191
|
+
}
|
|
5192
|
+
previousEntryPosition = entryPosition;
|
|
5164
5193
|
}
|
|
5165
|
-
previousEntryPosition = entryPosition;
|
|
5166
5194
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5167
5195
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5168
5196
|
}
|
|
@@ -5199,12 +5227,15 @@ class ZipReader {
|
|
|
5199
5227
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5200
5228
|
});
|
|
5201
5229
|
const entry = new Entry(fileEntry);
|
|
5202
|
-
|
|
5230
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5231
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5232
|
+
}
|
|
5233
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5203
5234
|
entry.arrayBuffer = async options => {
|
|
5204
5235
|
const writer = new TransformStream();
|
|
5205
5236
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5206
5237
|
arrayBufferPromise.catch(() => { });
|
|
5207
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5238
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5208
5239
|
Object.assign({}, options, { preventClose: false }));
|
|
5209
5240
|
return arrayBufferPromise;
|
|
5210
5241
|
};
|
|
@@ -5412,8 +5443,9 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5412
5443
|
});
|
|
5413
5444
|
}
|
|
5414
5445
|
|
|
5415
|
-
async getData(writer, fileEntry,
|
|
5446
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5416
5447
|
const zipEntry = this;
|
|
5448
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5417
5449
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5418
5450
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5419
5451
|
}
|
|
@@ -5487,10 +5519,10 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5487
5519
|
}
|
|
5488
5520
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5489
5521
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5490
|
-
if (lastAccessDate) {
|
|
5522
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5491
5523
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5492
5524
|
}
|
|
5493
|
-
if (creationDate) {
|
|
5525
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5494
5526
|
fileEntry.creationDate = creationDate;
|
|
5495
5527
|
}
|
|
5496
5528
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5519,7 +5551,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5519
5551
|
throw new Error(ERR_ENCRYPTED);
|
|
5520
5552
|
}
|
|
5521
5553
|
}
|
|
5522
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5554
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5523
5555
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5524
5556
|
}
|
|
5525
5557
|
const size = compressedSize;
|
|
@@ -5585,6 +5617,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5585
5617
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5586
5618
|
readRanges
|
|
5587
5619
|
});
|
|
5620
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5588
5621
|
}
|
|
5589
5622
|
let writable, abortError, aborted;
|
|
5590
5623
|
try {
|
|
@@ -5604,10 +5637,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5604
5637
|
writer.size += writtenSize;
|
|
5605
5638
|
}
|
|
5606
5639
|
} catch (error) {
|
|
5607
|
-
|
|
5608
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5609
|
-
writer.size += failedOutputSize;
|
|
5610
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5640
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5611
5641
|
writer.size += error.outputSize;
|
|
5612
5642
|
}
|
|
5613
5643
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5635,13 +5665,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5635
5665
|
};
|
|
5636
5666
|
|
|
5637
5667
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5638
|
-
|
|
5639
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5640
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5641
|
-
return true;
|
|
5642
|
-
}
|
|
5643
|
-
}
|
|
5644
|
-
return false;
|
|
5668
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5645
5669
|
}
|
|
5646
5670
|
|
|
5647
5671
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5678,6 +5702,46 @@ async function findDigitalSignatureRecordOffset(reader, endOffset) {
|
|
|
5678
5702
|
}
|
|
5679
5703
|
}
|
|
5680
5704
|
|
|
5705
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5706
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5707
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5708
|
+
const tailView = getDataView(tailArray);
|
|
5709
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5710
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5711
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5712
|
+
return startOffset + indexByte;
|
|
5713
|
+
}
|
|
5714
|
+
}
|
|
5715
|
+
}
|
|
5716
|
+
|
|
5717
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5718
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5719
|
+
return UNDEFINED_VALUE;
|
|
5720
|
+
}
|
|
5721
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5722
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5723
|
+
return localHeaderOffset;
|
|
5724
|
+
}
|
|
5725
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5726
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5727
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5728
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5729
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5730
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5731
|
+
let offsetValue = offsetExtraField + 4;
|
|
5732
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5733
|
+
offsetValue += 8;
|
|
5734
|
+
}
|
|
5735
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5736
|
+
offsetValue += 8;
|
|
5737
|
+
}
|
|
5738
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5739
|
+
}
|
|
5740
|
+
offsetExtraField += 4 + size;
|
|
5741
|
+
}
|
|
5742
|
+
return UNDEFINED_VALUE;
|
|
5743
|
+
}
|
|
5744
|
+
|
|
5681
5745
|
function readDigitalSignature(signatureRecordArray) {
|
|
5682
5746
|
if (signatureRecordArray.length >= 6) {
|
|
5683
5747
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5767,6 +5831,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5767
5831
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5768
5832
|
});
|
|
5769
5833
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5834
|
+
let extraFieldZip64Missing;
|
|
5770
5835
|
if (extraFieldZip64) {
|
|
5771
5836
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5772
5837
|
malformedExtraField = true;
|
|
@@ -5776,7 +5841,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5776
5841
|
if (localDirectory) {
|
|
5777
5842
|
malformedExtraField = true;
|
|
5778
5843
|
} else {
|
|
5779
|
-
|
|
5844
|
+
extraFieldZip64Missing = true;
|
|
5780
5845
|
}
|
|
5781
5846
|
}
|
|
5782
5847
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5834,6 +5899,9 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5834
5899
|
if (extraFieldUSDZ) {
|
|
5835
5900
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5836
5901
|
}
|
|
5902
|
+
if (extraFieldZip64Missing) {
|
|
5903
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5904
|
+
}
|
|
5837
5905
|
return malformedExtraField;
|
|
5838
5906
|
}
|
|
5839
5907
|
|
|
@@ -6048,13 +6116,7 @@ async function detectOverlappingEntry({
|
|
|
6048
6116
|
let dataDescriptorLength = 0;
|
|
6049
6117
|
if (dataDescriptor) {
|
|
6050
6118
|
const zip64 = Boolean(extraFieldZip64);
|
|
6051
|
-
const
|
|
6052
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6053
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6054
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6055
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6056
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6057
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6119
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6058
6120
|
if (localDataDescriptor) {
|
|
6059
6121
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6060
6122
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6124,6 +6186,25 @@ function mergeRanges(sortedRanges, pendingRanges) {
|
|
|
6124
6186
|
return mergedRanges;
|
|
6125
6187
|
}
|
|
6126
6188
|
|
|
6189
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6190
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6191
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6192
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6193
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6194
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6195
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6196
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6197
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6198
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6199
|
+
}
|
|
6200
|
+
|
|
6201
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6202
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6203
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6204
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6205
|
+
}
|
|
6206
|
+
}
|
|
6207
|
+
|
|
6127
6208
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6128
6209
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6129
6210
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6383,6 +6464,18 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
|
|
|
6383
6464
|
}
|
|
6384
6465
|
}
|
|
6385
6466
|
|
|
6467
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6468
|
+
const { dataDescriptor } = localDirectory;
|
|
6469
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6470
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6471
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6472
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6473
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6474
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6475
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6476
|
+
}
|
|
6477
|
+
}
|
|
6478
|
+
|
|
6386
6479
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6387
6480
|
if (reject) {
|
|
6388
6481
|
throwAmbiguousArchive(reason);
|
|
@@ -6485,6 +6578,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6485
6578
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6486
6579
|
ZipReader: ZipReader,
|
|
6487
6580
|
ZipReaderStream: ZipReaderStream,
|
|
6581
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6488
6582
|
isZipFile: isZipFile
|
|
6489
6583
|
});
|
|
6490
6584
|
|
|
@@ -6608,136 +6702,7 @@ class ZipWriter {
|
|
|
6608
6702
|
}
|
|
6609
6703
|
|
|
6610
6704
|
appendZip(reader, options = {}) {
|
|
6611
|
-
return watchPromiseError(this,
|
|
6612
|
-
}
|
|
6613
|
-
|
|
6614
|
-
async appendZipEntries(reader, options = {}) {
|
|
6615
|
-
const zipWriter = this;
|
|
6616
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6617
|
-
const filter = checkFunctionOption(options.filter);
|
|
6618
|
-
while (pendingAddFileCalls.size) {
|
|
6619
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6620
|
-
}
|
|
6621
|
-
let resolveAppendZip;
|
|
6622
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6623
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6624
|
-
const appendedFilenames = [];
|
|
6625
|
-
let releaseLockWriter;
|
|
6626
|
-
try {
|
|
6627
|
-
reader = new GenericReader(reader);
|
|
6628
|
-
await initStream(reader);
|
|
6629
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6630
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6631
|
-
await initStream(reader);
|
|
6632
|
-
}
|
|
6633
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6634
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6635
|
-
const entries = await zipReader$1.getEntries();
|
|
6636
|
-
const keptEntries = [];
|
|
6637
|
-
for (const entry of entries) {
|
|
6638
|
-
if (!filter || await filter(entry)) {
|
|
6639
|
-
keptEntries.push(entry);
|
|
6640
|
-
}
|
|
6641
|
-
}
|
|
6642
|
-
await zipReader$1.close();
|
|
6643
|
-
await initStream(zipWriter.writer);
|
|
6644
|
-
const { directoryOffset } = zipReader$1;
|
|
6645
|
-
keptEntries.forEach(({ filename }) => {
|
|
6646
|
-
if (filenames.has(filename)) {
|
|
6647
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6648
|
-
}
|
|
6649
|
-
filenames.add(filename);
|
|
6650
|
-
appendedFilenames.push(filename);
|
|
6651
|
-
});
|
|
6652
|
-
zipWriter.writerLocked = true;
|
|
6653
|
-
const { lockWriter } = zipWriter;
|
|
6654
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6655
|
-
zipWriter.writerLocked = false;
|
|
6656
|
-
resolve();
|
|
6657
|
-
});
|
|
6658
|
-
await lockWriter;
|
|
6659
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6660
|
-
delete zipWriter.addSplitZipSignature;
|
|
6661
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6662
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6663
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6664
|
-
}
|
|
6665
|
-
}
|
|
6666
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6667
|
-
keptEntries.forEach(entry => {
|
|
6668
|
-
const {
|
|
6669
|
-
version,
|
|
6670
|
-
rawLastModDate,
|
|
6671
|
-
rawFilename,
|
|
6672
|
-
bitFlag,
|
|
6673
|
-
encrypted,
|
|
6674
|
-
uncompressedSize,
|
|
6675
|
-
compressedSize,
|
|
6676
|
-
extraFieldZip64
|
|
6677
|
-
} = entry;
|
|
6678
|
-
let {
|
|
6679
|
-
compressionMethod,
|
|
6680
|
-
rawExtraField,
|
|
6681
|
-
} = entry;
|
|
6682
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6683
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6684
|
-
if (entry.extraFieldAES) {
|
|
6685
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6686
|
-
}
|
|
6687
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6688
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6689
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6690
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6691
|
-
const {
|
|
6692
|
-
headerArray,
|
|
6693
|
-
headerView
|
|
6694
|
-
} = getHeaderArrayData({
|
|
6695
|
-
version,
|
|
6696
|
-
bitFlag: bitFlagValue,
|
|
6697
|
-
compressionMethod,
|
|
6698
|
-
uncompressedSize,
|
|
6699
|
-
compressedSize,
|
|
6700
|
-
rawLastModDate,
|
|
6701
|
-
rawFilename,
|
|
6702
|
-
zip64CompressedSize,
|
|
6703
|
-
zip64UncompressedSize,
|
|
6704
|
-
extraFieldLength
|
|
6705
|
-
});
|
|
6706
|
-
const { crc32 } = entry;
|
|
6707
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6708
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6709
|
-
}
|
|
6710
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6711
|
-
Object.assign(entry, {
|
|
6712
|
-
zip64Enabled: true,
|
|
6713
|
-
zip64UncompressedSize,
|
|
6714
|
-
zip64CompressedSize,
|
|
6715
|
-
offset,
|
|
6716
|
-
diskNumberStart,
|
|
6717
|
-
zip64DiskNumberStart: false,
|
|
6718
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6719
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6720
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6721
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6722
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6723
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6724
|
-
rawExtraField,
|
|
6725
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6726
|
-
headerArray,
|
|
6727
|
-
headerView
|
|
6728
|
-
});
|
|
6729
|
-
fileEntries.set(entry.filename, entry);
|
|
6730
|
-
});
|
|
6731
|
-
} catch (error) {
|
|
6732
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6733
|
-
throw error;
|
|
6734
|
-
} finally {
|
|
6735
|
-
resolveAppendZip();
|
|
6736
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6737
|
-
if (releaseLockWriter) {
|
|
6738
|
-
releaseLockWriter();
|
|
6739
|
-
}
|
|
6740
|
-
}
|
|
6705
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6741
6706
|
}
|
|
6742
6707
|
|
|
6743
6708
|
add(name = "", reader, options = {}) {
|
|
@@ -6899,11 +6864,149 @@ function watchPromiseError(zipWriter, promise) {
|
|
|
6899
6864
|
return watchedPromise;
|
|
6900
6865
|
}
|
|
6901
6866
|
|
|
6867
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6868
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6869
|
+
const filter = checkFunctionOption(options.filter);
|
|
6870
|
+
const readerOptions = checkReaderOptionsObject(options.readerOptions);
|
|
6871
|
+
while (pendingAddFileCalls.size) {
|
|
6872
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6873
|
+
}
|
|
6874
|
+
let resolveAppendZip;
|
|
6875
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6876
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6877
|
+
const appendedFilenames = [];
|
|
6878
|
+
let releaseLockWriter;
|
|
6879
|
+
try {
|
|
6880
|
+
reader = new GenericReader(reader);
|
|
6881
|
+
await initStream(reader);
|
|
6882
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6883
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6884
|
+
await initStream(reader);
|
|
6885
|
+
}
|
|
6886
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6887
|
+
const zipReader$1 = new ZipReader(reader, readerOptions);
|
|
6888
|
+
const keptEntries = [];
|
|
6889
|
+
let entries;
|
|
6890
|
+
try {
|
|
6891
|
+
entries = await zipReader$1.getEntries();
|
|
6892
|
+
for (const entry of entries) {
|
|
6893
|
+
if (!filter || await filter(entry, getExistingEntry(fileEntries, entry.filename))) {
|
|
6894
|
+
keptEntries.push(entry);
|
|
6895
|
+
}
|
|
6896
|
+
}
|
|
6897
|
+
} finally {
|
|
6898
|
+
await zipReader$1.close();
|
|
6899
|
+
}
|
|
6900
|
+
await initStream(zipWriter.writer);
|
|
6901
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6902
|
+
keptEntries.forEach(entry => {
|
|
6903
|
+
const { filename } = entry;
|
|
6904
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6905
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6906
|
+
}
|
|
6907
|
+
if (filenames.has(filename)) {
|
|
6908
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6909
|
+
}
|
|
6910
|
+
filenames.add(filename);
|
|
6911
|
+
appendedFilenames.push(filename);
|
|
6912
|
+
});
|
|
6913
|
+
zipWriter.writerLocked = true;
|
|
6914
|
+
const { lockWriter } = zipWriter;
|
|
6915
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6916
|
+
zipWriter.writerLocked = false;
|
|
6917
|
+
resolve();
|
|
6918
|
+
});
|
|
6919
|
+
await lockWriter;
|
|
6920
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6921
|
+
delete zipWriter.addSplitZipSignature;
|
|
6922
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6923
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6924
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6925
|
+
}
|
|
6926
|
+
}
|
|
6927
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6928
|
+
keptEntries.forEach(entry => {
|
|
6929
|
+
const {
|
|
6930
|
+
version,
|
|
6931
|
+
rawLastModDate,
|
|
6932
|
+
rawFilename,
|
|
6933
|
+
rawBitFlag,
|
|
6934
|
+
uncompressedSize,
|
|
6935
|
+
compressedSize,
|
|
6936
|
+
extraFieldZip64
|
|
6937
|
+
} = entry;
|
|
6938
|
+
let {
|
|
6939
|
+
compressionMethod,
|
|
6940
|
+
rawExtraField,
|
|
6941
|
+
} = entry;
|
|
6942
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6943
|
+
if (entry.extraFieldAES) {
|
|
6944
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6945
|
+
}
|
|
6946
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6947
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6948
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6949
|
+
const {
|
|
6950
|
+
headerArray,
|
|
6951
|
+
headerView
|
|
6952
|
+
} = getHeaderArrayData({
|
|
6953
|
+
version,
|
|
6954
|
+
bitFlag: rawBitFlag,
|
|
6955
|
+
compressionMethod,
|
|
6956
|
+
uncompressedSize,
|
|
6957
|
+
compressedSize,
|
|
6958
|
+
rawLastModDate,
|
|
6959
|
+
rawFilename,
|
|
6960
|
+
zip64CompressedSize,
|
|
6961
|
+
zip64UncompressedSize,
|
|
6962
|
+
extraFieldLength
|
|
6963
|
+
});
|
|
6964
|
+
const { crc32 } = entry;
|
|
6965
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6966
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6967
|
+
}
|
|
6968
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6969
|
+
fileEntries.set(entry.filename, Object.assign({}, entry, {
|
|
6970
|
+
zip64Enabled: true,
|
|
6971
|
+
zip64UncompressedSize,
|
|
6972
|
+
zip64CompressedSize,
|
|
6973
|
+
offset,
|
|
6974
|
+
diskNumberStart,
|
|
6975
|
+
zip64DiskNumberStart: false,
|
|
6976
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6977
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6978
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6979
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6980
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6981
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6982
|
+
rawExtraField,
|
|
6983
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6984
|
+
headerArray,
|
|
6985
|
+
headerView
|
|
6986
|
+
}));
|
|
6987
|
+
});
|
|
6988
|
+
} catch (error) {
|
|
6989
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6990
|
+
throw error;
|
|
6991
|
+
} finally {
|
|
6992
|
+
resolveAppendZip();
|
|
6993
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6994
|
+
if (releaseLockWriter) {
|
|
6995
|
+
releaseLockWriter();
|
|
6996
|
+
}
|
|
6997
|
+
}
|
|
6998
|
+
}
|
|
6999
|
+
|
|
7000
|
+
function getExistingEntry(fileEntries, filename) {
|
|
7001
|
+
const fileEntry = fileEntries.get(filename);
|
|
7002
|
+
return fileEntry ? new Entry(fileEntry) : UNDEFINED_VALUE;
|
|
7003
|
+
}
|
|
7004
|
+
|
|
6902
7005
|
async function prependZipEntries(zipWriter, reader) {
|
|
6903
7006
|
if (zipWriter.filenames.size) {
|
|
6904
7007
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6905
7008
|
}
|
|
6906
|
-
await
|
|
7009
|
+
await appendZipEntries(zipWriter, reader);
|
|
6907
7010
|
}
|
|
6908
7011
|
|
|
6909
7012
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8675,7 +8778,7 @@ function removeExtraFieldZip64(rawExtraField) {
|
|
|
8675
8778
|
return rawExtraField;
|
|
8676
8779
|
}
|
|
8677
8780
|
|
|
8678
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8781
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8679
8782
|
const { writer } = zipWriter;
|
|
8680
8783
|
const entryPositions = new Map();
|
|
8681
8784
|
if (writer.closeDisk || compact) {
|
|
@@ -8683,6 +8786,27 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8683
8786
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8684
8787
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8685
8788
|
const keptEntrySet = new Set(keptEntries);
|
|
8789
|
+
const localHeaderLengths = new Map();
|
|
8790
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8791
|
+
const entry = sortedEntries[indexEntry];
|
|
8792
|
+
if (keptEntrySet.has(entry)) {
|
|
8793
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8794
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8795
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8796
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8797
|
+
}
|
|
8798
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8799
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8800
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8801
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8802
|
+
}
|
|
8803
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8804
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8805
|
+
}
|
|
8806
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8807
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8808
|
+
}
|
|
8809
|
+
}
|
|
8686
8810
|
let copiedOffset = 0;
|
|
8687
8811
|
let lastPosition;
|
|
8688
8812
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8695,7 +8819,7 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8695
8819
|
if (!compact) {
|
|
8696
8820
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8697
8821
|
}
|
|
8698
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8822
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8699
8823
|
await writer.closeDisk();
|
|
8700
8824
|
}
|
|
8701
8825
|
lastPosition = {
|
|
@@ -8729,7 +8853,7 @@ function getRegionEnds(reader, sortedEntries, directoryOffset) {
|
|
|
8729
8853
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8730
8854
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8731
8855
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8732
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8856
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8733
8857
|
}
|
|
8734
8858
|
regionEnds[indexEntry] = regionEnd;
|
|
8735
8859
|
}
|
|
@@ -8743,11 +8867,13 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8743
8867
|
try {
|
|
8744
8868
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8745
8869
|
} catch (error) {
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8870
|
+
if (copiedLength) {
|
|
8871
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8872
|
+
try {
|
|
8873
|
+
error.corruptedEntry = true;
|
|
8874
|
+
} catch {
|
|
8875
|
+
// ignored
|
|
8876
|
+
}
|
|
8751
8877
|
}
|
|
8752
8878
|
throw error;
|
|
8753
8879
|
} finally {
|
|
@@ -8758,11 +8884,16 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8758
8884
|
}
|
|
8759
8885
|
|
|
8760
8886
|
async function getLocalHeaderLength(reader, offset) {
|
|
8761
|
-
const headerArray =
|
|
8887
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8888
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8889
|
+
EMPTY_UINT8_ARRAY;
|
|
8762
8890
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8763
|
-
return
|
|
8891
|
+
return UNDEFINED_VALUE;
|
|
8764
8892
|
}
|
|
8765
8893
|
const headerView = getDataView(headerArray);
|
|
8894
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8895
|
+
return UNDEFINED_VALUE;
|
|
8896
|
+
}
|
|
8766
8897
|
return HEADER_SIZE +
|
|
8767
8898
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8768
8899
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9113,7 +9244,7 @@ function formatSupported(StreamClass, format) {
|
|
|
9113
9244
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9114
9245
|
*/
|
|
9115
9246
|
|
|
9116
|
-
const VERSION = "2.
|
|
9247
|
+
const VERSION = "2.22.0";
|
|
9117
9248
|
|
|
9118
9249
|
/*
|
|
9119
9250
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9642,7 +9773,6 @@ const DUPLICATES_KEEP_FIRST = "keep-first";
|
|
|
9642
9773
|
const DUPLICATES_KEEP_LAST = "keep-last";
|
|
9643
9774
|
const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
|
|
9644
9775
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
9645
|
-
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
9646
9776
|
const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
|
|
9647
9777
|
const ERR_INVALID_PASSWORDS = "Invalid passwords option (must be an array of strings)";
|
|
9648
9778
|
const ERR_INVALID_REQUEST_PASSWORD = "Invalid requestPassword option (must be a function returning a string or undefined)";
|
|
@@ -10568,9 +10698,7 @@ function getDeterminedSize(child, passThrough) {
|
|
|
10568
10698
|
}
|
|
10569
10699
|
|
|
10570
10700
|
function checkReaderOptions(readerOptions) {
|
|
10571
|
-
|
|
10572
|
-
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
10573
|
-
}
|
|
10701
|
+
checkReaderOptionsObject(readerOptions);
|
|
10574
10702
|
if (readerOptions) {
|
|
10575
10703
|
checkPassThroughValue(readerOptions.passThrough);
|
|
10576
10704
|
checkPasswordCandidatesOptions(readerOptions);
|