@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
|
@@ -117,6 +117,10 @@ const MIN_DATE = new Date(1980, 0, 1);
|
|
|
117
117
|
|
|
118
118
|
const UNDEFINED_VALUE = undefined;
|
|
119
119
|
const INFINITY_VALUE = Infinity;
|
|
120
|
+
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
121
|
+
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
122
|
+
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
123
|
+
|
|
120
124
|
const UNDEFINED_TYPE = "undefined";
|
|
121
125
|
const FUNCTION_TYPE = "function";
|
|
122
126
|
const OBJECT_TYPE = "object";
|
|
@@ -212,6 +216,7 @@ const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
|
|
|
212
216
|
const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
|
|
213
217
|
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
214
218
|
const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
|
|
219
|
+
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
215
220
|
const ERR_ABORTED = "The operation was aborted";
|
|
216
221
|
const ABORT_ERROR_NAME$1 = "AbortError";
|
|
217
222
|
|
|
@@ -222,6 +227,13 @@ function checkFunctionOption(value) {
|
|
|
222
227
|
return value;
|
|
223
228
|
}
|
|
224
229
|
|
|
230
|
+
function checkReaderOptionsObject(readerOptions) {
|
|
231
|
+
if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
|
|
232
|
+
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
233
|
+
}
|
|
234
|
+
return readerOptions;
|
|
235
|
+
}
|
|
236
|
+
|
|
225
237
|
function checkSignalOption(signal) {
|
|
226
238
|
if (signal && (typeof signal.addEventListener != FUNCTION_TYPE || typeof signal.aborted != BOOLEAN_TYPE)) {
|
|
227
239
|
throw new Error(ERR_INVALID_SIGNAL);
|
|
@@ -317,7 +329,6 @@ const DEFAULT_CONFIGURATION = {
|
|
|
317
329
|
workerStartupTimeout: 5000,
|
|
318
330
|
useWebWorkers: true,
|
|
319
331
|
useCompressionStream: true,
|
|
320
|
-
transferStreams: true,
|
|
321
332
|
CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
|
|
322
333
|
DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
323
334
|
};
|
|
@@ -331,8 +342,7 @@ const URI_PROPERTY_NAMES = [
|
|
|
331
342
|
];
|
|
332
343
|
const BOOLEAN_PROPERTY_NAMES = [
|
|
333
344
|
"useCompressionStream",
|
|
334
|
-
"useWebWorkers"
|
|
335
|
-
"transferStreams"
|
|
345
|
+
"useWebWorkers"
|
|
336
346
|
];
|
|
337
347
|
const NUMBER_PROPERTY_NAMES = [
|
|
338
348
|
"chunkSize",
|
|
@@ -4810,12 +4820,9 @@ const ERR_BAD_FORMAT = "File format is not recognized";
|
|
|
4810
4820
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4811
4821
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4812
4822
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4813
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4814
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4815
4823
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4816
4824
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4817
4825
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4818
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4819
4826
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4820
4827
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4821
4828
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4879,8 +4886,9 @@ class ZipReader {
|
|
|
4879
4886
|
constructor(reader, options = {}) {
|
|
4880
4887
|
Object.assign(this, {
|
|
4881
4888
|
reader: new GenericReader(reader),
|
|
4882
|
-
options,
|
|
4883
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4889
|
+
options: options || {},
|
|
4890
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4891
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4884
4892
|
});
|
|
4885
4893
|
}
|
|
4886
4894
|
|
|
@@ -4951,16 +4959,22 @@ class ZipReader {
|
|
|
4951
4959
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4952
4960
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4953
4961
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4962
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4963
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4964
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4965
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4966
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4967
|
+
}
|
|
4968
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4969
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4970
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4971
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4972
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4973
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4974
|
+
}
|
|
4975
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4976
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4961
4977
|
}
|
|
4962
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4963
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4964
4978
|
}
|
|
4965
4979
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4966
4980
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -5005,10 +5019,6 @@ class ZipReader {
|
|
|
5005
5019
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
5006
5020
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
5007
5021
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
5008
|
-
if (directoryDataOffset >= reader.size) {
|
|
5009
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
5010
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
5011
|
-
}
|
|
5012
5022
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
5013
5023
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
5014
5024
|
}
|
|
@@ -5016,52 +5026,64 @@ class ZipReader {
|
|
|
5016
5026
|
throw new Error(ERR_BAD_FORMAT);
|
|
5017
5027
|
}
|
|
5018
5028
|
let offset = 0;
|
|
5019
|
-
let directoryArray =
|
|
5029
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
5030
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
5031
|
+
EMPTY_UINT8_ARRAY;
|
|
5020
5032
|
let directoryView = getDataView(directoryArray);
|
|
5021
5033
|
if (directoryDataLength) {
|
|
5022
|
-
if (directoryArray.length < 4) {
|
|
5023
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
5024
|
-
}
|
|
5025
5034
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
5026
5035
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
5027
|
-
const storedPointsAtDirectory =
|
|
5036
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
5037
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
5028
5038
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
5029
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5039
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5040
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5041
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5042
|
+
}
|
|
5030
5043
|
let reconcile = !storedPointsAtDirectory;
|
|
5031
5044
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
5032
|
-
|
|
5033
|
-
if (
|
|
5034
|
-
reconcile = expectedPointsAtDirectory;
|
|
5035
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5045
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5046
|
+
if (!expectedPointsAtDirectory) {
|
|
5036
5047
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5037
5048
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5038
5049
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5039
5050
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5040
5051
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5052
|
+
expectedPointsAtDirectory = true;
|
|
5041
5053
|
}
|
|
5042
5054
|
}
|
|
5055
|
+
if (storedPointsAtDirectory) {
|
|
5056
|
+
reconcile = expectedPointsAtDirectory;
|
|
5057
|
+
}
|
|
5043
5058
|
}
|
|
5044
|
-
if (reconcile) {
|
|
5059
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5045
5060
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5046
5061
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5047
5062
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5048
5063
|
directoryView = getDataView(directoryArray);
|
|
5049
|
-
|
|
5050
|
-
|
|
5064
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5065
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5066
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5067
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5068
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5069
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5070
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5071
|
+
prependedDataLength += offsetDelta;
|
|
5051
5072
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5052
5073
|
} else {
|
|
5053
5074
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5057
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5058
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5059
|
-
prependedDataLength += offsetDelta;
|
|
5060
|
-
}
|
|
5075
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5076
|
+
prependedDataLength += offsetDelta;
|
|
5061
5077
|
}
|
|
5062
5078
|
}
|
|
5063
5079
|
}
|
|
5064
5080
|
}
|
|
5081
|
+
if (directoryArray.length < 4) {
|
|
5082
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5083
|
+
}
|
|
5084
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5085
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5086
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5065
5087
|
}
|
|
5066
5088
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5067
5089
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5103,8 +5125,10 @@ class ZipReader {
|
|
|
5103
5125
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5104
5126
|
}
|
|
5105
5127
|
}
|
|
5128
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5129
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5106
5130
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5107
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5131
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5108
5132
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5109
5133
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5110
5134
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5195,13 +5219,17 @@ class ZipReader {
|
|
|
5195
5219
|
if (malformedExtraField) {
|
|
5196
5220
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5197
5221
|
}
|
|
5198
|
-
fileEntry.offset
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5222
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5223
|
+
startOffset = 0;
|
|
5224
|
+
} else {
|
|
5225
|
+
fileEntry.offset += prependedDataLength;
|
|
5226
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5227
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5228
|
+
if (entryPosition < previousEntryPosition) {
|
|
5229
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5230
|
+
}
|
|
5231
|
+
previousEntryPosition = entryPosition;
|
|
5203
5232
|
}
|
|
5204
|
-
previousEntryPosition = entryPosition;
|
|
5205
5233
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5206
5234
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5207
5235
|
}
|
|
@@ -5238,12 +5266,15 @@ class ZipReader {
|
|
|
5238
5266
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5239
5267
|
});
|
|
5240
5268
|
const entry = new Entry(fileEntry);
|
|
5241
|
-
|
|
5269
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5270
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5271
|
+
}
|
|
5272
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5242
5273
|
entry.arrayBuffer = async options => {
|
|
5243
5274
|
const writer = new TransformStream();
|
|
5244
5275
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5245
5276
|
arrayBufferPromise.catch(() => { });
|
|
5246
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5277
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5247
5278
|
Object.assign({}, options, { preventClose: false }));
|
|
5248
5279
|
return arrayBufferPromise;
|
|
5249
5280
|
};
|
|
@@ -5451,8 +5482,9 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5451
5482
|
});
|
|
5452
5483
|
}
|
|
5453
5484
|
|
|
5454
|
-
async getData(writer, fileEntry,
|
|
5485
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5455
5486
|
const zipEntry = this;
|
|
5487
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5456
5488
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5457
5489
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5458
5490
|
}
|
|
@@ -5526,10 +5558,10 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5526
5558
|
}
|
|
5527
5559
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5528
5560
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5529
|
-
if (lastAccessDate) {
|
|
5561
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5530
5562
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5531
5563
|
}
|
|
5532
|
-
if (creationDate) {
|
|
5564
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5533
5565
|
fileEntry.creationDate = creationDate;
|
|
5534
5566
|
}
|
|
5535
5567
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5558,7 +5590,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5558
5590
|
throw new Error(ERR_ENCRYPTED);
|
|
5559
5591
|
}
|
|
5560
5592
|
}
|
|
5561
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5593
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5562
5594
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5563
5595
|
}
|
|
5564
5596
|
const size = compressedSize;
|
|
@@ -5624,6 +5656,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5624
5656
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5625
5657
|
readRanges
|
|
5626
5658
|
});
|
|
5659
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5627
5660
|
}
|
|
5628
5661
|
let writable, abortError, aborted;
|
|
5629
5662
|
try {
|
|
@@ -5643,10 +5676,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5643
5676
|
writer.size += writtenSize;
|
|
5644
5677
|
}
|
|
5645
5678
|
} catch (error) {
|
|
5646
|
-
|
|
5647
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5648
|
-
writer.size += failedOutputSize;
|
|
5649
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5679
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5650
5680
|
writer.size += error.outputSize;
|
|
5651
5681
|
}
|
|
5652
5682
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5674,13 +5704,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5674
5704
|
};
|
|
5675
5705
|
|
|
5676
5706
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5677
|
-
|
|
5678
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5679
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5680
|
-
return true;
|
|
5681
|
-
}
|
|
5682
|
-
}
|
|
5683
|
-
return false;
|
|
5707
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5684
5708
|
}
|
|
5685
5709
|
|
|
5686
5710
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5717,6 +5741,46 @@ async function findDigitalSignatureRecordOffset(reader, endOffset) {
|
|
|
5717
5741
|
}
|
|
5718
5742
|
}
|
|
5719
5743
|
|
|
5744
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5745
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5746
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5747
|
+
const tailView = getDataView(tailArray);
|
|
5748
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5749
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5750
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5751
|
+
return startOffset + indexByte;
|
|
5752
|
+
}
|
|
5753
|
+
}
|
|
5754
|
+
}
|
|
5755
|
+
|
|
5756
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5757
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5758
|
+
return UNDEFINED_VALUE;
|
|
5759
|
+
}
|
|
5760
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5761
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5762
|
+
return localHeaderOffset;
|
|
5763
|
+
}
|
|
5764
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5765
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5766
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5767
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5768
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5769
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5770
|
+
let offsetValue = offsetExtraField + 4;
|
|
5771
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5772
|
+
offsetValue += 8;
|
|
5773
|
+
}
|
|
5774
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5775
|
+
offsetValue += 8;
|
|
5776
|
+
}
|
|
5777
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5778
|
+
}
|
|
5779
|
+
offsetExtraField += 4 + size;
|
|
5780
|
+
}
|
|
5781
|
+
return UNDEFINED_VALUE;
|
|
5782
|
+
}
|
|
5783
|
+
|
|
5720
5784
|
function readDigitalSignature(signatureRecordArray) {
|
|
5721
5785
|
if (signatureRecordArray.length >= 6) {
|
|
5722
5786
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5806,6 +5870,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5806
5870
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5807
5871
|
});
|
|
5808
5872
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5873
|
+
let extraFieldZip64Missing;
|
|
5809
5874
|
if (extraFieldZip64) {
|
|
5810
5875
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5811
5876
|
malformedExtraField = true;
|
|
@@ -5815,7 +5880,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5815
5880
|
if (localDirectory) {
|
|
5816
5881
|
malformedExtraField = true;
|
|
5817
5882
|
} else {
|
|
5818
|
-
|
|
5883
|
+
extraFieldZip64Missing = true;
|
|
5819
5884
|
}
|
|
5820
5885
|
}
|
|
5821
5886
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5873,6 +5938,9 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5873
5938
|
if (extraFieldUSDZ) {
|
|
5874
5939
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5875
5940
|
}
|
|
5941
|
+
if (extraFieldZip64Missing) {
|
|
5942
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5943
|
+
}
|
|
5876
5944
|
return malformedExtraField;
|
|
5877
5945
|
}
|
|
5878
5946
|
|
|
@@ -6087,13 +6155,7 @@ async function detectOverlappingEntry({
|
|
|
6087
6155
|
let dataDescriptorLength = 0;
|
|
6088
6156
|
if (dataDescriptor) {
|
|
6089
6157
|
const zip64 = Boolean(extraFieldZip64);
|
|
6090
|
-
const
|
|
6091
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6092
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6093
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6094
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6095
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6096
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6158
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6097
6159
|
if (localDataDescriptor) {
|
|
6098
6160
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6099
6161
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6163,6 +6225,25 @@ function mergeRanges(sortedRanges, pendingRanges) {
|
|
|
6163
6225
|
return mergedRanges;
|
|
6164
6226
|
}
|
|
6165
6227
|
|
|
6228
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6229
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6230
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6231
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6232
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6233
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6234
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6235
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6236
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6237
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6238
|
+
}
|
|
6239
|
+
|
|
6240
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6241
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6242
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6243
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6244
|
+
}
|
|
6245
|
+
}
|
|
6246
|
+
|
|
6166
6247
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6167
6248
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6168
6249
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6422,6 +6503,18 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
|
|
|
6422
6503
|
}
|
|
6423
6504
|
}
|
|
6424
6505
|
|
|
6506
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6507
|
+
const { dataDescriptor } = localDirectory;
|
|
6508
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6509
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6510
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6511
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6512
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6513
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6514
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6515
|
+
}
|
|
6516
|
+
}
|
|
6517
|
+
|
|
6425
6518
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6426
6519
|
if (reject) {
|
|
6427
6520
|
throwAmbiguousArchive(reason);
|
|
@@ -6524,6 +6617,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6524
6617
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6525
6618
|
ZipReader: ZipReader,
|
|
6526
6619
|
ZipReaderStream: ZipReaderStream,
|
|
6620
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6527
6621
|
isZipFile: isZipFile
|
|
6528
6622
|
});
|
|
6529
6623
|
|
|
@@ -6647,136 +6741,7 @@ class ZipWriter {
|
|
|
6647
6741
|
}
|
|
6648
6742
|
|
|
6649
6743
|
appendZip(reader, options = {}) {
|
|
6650
|
-
return watchPromiseError(this,
|
|
6651
|
-
}
|
|
6652
|
-
|
|
6653
|
-
async appendZipEntries(reader, options = {}) {
|
|
6654
|
-
const zipWriter = this;
|
|
6655
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6656
|
-
const filter = checkFunctionOption(options.filter);
|
|
6657
|
-
while (pendingAddFileCalls.size) {
|
|
6658
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6659
|
-
}
|
|
6660
|
-
let resolveAppendZip;
|
|
6661
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6662
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6663
|
-
const appendedFilenames = [];
|
|
6664
|
-
let releaseLockWriter;
|
|
6665
|
-
try {
|
|
6666
|
-
reader = new GenericReader(reader);
|
|
6667
|
-
await initStream(reader);
|
|
6668
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6669
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6670
|
-
await initStream(reader);
|
|
6671
|
-
}
|
|
6672
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6673
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6674
|
-
const entries = await zipReader$1.getEntries();
|
|
6675
|
-
const keptEntries = [];
|
|
6676
|
-
for (const entry of entries) {
|
|
6677
|
-
if (!filter || await filter(entry)) {
|
|
6678
|
-
keptEntries.push(entry);
|
|
6679
|
-
}
|
|
6680
|
-
}
|
|
6681
|
-
await zipReader$1.close();
|
|
6682
|
-
await initStream(zipWriter.writer);
|
|
6683
|
-
const { directoryOffset } = zipReader$1;
|
|
6684
|
-
keptEntries.forEach(({ filename }) => {
|
|
6685
|
-
if (filenames.has(filename)) {
|
|
6686
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6687
|
-
}
|
|
6688
|
-
filenames.add(filename);
|
|
6689
|
-
appendedFilenames.push(filename);
|
|
6690
|
-
});
|
|
6691
|
-
zipWriter.writerLocked = true;
|
|
6692
|
-
const { lockWriter } = zipWriter;
|
|
6693
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6694
|
-
zipWriter.writerLocked = false;
|
|
6695
|
-
resolve();
|
|
6696
|
-
});
|
|
6697
|
-
await lockWriter;
|
|
6698
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6699
|
-
delete zipWriter.addSplitZipSignature;
|
|
6700
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6701
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6702
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6703
|
-
}
|
|
6704
|
-
}
|
|
6705
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6706
|
-
keptEntries.forEach(entry => {
|
|
6707
|
-
const {
|
|
6708
|
-
version,
|
|
6709
|
-
rawLastModDate,
|
|
6710
|
-
rawFilename,
|
|
6711
|
-
bitFlag,
|
|
6712
|
-
encrypted,
|
|
6713
|
-
uncompressedSize,
|
|
6714
|
-
compressedSize,
|
|
6715
|
-
extraFieldZip64
|
|
6716
|
-
} = entry;
|
|
6717
|
-
let {
|
|
6718
|
-
compressionMethod,
|
|
6719
|
-
rawExtraField,
|
|
6720
|
-
} = entry;
|
|
6721
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6722
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6723
|
-
if (entry.extraFieldAES) {
|
|
6724
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6725
|
-
}
|
|
6726
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6727
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6728
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6729
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6730
|
-
const {
|
|
6731
|
-
headerArray,
|
|
6732
|
-
headerView
|
|
6733
|
-
} = getHeaderArrayData({
|
|
6734
|
-
version,
|
|
6735
|
-
bitFlag: bitFlagValue,
|
|
6736
|
-
compressionMethod,
|
|
6737
|
-
uncompressedSize,
|
|
6738
|
-
compressedSize,
|
|
6739
|
-
rawLastModDate,
|
|
6740
|
-
rawFilename,
|
|
6741
|
-
zip64CompressedSize,
|
|
6742
|
-
zip64UncompressedSize,
|
|
6743
|
-
extraFieldLength
|
|
6744
|
-
});
|
|
6745
|
-
const { crc32 } = entry;
|
|
6746
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6747
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6748
|
-
}
|
|
6749
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6750
|
-
Object.assign(entry, {
|
|
6751
|
-
zip64Enabled: true,
|
|
6752
|
-
zip64UncompressedSize,
|
|
6753
|
-
zip64CompressedSize,
|
|
6754
|
-
offset,
|
|
6755
|
-
diskNumberStart,
|
|
6756
|
-
zip64DiskNumberStart: false,
|
|
6757
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6758
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6759
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6760
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6761
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6762
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6763
|
-
rawExtraField,
|
|
6764
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6765
|
-
headerArray,
|
|
6766
|
-
headerView
|
|
6767
|
-
});
|
|
6768
|
-
fileEntries.set(entry.filename, entry);
|
|
6769
|
-
});
|
|
6770
|
-
} catch (error) {
|
|
6771
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6772
|
-
throw error;
|
|
6773
|
-
} finally {
|
|
6774
|
-
resolveAppendZip();
|
|
6775
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6776
|
-
if (releaseLockWriter) {
|
|
6777
|
-
releaseLockWriter();
|
|
6778
|
-
}
|
|
6779
|
-
}
|
|
6744
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6780
6745
|
}
|
|
6781
6746
|
|
|
6782
6747
|
add(name = "", reader, options = {}) {
|
|
@@ -6938,11 +6903,149 @@ function watchPromiseError(zipWriter, promise) {
|
|
|
6938
6903
|
return watchedPromise;
|
|
6939
6904
|
}
|
|
6940
6905
|
|
|
6906
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6907
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6908
|
+
const filter = checkFunctionOption(options.filter);
|
|
6909
|
+
const readerOptions = checkReaderOptionsObject(options.readerOptions);
|
|
6910
|
+
while (pendingAddFileCalls.size) {
|
|
6911
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6912
|
+
}
|
|
6913
|
+
let resolveAppendZip;
|
|
6914
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6915
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6916
|
+
const appendedFilenames = [];
|
|
6917
|
+
let releaseLockWriter;
|
|
6918
|
+
try {
|
|
6919
|
+
reader = new GenericReader(reader);
|
|
6920
|
+
await initStream(reader);
|
|
6921
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6922
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6923
|
+
await initStream(reader);
|
|
6924
|
+
}
|
|
6925
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6926
|
+
const zipReader$1 = new ZipReader(reader, readerOptions);
|
|
6927
|
+
const keptEntries = [];
|
|
6928
|
+
let entries;
|
|
6929
|
+
try {
|
|
6930
|
+
entries = await zipReader$1.getEntries();
|
|
6931
|
+
for (const entry of entries) {
|
|
6932
|
+
if (!filter || await filter(entry, getExistingEntry(fileEntries, entry.filename))) {
|
|
6933
|
+
keptEntries.push(entry);
|
|
6934
|
+
}
|
|
6935
|
+
}
|
|
6936
|
+
} finally {
|
|
6937
|
+
await zipReader$1.close();
|
|
6938
|
+
}
|
|
6939
|
+
await initStream(zipWriter.writer);
|
|
6940
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6941
|
+
keptEntries.forEach(entry => {
|
|
6942
|
+
const { filename } = entry;
|
|
6943
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6944
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6945
|
+
}
|
|
6946
|
+
if (filenames.has(filename)) {
|
|
6947
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6948
|
+
}
|
|
6949
|
+
filenames.add(filename);
|
|
6950
|
+
appendedFilenames.push(filename);
|
|
6951
|
+
});
|
|
6952
|
+
zipWriter.writerLocked = true;
|
|
6953
|
+
const { lockWriter } = zipWriter;
|
|
6954
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6955
|
+
zipWriter.writerLocked = false;
|
|
6956
|
+
resolve();
|
|
6957
|
+
});
|
|
6958
|
+
await lockWriter;
|
|
6959
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6960
|
+
delete zipWriter.addSplitZipSignature;
|
|
6961
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6962
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6963
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6964
|
+
}
|
|
6965
|
+
}
|
|
6966
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6967
|
+
keptEntries.forEach(entry => {
|
|
6968
|
+
const {
|
|
6969
|
+
version,
|
|
6970
|
+
rawLastModDate,
|
|
6971
|
+
rawFilename,
|
|
6972
|
+
rawBitFlag,
|
|
6973
|
+
uncompressedSize,
|
|
6974
|
+
compressedSize,
|
|
6975
|
+
extraFieldZip64
|
|
6976
|
+
} = entry;
|
|
6977
|
+
let {
|
|
6978
|
+
compressionMethod,
|
|
6979
|
+
rawExtraField,
|
|
6980
|
+
} = entry;
|
|
6981
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6982
|
+
if (entry.extraFieldAES) {
|
|
6983
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6984
|
+
}
|
|
6985
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6986
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6987
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6988
|
+
const {
|
|
6989
|
+
headerArray,
|
|
6990
|
+
headerView
|
|
6991
|
+
} = getHeaderArrayData({
|
|
6992
|
+
version,
|
|
6993
|
+
bitFlag: rawBitFlag,
|
|
6994
|
+
compressionMethod,
|
|
6995
|
+
uncompressedSize,
|
|
6996
|
+
compressedSize,
|
|
6997
|
+
rawLastModDate,
|
|
6998
|
+
rawFilename,
|
|
6999
|
+
zip64CompressedSize,
|
|
7000
|
+
zip64UncompressedSize,
|
|
7001
|
+
extraFieldLength
|
|
7002
|
+
});
|
|
7003
|
+
const { crc32 } = entry;
|
|
7004
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
7005
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
7006
|
+
}
|
|
7007
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
7008
|
+
fileEntries.set(entry.filename, Object.assign({}, entry, {
|
|
7009
|
+
zip64Enabled: true,
|
|
7010
|
+
zip64UncompressedSize,
|
|
7011
|
+
zip64CompressedSize,
|
|
7012
|
+
offset,
|
|
7013
|
+
diskNumberStart,
|
|
7014
|
+
zip64DiskNumberStart: false,
|
|
7015
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
7016
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
7017
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
7018
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
7019
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
7020
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
7021
|
+
rawExtraField,
|
|
7022
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
7023
|
+
headerArray,
|
|
7024
|
+
headerView
|
|
7025
|
+
}));
|
|
7026
|
+
});
|
|
7027
|
+
} catch (error) {
|
|
7028
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
7029
|
+
throw error;
|
|
7030
|
+
} finally {
|
|
7031
|
+
resolveAppendZip();
|
|
7032
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
7033
|
+
if (releaseLockWriter) {
|
|
7034
|
+
releaseLockWriter();
|
|
7035
|
+
}
|
|
7036
|
+
}
|
|
7037
|
+
}
|
|
7038
|
+
|
|
7039
|
+
function getExistingEntry(fileEntries, filename) {
|
|
7040
|
+
const fileEntry = fileEntries.get(filename);
|
|
7041
|
+
return fileEntry ? new Entry(fileEntry) : UNDEFINED_VALUE;
|
|
7042
|
+
}
|
|
7043
|
+
|
|
6941
7044
|
async function prependZipEntries(zipWriter, reader) {
|
|
6942
7045
|
if (zipWriter.filenames.size) {
|
|
6943
7046
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6944
7047
|
}
|
|
6945
|
-
await
|
|
7048
|
+
await appendZipEntries(zipWriter, reader);
|
|
6946
7049
|
}
|
|
6947
7050
|
|
|
6948
7051
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8714,7 +8817,7 @@ function removeExtraFieldZip64(rawExtraField) {
|
|
|
8714
8817
|
return rawExtraField;
|
|
8715
8818
|
}
|
|
8716
8819
|
|
|
8717
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8820
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8718
8821
|
const { writer } = zipWriter;
|
|
8719
8822
|
const entryPositions = new Map();
|
|
8720
8823
|
if (writer.closeDisk || compact) {
|
|
@@ -8722,6 +8825,27 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8722
8825
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8723
8826
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8724
8827
|
const keptEntrySet = new Set(keptEntries);
|
|
8828
|
+
const localHeaderLengths = new Map();
|
|
8829
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8830
|
+
const entry = sortedEntries[indexEntry];
|
|
8831
|
+
if (keptEntrySet.has(entry)) {
|
|
8832
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8833
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8834
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8835
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8836
|
+
}
|
|
8837
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8838
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8839
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8840
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8841
|
+
}
|
|
8842
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8843
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8844
|
+
}
|
|
8845
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8846
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8847
|
+
}
|
|
8848
|
+
}
|
|
8725
8849
|
let copiedOffset = 0;
|
|
8726
8850
|
let lastPosition;
|
|
8727
8851
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8734,7 +8858,7 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8734
8858
|
if (!compact) {
|
|
8735
8859
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8736
8860
|
}
|
|
8737
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8861
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8738
8862
|
await writer.closeDisk();
|
|
8739
8863
|
}
|
|
8740
8864
|
lastPosition = {
|
|
@@ -8768,7 +8892,7 @@ function getRegionEnds(reader, sortedEntries, directoryOffset) {
|
|
|
8768
8892
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8769
8893
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8770
8894
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8771
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8895
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8772
8896
|
}
|
|
8773
8897
|
regionEnds[indexEntry] = regionEnd;
|
|
8774
8898
|
}
|
|
@@ -8782,11 +8906,13 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8782
8906
|
try {
|
|
8783
8907
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8784
8908
|
} catch (error) {
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
|
|
8789
|
-
|
|
8909
|
+
if (copiedLength) {
|
|
8910
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8911
|
+
try {
|
|
8912
|
+
error.corruptedEntry = true;
|
|
8913
|
+
} catch {
|
|
8914
|
+
// ignored
|
|
8915
|
+
}
|
|
8790
8916
|
}
|
|
8791
8917
|
throw error;
|
|
8792
8918
|
} finally {
|
|
@@ -8797,11 +8923,16 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8797
8923
|
}
|
|
8798
8924
|
|
|
8799
8925
|
async function getLocalHeaderLength(reader, offset) {
|
|
8800
|
-
const headerArray =
|
|
8926
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8927
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8928
|
+
EMPTY_UINT8_ARRAY;
|
|
8801
8929
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8802
|
-
return
|
|
8930
|
+
return UNDEFINED_VALUE;
|
|
8803
8931
|
}
|
|
8804
8932
|
const headerView = getDataView(headerArray);
|
|
8933
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8934
|
+
return UNDEFINED_VALUE;
|
|
8935
|
+
}
|
|
8805
8936
|
return HEADER_SIZE +
|
|
8806
8937
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8807
8938
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9152,7 +9283,7 @@ function formatSupported(StreamClass, format) {
|
|
|
9152
9283
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9153
9284
|
*/
|
|
9154
9285
|
|
|
9155
|
-
const VERSION = "2.
|
|
9286
|
+
const VERSION = "2.22.0";
|
|
9156
9287
|
|
|
9157
9288
|
/*
|
|
9158
9289
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -10199,7 +10330,6 @@ const DUPLICATES_KEEP_FIRST = "keep-first";
|
|
|
10199
10330
|
const DUPLICATES_KEEP_LAST = "keep-last";
|
|
10200
10331
|
const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
|
|
10201
10332
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
10202
|
-
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
10203
10333
|
const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
|
|
10204
10334
|
const ERR_INVALID_PASSWORDS = "Invalid passwords option (must be an array of strings)";
|
|
10205
10335
|
const ERR_INVALID_REQUEST_PASSWORD = "Invalid requestPassword option (must be a function returning a string or undefined)";
|
|
@@ -11125,9 +11255,7 @@ function getDeterminedSize(child, passThrough) {
|
|
|
11125
11255
|
}
|
|
11126
11256
|
|
|
11127
11257
|
function checkReaderOptions(readerOptions) {
|
|
11128
|
-
|
|
11129
|
-
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
11130
|
-
}
|
|
11258
|
+
checkReaderOptionsObject(readerOptions);
|
|
11131
11259
|
if (readerOptions) {
|
|
11132
11260
|
checkPassThroughValue(readerOptions.passThrough);
|
|
11133
11261
|
checkPasswordCandidatesOptions(readerOptions);
|